[Agda] Records and irrelevant fields

Dan Doel dan.doel at gmail.com
Thu Sep 23 16:58:38 CEST 2010


On Thursday 23 September 2010 8:22:53 am Andreas Abel wrote:

> 2 looks a bit weird at first glance, but it is inessence what is
> described in Benjamin Werner's 2008 paper on proof irr.  Here, we
> never check p for refl, but always compare a and b for equality.  This
> looks like a systematic solution, but in terms of performance it could
> be cheaper to check p for refl.  Who knows?  There might be a lot of
> computation necessary to normalize p to refl, but likewise to
> normalize both a and b to check for equality.

What is the motivation for this? Is it to make

  subst P a b eq Pa = Pa

hold definitionally when a and b are definitionally equal?

> This is THE difference. ;-)

I thought some of the other rules might be different, as well. But of course, 
the systematic difference is that irrelevance in terms requires irrelevance in 
types in Pfenning's theory, and not in EPTS.

> Pfennings system is good for *proof* irrelevance only, since he has
> 
>    (x : Squash A) -> B x   isomorphic to    [x : A] -> B x

Ah, okay.

> You mean that if you had the projections (mod.T is not exactly right,
> but in essence)
> 
>    Z : mod -> mod.T
>    S : mod -> mod.T -> mod.T
>    iter : ...
> 
> Then
> 
>    Z nat_mod : Nat
>    S nat_mod : Nat -> Nat
> 
> I see, then compile-time erasure is again not possible.

Yes, something like this.

> Thanks, this shows that my idea of first-class irrefutable patterns
> and erasure is flawed.
> Indeed, it does not work:
> 
>    snd : (exist a b : Exists A B) -> B a
> 
> is illtyped.  We have to show
> 
>    (exists a b : Exists A B) |- B a : Set
> 
> which simplifies to
> 
>    [a : A], b : B a |- B a : Set
> 
> which gives a type error since a is irrelevant and cannot appear in B
> a.  (Also the context is ill-formed).
> So I should drop this idea, at least for compile-time erasure.

I should mention, I have thought that it might be useful to be able to make 
compile-time definitions. Something like:

  module Foo where
    size :c Nat
    size = 10

    vec :r Vec Nat size
    vec = ...

    Abbr :c Set -> Set
    Abbr T = ...

which sort of corresponds to extension of some global context in the obvious 
way. 'size' and 'Abbr' would only be able to appear in types or other 
irrelevant positions (which would include other compile-time definitions), and 
so, ultimately, a compiler would not have to generate any run-time code for 
them. (As another example, I suspect that for any declaration 'data T : Srt', 
we could treat T :c Srt, although I doubt that'll be a great boon to any 
compiler.)

If we were to try to translate modules with definitions like these to terms in 
a type theory, I think they would work like you were thinking. They're 
compile-time only, but they're transparent. Higher-order irrelevant terms and 
inductive types in an EPTS, by contrast, are opaque, and enforce abstraction. 
It would be the difference between:

  module Bar where
    open import Foo

    vec' :r Vec Nat size
    vec' = [1..10]

where we can, in Bar, know that size = 10, and:

  module Baz where
    open import Foo

    vec' :r Vec Nat size
    vec' = ? -- we can't hope to put anything here but Foo.vec

I believe a lot of thought has been put into these distinctions by people 
working in ML variants, and the ultimate aim there is to allow you to do 
*both*, because both are useful (and insasmuch as Agda's dependent records are 
used as first-class modules, they'd probably both be useful in Agda). But 
they're definitely different animals, and I'm not certain how to make them 
coexist in this type of framework. It may be as simple as an intermediate 
modality, though.

-- Dan


More information about the Agda mailing list