-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStackMachine.v
100 lines (77 loc) · 2.52 KB
/
StackMachine.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Require Import Bool Arith List Cpdt.CpdtTactics.
Set Implicit Arguments.
Set Asymmetric Patterns.
Inductive binop : Set := Plus | Times.
Inductive exp : Set :=
| Const : nat -> exp
| Binop : binop -> exp -> exp -> exp.
(* [binop] denotes to a function that will be applied to two [nat] values *)
Definition binopDenote(b:binop) : nat -> nat -> nat :=
match b with
| Plus => plus
| Times => mult
end.
Fixpoint expDenote(e:exp) : nat :=
match e with
| Const n => n
| Binop b e1 e2 => (binopDenote b) (expDenote e1) (expDenote e2)
end.
Eval simpl in expDenote (Const 42).
Eval simpl in expDenote (Binop Plus (Const 2) (Const 2)).
Eval simpl in expDenote (Binop Times (Binop Plus (Const 2) (Const 2)) (Const 7)).
(* Stack Language *)
Inductive instr : Set :=
| iConst : nat -> instr
| iBinop : binop -> instr.
Definition prog := list instr.
Definition stack := list nat.
(* [stack] stores the state of the computation. *)
Definition instrDenote (i:instr)(s:stack) : option stack :=
match i with
| iConst n => Some (n::s)
| iBinop b =>
match s with
| arg1 :: arg2 :: s' => Some ((binopDenote b) arg1 arg2 :: s')
| _ => None
end
end.
Fixpoint progDenote (p:prog)(s:stack) : option stack :=
match p with
| nil => Some s
| i :: p' =>
match instrDenote i s with
| None => None
| Some s' => progDenote p' s'
end
end.
Eval simpl in (progDenote ((iConst 3) :: (iConst 4) :: (iBinop Plus) :: nil) nil).
Fixpoint compile (e:exp) : prog :=
match e with
| Const n => iConst n :: nil
| Binop b exp1 exp2 => (compile exp2) ++ (compile exp1) ++ ((iBinop b) :: nil)
end.
Eval simpl in compile (Const 42).
Eval simpl in compile (Binop Plus (Const 2) (Const 2)).
Eval simpl in compile (Binop Times (Binop Plus (Const 2) (Const 2)) (Const 7)).
Eval simpl in progDenote (compile (Const 42)) nil.
Eval simpl in progDenote (compile (Binop Plus (Const 2) (Const 2))) nil.
Eval simpl in progDenote (compile (Binop Times (Binop Plus (Const 2) (Const 2)) (Const 7))) nil.
Theorem compile_correct: forall e, progDenote (compile e) nil = Some (expDenote e :: nil).
Proof.
induction e.
unfold compile.
unfold expDenote.
reflexivity.
Abort.
(* Strengthening the hypothesis. Need to understand better where this comes from. Why this particular strengthening? *)
Lemma compile_correct': forall e p s, progDenote (compile e ++ p) s = progDenote p (expDenote e::s).
Proof.
induction e.
intros.
unfold compile.
unfold expDenote.
unfold progDenote at 1.
simpl.
fold progDenote.
reflexivity.
Qed.