Thank you guys,<div><br></div><div>There is one thing that is not clear to me yet. Actually &quot;cong (λ xs → x ∷ xs) (lem-tab-! xs)&quot; gives Agda proof that</div><div>x <span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">∷ tabulate(_!_ xs) </span><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">≡ x </span><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">∷ xs</span><br>
<br></div><div>but how Agda knows that </div><div>tabulate(_!_ (x ∷ xs)) is the same as x <span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">∷ tabulate(_!_ xs) ?</span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><br></span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">When I remove the whole cong expression and replace it with {! !} ant then try to </span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">reduce tabulate(_!_ (x ∷ xs)) to normal form (C-c C-n) it gives &quot;x ∷ tabulate ((λ {.x} → _!_ (x ∷ xs)) ∘ fsuc)&quot;</span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><br></span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">How to know that it can evaluate it to &quot;x ∷ tabulate(_!_ xs)&quot;?</span></div>
<div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><br></span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">Thanks.</span></div>
<div><br><div class="gmail_quote">2009/11/30 Andreas Abel <span dir="ltr">&lt;<a href="mailto:andreas.abel@ifi.lmu.de">andreas.abel@ifi.lmu.de</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Julian is correct that in this case the EqReasoning is not necessary.  If you look at the justifications I use in this equality chain<br>
<br>
 begin<br>
    tabulate (_!_ (x ∷ xs))<br>
  ≡⟨ refl ⟩<br>
    (x ∷ xs) ! zero ∷ tabulate (λ i → (x ∷ xs) ! (suc i))<br>
  ≡⟨ refl ⟩<br>
    x ∷ tabulate (λ i → xs ! i)<br>
  ≡⟨ cong (λ xs → x ∷ xs) (lem-tab-! xs) ⟩<br>
    x ∷ xs<br>
  ∎<br>
<br>
the first two steps are justified by &quot;refl&quot; which means they do not need a justification, they follow by computation (unfolding of definitions).  Only the last step needs a non-trivial justification, a call to the induction hypothesis at position x ∷ _. &quot;cong&quot; has the role of telling which subterm should be rewritten by the induction hypothesis.<br>

<br>
Since there is only one non-trivial step, the equality chain can be collapsed into Julian&#39;s single-step proof.  Equality chains are made for reasoning involving transitivity.  I, however, find then also nice to document the proof in a human-readable way.  Instead of doing the calculation on paper, I did it directly in Agda, using EqReasoning as notation.<br>

