comparison src/Hoas.v @ 166:73279a8aac71

More easy syntactic examples
author Adam Chlipala <adamc@hcoop.net>
date Wed, 05 Nov 2008 09:21:11 -0500
parents cf60d8dc57c9
children ef485f86a7b6
comparison
equal deleted inserted replaced
165:cf60d8dc57c9 166:73279a8aac71
54 fun _ => Plus' (E1 _) (E2 _). 54 fun _ => Plus' (E1 _) (E2 _).
55 Definition App dom ran (F : Exp (dom --> ran)) (X : Exp dom) : Exp ran := 55 Definition App dom ran (F : Exp (dom --> ran)) (X : Exp dom) : Exp ran :=
56 fun _ => App' (F _) (X _). 56 fun _ => App' (F _) (X _).
57 Definition Abs dom ran (B : Exp1 dom ran) : Exp (dom --> ran) := 57 Definition Abs dom ran (B : Exp1 dom ran) : Exp (dom --> ran) :=
58 fun _ => Abs' (B _). 58 fun _ => Abs' (B _).
59
60 Definition zero := Const 0.
61 Definition one := Const 1.
62 Definition one_again := Plus zero one.
63 Definition ident : Exp (Nat --> Nat) := Abs (fun _ X => Var X).
64 Definition app_ident := App ident one_again.
65 Definition app : Exp ((Nat --> Nat) --> Nat --> Nat) := fun _ =>
66 Abs' (fun f => Abs' (fun x => App' (Var f) (Var x))).
67 Definition app_ident' := App (App app ident) one_again.
68
69 Fixpoint countVars t (e : exp (fun _ => unit) t) {struct e} : nat :=
70 match e with
71 | Const' _ => 0
72 | Plus' e1 e2 => countVars e1 + countVars e2
73 | Var _ _ => 1
74 | App' _ _ e1 e2 => countVars e1 + countVars e2
75 | Abs' _ _ e' => countVars (e' tt)
76 end.
77
78 Definition CountVars t (E : Exp t) : nat := countVars (E _).
79
80 Eval compute in CountVars zero.
81 Eval compute in CountVars one.
82 Eval compute in CountVars one_again.
83 Eval compute in CountVars ident.
84 Eval compute in CountVars app_ident.
85 Eval compute in CountVars app.
86 Eval compute in CountVars app_ident'.
87
88 Fixpoint countOne t (e : exp (fun _ => bool) t) {struct e} : nat :=
89 match e with
90 | Const' _ => 0
91 | Plus' e1 e2 => countOne e1 + countOne e2
92 | Var _ true => 1
93 | Var _ false => 0
94 | App' _ _ e1 e2 => countOne e1 + countOne e2
95 | Abs' _ _ e' => countOne (e' false)
96 end.
97
98 Definition CountOne t1 t2 (E : Exp1 t1 t2) : nat :=
99 countOne (E _ true).
100
101 Definition ident1 : Exp1 Nat Nat := fun _ X => Var X.
102 Definition add_self : Exp1 Nat Nat := fun _ X => Plus' (Var X) (Var X).
103 Definition app_zero : Exp1 (Nat --> Nat) Nat := fun _ X => App' (Var X) (Const' 0).
104 Definition app_ident1 : Exp1 Nat Nat := fun _ X => App' (Abs' (fun Y => Var Y)) (Var X).
105
106 Eval compute in CountOne ident1.
107 Eval compute in CountOne add_self.
108 Eval compute in CountOne app_zero.
109 Eval compute in CountOne app_ident1.
110
111 Section ToString.
112 Open Scope string_scope.
113
114 Fixpoint natToString (n : nat) : string :=
115 match n with
116 | O => "O"
117 | S n' => "S(" ++ natToString n' ++ ")"
118 end.
119
120 Fixpoint toString t (e : exp (fun _ => string) t) (cur : string) {struct e} : string * string :=
121 match e with
122 | Const' n => (cur, natToString n)
123 | Plus' e1 e2 =>
124 let (cur', s1) := toString e1 cur in
125 let (cur'', s2) := toString e2 cur' in
126 (cur'', "(" ++ s1 ++ ") + (" ++ s2 ++ ")")
127 | Var _ s => (cur, s)
128 | App' _ _ e1 e2 =>
129 let (cur', s1) := toString e1 cur in
130 let (cur'', s2) := toString e2 cur' in
131 (cur'', "(" ++ s1 ++ ") (" ++ s2 ++ ")")
132 | Abs' _ _ e' =>
133 let (cur', s) := toString (e' cur) (cur ++ "'") in
134 (cur', "(\" ++ cur ++ ", " ++ s ++ ")")
135 end.
136
137 Definition ToString t (E : Exp t) : string := snd (toString (E _) "x").
138 End ToString.
139
140 Eval compute in ToString zero.
141 Eval compute in ToString one.
142 Eval compute in ToString one_again.
143 Eval compute in ToString ident.
144 Eval compute in ToString app_ident.
145 Eval compute in ToString app.
146 Eval compute in ToString app_ident'.
59 147
60 Section flatten. 148 Section flatten.
61 Variable var : type -> Type. 149 Variable var : type -> Type.
62 150
63 Fixpoint flatten t (e : exp (exp var) t) {struct e} : exp var t := 151 Fixpoint flatten t (e : exp (exp var) t) {struct e} : exp var t :=
70 end. 158 end.
71 End flatten. 159 End flatten.
72 160
73 Definition Subst t1 t2 (E1 : Exp t1) (E2 : Exp1 t1 t2) : Exp t2 := fun _ => 161 Definition Subst t1 t2 (E1 : Exp t1) (E2 : Exp1 t1 t2) : Exp t2 := fun _ =>
74 flatten (E2 _ (E1 _)). 162 flatten (E2 _ (E1 _)).
163
164 Eval compute in Subst one ident1.
165 Eval compute in Subst one add_self.
166 Eval compute in Subst ident app_zero.
167 Eval compute in Subst one app_ident1.
75 168
76 169
77 (** * A Type Soundness Proof *) 170 (** * A Type Soundness Proof *)
78 171
79 Reserved Notation "E1 ==> E2" (no associativity, at level 90). 172 Reserved Notation "E1 ==> E2" (no associativity, at level 90).
327 E ==>* V 420 E ==>* V
328 -> Val V 421 -> Val V
329 -> E ===> V. 422 -> E ===> V.
330 induction 1; crush; eauto. 423 induction 1; crush; eauto.
331 Qed. 424 Qed.
332
333
334 (** * Constant folding *)
335
336 Section cfold.
337 Variable var : type -> Type.
338
339 Fixpoint cfold t (e : exp var t) {struct e} : exp var t :=
340 match e in exp _ t return exp _ t with
341 | Const' n => Const' n
342 | Plus' e1 e2 =>
343 let e1' := cfold e1 in
344 let e2' := cfold e2 in
345 match e1', e2' with
346 | Const' n1, Const' n2 => Const' (n1 + n2)
347 | _, _ => Plus' e1' e2'
348 end
349
350 | Var _ x => Var x
351 | App' _ _ e1 e2 => App' (cfold e1) (cfold e2)
352 | Abs' _ _ e' => Abs' (fun x => cfold (e' x))
353 end.
354 End cfold.
355
356 Definition Cfold t (E : Exp t) : Exp t := fun _ => cfold (E _).
357 Definition Cfold1 t1 t2 (E : Exp1 t1 t2) : Exp1 t1 t2 := fun _ x => cfold (E _ x).
358
359 Lemma fold_Cfold : forall t (E : Exp t),
360 (fun _ => cfold (E _)) = Cfold E.
361 reflexivity.
362 Qed.
363
364 Hint Rewrite fold_Cfold : fold.
365
366 Lemma fold_Cfold1 : forall t1 t2 (E : Exp1 t1 t2),
367 (fun _ x => cfold (E _ x)) = Cfold1 E.
368 reflexivity.
369 Qed.
370
371 Hint Rewrite fold_Cfold1 : fold.
372
373 Lemma fold_Subst_Cfold1 : forall t1 t2 (E : Exp1 t1 t2) (V : Exp t1),
374 (fun _ => flatten (cfold (E _ (V _))))
375 = Subst V (Cfold1 E).
376 reflexivity.
377 Qed.
378
379 Axiom cheat : forall T, T.
380
381
382 Lemma fold_Const : forall n, (fun _ => Const' n) = Const n.
383 reflexivity.
384 Qed.
385 Lemma fold_Plus : forall (E1 E2 : Exp _), (fun _ => Plus' (E1 _) (E2 _)) = Plus E1 E2.
386 reflexivity.
387 Qed.
388 Lemma fold_App : forall dom ran (F : Exp (dom --> ran)) (X : Exp dom),
389 (fun _ => App' (F _) (X _)) = App F X.
390 reflexivity.
391 Qed.
392 Lemma fold_Abs : forall dom ran (B : Exp1 dom ran),
393 (fun _ => Abs' (B _)) = Abs B.
394 reflexivity.
395 Qed.
396
397 Hint Rewrite fold_Const fold_Plus fold_App fold_Abs : fold.
398
399 Lemma fold_Subst : forall t1 t2 (E1 : Exp1 t1 t2) (V : Exp t1),
400 (fun _ => flatten (E1 _ (V _))) = Subst V E1.
401 reflexivity.
402 Qed.
403
404 Hint Rewrite fold_Subst : fold.
405
406 Section Closed1.
407 Variable xt : type.
408
409 Definition Const1 (n : nat) : Exp1 xt Nat :=
410 fun _ _ => Const' n.
411 Definition Var1 : Exp1 xt xt := fun _ x => Var x.
412 Definition Plus1 (E1 E2 : Exp1 xt Nat) : Exp1 xt Nat :=
413 fun _ s => Plus' (E1 _ s) (E2 _ s).
414 Definition App1 dom ran (F : Exp1 xt (dom --> ran)) (X : Exp1 xt dom) : Exp1 xt ran :=
415 fun _ s => App' (F _ s) (X _ s).
416 Definition Abs1 dom ran (B : forall var, var dom -> Exp1 xt ran) : Exp1 xt (dom --> ran) :=
417 fun _ s => Abs' (fun x => B _ x _ s).
418
419 Inductive Closed1 : forall t, Exp1 xt t -> Prop :=
420 | CConst1 : forall n,
421 Closed1 (Const1 n)
422 | CPlus1 : forall E1 E2,
423 Closed1 E1
424 -> Closed1 E2
425 -> Closed1 (Plus1 E1 E2)
426 | CApp1 : forall dom ran (E1 : Exp1 _ (dom --> ran)) E2,
427 Closed1 E1
428 -> Closed1 E2
429 -> Closed1 (App1 E1 E2)
430 | CAbs1 : forall dom ran (E1 : forall var, var dom -> Exp1 _ ran),
431 Closed1 (Abs1 E1).
432
433 Axiom closed1 : forall t (E : Exp1 xt t), Closed1 E.
434 End Closed1.
435
436 Hint Resolve closed1.
437
438 Ltac ssimp := unfold Subst, Cfold in *; simpl in *; autorewrite with fold in *;
439 repeat match goal with
440 | [ xt : type |- _ ] =>
441 rewrite (@fold_Subst xt) in *
442 end;
443 autorewrite with fold in *.
444
445 Lemma cfold_thorough : forall var t (e : exp var t),
446 cfold (cfold e) = cfold e.
447 induction e; crush; try (f_equal; ext_eq; eauto);
448 match goal with
449 | [ e1 : exp _ Nat, e2 : exp _ Nat |- _ ] =>
450 dep_destruct (cfold e1); crush;
451 dep_destruct (cfold e2); crush
452 end.
453 Qed.
454
455 Lemma Cfold_thorough : forall t (E : Exp t),
456 Cfold (Cfold E) = Cfold E.
457 intros; unfold Cfold, Exp; ext_eq;
458 apply cfold_thorough.
459 Qed.
460
461 Hint Resolve Cfold_thorough.
462
463 Section eq_arg.
464 Variable A : Type.
465 Variable B : A -> Type.
466
467 Variable x : A.
468
469 Variables f g : forall x, B x.
470 Hypothesis Heq : f = g.
471
472 Theorem eq_arg : f x = g x.
473 congruence.
474 Qed.
475 End eq_arg.
476
477 Implicit Arguments eq_arg [A B f g].
478
479 Lemma Cfold_Subst_thorough : forall t1 (V : Exp t1) t2 (B : Exp1 t1 t2),
480 Subst (Cfold V) (Cfold1 B) = Cfold (Subst (Cfold V) (Cfold1 B)).
481
482 Lemma Cfold_Step_thorough' : forall t (E V : Exp t),
483 E ===> V
484 -> forall E', E = Cfold E'
485 -> Cfold V = V.
486 induction 1; crush.
487 apply IHBigStep3 with (Subst V2 B).
488
489 generalize (closed E'); inversion 1; my_crush.
490
491 generalize (eq_arg (fun _ => Set) H2); ssimp.
492 dep_destruct (cfold (E0 (fun _ => Set))); try discriminate;
493 dep_destruct (cfold (E3 (fun _ => Set))); discriminate.
494
495 ssimp; my_crush.
496
497 rewrite <- (IHBigStep2 _ (refl_equal _)).
498 generalize (IHBigStep1 _ (refl_equal _)).
499 my_crush.
500 ssimp.
501 assert (B = Cfold1 B).
502 generalize H2; clear_all; my_crush.
503 unfold Exp1; ext_eq.
504 generalize (eq_arg x H2); injection 1; my_crush.
505
506 rewrite H8.
507
508
509 my_crush.
510
511 Lemma Cfold_thorough : forall t (E V : Exp t),
512 Cfold E ===> V
513 -> V = Cfold V.
514
515 Lemma Cfold_Subst' : forall t (E V : Exp t),
516 E ===> V
517 -> forall t' B (V' : Exp t') V'', E = Cfold (Subst V' B)
518 -> V = Cfold V''
519 -> Closed1 B
520 -> Subst (Cfold V') (Cfold1 B) ===> Cfold V''.
521 induction 1; inversion 3; my_crush; ssimp; my_crush.
522
523 rewrite <- H0; auto.
524
525 apply cheat.
526 apply cheat.
527 apply cheat.
528
529 repeat rewrite (@fold_Subst_Cfold1 t') in *.
530 repeat rewrite fold_Cfold in *.
531 apply SApp with (Cfold1 B) V2.
532
533 unfold Abs, Subst, Cfold, Cfold1 in *.
534 match goal with
535 | [ |- _ ===> ?F ] =>
536 replace F with (fun var => cfold (Abs' (fun x : var _ => B var x)))
537 end.
538 apply IHBigStep1; auto.
539 ssimp.
540 apply cheat.
541 reflexivity.
542
543 replace V2 with (Cfold V2).
544 unfold Cfold, Subst.
545 apply IHBigStep2; auto.
546 apply cheat.
547 apply cheat.
548
549 replace V2 with (Cfold V2).
550 unfold Subst, Cfold.
551 apply IHBigStep3; auto.
552 apply cheat.
553 apply cheat.
554
555 apply cheat.
556 Qed.
557
558 Theorem Cfold_Subst : forall t1 t2 (V : Exp t1) B (V' : Exp t2),
559 Subst (Cfold V) (Cfold1 B) ===> Cfold V'
560 -> Subst (Cfold V) (Cfold1 B) ===> Cfold V'.
561 Hint Resolve Cfold_Subst'.
562
563 eauto.
564 Qed.
565
566 Hint Resolve Cfold_Subst.
567
568 Theorem Cfold_correct : forall t (E V : Exp t),
569 E ===> V
570 -> Cfold E ===> Cfold V.
571 induction 1; crush; ssimp; eauto.
572
573 change ((fun H1 : type -> Type =>
574 match Cfold E1 H1 with
575 | Const' n3 =>
576 match Cfold E2 H1 with
577 | Const' n4 => Const' (var:=H1) (n3 + n4)
578 | Plus' _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
579 | Var _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
580 | App' _ _ _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
581 | Abs' _ _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
582 end
583 | Plus' _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
584 | Var _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
585 | App' _ _ _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
586 | Abs' _ _ _ => Plus' (cfold (E1 H1)) (cfold (E2 H1))
587 end) ===> Const (n1 + n2)).
588
589 Ltac simp :=
590 repeat match goal with
591 | [ H : _ = Cfold _ |- _ ] => rewrite <- H in *
592 | [ H : Const _ ===> Const _ |- _ ] =>
593 inversion H; clear H; my_crush
594 end.
595
596 generalize (closed (Cfold E1)); inversion 1; my_crush; simp;
597 try solve [ ssimp; simp; eauto ];
598 generalize (closed (Cfold E2)); inversion 1; my_crush; simp; ssimp; simp; eauto.
599 Qed.