coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Pierre Courtieu <pierre.courtieu AT gmail.com>
- To: Coq Club <coq-club AT inria.fr>
- Subject: Re: [Coq-Club] Proof in functional style
- Date: Fri, 30 Nov 2018 10:45:33 +0100
- Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=pierre.courtieu AT gmail.com; spf=Pass smtp.mailfrom=pierre.courtieu AT gmail.com; spf=None smtp.helo=postmaster AT mail-ot1-f49.google.com
- Ironport-phdr: 9a23:hV8nIByWJwwBsG/XCy+O+j09IxM/srCxBDY+r6Qd2+sfIJqq85mqBkHD//Il1AaPAd2Lraocw8Pt8InYEVQa5piAtH1QOLdtbDQizfssogo7HcSeAlf6JvO5JwYzHcBFSUM3tyrjaRsdF8nxfUDdrWOv5jAOBBr/KRB1JuPoEYLOksi7ze+/94HQbglSmDaxfa55IQmrownWqsQYm5ZpJLwryhvOrHtIeuBWyn1tKFmOgRvy5dq+8YB6/ShItP0v68BPUaPhf6QlVrNYFygpM3o05MLwqxbOSxaE62YGXWUXlhpIBBXF7A3/U5zsvCb2qvZx1S+HNsDtU7s6RSqt4LtqSB/wiScIKTg58H3MisdtiK5XuQ+tqwBjz4LRZoyeKfhwcb7Hfd4CSmVBUMReWSxPDI2/coUBEfYOM+lDoonhvlsDtweyCRWwCO7tzDJDm3/43bc90+QkCQzIxg0gEMwUsHTOstr+KbkfUeeozKnS0TXDbu1Z2Srg44XPahAhoO+DXahqccXP00UgCwTFjkiKqYz5PjOayPkNvnOU7+plT+2vimonpxttrTiow8chk4/EjZ8bxFDD8CV22oc1JdugRU50YN6kDJtQtzyBOIdsXswiRGRotSAnwbMFoZ62ZDYGxIgjyhLFaPGKc5KE7gz+WOqNOzt1i3ZodbSijBio60eg0PfzVsys3VZKsCVFlt7Mu2gI1xPJ68iHTuJx/kC92TqSzgzT5O5JLEQumarULJ4hxbEwlp4NvkjZAiD2n0D2gLeXdkUi5Oeo9/zqbqv6qpKYLYN5iQHzPr4wlsCiHeg0KAcDUmyD9eS5zrLj/En5QLtQjv0xl6nUqIjaJcUFqa6jGQ9azJwv5Aq4Dze7ytQYgXgHI0xYeB+cgIjpPkvBIPH8Dfuln1uslzJry+jcPrL9GpXNMmTDkLD5cLlh7E5c0RM/wsxb55JJEb4MO+nzW0/0tNzAFBA1KQ20w+D9CNV8zIwSQ2yPArXKeJ/V5HSP/6oEJ/SGLNsevy+4IPw47dbvi2U4kBkTZ//684EQbSWAH/l8OUjRSn3xmMsAHHpC6hI/QfbwhRuJViNJe3e/Qooz4zg6DMStCoKVFdPlu6CIwCruRs4eXWtBEF3ZVC6wL9zVCcdJUzqbJ4paqhJBULGgT4E70hT37V31zrNmKqzf/ShK7Mu/hugw3PXakFQJzRIxF96UijjfQGR9n2dOTDgzjvgm/B5Nj2yb2K09uMR2UNxe4/QTD1U/PJ/YiutmUpX8BlOHcdCOR1KrBN6hBGNpQw==
Hi,
I think this is due to the fact that you did not propagate the
"eq_refl trick" in the sub-patterns. You can see it when replace (F
(h2::t)) by (F l0) (l0 is syntactically a subterm of t).
Lemma map_intersperse_not_working : forall (A B : Type) (f : A -> B)
(c : A) (l : list A),
map f (intersperse _ c l) = intersperse _ (f c) (map f l).
refine (fun A B f c =>
fix F l :=
match l as l'
return l = l' ->
map f (intersperse A c l') =
intersperse B (f c) (map f l') with
| [] => fun H => eq_refl
| [h] => fun H => eq_refl
| h1 :: h2 :: t => fun H => _
end eq_refl).
pose proof (F l0).
(* This is certainly well-formed BUT you can't prove the l0 = h2::t,
because the eq_refl trick was not don for this intermediate. *)
Once you do the eq_refl trick at each level it works:
Lemma map_intersperse_not_working : forall (A B : Type) (f : A -> B)
(c : A) (l : list A),
map f (intersperse _ c l) = intersperse _ (f c) (map f l).
refine (fun A B f c =>
fix F l :=
match l as l'
return l = l' ->
map f (intersperse A c l') =
intersperse B (f c) (map f l') with
| [] => fun H => eq_refl
| h1 :: h2l =>
fun H => match h2l as l''
return h2l = l'' ->
map f (intersperse A c (h1::l'')) =
intersperse B (f c) (map f (h1::l''))
with
| [] => fun H => eq_refl
| h2 :: t => fun H => _
end eq_refl
end eq_refl).
pose proof (F h2l).
cbn.
cbn in *. repeat f_equal. Guarded.
(* At this point assumption H0 is same as goal [2] so apply H0
should discharge the goal*)
subst h2l.
apply H1. Guarded.
Hope this helps,
Pierre
Le ven. 30 nov. 2018 à 06:14, Larry Lee
<llee454 AT gmail.com>
a écrit :
>
> Hi mukesh,
>
> I hope this helps you identify the problem in your proof.
>
> - Larry
>
> Require Import List.
> Import ListNotations.
>
> Open Scope list_scope.
>
> Fixpoint intersperse (A : Type) (c : A) (l : list A) : list A :=
> match l with
> | [] => []
> | [h] => [h]
> | h :: t => h :: c :: intersperse _ c t
> end.
>
> Lemma map_intersperse_not_working : forall (A B : Type) (f : A -> B) (c :
> A) (l : list A),
> map f (intersperse _ c l) = intersperse _ (f c) (map f l).
> Proof.
> exact (
> fun (A B : Type) (f : A -> B) (c : A)
> => list_ind
> (fun l => map f (intersperse _ c l) = intersperse _ (f c) (map f
> l))
> (eq_refl [])
> (fun x0
> => list_ind
> (fun xs => map f (intersperse _ c xs) = intersperse _ (f
> c) (map f xs) -> map f (intersperse _ c (x0 :: xs)) = intersperse _ (f c)
> (map f (x0 :: xs)))
> (*
> goal:
> map f (intersperse _ c (x0 :: [])) = intersperse _ (f
> c) (map f (x0 :: []))
> map f [x0] = intersperse _ (f c) [f x0]
> [f x0] = [f x0]
> *)
> (fun _ => eq_refl [f x0])
> (*
> goal:
> map f (intersperse _ c (x0 :: y0 :: ys)) = intersperse
> _ (f c) (map f (x0 :: y0 :: ys))
> map f (x0 :: c :: intersperse _ c (y0 :: ys)) =
> intersperse _ (f c) (f x0 :: f y0 :: (map f ys))
> (f x0 :: f c :: map f (intersperse _ c (y0 :: ys)) =
> (f x0 :: f c :: intersperse _ (f c) (f y0 :: map f xs))
> *)
> (fun y0 ys _ (H : map f (intersperse _ c (y0 :: ys)) =
> intersperse _ (f c) (map f (y0 :: ys)))
> => ((eq_ind
> (map f (intersperse _ c (y0 :: ys)))
> (fun zs => (f x0 :: f c :: map f (intersperse _ c
> (y0 :: ys))) = (f x0 :: f c :: zs))
> (eq_refl (f x0 :: f c :: map f (intersperse _ c
> (y0 :: ys))))
> (intersperse _ (f c) (map f (y0 :: ys)))
> H))))).
>
>
> On Fri, 2018-11-30 at 15:24 +1100, mukesh tiwari wrote:
>
> Hi Everyone, I have written a function (basically Haskell intersperse
> function)
>
> Fixpoint intersperse (A : Type) (c : A) (l : list A) : list A :=
> match l with
> | [] => []
> | [h] => [h]
> | h :: t => h :: c :: intersperse _ c t
> end.
>
>
> Compute (intersperse _ 0 []).
> Compute (intersperse _ 0 [1]).
> Compute (intersperse _ 0 [1; 2; 3]).
>
> and proof about it's correctness
>
> Lemma map_intersperse : forall (A B : Type) (f : A -> B) (c : A) (l :
> list A),
> map f (intersperse _ c l) = intersperse _ (f c) (map f l).
> Proof.
> intros A B f c.
> induction l.
> + cbn; auto.
> + destruct l.
> ++ cbn; auto.
> ++ cbn in *. repeat f_equal.
> (* At this point, the induction hypothesis is [1], and
> assumption is able to discharge
> the proof *)
> assumption.
> Qed.
>
> Now I rewrote the same proof in function style using refine tactic.
>
> Lemma map_intersperse_not_working : forall (A B : Type) (f : A -> B) (c :
> A) (l : list A),
> map f (intersperse _ c l) = intersperse _ (f c) (map f l).
> refine (fun A B f c =>
> fix F l :=
> match l as l'
> return l = l' ->
> map f (intersperse A c l') =
> intersperse B (f c) (map f l') with
>
> | [] => fun H => eq_refl
> | [h] => fun H => eq_refl
> | h1 :: h2 :: t => fun H => _
> end eq_refl).
> pose proof (F (h2 :: t)).
> cbn in *. repeat f_equal. Guarded.
> (* At this point assumption H0 is same as goal [2] so apply H0
> should discharge the goal*)
> apply H0. Guarded.
> (* I am getting Recursive definition of F is ill-formed. *)
>
> Could some one point me why it's saying F is ill-formed ? I am calling it
> smaller argument (At least that is my understanding).
>
> I got working solution with help of Li-yao [3], but I am wondering why
> destruct t is making a difference in this solution which I am doing
> explicitly in previous one (matching on one element list [h])
>
> Lemma map_intersperse_not_working : forall (A B : Type) (f : A -> B) (c
> : A) (l : list A),
> map f (intersperse _ c l) = intersperse _ (f c) (map f l).
> refine (fun A B f c =>
> fix F l :=
> match l as l'
> return l = l' ->
> map f (intersperse A c l') =
> intersperse B (f c) (map f l') with
>
> | [] => fun H => eq_refl
> | h :: t => fun H => _
> end eq_refl).
> pose proof (F t).
> destruct t.
> + cbn. exact eq_refl.
> + cbn in *. repeat f_equal. apply H0. Guarded.
> Qed.
>
> Best regards,
> Mukesh Tiwari
>
>
> [1]
> https://gist.github.com/mukeshtiwari/3effe799a8c76a9aaf1c9de27d4a89f0#file-function-v-L6
> [2]
> https://gist.github.com/mukeshtiwari/3effe799a8c76a9aaf1c9de27d4a89f0#file-function-v-L36
> [3] https://gist.github.com/Lysxia/13109240eff4082a9c17634c6e2f6c5f
- [Coq-Club] Proof in functional style, mukesh tiwari, 11/30/2018
- Re: [Coq-Club] Proof in functional style, mukesh tiwari, 11/30/2018
- Re: [Coq-Club] Proof in functional style, Larry Lee, 11/30/2018
- Re: [Coq-Club] Proof in functional style, Pierre Courtieu, 11/30/2018
Archive powered by MHonArc 2.6.18.