<br>
Cheers,<br><font color="#888888">
Andreas</font><div><div></div><div class="h5"><br>
<br>
On Nov 30, 2009, at 9:53 AM, Julian Beaumont wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It&#39;s worth pointing out that you can do this fairly simply without<br>
using EqReasoning. The downside is that the proof is generally less<br>
readable. Agda will reduce all functions using the definitions as much<br>
as possible for you. In the inductive case this means the goal is<br>
simplified to proving x :: tabulate (_!_ xs) == x :: xs. This may be<br>
proven trivially using cong and a recursive call to lem-tab-!.<br>
<br>
cong : {A B : Set} {x y : A} (f : A -&gt; B) -&gt; x == y -&gt; f x == f y<br>
cong f refl = refl<br>
<br>
lem-tab-! [] = refl<br>
lem-tab-! (x :: xs) = cong {! !} {! !} -- you should be able to fill<br>
in the blanks easily enough.<br>
<br>
In this case the version without EqReasoning is fairly readable and<br>
easy to understand, however, for more complicated equational proofs<br>
you definately want to be using EqReasoning.<br>
<br>
On Mon, Nov 30, 2009 at 4:10 PM, Paul Graphov &lt;<a href="mailto:graphov@gmail.com" target="_blank">graphov@gmail.com</a>&gt; wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It&#39;s much more complicated than I expected...<br>
Thanks a lot!<br>
2009/11/30 Andreas Abel &lt;<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a>&gt;<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Here is the file...<br>
<br>
<br>
<br>
<br>
On Nov 29, 2009, at 9:53 PM, Paul Graphov wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Yes, I am trying to do induction on xs, [] case is trivial but y::y&#39; is<br>
not for me.<br>
On paper I just substitute y::x&#39; in the definition of (_!_) and tabulate.<br>
<br>
EqReasoning looks quite difficult for me but I&#39;ll take a look, thanks.<br>
<br>
And yes, I can answer positively. But I don&#39;t see any attachment.<br>
<br>
Thanks!<br>
<br>
2009/11/29 Andreas Abel &lt;<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a>&gt;<br>
<br>
On Nov 29, 2009, at 7:47 PM, Andreas Abel wrote:<br>
<br>
<br>
On Nov 29, 2009, at 2:50 PM, Paul Graphov wrote:<br>
Now I am reading &quot;Dependently typed programming in Agda&quot; by Ulf Norell.<br>
I got stuck with exercise 2.2.b<br>
<br>
Here it is:<br>
<br>
(Nat, Fin and Vec are as usual)<br>
<br>
_!_ : {n : Nat}{A : Set} -&gt; Vec A n -&gt; Fin n -&gt; A<br>
[]        ! ()<br>
(x :: xs) ! fzero    = x<br>
(x :: xs) ! (fsuc i) = xs ! i<br>
<br>
tabulate : {n : Nat}{A : Set} -&gt; (Fin n -&gt; A) -&gt; Vec A n<br>
tabulate {zero} f = []<br>
tabulate {suc n} f = f fzero :: tabulate (f ◦ fsuc)<br>
<br>
Prove that they are indeed each other’s inverses.<br>
<br>
lem-tab-! : forall {A n} (xs : Vec A n) -&gt; tabulate (_!_ xs) == xs<br>
lem-tab-! xs = {! !}<br>
<br>
I figured out the proof on the paper but can&#39;t translate it to Agda<br>
code...<br>
<br>
Can you be more specific?  What does your paper proof look like and at<br>
which point does its implementation fail?  Or do you just want to see a<br>
solution?<br>
<br>
<br>
If you can answer the last question positively, please consult the<br>
attachment.  Basically, you need induction on xs and then equality<br>
reasoning.  The latter is greatly simplified by the module EqReasoning in<br>
the standard library, if you know the right incantations to set it up,<br>
like local module opening and on the spot module specialization...<br>
<br>
 .... where open Relation.Binary.EqReasoning (setoid (Vec _ _))<br>
<br>
[To figure that out, took me longest...]<br>
<br>
Cheers,<br>
<br>
<br>
Andreas ABEL<br>
INRIA, Projet Pi.R2<br>
23, avenue d&#39;Italie<br>
F-75013 Paris<br>
Tel: +33.1.39.63.59.41<br>
<br>
<br>
<br>
<br>
</blockquote>
<br>
Andreas ABEL<br>
INRIA, Projet Pi.R2<br>
23, avenue d&#39;Italie<br>
F-75013 Paris<br>
Tel: +33.1.39.63.59.41<br>
<br>
<br>
<br>
<br>
</blockquote>
<br>
<br>
_______________________________________________<br>
Agda mailing list<br>
<a href="mailto:Agda@lists.chalmers.se" target="_blank">Agda@lists.chalmers.se</a><br>
<a href="https://lists.chalmers.se/mailman/listinfo/agda" target="_blank">https://lists.chalmers.se/mailman/listinfo/agda</a><br>
<br>
<br>
</blockquote>
_______________________________________________<br>
Agda mailing list<br>
<a href="mailto:Agda@lists.chalmers.se" target="_blank">Agda@lists.chalmers.se</a><br>
<a href="https://lists.chalmers.se/mailman/listinfo/agda" target="_blank">https://lists.chalmers.se/mailman/listinfo/agda</a><br>
<br>
</blockquote>
<br>
Andreas ABEL<br>
INRIA, Projet Pi.R2<br>
23, avenue d&#39;Italie<br>
F-75013 Paris<br>
Tel: +33.1.39.63.59.41<br>
<br>
<br>
<br>
</div></div></blockquote></div><br></div>