Equality on Types [Re: [Agda] Is this a bug?]

Andreas Abel andreas.abel at ifi.lmu.de
Thu May 5 10:06:01 CEST 2011


[This message concerns all that are interested in the theory and 
practice of dependently typed pattern matching...]

Hi Nisse,

If you turn the type indexed data type into its semantics, a 
parametrized datatype with equality proofs, you get:

   data _==_ {U : Set1}(A : U) : U -> Set1 where
     refl : A == A

   data Ty (A : Set) : Set1 where
     isB : (A == Bool) -> Ty A
     isN : (A == ℕ) -> Ty A

Now, there is no good reason why isN should not match against TyBool

   F : Ty Bool -> ℕ
   F (isB p) = zero
   F (isN p) = suc zero  -- match fine

All you get is an equality Bool == Nat, but you cannot use this to 
derive a contradiction.

So what is the justification that Agda refuses to match isNat against 
Type Bool in your previous message (unfortunately cut away)?

The only justification I can think of is

   "uh, if you matched isNat against Type Bool, you would get an 
equality of  Bool == Nat, but I have no means to hand it to you, so I 
report an error instead"

Also you can write:

   G : (A : Set) -> Ty A -> Ty A -> ℕ
   G .Bool (isB refl) (isB q) = zero
   G .ℕ    (isN refl) (isN q) = succ zero

and this gives a correct "match incomplete" error.

It seems that our current handling of type indices in constructors is 
not principled.  What can we do?

1. Discriminate data types and make Nat == Bool an empty type.
    This strengthens the theory, of course.
    It is not Voevodsky-compatible.

2. Not unify types during matching.  That would be consistent with the
    current view that Nat == Bool is not disprovable.

    This leads to the Coq situation:  You can match, but you
    do not get the type equalities.

3. Forbid matching that would lead to unification of types.
    That might give better error message, but feels a bit like a
    dictatorship.  Are there good programs we would exclude?

Anyway, the current situation lacks a foundation.

On 04.05.11 6:53 PM, Nils Anders Danielsson wrote:
> On 2011-05-04 17:55, Andreas Abel wrote:
>> But Nisse, should not this fail then also?
>>
>> f : (A : Set) → Type A → ℕ
>> f .Bool isBool = zero
>> f .ℕ isℕ = succ zero
>>
>> Agda does unify A with Bool in the first case. If Agda could not tell
>> apart Bool and Nat, then it could not unify A with Bool.
>
> I don't follow you. Unifying a variable and a data type doesn't strike
> me as problematic.

If you write

   g : {A : Set} -> Type A -> Type A -> A
   g isBool isNat = zero

then there are two competitors for A: you get the equations

   A == Bool
   A == Nat

There is no reason to just grab the first one.  This would only be 
justifiable if Bool == Nat was disprovable.

In the current situation, if you choose A := Bool then you get a type 
error for zero : Bool.  The proper error should be that zero is not of 
type *A*.

Cheers,
Andreas

-- 
Andreas Abel  <><      Du bist der geliebte Mensch.

Theoretical Computer Science, University of Munich
Oettingenstr. 67, D-80538 Munich, GERMANY

andreas.abel at ifi.lmu.de
http://www2.tcs.ifi.lmu.de/~abel/


More information about the Agda mailing list