comparison src/Extensional.v @ 179:8f3fc56b90d4

PatMatch Elaborate_correct
author Adam Chlipala <adamc@hcoop.net>
date Mon, 10 Nov 2008 14:12:22 -0500
parents f41d4e43fd30
children de33d1ed7c63
comparison
equal deleted inserted replaced
178:f41d4e43fd30 179:8f3fc56b90d4
210 Infix "+^" := Plus (left associativity, at level 79) : cps_scope. 210 Infix "+^" := Plus (left associativity, at level 79) : cps_scope.
211 211
212 Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : cps_scope. 212 Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : cps_scope.
213 Notation "\ ! , e" := (Abs (fun _ => e)) (at level 78) : cps_scope. 213 Notation "\ ! , e" := (Abs (fun _ => e)) (at level 78) : cps_scope.
214 214
215 Notation "[ x1 , x2 ]" := (Pair x1 x2) (at level 73) : cps_scope. 215 Notation "[ x1 , x2 ]" := (Pair x1 x2) : cps_scope.
216 Notation "#1 x" := (Fst x) (at level 72) : cps_scope. 216 Notation "#1 x" := (Fst x) (at level 72) : cps_scope.
217 Notation "#2 x" := (Snd x) (at level 72) : cps_scope. 217 Notation "#2 x" := (Snd x) (at level 72) : cps_scope.
218 218
219 Bind Scope cps_scope with prog primop. 219 Bind Scope cps_scope with prog primop.
220 220
408 Implicit Arguments PVar [t]. 408 Implicit Arguments PVar [t].
409 Implicit Arguments PInl [t1 t2 ts]. 409 Implicit Arguments PInl [t1 t2 ts].
410 Implicit Arguments PInr [t1 t2 ts]. 410 Implicit Arguments PInr [t1 t2 ts].
411 411
412 Notation "##" := PVar (at level 70) : pat_scope. 412 Notation "##" := PVar (at level 70) : pat_scope.
413 Notation "[ p1 , p2 ]" := (PPair p1 p2) (at level 72) : pat_scope. 413 Notation "[ p1 , p2 ]" := (PPair p1 p2) : pat_scope.
414 Notation "'Inl' p" := (PInl p) (at level 71) : pat_scope. 414 Notation "'Inl' p" := (PInl p) (at level 71) : pat_scope.
415 Notation "'Inr' p" := (PInr p) (at level 71) : pat_scope. 415 Notation "'Inr' p" := (PInr p) (at level 71) : pat_scope.
416 416
417 Bind Scope pat_scope with pat. 417 Bind Scope pat_scope with pat.
418 Delimit Scope pat_scope with pat. 418 Delimit Scope pat_scope with pat.
471 Notation "()" := EUnit : source_scope. 471 Notation "()" := EUnit : source_scope.
472 472
473 Infix "@" := App (left associativity, at level 77) : source_scope. 473 Infix "@" := App (left associativity, at level 77) : source_scope.
474 Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : source_scope. 474 Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : source_scope.
475 475
476 Notation "[ x , y ]" := (Pair x y) (at level 72) : source_scope. 476 Notation "[ x , y ]" := (Pair x y) : source_scope.
477 477
478 Notation "'Inl' e" := (EInl e) (at level 71) : source_scope. 478 Notation "'Inl' e" := (EInl e) (at level 71) : source_scope.
479 Notation "'Inr' e" := (EInr e) (at level 71) : source_scope. 479 Notation "'Inr' e" := (EInr e) (at level 71) : source_scope.
480 480
481 Delimit Scope source_scope with source. 481 Delimit Scope source_scope with source.
625 625
626 Infix "@" := App (left associativity, at level 77) : elab_scope. 626 Infix "@" := App (left associativity, at level 77) : elab_scope.
627 Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : elab_scope. 627 Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : elab_scope.
628 Notation "\ ? , e" := (Abs (fun _ => e)) (at level 78) : elab_scope. 628 Notation "\ ? , e" := (Abs (fun _ => e)) (at level 78) : elab_scope.
629 629
630 Notation "[ x , y ]" := (Pair x y) (at level 72) : elab_scope. 630 Notation "[ x , y ]" := (Pair x y) : elab_scope.
631 Notation "#1 e" := (Fst e) (at level 72) : elab_scope. 631 Notation "#1 e" := (Fst e) (at level 72) : elab_scope.
632 Notation "#2 e" := (Snd e) (at level 72) : elab_scope. 632 Notation "#2 e" := (Snd e) (at level 72) : elab_scope.
633 633
634 Notation "'Inl' e" := (EInl e) (at level 71) : elab_scope. 634 Notation "'Inl' e" := (EInl e) (at level 71) : elab_scope.
635 Notation "'Inr' e" := (EInr e) (at level 71) : elab_scope. 635 Notation "'Inr' e" := (EInr e) (at level 71) : elab_scope.
842 End elaborate. 842 End elaborate.
843 843
844 Definition Elaborate t (E : Source.Exp t) : Elab.Exp t := 844 Definition Elaborate t (E : Source.Exp t) : Elab.Exp t :=
845 fun _ => elaborate (E _). 845 fun _ => elaborate (E _).
846 846
847 Fixpoint grab t result : choice_tree typeDenote t result -> typeDenote t -> result :=
848 match t return (choice_tree typeDenote t result -> typeDenote t -> result) with
849 | t1 ** t2 => fun ct v =>
850 grab t2 _ (grab t1 _ ct (fst v)) (snd v)
851 | t1 ++ t2 => fun ct v =>
852 match v with
853 | inl v' => grab t1 _ (fst ct) v'
854 | inr v' => grab t2 _ (snd ct) v'
855 end
856 | t => fun ct v => ct (#v)%elab
857 end%source%type.
858
859 Implicit Arguments grab [t result].
860
861 Ltac my_crush :=
862 crush;
863 repeat (match goal with
864 | [ |- context[match ?E with inl _ => _ | inr _ => _ end] ] =>
865 destruct E
866 end; crush).
867
868 Lemma expand_grab : forall t2 t1 result
869 (out : result -> Elab.exp typeDenote t2)
870 (ct : choice_tree typeDenote t1 result)
871 (disc : Elab.exp typeDenote t1),
872 Elab.expDenote (expand out ct disc) = Elab.expDenote (out (grab ct (Elab.expDenote disc))).
873 induction t1; my_crush.
874 Qed.
875
876 Lemma recreate_pair : forall t1 t2
877 (x : Elab.exp typeDenote t1)
878 (x0 : Elab.exp typeDenote t2)
879 (v : typeDenote (t1 ** t2)),
880 expDenote x = fst v
881 -> expDenote x0 = snd v
882 -> @eq (typeDenote t1 * typeDenote t2) (expDenote [x, x0]) v.
883 destruct v; crush.
884 Qed.
885
886 Lemma everywhere_correct : forall t1 result
887 (succ : Elab.exp typeDenote t1 -> result) disc,
888 exists disc', grab (everywhere succ) (Elab.expDenote disc) = succ disc'
889 /\ Elab.expDenote disc' = Elab.expDenote disc.
890 Hint Resolve recreate_pair.
891
892 induction t1; my_crush; eauto; fold choice_tree;
893 repeat (fold typeDenote in *; crush;
894 match goal with
895 | [ IH : forall result succ, _ |- context[grab (everywhere ?S) _] ] =>
896 generalize (IH _ S); clear IH
897 | [ e : exp typeDenote (?T ** _), IH : forall _ : exp typeDenote ?T, _ |- _ ] =>
898 generalize (IH (#1 e)); clear IH
899 | [ e : exp typeDenote (_ ** ?T), IH : forall _ : exp typeDenote ?T, _ |- _ ] =>
900 generalize (IH (#2 e)); clear IH
901 | [ e : typeDenote ?T, IH : forall _ : exp typeDenote ?T, _ |- _ ] =>
902 generalize (IH (#e)); clear IH
903 end; crush); eauto.
904 Qed.
905
906 Lemma merge_correct : forall t result
907 (ct1 ct2 : choice_tree typeDenote t result)
908 (mr : result -> result -> result) v,
909 grab (merge mr ct1 ct2) v = mr (grab ct1 v) (grab ct2 v).
910 induction t; crush.
911 Qed.
912
913 Lemma everywhere_fail : forall t result
914 (fail : result) v,
915 grab (everywhere (fun _ : Elab.exp typeDenote t => fail)) v = fail.
916 induction t; crush.
917 Qed.
918
919 Lemma elaboratePat_correct : forall t1 ts (p : pat t1 ts)
920 result (succ : hlist (Elab.exp typeDenote) ts -> result)
921 (fail : result) v env,
922 patDenote p v = Some env
923 -> exists env', grab (elaboratePat typeDenote p succ fail) v = succ env'
924 /\ env = hmap Elab.expDenote env'.
925 Hint Resolve hmap_happ.
926
927 induction p; crush; fold choice_tree;
928 repeat (match goal with
929 | [ |- context[grab (everywhere ?succ) ?v] ] =>
930 generalize (everywhere_correct succ (#v)%elab)
931
932 | [ H : forall result sudc fail, _ |- context[grab (elaboratePat _ _ ?S ?F) ?V] ] =>
933 generalize (H _ S F V); clear H
934 | [ H1 : context[match ?E with Some _ => _ | None => _ end],
935 H2 : forall env, ?E = Some env -> _ |- _ ] =>
936 destruct E
937 | [ H : forall env, Some ?E = Some env -> _ |- _ ] =>
938 generalize (H _ (refl_equal _)); clear H
939 end; crush); eauto.
940 Qed.
941
942 Lemma elaboratePat_fails : forall t1 ts (p : pat t1 ts)
943 result (succ : hlist (Elab.exp typeDenote) ts -> result)
944 (fail : result) v,
945 patDenote p v = None
946 -> grab (elaboratePat typeDenote p succ fail) v = fail.
947 Hint Resolve everywhere_fail.
948
949 induction p; try solve [ crush ];
950 simpl; fold choice_tree; intuition; simpl in *;
951 repeat match goal with
952 | [ IH : forall result succ fail v, patDenote ?P v = _ -> _
953 |- context[grab (elaboratePat _ ?P ?S ?F) ?V] ] =>
954 generalize (IH _ S F V); clear IH; intro IH;
955 generalize (elaboratePat_correct P S F V); intros;
956 destruct (patDenote P V); try discriminate
957 | [ H : forall env, Some _ = Some env -> _ |- _ ] =>
958 destruct (H _ (refl_equal _)); clear H; intuition
959 | [ H : _ |- _ ] => rewrite H; intuition
960 end.
961 Qed.
962
963 Implicit Arguments letify [var t ts].
964
965 Lemma letify_correct : forall t ts (f : hlist typeDenote ts -> Elab.exp typeDenote t)
966 (env : hlist (Elab.exp typeDenote) ts),
967 Elab.expDenote (letify f env)
968 = Elab.expDenote (f (hmap Elab.expDenote env)).
969 induction ts; crush.
970 Qed.
971
972 Theorem elaborate_correct : forall t (e : Source.exp typeDenote t),
973 Elab.expDenote (elaborate e) = Source.expDenote e.
974 Hint Rewrite expand_grab merge_correct letify_correct : cpdt.
975 Hint Rewrite everywhere_fail elaboratePat_fails using assumption : cpdt.
976
977 induction e; crush; try (ext_eq; crush);
978 match goal with
979 | [ tss : list (list type) |- _ ] =>
980 induction tss; crush;
981 match goal with
982 | [ |- context[grab (elaboratePat _ ?P ?S ?F) ?V] ] =>
983 case_eq (patDenote P V); [intros env Heq;
984 destruct (elaboratePat_correct P S F _ Heq); crush;
985 match goal with
986 | [ H : _ |- _ ] => rewrite <- H; crush
987 end
988 | crush ]
989 end
990 end.
991 Qed.
992
993 Theorem Elaborate_correct : forall t (E : Source.Exp t),
994 Elab.ExpDenote (Elaborate E) = Source.ExpDenote E.
995 unfold Elab.ExpDenote, Elaborate, Source.ExpDenote;
996 intros; apply elaborate_correct.
997 Qed.
998
847 End PatMatch. 999 End PatMatch.