aboutsummaryrefslogtreecommitdiffstats
path: root/correct.v
diff options
context:
space:
mode:
Diffstat (limited to 'correct.v')
-rw-r--r--correct.v299
1 files changed, 299 insertions, 0 deletions
diff --git a/correct.v b/correct.v
new file mode 100644
index 0000000..89f5894
--- /dev/null
+++ b/correct.v
@@ -0,0 +1,299 @@
1Require Import Coq.Strings.String.
2From stdpp Require Import gmap.
3From mininix Require Import
4 expr relations sem interpreter complete sound shared.
5
6Theorem correct e v' : (∃ n, eval n false e = Some v') ↔ e -->* v'.
7Proof.
8 split.
9 - intros [n Heval]. by apply (eval_sound_strong n false).
10 - intros Heval. by apply eval_complete.
11Qed.
12
13(* Top-level program reduction/evaluation:
14 we make the prelude available here. *)
15
16Definition with_prelude (e : expr) : expr :=
17 subst (closed prelude) e.
18
19Definition tl_reds (e e' : expr) :=
20 with_prelude e -->* e'.
21
22Definition tl_eval (n : nat) (e : expr) : option value :=
23 eval n false (subst (closed prelude) e).
24
25Definition tl_evals e e' := ∃ n, tl_eval n e = Some e'.
26
27(* Macros *)
28
29Definition μ_neq e1 e2 := X_Cond (X_Op O_Eq e1 e2) false true.
30Definition μ_or e1 e2 := X_Cond e1 true e2.
31Definition μ_and e1 e2 := X_Cond e1 e2 false.
32Definition μ_impl e1 e2 := X_Cond e1 e2 true.
33Definition μ_neg e := X_Cond e false true.
34
35Definition μ_le n m := μ_or (X_Op O_Eq n m) (X_Op O_Lt n m).
36Definition μ_gt n m := X_Op O_Lt m n.
37Definition μ_ge n m := μ_or (X_Op O_Eq n m) (μ_gt n m).
38
39(* Tests/examples *)
40
41Definition ex1 := X_LetBinding {[ "a" := B_Rec 1%Z ]} "a".
42
43(* [let a = 1; in a] gives 1 *)
44Theorem ex1_step : tl_reds ex1 1%Z.
45Proof.
46 unfold ex1.
47 eapply rtc_l.
48 - by eapply E_Ctx with (E := id).
49 - simplify_option_eq.
50 eapply rtc_once.
51 by eapply E_Ctx with (E := id).
52Qed.
53
54Example ex1_eval : tl_evals ex1 (V_Int 1).
55Proof. by exists 3. Qed.
56
57(* Definition ex2 := <{ let a = 1 in with { a = 2 }; a }>. *)
58Definition ex2 := X_LetBinding {[ "a" := B_Rec 1%Z ]}
59 (X_Incl (V_Attrset {[ "a" := X_V 2%Z ]}) "a").
60
61(* [let a = 1; in with { a = 2; }; a] gives 1 *)
62Theorem ex2_step : tl_reds ex2 1%Z.
63Proof.
64 unfold ex2.
65 eapply rtc_l.
66 - by eapply E_Ctx with (E := id).
67 - simplify_option_eq.
68 eapply rtc_l.
69 + by eapply E_Ctx with (E := id).
70 + simpl. eapply rtc_once.
71 by eapply E_Ctx with (E := id).
72Qed.
73
74Example ex2_eval : tl_evals ex2 (V_Int 1).
75Proof. by exists 4. Qed.
76
77(* [with { a = 1; }; with { a = 2; }; a] gives 2 *)
78Definition ex3 :=
79 X_Incl (V_Attrset {[ "a" := X_V 1%Z ]})
80 (X_Incl (V_Attrset {[ "a" := X_V 2%Z ]}) "a").
81
82Theorem ex3_step : tl_reds ex3 2%Z.
83Proof.
84 unfold ex3.
85 eapply rtc_l.
86 - eapply E_Ctx with (E := id); [done | apply E_With].
87 - simpl. eapply rtc_l.
88 + by eapply E_Ctx with (E := id).
89 + simplify_option_eq.
90 eapply rtc_once.
91 by eapply E_Ctx with (E := id).
92Qed.
93
94Example ex3_eval : tl_evals ex3 (V_Int 2).
95Proof. by exists 4. Qed.
96
97(* [({ x, y ? x } : y) { x = 1; }] gives 1 *)
98Definition ex4 :=
99 X_Apply
100 (V_AttrsetFn
101 (M_Matcher
102 {[ "x" := M_Mandatory;
103 "y" := M_Optional "x"
104 ]}
105 true)
106 "y")
107 (V_Attrset {[ "x" := X_V 1%Z ]}).
108
109Example ex4_eval : tl_evals ex4 (V_Int 1).
110Proof. by exists 7. Qed.
111
112(* [({ x ? y, y ? x } : y) { x = 1; }] gives 1 *)
113Definition ex5 :=
114 X_Apply
115 (V_AttrsetFn
116 (M_Matcher
117 {[ "x" := M_Optional "y";
118 "y" := M_Optional "x"
119 ]}
120 true)
121 "y")
122 (V_Attrset {[ "x" := X_V 1%Z ]}).
123
124Example ex5_eval : tl_evals ex5 (V_Int 1).
125Proof. by exists 7. Qed.
126
127(* [let binToString = n:
128 if n == 0
129 then "0"
130 else if n == 1
131 then "1"
132 else binToString (n / 2) + (if isEven n then "0" else "1");
133 isEven = n: n != 1 && (n = 0 || isEven (n - 2));
134 test = { x, y ? attrs.x, ... } @ attrs:
135 "x: " + x + ", y: " + y + ", z: " + attrs.z or "(no z)"
136 in test { x = binToString 6; }] gives "x: 110, y: 110, z: (no z)" *)
137Definition ex6 :=
138 X_LetBinding
139 {[ "binToString" := B_Rec $ V_Fn "n" $
140 X_Cond
141 (X_Op O_Eq "n" 0%Z)
142 (V_Str "0")
143 (X_Cond
144 (X_Op O_Eq "n" 1%Z)
145 (V_Str "1")
146 (X_Op O_Plus
147 (X_Apply
148 "binToString"
149 (X_Op O_Div "n" 2%Z))
150 (X_Cond
151 (X_Apply "isEven" "n")
152 (V_Str "0")
153 (V_Str "1"))));
154 "isEven" := B_Rec $ V_Fn "n" $
155 μ_and
156 (μ_neq "n" 1%Z)
157 (μ_or
158 (X_Op O_Eq "n" 0%Z)
159 (X_Apply "isEven" (X_Op O_Min "n" 2%Z)));
160 "test" := B_Rec $ V_Fn "attrs" $
161 X_Apply
162 (V_AttrsetFn
163 (M_Matcher
164 {[ "x" := M_Mandatory;
165 "y" := M_Optional
166 (X_Select "attrs"
167 (nonempty_singleton "x"))
168 ]} false)
169 (X_Op O_Plus
170 (X_Op O_Plus
171 (X_Op O_Plus
172 (X_Op O_Plus
173 (X_Op O_Plus
174 (V_Str "x: ")
175 "x")
176 (V_Str ", y: "))
177 "y")
178 (V_Str ", z: "))
179 (X_SelectOr
180 "attrs"
181 (nonempty_singleton "z")
182 (V_Str "(no z)"))))
183 "attrs"
184 ]}
185 (X_Apply "test" $ V_Attrset
186 {[ "x" := X_Apply "binToString" 6%Z ]}).
187
188Example ex6_eval : tl_evals ex6 (V_Str "x: 110, y: 110, z: (no z)").
189Proof. by exists 37. Qed.
190
191(* Important check of if placeholders work correctly:
192 [with { x = 1; }; let foo = y: let x = 2; in y; foo x]
193 gives 1 *)
194Definition ex7 := X_Incl
195 (V_Attrset {[ "x" := X_V 1%Z ]})
196 (X_LetBinding
197 {[ "foo" := B_Rec $ V_Fn "y" $
198 X_LetBinding {[ "x" := B_Rec 2%Z ]} "y"
199 ]}
200 (X_Apply "foo" "x")).
201
202Example ex7_eval : tl_evals ex7 (V_Int 1).
203Proof. by exists 7. Qed.
204
205Definition ex8 :=
206 X_LetBinding
207 {[ "divide" := B_Rec $ V_Fn "a" $ V_Fn "b" $
208 X_Assert
209 (μ_and (μ_ge "a" 0%Z) (μ_gt "b" 0%Z))
210 (X_Cond
211 (X_Op O_Lt "a" "b")
212 0
213 (X_Op
214 O_Plus
215 (X_Apply
216 (X_Apply
217 "divide"
218 (X_Op O_Min "a" "b"))
219 "b")
220 1));
221 "divider" := B_Rec $ X_Attrset
222 {[ "__functor" := B_Nonrec $ V_Fn "self" $ V_Fn "x" $
223 X_Op
224 O_Upd
225 "self"
226 (X_Attrset
227 {[ "value" := B_Nonrec $
228 X_Apply
229 (X_Apply
230 "divide"
231 (X_Select "self" $ nonempty_singleton "value"))
232 "x"
233 ]})
234 ]};
235 "mkDivider" := B_Rec $ V_Fn "value" $
236 X_Op
237 O_Upd
238 "divider"
239 (X_Attrset {[ "value" := B_Nonrec "value" ]})
240 ]}%Z
241 (X_Select
242 (X_Apply (X_Apply (X_Apply "mkDivider" 100) 5) 4)
243 (nonempty_singleton "value"))%Z.
244
245Example ex8_eval : tl_evals ex8 (V_Int 5).
246Proof. by exists 170. Qed.
247
248Example ex9 :=
249 X_Apply
250 (X_Apply
251 (V_Attrset
252 {[ "__functor" := X_V $ V_Fn "self" $ V_Fn "f" $
253 X_Apply "f" (X_Apply "self" "f")
254 ]})
255 (V_Fn "go" $ V_Fn "n" $
256 X_Cond
257 (μ_le "n" 1)
258 "n"
259 (X_Op
260 O_Plus
261 (X_Apply "go" (X_Op O_Min "n" 1))
262 (X_Apply "go" (X_Op O_Min "n" 2)))))%Z
263 15%Z.
264
265Example ex9_eval : tl_evals ex9 (V_Int 610).
266Proof. by exists 78. Qed.
267
268Example ex10 :=
269 X_LetBinding
270 {[ "true" := B_Rec 42 ]}%Z
271 (X_Op O_Eq "true" 42)%Z.
272
273Example ex10_eval : tl_evals ex10 (V_Bool true).
274Proof. by exists 4. Qed.
275
276Definition ex11 :=
277 X_LetBinding
278 {[ "x" := B_Rec "y" ]}%Z
279 (X_LetBinding {[ "y" := B_Rec 10 ]} "x")%Z.
280
281Example ex11_eval : tl_eval 1000 ex11 = None.
282Proof. done. Qed.
283
284Definition ex12 :=
285 X_LetBinding
286 {[ "pkgs" := B_Rec $ V_Attrset
287 {[ "x" := X_Incl (V_Attrset {[ "y" := X_V 1%Z ]}) "y" ]}
288 ]}
289 (X_Select
290 (X_Attrset
291 {[ "x" := B_Rec $ X_Select "pkgs" (nonempty_singleton "x");
292 "y" := B_Rec 3%Z
293 ]})
294 (nonempty_singleton "x")).
295
296Example ex12_eval : tl_eval 1000 ex12 = Some (V_Int 1).
297Proof. done. Qed.
298
299(* Aio, quantitas magna frumentorum est. *)