Smart Case [Re: [Agda] A puzzle with "with"]

Andreas Abel andreas.abel at ifi.lmu.de
Fri Jul 3 11:13:29 CEST 2009


Let me add my 5 cent to this discussion.

It seems that the "naive" user (for instance, me) expects that Agda  
"knows" that "bla = true" in "anotherthing" when writing

something with bla
...  | true = anotherthing

The "magic with" meets this expectation partially by rewriting the  
current goal.  However, the equation "bla = true" may be needed not  
only in the goal, but otherwhere as well.  The inspect pattern  
provides this equation as a proof which can be manipulated explicitly,  
yet inspect is complicated to use, in the general case you have to  
apply Josh Ko's pattern.  It is desirable that Agda considers "bla"  
and "true" as definitionally equal.

I have played with idea by adding rewriting to MiniAgda

   http://www.tcs.ifi.lmu.de/~abel/miniagda/

While type checking "anotherthing", the rewrite rule "bla --> true"  
may fire.

For example, this enables a simple proof of  f = f . f . f  for  
boolean functions f in MiniAgda.

data Bool : Set
{ true  : Bool
; false : Bool
}

data Id (A : Set)(a : A) : A -> Set
{ refl : Id A a a
}

-- Lemma: f x = f (f (f x))  for all f : Bool -> Bool
-- Proof by cases on x, f true, and f false
fun tripleF : (f : Bool -> Bool) -> (x : Bool) -> Id Bool (f x) (f (f  
(f x)))
{ tripleF f true = case f true
   { true -> refl Bool true
   ; false -> case f false
     { true  -> refl Bool false
     ; false -> refl Bool false
     }
   }
; tripleF f false = case f false
   { true -> case f true
     { true -> refl Bool true
     ; false -> refl Bool true
     }
   ; false -> refl Bool false
   }
}

The same proof cannot be done with "magic with", since, the equations  
like "f true = true" have to be used more than once in the goal.  [A  
proof with inspect would certainly be possible.]

Case is limited to inductive /types/ at the moment, for inductive  
families one would need a combination of "with" and rewriting.

Another example: Insertion into sorted lists.  Here I need to compare  
n and m with leq n m and in case true, I need to embed a proof of leq  
n m == true into my sorted list structure by passing it as an argument  
to scons. Since this equation holds definitionally, the proof is  
"triv"ial.  Here is an excerpt, I include the full code.

data SList : Nat -> Set
{ snil  : SList zero
; scons : (m : Nat) -> (n : Nat) -> True (leq n m)  -> SList n ->  
SList m
}

fun insert : (m : Nat) -> (n : Nat) -> SList n -> SList (max n m)
{ insert m .zero snil = scons m zero triv snil
; insert m .n (scons n k p l) = case leq n m
   { true  -> scons m n triv (scons n k p l)
   ; false -> scons n (max k m) (maxLemma k m n p (leFalse n m triv'))
                    (insert m k l)
   }
}

Adding rewriting could make Agda's with more "magic" (and more  
intuitive).  Certainly, this must have been discussed, and there are  
reasons why it has not been implemented.

Conor? Ulf?

Are there theoretical obstacles (non-termination?) or is it too  
complicated/inefficient?

Cheers,
Andreas


-------------- next part --------------
A non-text attachment was scrubbed...
Name: caseSList.ma
Type: application/octet-stream
Size: 1404 bytes
Desc: not available
Url : https://lists.chalmers.se/mailman/private/agda/attachments/20090703/e527ed5d/caseSList.obj
-------------- next part --------------



On Jun 25, 2009, at 6:40 PM, Ana Bove wrote:

> Hi,
>
> I must say I am confuse as well....
>
> let us simply consider the case were we want to insert x in (y ::  
> ys) and comp x y = Lt
>
> Then the insert function simply returns x :: y :: ys and in that eq.  
> of the sorted-insert we need to simply give a proof that Sorted  
> (x :: y :: ys).
>
> Now, if in this equation I write
>
> ......
> sorted-insert x (y ? ys) prf with Order.comp o x y
> sorted-insert x (y ? ys) prf | Lt =
> let q : Sorted (x ? y ? ys)
> q = ?
> in q
> ......
>
> then I can type check.
>
> However, if I try to do the same in the sorted-insert2 it does not!
>
> ......
> sorted-insert2 x (y ? ys) prf with inspect (Order.comp o x y)
> sorted-insert2 x (y ? ys) prf | Lt with-? p =
> let q : Sorted (x ? y ? ys)
> q = ?
> in q
> ......
>
> I get the error
>
> x ? y ? ys != insert x (y ? ys) | Order.comp o x y of type List  
> A
> when checking that the expression q has type
> Sorted (insert x (y ? ys) | Order.comp o x y)
>
> q should be the term
> sorted-cons2 x y ys prf (biimply-fwd (Order.isLtComp o x y) (symm p))
> (well, the whole let of course should not be used)
>
> And I must say I do not understand why. I never used inspect before  
> but I thought the difference with inspect was that not only gave me  
> the result I would get without inspect but also the "evidence" of  
> that result.
> But otherwise it should not matter.



More information about the Agda mailing list