-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFMachine.v
154 lines (133 loc) · 3.7 KB
/
FMachine.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
Definition is_value (M : term) : bool :=
match M with
| Var _ => true
| Nat _ => true
| _ ! => true
| _ => false
end.
Definition value_is_value V :
value V <-> is_value V = true.
Proof.
intros. split; intro.
* destruct H; easy.
* destruct V; simpl in *; try easy.
- apply value_var.
- apply value_nat.
- apply value_bang.
Defined.
Inductive status := Running | Done | Stuck.
Inductive state :=
| State (M : term) (π : stack) (status : status).
Bind Scope machine_scope with state.
Notation "M -| π " := (State M π Running) (at level 100) : machine_scope.
Definition fstep '(State M π status) : state :=
match status with
| Running =>
match M, π with
(* Stack update rules *)
| der M, π => M -| Der :: π
| succ M, π => M -| Succ :: π
| <M>N, π => N -| Fun M :: π
| V, Fun M :: π =>
if is_value V
then M -| Arg V :: π
else V -| Fun M :: π
| #if (M, N, [z] P), π => M -| If N z P :: π
(* Reduction rules *)
| M!, Der :: π => M -| π
| Nat n, Succ :: π => Nat (S n) -| π
| λ x:φ, M, Arg V :: π => M[V/x] -| π
| Nat 0, If N z P :: π => N -| π
| Nat (S n), If N z P :: π => P[(Nat n)/z] -| π
(* Status management *)
| _, [] => State M π Done
| _, _ => State M π Stuck
end
| _ => State M π status
end.
Lemma progress M π :
let (_, _, status) := fstep (M -| π) in
well_typed M -> status <> Stuck.
Proof.
Admitted.
Reserved Notation "| M |" (at level 100).
Fixpoint size_term M :=
1 + match M with
| Var _ | Nat _ => 0
| M ! | der M | λ _:_, M => |M|
| succ M => |M| + 1
| <M>N => |M| + |N|
| #if (M, N, [_] P) => |M| + |N| + |P|
end
where "| M |" := (size_term M) : terms_scope.
Fixpoint size_stack π :=
match π with
| [] => 0
| m :: π => |π| + match m with
| Der => 0
| Succ => 1
| Fun M => |M|%terms
| Arg _ => 0
| If N _ P => (|N| + |P|)%terms
end
end
where "| π |" := (size_stack π) : stack_scope.
Bind Scope stack_scope with stack.
Definition size '(State M π _) := size_term M + size_stack π.
Lemma size_subst_var M y x :
|M[(Var y)/x]| = |M|.
Proof.
induction M; simpl; try auto; try (case (x =? x0); auto).
case (x =? z); auto.
Qed.
Lemma size_subst_nat M n x :
|M[(Nat n)/x]| = |M|.
Proof.
induction M; simpl; try auto; try (case (x =? x0); auto).
case (x =? z); auto.
Qed.
Definition scc := λ "n":ι, #if ("n", 1, ["z"] "z").
Definition two_church := λ"f" : !(ι -o ι), <der "f"> <der "f"> 0.
Definition two := <two_church> scc!.
Lemma well_typed_two :
[] ⊢ two : ι.
Proof.
unfold two. apply RApp with (φ := !(ι -o ι)).
* unfold two_church. apply RAbs. apply RApp with (φ := ι).
- apply RDer. apply RVar. intuition.
- apply RApp with (φ := ι).
+ apply RDer. apply RVar. intuition.
+ apply RNat.
* apply RBang. unfold scc. apply RAbs. apply RIf.
- apply RVar. intuition.
- apply RNat.
- apply RVar. intuition.
Qed.
Compute |two|.
Compute let (M, _, _) := fstep (fstep (fstep (two -| []))) in |M|.
Compute size (two -| []).
Compute size (fstep (fstep (fstep (two -| [])))).
Lemma size_subst_value x φ M σ V :
value V -> [x : φ] ⊢ M : σ -> [] ⊢ V : φ ->
(|M| + |V| + 2) > |M[V/x]|.
Proof.
intros. induction V.
* rewrite size_subst_var. lia.
* rewrite size_subst_nat. lia.
* induction M.
- simpl. case (x =? x0); simpl; lia.
- simpl. lia.
- simpl.
Admitted.
Function run (s : state) { measure size s } : state :=
let s := fstep s in
let (M, π, status) := s in
match status with
| Running => run (State M π status)
| _ => s
end.
Proof.
Admitted.
Definition eval (M : term) : term :=
let (V, _, _) := run (M -| []) in V.
Compute eval 0.