agda / agda

Agda is a dependently typed programming language / interactive theorem prover.

Home Page:https://wiki.portal.chalmers.se/agda/pmwiki.php

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unhelpful `@++` errors

lawcho opened this issue · comments

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 ℓ)  Setwhere
  [] : 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:

  • Exp is an inductive data type
  • So Exp may only appear in its own definition at ++ positions
  • But Exp appears in its own definition at a * position, because...
    • Exp occurs in argument 0 of the bound variable rec
    • rec uses its argument 0 with polarity *

The error message is unsatisfactory because:

  • I explicitly wrote (rec : @++ Set → Set),

  • The error message contracticts this by saying

    uses its argument with polarity *
    
  • The error does not tell me where the polarity * information came from

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:

  • it does not tell me what the expected/actual polarities are
  • it has a different style compared to the other error: argument 0 vs first argument

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).

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.

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 *