agda / agda

Agda is a dependently typed programming language / interactive theorem prover.
https://wiki.portal.chalmers.se/agda/pmwiki.php
Other
2.41k stars 339 forks source link

Unhelpful `@++` errors #7189

Open lawcho opened 3 months ago

lawcho commented 3 months ago

The new polarity checker (#6385) rejects this code:

{-# OPTIONS --polarity #-}

open import Agda.Builtin.Bool
open import Agda.Builtin.Equality
open import Agda.Builtin.String
open import Agda.Builtin.List
open import Agda.Builtin.Nat

-- Hetrogenous vector
data HVec {ℓ} : List (Set ℓ) → Set ℓ where
  [] : HVec []
  _∷_ : ∀{A As} → A → HVec As → HVec (A ∷ As)

-- Names of syntax constructors of an ML-like language
data SynHead : Set where
  piTy natTy : SynHead
  lam app var : SynHead
  plus times natLit : SynHead

-- postulate rec : @++ Set → Set
module _
    (rec : @++ Set → Set) -- Use to write folds with non-Exp return type
    where

  record Exp : Set

  synArgs : SynHead → List Set
  synArgs piTy    = rec Exp ∷ rec Exp ∷ []
  synArgs natTy   = []
  synArgs lam     = String ∷ rec Exp ∷ []
  synArgs var     = String ∷ []
  synArgs app     = rec Exp ∷ rec Exp ∷ []
  synArgs natLit  = Nat ∷ []
  synArgs plus    = rec Exp ∷ rec Exp ∷ []
  synArgs times   = rec Exp ∷ rec Exp ∷ []

  record Exp where
    inductive
    field head : SynHead
    field sub-exprs : HVec (synArgs head)

I am not satisfied with Agda's error message:

/home/lawrence/pre-release/east/src/bugreport2.agda:26,3-41,42
Exp is not strictly positive, because it occurs
in an argument of a bound variable at position 0 which uses its
argument with polarity *
in the first clause
in the definition of synArgs, which occurs
                            in the second argument of HVec
                            in the definition of Exp.

I parsed this error message as:

The error message is unsatisfactory because:

N.B. I think this is a separate bug from #7188, because if I replace the module parameter with a postulate, I get a similar error:

/home/lawrence/pre-release/east/src/bugreport2.agda:26,3-41,42
Exp is not strictly positive, because it occurs
in the first argument of rec
in the first clause
in the definition of synArgs, which occurs
                            in the second argument of HVec
                            in the definition of Exp.

This error is even less satisfying, because:

My Agda version is the latest commit (4573e2d) of the un-merged PR #6385.

I'm reporting via a new issue to avoid blocking the merge (no existing code is broken).

jpoiret commented 2 months ago

I think it's rather because HVec doesn't use its index strictly postiviely, and Exp indirectly appears through that.

We don't support annotating indices with polarities, because atm we don't even know if it makes sense.

Wrt the error message, it does tell you the occurence precisely, but I agree we could also add the given polarity of the argument for each call.

lawcho commented 1 month ago

I think it's rather because HVec doesn't use its index strictly postively, and Exp indirectly appears through that.

Thanks, that makes sense.

Wrt the error message, it does tell you the occurence precisely, but I agree we could also add the given polarity of the argument for each call.

This would make it much easier to find the non-++ positions in the cycle.

In fact, the non-++ positions are the only positions the user needs to see!

So I suggest a message like:

/home/lawrence/pre-release/east/src/bsugreport2.agda:26,3-41,42
Exp is not strictly positive,
because its definition depends on the expression:
(line 43)   ...  HVec (synArgs ...) ...
                      ^^^^^^^^^^^^^
  this sub-expresssion depends on Exp,
  but is passed into the 1st argument of HVec
  which is a position with polarity *