[Agda] change in handling of irrelevant parameters (bug?)

Darin Morrison dwm at cs.nott.ac.uk
Tue Mar 15 14:20:07 CET 2011


On 15 Mar 2011, at 12:35, Nils Anders Danielsson wrote:

> On 2011-03-15 12:02, Darin Morrison wrote:
>> I noticed a change in the handling of irrelevant parameters between
>> 2.2.9 and 2.2.10 which I think is beyond having irrelevant projections
>> enabled by default. [...]
> 
> I don't know too much about irrelevance, but this doesn't look good.

From the 2.2.8 release notes, it says:

>     Irrelevant arguments can only be used in irrelevant contexts.
>     Consider the following subset type:
> 
>       data Subset (A : Set) (P : A → Set) : Set where
>         _#_ : (elem : A) → .(P elem) → Subset A P
> 
>     The following two uses are fine:
> 
>       elimSubset : ∀ {A C : Set} {P} →
>                    Subset A P → ((a : A) → .(P a) → C) → C
>       elimSubset (a # p) k = k a p
> 
>       elem : {A : Set} {P : A → Set} → Subset A P → A
>       elem (x # p) = x
> 
>     However, if we try to project out the proof component, then Agda
>     complains that “variable p is declared irrelevant, so it cannot be
>     used here”:
> 
>       prjProof : ∀ {A P} (x : Subset A P) → P (elem x)
>       prjProof (a # p) = p

This restriction to using irrelevant arguments in irrelevant contexts is what I would expect and that is what seems to have been changed in the most recent release.

However, in the 2.2.10 release notes, it states the following:

>    Postulates and functions can be marked as irrelevant by prefixing
>    the name with a dot when the name is declared. Example:
> 
>      postulate
>        .irrelevant : {A : Set} → .A → A
> 
>    Irrelevant names may only be used in irrelevant positions or in
>    definitions of things which have been declared irrelevant.
> 
>    The axiom irrelevant above can be used to define a projection from
>    an irrelevant record field:
> 
>      data Subset (A : Set) (P : A → Set) : Set where
>        _#_ : (a : A) → .(P a) → Subset A P
> 
>      elem : ∀ {A P} → Subset A P → A
>      elem (a # p) = a
> 
>      .certificate : ∀ {A P} (x : Subset A P) → P (elem x)
>      certificate (a # p) = irrelevant p
> 
>    The right-hand side of certificate is relevant, so we cannot define
> 
>      certificate (a # p) = p
> 
>    (because p is irrelevant). However, certificate is declared to be
>    irrelevant, so it can use the axiom irrelevant. Furthermore the
>    first argument of the axiom is irrelevant, which means that
>    irrelevant p is well-formed.

This makes me think that in the code you posted, 'proj' should have to be marked as irrelevant to typecheck, e.g.,

  data Bool : Set where
    true : Bool
    false : Bool

  data _≡_ {A} (x : A) : A → Set where
    refl : x ≡ x

  resp : ∀ {A₁ A₂ x₁ x₂} (f : A₁ → A₂) → x₁ ≡ x₂ → f x₁ ≡ f x₂
  resp f refl = refl

  data D : Set where
    c : .Bool → D

  irr : c true ≡ c false
  irr = refl

  .proj : D → Bool
  proj (c x) = x

  bad : proj (c true) ≡ proj (c false)
  bad = resp proj irr

In this case, 'bad' would fail to type check for a more expected reason, namely that 'proj' is being used in a non-relevant position.

So maybe the problem is just that the condition mentioned in the 2.2.10 release notes is not properly enforced?

This is pretty important for me as I have a large development that relies on irrelevant fields quite heavily.  Without them, the code type-checks far too slowly to be usable.  I don't think I'm unintentionally relying on bugs in the implementation in my proofs but now I'm a little bit worried...

Cheers,
Darin



More information about the Agda mailing list