1 | (* *********************************************************************) |
---|
2 | (* *) |
---|
3 | (* The Compcert verified compiler *) |
---|
4 | (* *) |
---|
5 | (* Xavier Leroy, INRIA Paris-Rocquencourt *) |
---|
6 | (* *) |
---|
7 | (* Copyright Institut National de Recherche en Informatique et en *) |
---|
8 | (* Automatique. All rights reserved. This file is distributed *) |
---|
9 | (* under the terms of the GNU General Public License as published by *) |
---|
10 | (* the Free Software Foundation, either version 2 of the License, or *) |
---|
11 | (* (at your option) any later version. This file is also distributed *) |
---|
12 | (* under the terms of the INRIA Non-Commercial License Agreement. *) |
---|
13 | (* *) |
---|
14 | (* *********************************************************************) |
---|
15 | |
---|
16 | (* * Dynamic semantics for the Clight language *) |
---|
17 | |
---|
18 | include "Coqlib.ma". |
---|
19 | include "Errors.ma". |
---|
20 | include "Integers.ma". |
---|
21 | include "Floats.ma". |
---|
22 | include "Values.ma". |
---|
23 | include "AST.ma". |
---|
24 | include "Mem.ma". |
---|
25 | include "Globalenvs.ma". |
---|
26 | include "Csyntax.ma". |
---|
27 | include "Maps.ma". |
---|
28 | include "Events.ma". |
---|
29 | include "Smallstep.ma". |
---|
30 | |
---|
31 | (* * * Semantics of type-dependent operations *) |
---|
32 | |
---|
33 | (* * Interpretation of values as truth values. |
---|
34 | Non-zero integers, non-zero floats and non-null pointers are |
---|
35 | considered as true. The integer zero (which also represents |
---|
36 | the null pointer) and the float 0.0 are false. *) |
---|
37 | |
---|
38 | ninductive is_false: val → type → Prop ≝ |
---|
39 | | is_false_int: ∀sz,sg. |
---|
40 | is_false (Vint zero) (Tint sz sg) |
---|
41 | | is_false_pointer: ∀s,t. |
---|
42 | is_false (Vint zero) (Tpointer s t) |
---|
43 | | is_false_float: ∀sz. |
---|
44 | is_false (Vfloat Fzero) (Tfloat sz). |
---|
45 | |
---|
46 | ninductive is_true: val → type → Prop ≝ |
---|
47 | | is_true_int_int: ∀n,sz,sg. |
---|
48 | n ≠ zero → |
---|
49 | is_true (Vint n) (Tint sz sg) |
---|
50 | | is_true_pointer_int: ∀psp,b,ofs,sz,sg. |
---|
51 | is_true (Vptr psp b ofs) (Tint sz sg) |
---|
52 | | is_true_int_pointer: ∀n,s,t. |
---|
53 | n ≠ zero → |
---|
54 | is_true (Vint n) (Tpointer s t) |
---|
55 | | is_true_pointer_pointer: ∀psp,b,ofs,s,t. |
---|
56 | is_true (Vptr psp b ofs) (Tpointer s t) |
---|
57 | | is_true_float: ∀f,sz. |
---|
58 | f ≠ Fzero → |
---|
59 | is_true (Vfloat f) (Tfloat sz). |
---|
60 | |
---|
61 | ninductive bool_of_val : val → type → val → Prop ≝ |
---|
62 | | bool_of_val_true: ∀v,ty. |
---|
63 | is_true v ty → |
---|
64 | bool_of_val v ty Vtrue |
---|
65 | | bool_of_val_false: ∀v,ty. |
---|
66 | is_false v ty → |
---|
67 | bool_of_val v ty Vfalse. |
---|
68 | |
---|
69 | (* * The following [sem_] functions compute the result of an operator |
---|
70 | application. Since operators are overloaded, the result depends |
---|
71 | both on the static types of the arguments and on their run-time values. |
---|
72 | Unlike in C, automatic conversions between integers and floats |
---|
73 | are not performed. For instance, [e1 + e2] is undefined if [e1] |
---|
74 | is a float and [e2] an integer. The Clight producer must have explicitly |
---|
75 | promoted [e2] to a float. *) |
---|
76 | |
---|
77 | nlet rec sem_neg (v: val) (ty: type) : option val ≝ |
---|
78 | match ty with |
---|
79 | [ Tint _ _ ⇒ |
---|
80 | match v with |
---|
81 | [ Vint n ⇒ Some ? (Vint (neg n)) |
---|
82 | | _ => None ? |
---|
83 | ] |
---|
84 | | Tfloat _ ⇒ |
---|
85 | match v with |
---|
86 | [ Vfloat f ⇒ Some ? (Vfloat (Fneg f)) |
---|
87 | | _ ⇒ None ? |
---|
88 | ] |
---|
89 | | _ ⇒ None ? |
---|
90 | ]. |
---|
91 | |
---|
92 | nlet rec sem_notint (v: val) : option val ≝ |
---|
93 | match v with |
---|
94 | [ Vint n ⇒ Some ? (Vint (xor n mone)) |
---|
95 | | _ ⇒ None ? |
---|
96 | ]. |
---|
97 | |
---|
98 | nlet rec sem_notbool (v: val) (ty: type) : option val ≝ |
---|
99 | match ty with |
---|
100 | [ Tint _ _ ⇒ |
---|
101 | match v with |
---|
102 | [ Vint n ⇒ Some ? (of_bool (eq n zero)) |
---|
103 | | Vptr _ _ _ ⇒ Some ? Vfalse |
---|
104 | | _ ⇒ None ? |
---|
105 | ] |
---|
106 | | Tpointer _ _ ⇒ |
---|
107 | match v with |
---|
108 | [ Vint n ⇒ Some ? (of_bool (eq n zero)) |
---|
109 | | Vptr _ _ _ ⇒ Some ? Vfalse |
---|
110 | | _ ⇒ None ? |
---|
111 | ] |
---|
112 | | Tfloat _ ⇒ |
---|
113 | match v with |
---|
114 | [ Vfloat f ⇒ Some ? (of_bool (Fcmp Ceq f Fzero)) |
---|
115 | | _ ⇒ None ? |
---|
116 | ] |
---|
117 | | _ ⇒ None ? |
---|
118 | ]. |
---|
119 | |
---|
120 | nlet rec sem_add (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
---|
121 | match classify_add t1 t2 with |
---|
122 | [ add_case_ii ⇒ (**r integer addition *) |
---|
123 | match v1 with |
---|
124 | [ Vint n1 ⇒ match v2 with |
---|
125 | [ Vint n2 ⇒ Some ? (Vint (add n1 n2)) |
---|
126 | | _ ⇒ None ? ] |
---|
127 | | _ ⇒ None ? ] |
---|
128 | | add_case_ff ⇒ (**r float addition *) |
---|
129 | match v1 with |
---|
130 | [ Vfloat n1 ⇒ match v2 with |
---|
131 | [ Vfloat n2 ⇒ Some ? (Vfloat (Fadd n1 n2)) |
---|
132 | | _ ⇒ None ? ] |
---|
133 | | _ ⇒ None ? ] |
---|
134 | | add_case_pi ty ⇒ (**r pointer plus integer *) |
---|
135 | match v1 with |
---|
136 | [ Vptr pcl1 b1 ofs1 ⇒ match v2 with |
---|
137 | [ Vint n2 ⇒ Some ? (Vptr pcl1 b1 (add ofs1 (mul (repr (sizeof ty)) n2))) |
---|
138 | | _ ⇒ None ? ] |
---|
139 | | _ ⇒ None ? ] |
---|
140 | | add_case_ip ty ⇒ (**r integer plus pointer *) |
---|
141 | match v1 with |
---|
142 | [ Vint n1 ⇒ match v2 with |
---|
143 | [ Vptr pcl2 b2 ofs2 ⇒ Some ? (Vptr pcl2 b2 (add ofs2 (mul (repr (sizeof ty)) n1))) |
---|
144 | | _ ⇒ None ? ] |
---|
145 | | _ ⇒ None ? ] |
---|
146 | | add_default ⇒ None ? |
---|
147 | ]. |
---|
148 | |
---|
149 | nlet rec sem_sub (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
---|
150 | match classify_sub t1 t2 with |
---|
151 | [ sub_case_ii ⇒ (**r integer subtraction *) |
---|
152 | match v1 with |
---|
153 | [ Vint n1 ⇒ match v2 with |
---|
154 | [ Vint n2 ⇒ Some ? (Vint (sub n1 n2)) |
---|
155 | | _ ⇒ None ? ] |
---|
156 | | _ ⇒ None ? ] |
---|
157 | | sub_case_ff ⇒ (**r float subtraction *) |
---|
158 | match v1 with |
---|
159 | [ Vfloat f1 ⇒ match v2 with |
---|
160 | [ Vfloat f2 ⇒ Some ? (Vfloat (Fsub f1 f2)) |
---|
161 | | _ ⇒ None ? ] |
---|
162 | | _ ⇒ None ? ] |
---|
163 | | sub_case_pi ty ⇒ (**r pointer minus integer *) |
---|
164 | match v1 with |
---|
165 | [ Vptr pcl1 b1 ofs1 ⇒ match v2 with |
---|
166 | [ Vint n2 ⇒ Some ? (Vptr pcl1 b1 (sub ofs1 (mul (repr (sizeof ty)) n2))) |
---|
167 | | _ ⇒ None ? ] |
---|
168 | | _ ⇒ None ? ] |
---|
169 | | sub_case_pp ty ⇒ (**r pointer minus pointer *) |
---|
170 | match v1 with |
---|
171 | [ Vptr pcl1 b1 ofs1 ⇒ match v2 with |
---|
172 | [ Vptr pcl2 b2 ofs2 ⇒ |
---|
173 | if eqZb b1 b2 then |
---|
174 | if eq (repr (sizeof ty)) zero then None ? |
---|
175 | else Some ? (Vint (divu (sub ofs1 ofs2) (repr (sizeof ty)))) |
---|
176 | else None ? |
---|
177 | | _ ⇒ None ? ] |
---|
178 | | _ ⇒ None ? ] |
---|
179 | | sub_default ⇒ None ? |
---|
180 | ]. |
---|
181 | |
---|
182 | nlet rec sem_mul (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
---|
183 | match classify_mul t1 t2 with |
---|
184 | [ mul_case_ii ⇒ |
---|
185 | match v1 with |
---|
186 | [ Vint n1 ⇒ match v2 with |
---|
187 | [ Vint n2 ⇒ Some ? (Vint (mul n1 n2)) |
---|
188 | | _ ⇒ None ? ] |
---|
189 | | _ ⇒ None ? ] |
---|
190 | | mul_case_ff ⇒ |
---|
191 | match v1 with |
---|
192 | [ Vfloat f1 ⇒ match v2 with |
---|
193 | [ Vfloat f2 ⇒ Some ? (Vfloat (Fmul f1 f2)) |
---|
194 | | _ ⇒ None ? ] |
---|
195 | | _ ⇒ None ? ] |
---|
196 | | mul_default ⇒ |
---|
197 | None ? |
---|
198 | ]. |
---|
199 | |
---|
200 | nlet rec sem_div (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
---|
201 | match classify_div t1 t2 with |
---|
202 | [ div_case_I32unsi ⇒ |
---|
203 | match v1 with |
---|
204 | [ Vint n1 ⇒ match v2 with |
---|
205 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint (divu n1 n2)) |
---|
206 | | _ ⇒ None ? ] |
---|
207 | | _ ⇒ None ? ] |
---|
208 | | div_case_ii ⇒ |
---|
209 | match v1 with |
---|
210 | [ Vint n1 ⇒ match v2 with |
---|
211 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint(divs n1 n2)) |
---|
212 | | _ ⇒ None ? ] |
---|
213 | | _ ⇒ None ? ] |
---|
214 | | div_case_ff ⇒ |
---|
215 | match v1 with |
---|
216 | [ Vfloat f1 ⇒ match v2 with |
---|
217 | [ Vfloat f2 ⇒ Some ? (Vfloat(Fdiv f1 f2)) |
---|
218 | | _ ⇒ None ? ] |
---|
219 | | _ ⇒ None ? ] |
---|
220 | | div_default ⇒ |
---|
221 | None ? |
---|
222 | ]. |
---|
223 | |
---|
224 | nlet rec sem_mod (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
---|
225 | match classify_mod t1 t2 with |
---|
226 | [ mod_case_I32unsi ⇒ |
---|
227 | match v1 with |
---|
228 | [ Vint n1 ⇒ match v2 with |
---|
229 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint (modu n1 n2)) |
---|
230 | | _ ⇒ None ? ] |
---|
231 | | _ ⇒ None ? ] |
---|
232 | | mod_case_ii ⇒ |
---|
233 | match v1 with |
---|
234 | [ Vint n1 ⇒ match v2 with |
---|
235 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint (mods n1 n2)) |
---|
236 | | _ ⇒ None ? ] |
---|
237 | | _ ⇒ None ? ] |
---|
238 | | mod_default ⇒ |
---|
239 | None ? |
---|
240 | ]. |
---|
241 | |
---|
242 | nlet rec sem_and (v1,v2: val) : option val ≝ |
---|
243 | match v1 with |
---|
244 | [ Vint n1 ⇒ match v2 with |
---|
245 | [ Vint n2 ⇒ Some ? (Vint(i_and n1 n2)) |
---|
246 | | _ ⇒ None ? ] |
---|
247 | | _ ⇒ None ? |
---|
248 | ]. |
---|
249 | |
---|
250 | nlet rec sem_or (v1,v2: val) : option val ≝ |
---|
251 | match v1 with |
---|
252 | [ Vint n1 ⇒ match v2 with |
---|
253 | [ Vint n2 ⇒ Some ? (Vint(or n1 n2)) |
---|
254 | | _ ⇒ None ? ] |
---|
255 | | _ ⇒ None ? |
---|
256 | ]. |
---|
257 | |
---|
258 | nlet rec sem_xor (v1,v2: val) : option val ≝ |
---|
259 | match v1 with |
---|
260 | [ Vint n1 ⇒ match v2 with |
---|
261 | [ Vint n2 ⇒ Some ? (Vint(xor n1 n2)) |
---|
262 | | _ ⇒ None ? ] |
---|
263 | | _ ⇒ None ? |
---|
264 | ]. |
---|
265 | |
---|
266 | nlet rec sem_shl (v1,v2: val): option val ≝ |
---|
267 | match v1 with |
---|
268 | [ Vint n1 ⇒ match v2 with |
---|
269 | [ Vint n2 ⇒ |
---|
270 | if ltu n2 iwordsize then Some ? (Vint(shl n1 n2)) else None ? |
---|
271 | | _ ⇒ None ? ] |
---|
272 | | _ ⇒ None ? ]. |
---|
273 | |
---|
274 | nlet rec sem_shr (v1: val) (t1: type) (v2: val) (t2: type): option val ≝ |
---|
275 | match classify_shr t1 t2 with |
---|
276 | [ shr_case_I32unsi ⇒ |
---|
277 | match v1 with |
---|
278 | [ Vint n1 ⇒ match v2 with |
---|
279 | [ Vint n2 ⇒ |
---|
280 | if ltu n2 iwordsize then Some ? (Vint (shru n1 n2)) else None ? |
---|
281 | | _ ⇒ None ? ] |
---|
282 | | _ ⇒ None ? ] |
---|
283 | | shr_case_ii => |
---|
284 | match v1 with |
---|
285 | [ Vint n1 ⇒ match v2 with |
---|
286 | [ Vint n2 ⇒ |
---|
287 | if ltu n2 iwordsize then Some ? (Vint (shr n1 n2)) else None ? |
---|
288 | | _ ⇒ None ? ] |
---|
289 | | _ ⇒ None ? ] |
---|
290 | | shr_default ⇒ |
---|
291 | None ? |
---|
292 | ]. |
---|
293 | |
---|
294 | nlet rec sem_cmp_mismatch (c: comparison): option val ≝ |
---|
295 | match c with |
---|
296 | [ Ceq => Some ? Vfalse |
---|
297 | | Cne => Some ? Vtrue |
---|
298 | | _ => None ? |
---|
299 | ]. |
---|
300 | |
---|
301 | nlet rec sem_cmp (c:comparison) |
---|
302 | (v1: val) (t1: type) (v2: val) (t2: type) |
---|
303 | (m: mem): option val ≝ |
---|
304 | match classify_cmp t1 t2 with |
---|
305 | [ cmp_case_I32unsi ⇒ |
---|
306 | match v1 with |
---|
307 | [ Vint n1 ⇒ match v2 with |
---|
308 | [ Vint n2 ⇒ Some ? (of_bool (cmpu c n1 n2)) |
---|
309 | | _ ⇒ None ? ] |
---|
310 | | _ ⇒ None ? ] |
---|
311 | | cmp_case_ipip ⇒ |
---|
312 | match v1 with |
---|
313 | [ Vint n1 ⇒ match v2 with |
---|
314 | [ Vint n2 ⇒ Some ? (of_bool (cmp c n1 n2)) |
---|
315 | | Vptr psp b ofs ⇒ if eq n1 zero then sem_cmp_mismatch c else None ? |
---|
316 | | _ ⇒ None ? |
---|
317 | ] |
---|
318 | | Vptr pcl1 b1 ofs1 ⇒ |
---|
319 | match v2 with |
---|
320 | [ Vptr pcl2 b2 ofs2 ⇒ |
---|
321 | if valid_pointer m pcl1 b1 (signed ofs1) |
---|
322 | ∧ valid_pointer m pcl2 b2 (signed ofs2) then |
---|
323 | if eqZb b1 b2 |
---|
324 | then Some ? (of_bool (cmp c ofs1 ofs2)) |
---|
325 | else sem_cmp_mismatch c |
---|
326 | else None ? |
---|
327 | | Vint n ⇒ |
---|
328 | if eq n zero then sem_cmp_mismatch c else None ? |
---|
329 | | _ ⇒ None ? ] |
---|
330 | | _ ⇒ None ? ] |
---|
331 | | cmp_case_ff ⇒ |
---|
332 | match v1 with |
---|
333 | [ Vfloat f1 ⇒ |
---|
334 | match v2 with |
---|
335 | [ Vfloat f2 ⇒ Some ? (of_bool (Fcmp c f1 f2)) |
---|
336 | | _ ⇒ None ? ] |
---|
337 | | _ ⇒ None ? ] |
---|
338 | | cmp_default ⇒ None ? |
---|
339 | ]. |
---|
340 | |
---|
341 | ndefinition sem_unary_operation |
---|
342 | : unary_operation → val → type → option val ≝ |
---|
343 | λop,v,ty. |
---|
344 | match op with |
---|
345 | [ Onotbool => sem_notbool v ty |
---|
346 | | Onotint => sem_notint v |
---|
347 | | Oneg => sem_neg v ty |
---|
348 | ]. |
---|
349 | |
---|
350 | nlet rec sem_binary_operation |
---|
351 | (op: binary_operation) |
---|
352 | (v1: val) (t1: type) (v2: val) (t2:type) |
---|
353 | (m: mem): option val ≝ |
---|
354 | match op with |
---|
355 | [ Oadd ⇒ sem_add v1 t1 v2 t2 |
---|
356 | | Osub ⇒ sem_sub v1 t1 v2 t2 |
---|
357 | | Omul ⇒ sem_mul v1 t1 v2 t2 |
---|
358 | | Omod ⇒ sem_mod v1 t1 v2 t2 |
---|
359 | | Odiv ⇒ sem_div v1 t1 v2 t2 |
---|
360 | | Oand ⇒ sem_and v1 v2 |
---|
361 | | Oor ⇒ sem_or v1 v2 |
---|
362 | | Oxor ⇒ sem_xor v1 v2 |
---|
363 | | Oshl ⇒ sem_shl v1 v2 |
---|
364 | | Oshr ⇒ sem_shr v1 t1 v2 t2 |
---|
365 | | Oeq ⇒ sem_cmp Ceq v1 t1 v2 t2 m |
---|
366 | | One ⇒ sem_cmp Cne v1 t1 v2 t2 m |
---|
367 | | Olt ⇒ sem_cmp Clt v1 t1 v2 t2 m |
---|
368 | | Ogt ⇒ sem_cmp Cgt v1 t1 v2 t2 m |
---|
369 | | Ole ⇒ sem_cmp Cle v1 t1 v2 t2 m |
---|
370 | | Oge ⇒ sem_cmp Cge v1 t1 v2 t2 m |
---|
371 | ]. |
---|
372 | |
---|
373 | (* * Semantic of casts. [cast v1 t1 t2 v2] holds if value [v1], |
---|
374 | viewed with static type [t1], can be cast to type [t2], |
---|
375 | resulting in value [v2]. *) |
---|
376 | |
---|
377 | nlet rec cast_int_int (sz: intsize) (sg: signedness) (i: int) : int ≝ |
---|
378 | match sz with |
---|
379 | [ I8 ⇒ match sg with [ Signed ⇒ sign_ext 8 i | Unsigned ⇒ zero_ext 8 i ] |
---|
380 | | I16 ⇒ match sg with [ Signed => sign_ext 16 i | Unsigned ⇒ zero_ext 16 i ] |
---|
381 | | I32 ⇒ i |
---|
382 | ]. |
---|
383 | |
---|
384 | nlet rec cast_int_float (si : signedness) (i: int) : float ≝ |
---|
385 | match si with |
---|
386 | [ Signed ⇒ floatofint i |
---|
387 | | Unsigned ⇒ floatofintu i |
---|
388 | ]. |
---|
389 | |
---|
390 | nlet rec cast_float_int (si : signedness) (f: float) : int ≝ |
---|
391 | match si with |
---|
392 | [ Signed ⇒ intoffloat f |
---|
393 | | Unsigned ⇒ intuoffloat f |
---|
394 | ]. |
---|
395 | |
---|
396 | nlet rec cast_float_float (sz: floatsize) (f: float) : float ≝ |
---|
397 | match sz with |
---|
398 | [ F32 ⇒ singleoffloat f |
---|
399 | | F64 ⇒ f |
---|
400 | ]. |
---|
401 | |
---|
402 | ninductive type_pointable : type → Prop ≝ |
---|
403 | (* All integer sizes can represent at least one kind of pointer *) |
---|
404 | | type_ptr_pointer : ∀s,t. type_pointable (Tpointer s t) |
---|
405 | | type_ptr_array : ∀s,t,n. type_pointable (Tarray s t n) |
---|
406 | | type_ptr_function : ∀tys,ty. type_pointable (Tfunction tys ty). |
---|
407 | |
---|
408 | ninductive type_space : type → memory_space → Prop ≝ |
---|
409 | | type_spc_pointer : ∀s,t. type_space (Tpointer s t) s |
---|
410 | | type_spc_array : ∀s,t,n. type_space (Tarray s t n) s |
---|
411 | (* XXX Is the following necessary? *) |
---|
412 | | type_spc_code : ∀tys,ty. type_space (Tfunction tys ty) Code. |
---|
413 | |
---|
414 | ninductive cast : mem → val → type → type → val → Prop ≝ |
---|
415 | | cast_ii: ∀m,i,sz2,sz1,si1,si2. (**r int to int *) |
---|
416 | cast m (Vint i) (Tint sz1 si1) (Tint sz2 si2) |
---|
417 | (Vint (cast_int_int sz2 si2 i)) |
---|
418 | | cast_fi: ∀m,f,sz1,sz2,si2. (**r float to int *) |
---|
419 | cast m (Vfloat f) (Tfloat sz1) (Tint sz2 si2) |
---|
420 | (Vint (cast_int_int sz2 si2 (cast_float_int si2 f))) |
---|
421 | | cast_if: ∀m,i,sz1,sz2,si1. (**r int to float *) |
---|
422 | cast m (Vint i) (Tint sz1 si1) (Tfloat sz2) |
---|
423 | (Vfloat (cast_float_float sz2 (cast_int_float si1 i))) |
---|
424 | | cast_ff: ∀m,f,sz1,sz2. (**r float to float *) |
---|
425 | cast m (Vfloat f) (Tfloat sz1) (Tfloat sz2) |
---|
426 | (Vfloat (cast_float_float sz2 f)) |
---|
427 | | cast_pp: ∀m,psp,psp',ty,ty',b,ofs. |
---|
428 | type_space ty psp → |
---|
429 | type_space ty' psp' → |
---|
430 | pointer_compat (block_space m b) psp' → |
---|
431 | cast m (Vptr psp b ofs) ty ty' (Vptr psp' b ofs) |
---|
432 | | cast_ip_z: ∀m,sz,sg,ty'. |
---|
433 | type_pointable ty' → |
---|
434 | cast m (Vint zero) (Tint sz sg) ty' (Vint zero) |
---|
435 | | cast_pp_z: ∀m,ty,ty'. |
---|
436 | type_pointable ty → |
---|
437 | type_pointable ty' → |
---|
438 | cast m (Vint zero) ty ty' (Vint zero). |
---|
439 | (* Should probably also allow pointers to pass through sufficiently large |
---|
440 | unsigned integers. *) |
---|
441 | (* Perhaps a little too generous? For example, some integers may not |
---|
442 | represent a valid generic pointer. |
---|
443 | | cast_pp_i: ∀m,n,ty,ty',t1,t2. (**r no change in data representation *) |
---|
444 | type_pointable ty → |
---|
445 | type_pointable ty' → |
---|
446 | sizeof ty ≤ sizeof ty' → |
---|
447 | cast m (Vint n) t1 t2 (Vint n). |
---|
448 | *) |
---|
449 | |
---|
450 | (* * * Operational semantics *) |
---|
451 | |
---|
452 | (* * The semantics uses two environments. The global environment |
---|
453 | maps names of functions and global variables to memory block references, |
---|
454 | and function pointers to their definitions. (See module [Globalenvs].) *) |
---|
455 | |
---|
456 | ndefinition genv ≝ (genv_t Genv) fundef. |
---|
457 | |
---|
458 | (* * The local environment maps local variables to block references. |
---|
459 | The current value of the variable is stored in the associated memory |
---|
460 | block. *) |
---|
461 | |
---|
462 | ndefinition env ≝ (tree_t ? PTree) block. (* map variable -> location *) |
---|
463 | |
---|
464 | ndefinition empty_env: env ≝ (empty …). |
---|
465 | |
---|
466 | (* * [load_value_of_type ty m b ofs] computes the value of a datum |
---|
467 | of type [ty] residing in memory [m] at block [b], offset [ofs]. |
---|
468 | If the type [ty] indicates an access by value, the corresponding |
---|
469 | memory load is performed. If the type [ty] indicates an access by |
---|
470 | reference, the pointer [Vptr b ofs] is returned. *) |
---|
471 | |
---|
472 | nlet rec load_value_of_type (ty: type) (m: mem) (psp:memory_space) (b: block) (ofs: int) : option val ≝ |
---|
473 | match access_mode ty with |
---|
474 | [ By_value chunk ⇒ loadv chunk m (Vptr psp b ofs) |
---|
475 | | By_reference ⇒ Some ? (Vptr psp b ofs) |
---|
476 | | By_nothing ⇒ None ? |
---|
477 | ]. |
---|
478 | |
---|
479 | (* * Symmetrically, [store_value_of_type ty m b ofs v] returns the |
---|
480 | memory state after storing the value [v] in the datum |
---|
481 | of type [ty] residing in memory [m] at block [b], offset [ofs]. |
---|
482 | This is allowed only if [ty] indicates an access by value. *) |
---|
483 | |
---|
484 | nlet rec store_value_of_type (ty_dest: type) (m: mem) (psp:memory_space) (loc: block) (ofs: int) (v: val) : option mem ≝ |
---|
485 | match access_mode ty_dest with |
---|
486 | [ By_value chunk ⇒ storev chunk m (Vptr psp loc ofs) v |
---|
487 | | By_reference ⇒ None ? |
---|
488 | | By_nothing ⇒ None ? |
---|
489 | ]. |
---|
490 | |
---|
491 | (* * Allocation of function-local variables. |
---|
492 | [alloc_variables e1 m1 vars e2 m2] allocates one memory block |
---|
493 | for each variable declared in [vars], and associates the variable |
---|
494 | name with this block. [e1] and [m1] are the initial local environment |
---|
495 | and memory state. [e2] and [m2] are the final local environment |
---|
496 | and memory state. *) |
---|
497 | |
---|
498 | ninductive alloc_variables: env → mem → |
---|
499 | list (ident × type) → |
---|
500 | env → mem → Prop ≝ |
---|
501 | | alloc_variables_nil: |
---|
502 | ∀e,m. |
---|
503 | alloc_variables e m (nil ?) e m |
---|
504 | | alloc_variables_cons: |
---|
505 | ∀e,m,id,ty,vars,m1,b1,m2,e2. |
---|
506 | alloc m 0 (sizeof ty) Any = 〈m1, b1〉 → |
---|
507 | alloc_variables (set … id b1 e) m1 vars e2 m2 → |
---|
508 | alloc_variables e m (〈id, ty〉 :: vars) e2 m2. |
---|
509 | |
---|
510 | (* * Initialization of local variables that are parameters to a function. |
---|
511 | [bind_parameters e m1 params args m2] stores the values [args] |
---|
512 | in the memory blocks corresponding to the variables [params]. |
---|
513 | [m1] is the initial memory state and [m2] the final memory state. *) |
---|
514 | |
---|
515 | ninductive bind_parameters: env → |
---|
516 | mem → list (ident × type) → list val → |
---|
517 | mem → Prop ≝ |
---|
518 | | bind_parameters_nil: |
---|
519 | ∀e,m. |
---|
520 | bind_parameters e m (nil ?) (nil ?) m |
---|
521 | | bind_parameters_cons: |
---|
522 | ∀e,m,id,ty,params,v1,vl,b,m1,m2. |
---|
523 | get ??? id e = Some ? b → |
---|
524 | store_value_of_type ty m Any b zero v1 = Some ? m1 → |
---|
525 | bind_parameters e m1 params vl m2 → |
---|
526 | bind_parameters e m (〈id, ty〉 :: params) (v1 :: vl) m2. |
---|
527 | |
---|
528 | (* XXX: this doesn't look right - we're assigning arbitrary memory spaces to |
---|
529 | parameters? *) |
---|
530 | |
---|
531 | (* * Return the list of blocks in the codomain of [e]. *) |
---|
532 | |
---|
533 | ndefinition blocks_of_env : env → list block ≝ λe. |
---|
534 | map ?? (λx. snd ?? x) (elements ??? e). |
---|
535 | |
---|
536 | (* * Selection of the appropriate case of a [switch], given the value [n] |
---|
537 | of the selector expression. *) |
---|
538 | |
---|
539 | nlet rec select_switch (n: int) (sl: labeled_statements) |
---|
540 | on sl : labeled_statements ≝ |
---|
541 | match sl with |
---|
542 | [ LSdefault _ ⇒ sl |
---|
543 | | LScase c s sl' ⇒ if eq c n then sl else select_switch n sl' |
---|
544 | ]. |
---|
545 | |
---|
546 | (* * Turn a labeled statement into a sequence *) |
---|
547 | |
---|
548 | nlet rec seq_of_labeled_statement (sl: labeled_statements) : statement ≝ |
---|
549 | match sl with |
---|
550 | [ LSdefault s ⇒ s |
---|
551 | | LScase c s sl' ⇒ Ssequence s (seq_of_labeled_statement sl') |
---|
552 | ]. |
---|
553 | |
---|
554 | (* |
---|
555 | Section SEMANTICS. |
---|
556 | |
---|
557 | Variable ge: genv. |
---|
558 | |
---|
559 | (** ** Evaluation of expressions *) |
---|
560 | |
---|
561 | Section EXPR. |
---|
562 | |
---|
563 | Variable e: env. |
---|
564 | Variable m: mem. |
---|
565 | *) |
---|
566 | (* * [eval_expr ge e m a v] defines the evaluation of expression [a] |
---|
567 | in r-value position. [v] is the value of the expression. |
---|
568 | [e] is the current environment and [m] is the current memory state. *) |
---|
569 | |
---|
570 | ninductive eval_expr (ge:genv) (e:env) (m:mem) : expr → val → Prop ≝ |
---|
571 | | eval_Econst_int: ∀i,ty. |
---|
572 | eval_expr ge e m (Expr (Econst_int i) ty) (Vint i) |
---|
573 | | eval_Econst_float: ∀f,ty. |
---|
574 | eval_expr ge e m (Expr (Econst_float f) ty) (Vfloat f) |
---|
575 | | eval_Elvalue: ∀a,ty,psp,loc,ofs,v. |
---|
576 | eval_lvalue ge e m (Expr a ty) psp loc ofs -> |
---|
577 | load_value_of_type ty m psp loc ofs = Some ? v -> |
---|
578 | eval_expr ge e m (Expr a ty) v |
---|
579 | | eval_Eaddrof: ∀a,ty,psp,loc,ofs. |
---|
580 | eval_lvalue ge e m a psp loc ofs -> |
---|
581 | eval_expr ge e m (Expr (Eaddrof a) ty) (Vptr psp loc ofs) |
---|
582 | | eval_Esizeof: ∀ty',ty. |
---|
583 | eval_expr ge e m (Expr (Esizeof ty') ty) (Vint (repr (sizeof ty'))) |
---|
584 | | eval_Eunop: ∀op,a,ty,v1,v. |
---|
585 | eval_expr ge e m a v1 -> |
---|
586 | sem_unary_operation op v1 (typeof a) = Some ? v -> |
---|
587 | eval_expr ge e m (Expr (Eunop op a) ty) v |
---|
588 | | eval_Ebinop: ∀op,a1,a2,ty,v1,v2,v. |
---|
589 | eval_expr ge e m a1 v1 -> |
---|
590 | eval_expr ge e m a2 v2 -> |
---|
591 | sem_binary_operation op v1 (typeof a1) v2 (typeof a2) m = Some ? v -> |
---|
592 | eval_expr ge e m (Expr (Ebinop op a1 a2) ty) v |
---|
593 | | eval_Econdition_true: ∀a1,a2,a3,ty,v1,v2. |
---|
594 | eval_expr ge e m a1 v1 -> |
---|
595 | is_true v1 (typeof a1) -> |
---|
596 | eval_expr ge e m a2 v2 -> |
---|
597 | eval_expr ge e m (Expr (Econdition a1 a2 a3) ty) v2 |
---|
598 | | eval_Econdition_false: ∀a1,a2,a3,ty,v1,v3. |
---|
599 | eval_expr ge e m a1 v1 -> |
---|
600 | is_false v1 (typeof a1) -> |
---|
601 | eval_expr ge e m a3 v3 -> |
---|
602 | eval_expr ge e m (Expr (Econdition a1 a2 a3) ty) v3 |
---|
603 | | eval_Eorbool_1: ∀a1,a2,ty,v1. |
---|
604 | eval_expr ge e m a1 v1 -> |
---|
605 | is_true v1 (typeof a1) -> |
---|
606 | eval_expr ge e m (Expr (Eorbool a1 a2) ty) Vtrue |
---|
607 | | eval_Eorbool_2: ∀a1,a2,ty,v1,v2,v. |
---|
608 | eval_expr ge e m a1 v1 -> |
---|
609 | is_false v1 (typeof a1) -> |
---|
610 | eval_expr ge e m a2 v2 -> |
---|
611 | bool_of_val v2 (typeof a2) v -> |
---|
612 | eval_expr ge e m (Expr (Eorbool a1 a2) ty) v |
---|
613 | | eval_Eandbool_1: ∀a1,a2,ty,v1. |
---|
614 | eval_expr ge e m a1 v1 -> |
---|
615 | is_false v1 (typeof a1) -> |
---|
616 | eval_expr ge e m (Expr (Eandbool a1 a2) ty) Vfalse |
---|
617 | | eval_Eandbool_2: ∀a1,a2,ty,v1,v2,v. |
---|
618 | eval_expr ge e m a1 v1 -> |
---|
619 | is_true v1 (typeof a1) -> |
---|
620 | eval_expr ge e m a2 v2 -> |
---|
621 | bool_of_val v2 (typeof a2) v -> |
---|
622 | eval_expr ge e m (Expr (Eandbool a1 a2) ty) v |
---|
623 | | eval_Ecast: ∀a,ty,ty',v1,v. |
---|
624 | eval_expr ge e m a v1 -> |
---|
625 | cast m v1 (typeof a) ty v -> |
---|
626 | eval_expr ge e m (Expr (Ecast ty a) ty') v |
---|
627 | |
---|
628 | (* * [eval_lvalue ge e m a b ofs] defines the evaluation of expression [a] |
---|
629 | in l-value position. The result is the memory location [b, ofs] |
---|
630 | that contains the value of the expression [a]. *) |
---|
631 | |
---|
632 | with eval_lvalue (*(ge:genv) (e:env) (m:mem)*) : expr → memory_space → block -> int -> Prop ≝ |
---|
633 | | eval_Evar_local: ∀id,l,ty. |
---|
634 | (* XXX notation? e!id*) get ??? id e = Some ? l → |
---|
635 | eval_lvalue ge e m (Expr (Evar id) ty) Any l zero |
---|
636 | | eval_Evar_global: ∀id,sp,l,ty. |
---|
637 | (* XXX e!id *) get ??? id e = None ? -> |
---|
638 | find_symbol ?? ge id = Some ? 〈sp,l〉 -> |
---|
639 | eval_lvalue ge e m (Expr (Evar id) ty) sp l zero |
---|
640 | | eval_Ederef: ∀a,ty,psp,l,ofs. |
---|
641 | eval_expr ge e m a (Vptr psp l ofs) -> |
---|
642 | eval_lvalue ge e m (Expr (Ederef a) ty) psp l ofs |
---|
643 | | eval_Efield_struct: ∀a,i,ty,psp,l,ofs,id,fList,delta. |
---|
644 | eval_lvalue ge e m a psp l ofs -> |
---|
645 | typeof a = Tstruct id fList -> |
---|
646 | field_offset i fList = OK ? delta -> |
---|
647 | eval_lvalue ge e m (Expr (Efield a i) ty) psp l (add ofs (repr delta)) |
---|
648 | | eval_Efield_union: ∀a,i,ty,psp,l,ofs,id,fList. |
---|
649 | eval_lvalue ge e m a psp l ofs -> |
---|
650 | typeof a = Tunion id fList -> |
---|
651 | eval_lvalue ge e m (Expr (Efield a i) ty) psp l ofs. |
---|
652 | |
---|
653 | (* |
---|
654 | Scheme eval_expr_ind2 := Minimality for eval_expr Sort Prop |
---|
655 | with eval_lvalue_ind2 := Minimality for eval_lvalue Sort Prop. |
---|
656 | *) |
---|
657 | |
---|
658 | (* * [eval_exprlist ge e m al vl] evaluates a list of r-value |
---|
659 | expressions [al] to their values [vl]. *) |
---|
660 | |
---|
661 | ninductive eval_exprlist (ge:genv) (e:env) (m:mem) : list expr -> list val -> Prop := |
---|
662 | | eval_Enil: |
---|
663 | eval_exprlist ge e m (nil ?) (nil ?) |
---|
664 | | eval_Econs: ∀a,bl,v,vl. |
---|
665 | eval_expr ge e m a v -> |
---|
666 | eval_exprlist ge e m bl vl -> |
---|
667 | eval_exprlist ge e m (a :: bl) (v :: vl). |
---|
668 | |
---|
669 | (*End EXPR.*) |
---|
670 | |
---|
671 | (* * ** Transition semantics for statements and functions *) |
---|
672 | |
---|
673 | (* * Continuations *) |
---|
674 | |
---|
675 | ninductive cont: Type := |
---|
676 | | Kstop: cont |
---|
677 | | Kseq: statement -> cont -> cont |
---|
678 | (**r [Kseq s2 k] = after [s1] in [s1;s2] *) |
---|
679 | | Kwhile: expr -> statement -> cont -> cont |
---|
680 | (**r [Kwhile e s k] = after [s] in [while (e) s] *) |
---|
681 | | Kdowhile: expr -> statement -> cont -> cont |
---|
682 | (**r [Kdowhile e s k] = after [s] in [do s while (e)] *) |
---|
683 | | Kfor2: expr -> statement -> statement -> cont -> cont |
---|
684 | (**r [Kfor2 e2 e3 s k] = after [s] in [for(e1;e2;e3) s] *) |
---|
685 | | Kfor3: expr -> statement -> statement -> cont -> cont |
---|
686 | (**r [Kfor3 e2 e3 s k] = after [e3] in [for(e1;e2;e3) s] *) |
---|
687 | | Kswitch: cont -> cont |
---|
688 | (**r catches [break] statements arising out of [switch] *) |
---|
689 | | Kcall: option (memory_space × block × int × type) -> (**r where to store result *) |
---|
690 | function -> (**r calling function *) |
---|
691 | env -> (**r local env of calling function *) |
---|
692 | cont -> cont. |
---|
693 | |
---|
694 | (* * Pop continuation until a call or stop *) |
---|
695 | |
---|
696 | nlet rec call_cont (k: cont) : cont := |
---|
697 | match k with |
---|
698 | [ Kseq s k => call_cont k |
---|
699 | | Kwhile e s k => call_cont k |
---|
700 | | Kdowhile e s k => call_cont k |
---|
701 | | Kfor2 e2 e3 s k => call_cont k |
---|
702 | | Kfor3 e2 e3 s k => call_cont k |
---|
703 | | Kswitch k => call_cont k |
---|
704 | | _ => k |
---|
705 | ]. |
---|
706 | |
---|
707 | ndefinition is_call_cont : cont → Prop ≝ λk. |
---|
708 | match k with |
---|
709 | [ Kstop => True |
---|
710 | | Kcall _ _ _ _ => True |
---|
711 | | _ => False |
---|
712 | ]. |
---|
713 | |
---|
714 | (* * States *) |
---|
715 | |
---|
716 | ninductive state: Type := |
---|
717 | | State: |
---|
718 | ∀f: function. |
---|
719 | ∀s: statement. |
---|
720 | ∀k: cont. |
---|
721 | ∀e: env. |
---|
722 | ∀m: mem. state |
---|
723 | | Callstate: |
---|
724 | ∀fd: fundef. |
---|
725 | ∀args: list val. |
---|
726 | ∀k: cont. |
---|
727 | ∀m: mem. state |
---|
728 | | Returnstate: |
---|
729 | ∀res: val. |
---|
730 | ∀k: cont. |
---|
731 | ∀m: mem. state. |
---|
732 | |
---|
733 | (* * Find the statement and manufacture the continuation |
---|
734 | corresponding to a label *) |
---|
735 | |
---|
736 | nlet rec find_label (lbl: label) (s: statement) (k: cont) |
---|
737 | on s: option (statement × cont) := |
---|
738 | match s with |
---|
739 | [ Ssequence s1 s2 => |
---|
740 | match find_label lbl s1 (Kseq s2 k) with |
---|
741 | [ Some sk => Some ? sk |
---|
742 | | None => find_label lbl s2 k |
---|
743 | ] |
---|
744 | | Sifthenelse a s1 s2 => |
---|
745 | match find_label lbl s1 k with |
---|
746 | [ Some sk => Some ? sk |
---|
747 | | None => find_label lbl s2 k |
---|
748 | ] |
---|
749 | | Swhile a s1 => |
---|
750 | find_label lbl s1 (Kwhile a s1 k) |
---|
751 | | Sdowhile a s1 => |
---|
752 | find_label lbl s1 (Kdowhile a s1 k) |
---|
753 | | Sfor a1 a2 a3 s1 => |
---|
754 | match find_label lbl a1 (Kseq (Sfor Sskip a2 a3 s1) k) with |
---|
755 | [ Some sk => Some ? sk |
---|
756 | | None => |
---|
757 | match find_label lbl s1 (Kfor2 a2 a3 s1 k) with |
---|
758 | [ Some sk => Some ? sk |
---|
759 | | None => find_label lbl a3 (Kfor3 a2 a3 s1 k) |
---|
760 | ] |
---|
761 | ] |
---|
762 | | Sswitch e sl => |
---|
763 | find_label_ls lbl sl (Kswitch k) |
---|
764 | | Slabel lbl' s' => |
---|
765 | match ident_eq lbl lbl' with |
---|
766 | [ inl _ ⇒ Some ? 〈s', k〉 |
---|
767 | | inr _ ⇒ find_label lbl s' k |
---|
768 | ] |
---|
769 | | _ => None ? |
---|
770 | ] |
---|
771 | |
---|
772 | and find_label_ls (lbl: label) (sl: labeled_statements) (k: cont) |
---|
773 | on sl: option (statement × cont) := |
---|
774 | match sl with |
---|
775 | [ LSdefault s => find_label lbl s k |
---|
776 | | LScase _ s sl' => |
---|
777 | match find_label lbl s (Kseq (seq_of_labeled_statement sl') k) with |
---|
778 | [ Some sk => Some ? sk |
---|
779 | | None => find_label_ls lbl sl' k |
---|
780 | ] |
---|
781 | ]. |
---|
782 | |
---|
783 | (* * Transition relation *) |
---|
784 | |
---|
785 | ninductive step (ge:genv) : state -> trace -> state -> Prop := |
---|
786 | |
---|
787 | | step_assign: ∀f,a1,a2,k,e,m,psp,loc,ofs,v2,m'. |
---|
788 | eval_lvalue ge e m a1 psp loc ofs -> |
---|
789 | eval_expr ge e m a2 v2 -> |
---|
790 | store_value_of_type (typeof a1) m psp loc ofs v2 = Some ? m' -> |
---|
791 | step ge (State f (Sassign a1 a2) k e m) |
---|
792 | E0 (State f Sskip k e m') |
---|
793 | |
---|
794 | | step_call_none: ∀f,a,al,k,e,m,vf,vargs,fd. |
---|
795 | eval_expr ge e m a vf -> |
---|
796 | eval_exprlist ge e m al vargs -> |
---|
797 | find_funct ?? ge vf = Some ? fd -> |
---|
798 | type_of_fundef fd = typeof a -> |
---|
799 | step ge (State f (Scall (None ?) a al) k e m) |
---|
800 | E0 (Callstate fd vargs (Kcall (None ?) f e k) m) |
---|
801 | |
---|
802 | | step_call_some: ∀f,lhs,a,al,k,e,m,psp,loc,ofs,vf,vargs,fd. |
---|
803 | eval_lvalue ge e m lhs psp loc ofs -> |
---|
804 | eval_expr ge e m a vf -> |
---|
805 | eval_exprlist ge e m al vargs -> |
---|
806 | find_funct ?? ge vf = Some ? fd -> |
---|
807 | type_of_fundef fd = typeof a -> |
---|
808 | step ge (State f (Scall (Some ? lhs) a al) k e m) |
---|
809 | E0 (Callstate fd vargs (Kcall (Some ? 〈〈〈psp, loc〉, ofs〉, typeof lhs〉) f e k) m) |
---|
810 | |
---|
811 | | step_seq: ∀f,s1,s2,k,e,m. |
---|
812 | step ge (State f (Ssequence s1 s2) k e m) |
---|
813 | E0 (State f s1 (Kseq s2 k) e m) |
---|
814 | | step_skip_seq: ∀f,s,k,e,m. |
---|
815 | step ge (State f Sskip (Kseq s k) e m) |
---|
816 | E0 (State f s k e m) |
---|
817 | | step_continue_seq: ∀f,s,k,e,m. |
---|
818 | step ge (State f Scontinue (Kseq s k) e m) |
---|
819 | E0 (State f Scontinue k e m) |
---|
820 | | step_break_seq: ∀f,s,k,e,m. |
---|
821 | step ge (State f Sbreak (Kseq s k) e m) |
---|
822 | E0 (State f Sbreak k e m) |
---|
823 | |
---|
824 | | step_ifthenelse_true: ∀f,a,s1,s2,k,e,m,v1. |
---|
825 | eval_expr ge e m a v1 -> |
---|
826 | is_true v1 (typeof a) -> |
---|
827 | step ge (State f (Sifthenelse a s1 s2) k e m) |
---|
828 | E0 (State f s1 k e m) |
---|
829 | | step_ifthenelse_false: ∀f,a,s1,s2,k,e,m,v1. |
---|
830 | eval_expr ge e m a v1 -> |
---|
831 | is_false v1 (typeof a) -> |
---|
832 | step ge (State f (Sifthenelse a s1 s2) k e m) |
---|
833 | E0 (State f s2 k e m) |
---|
834 | |
---|
835 | | step_while_false: ∀f,a,s,k,e,m,v. |
---|
836 | eval_expr ge e m a v -> |
---|
837 | is_false v (typeof a) -> |
---|
838 | step ge (State f (Swhile a s) k e m) |
---|
839 | E0 (State f Sskip k e m) |
---|
840 | | step_while_true: ∀f,a,s,k,e,m,v. |
---|
841 | eval_expr ge e m a v -> |
---|
842 | is_true v (typeof a) -> |
---|
843 | step ge (State f (Swhile a s) k e m) |
---|
844 | E0 (State f s (Kwhile a s k) e m) |
---|
845 | | step_skip_or_continue_while: ∀f,x,a,s,k,e,m. |
---|
846 | x = Sskip ∨ x = Scontinue -> |
---|
847 | step ge (State f x (Kwhile a s k) e m) |
---|
848 | E0 (State f (Swhile a s) k e m) |
---|
849 | | step_break_while: ∀f,a,s,k,e,m. |
---|
850 | step ge (State f Sbreak (Kwhile a s k) e m) |
---|
851 | E0 (State f Sskip k e m) |
---|
852 | |
---|
853 | | step_dowhile: ∀f,a,s,k,e,m. |
---|
854 | step ge (State f (Sdowhile a s) k e m) |
---|
855 | E0 (State f s (Kdowhile a s k) e m) |
---|
856 | | step_skip_or_continue_dowhile_false: ∀f,x,a,s,k,e,m,v. |
---|
857 | x = Sskip ∨ x = Scontinue -> |
---|
858 | eval_expr ge e m a v -> |
---|
859 | is_false v (typeof a) -> |
---|
860 | step ge (State f x (Kdowhile a s k) e m) |
---|
861 | E0 (State f Sskip k e m) |
---|
862 | | step_skip_or_continue_dowhile_true: ∀f,x,a,s,k,e,m,v. |
---|
863 | x = Sskip ∨ x = Scontinue -> |
---|
864 | eval_expr ge e m a v -> |
---|
865 | is_true v (typeof a) -> |
---|
866 | step ge (State f x (Kdowhile a s k) e m) |
---|
867 | E0 (State f (Sdowhile a s) k e m) |
---|
868 | | step_break_dowhile: ∀f,a,s,k,e,m. |
---|
869 | step ge (State f Sbreak (Kdowhile a s k) e m) |
---|
870 | E0 (State f Sskip k e m) |
---|
871 | |
---|
872 | | step_for_start: ∀f,a1,a2,a3,s,k,e,m. |
---|
873 | a1 ≠ Sskip -> |
---|
874 | step ge (State f (Sfor a1 a2 a3 s) k e m) |
---|
875 | E0 (State f a1 (Kseq (Sfor Sskip a2 a3 s) k) e m) |
---|
876 | | step_for_false: ∀f,a2,a3,s,k,e,m,v. |
---|
877 | eval_expr ge e m a2 v -> |
---|
878 | is_false v (typeof a2) -> |
---|
879 | step ge (State f (Sfor Sskip a2 a3 s) k e m) |
---|
880 | E0 (State f Sskip k e m) |
---|
881 | | step_for_true: ∀f,a2,a3,s,k,e,m,v. |
---|
882 | eval_expr ge e m a2 v -> |
---|
883 | is_true v (typeof a2) -> |
---|
884 | step ge (State f (Sfor Sskip a2 a3 s) k e m) |
---|
885 | E0 (State f s (Kfor2 a2 a3 s k) e m) |
---|
886 | | step_skip_or_continue_for2: ∀f,x,a2,a3,s,k,e,m. |
---|
887 | x = Sskip ∨ x = Scontinue -> |
---|
888 | step ge (State f x (Kfor2 a2 a3 s k) e m) |
---|
889 | E0 (State f a3 (Kfor3 a2 a3 s k) e m) |
---|
890 | | step_break_for2: ∀f,a2,a3,s,k,e,m. |
---|
891 | step ge (State f Sbreak (Kfor2 a2 a3 s k) e m) |
---|
892 | E0 (State f Sskip k e m) |
---|
893 | | step_skip_for3: ∀f,a2,a3,s,k,e,m. |
---|
894 | step ge (State f Sskip (Kfor3 a2 a3 s k) e m) |
---|
895 | E0 (State f (Sfor Sskip a2 a3 s) k e m) |
---|
896 | |
---|
897 | | step_return_0: ∀f,k,e,m. |
---|
898 | fn_return f = Tvoid -> |
---|
899 | step ge (State f (Sreturn (None ?)) k e m) |
---|
900 | E0 (Returnstate Vundef (call_cont k) (free_list m (blocks_of_env e))) |
---|
901 | | step_return_1: ∀f,a,k,e,m,v. |
---|
902 | fn_return f ≠ Tvoid -> |
---|
903 | eval_expr ge e m a v -> |
---|
904 | step ge (State f (Sreturn (Some ? a)) k e m) |
---|
905 | E0 (Returnstate v (call_cont k) (free_list m (blocks_of_env e))) |
---|
906 | | step_skip_call: ∀f,k,e,m. |
---|
907 | is_call_cont k -> |
---|
908 | fn_return f = Tvoid -> |
---|
909 | step ge (State f Sskip k e m) |
---|
910 | E0 (Returnstate Vundef k (free_list m (blocks_of_env e))) |
---|
911 | |
---|
912 | | step_switch: ∀f,a,sl,k,e,m,n. |
---|
913 | eval_expr ge e m a (Vint n) -> |
---|
914 | step ge (State f (Sswitch a sl) k e m) |
---|
915 | E0 (State f (seq_of_labeled_statement (select_switch n sl)) (Kswitch k) e m) |
---|
916 | | step_skip_break_switch: ∀f,x,k,e,m. |
---|
917 | x = Sskip ∨ x = Sbreak -> |
---|
918 | step ge (State f x (Kswitch k) e m) |
---|
919 | E0 (State f Sskip k e m) |
---|
920 | | step_continue_switch: ∀f,k,e,m. |
---|
921 | step ge (State f Scontinue (Kswitch k) e m) |
---|
922 | E0 (State f Scontinue k e m) |
---|
923 | |
---|
924 | | step_label: ∀f,lbl,s,k,e,m. |
---|
925 | step ge (State f (Slabel lbl s) k e m) |
---|
926 | E0 (State f s k e m) |
---|
927 | |
---|
928 | | step_goto: ∀f,lbl,k,e,m,s',k'. |
---|
929 | find_label lbl (fn_body f) (call_cont k) = Some ? 〈s', k'〉 -> |
---|
930 | step ge (State f (Sgoto lbl) k e m) |
---|
931 | E0 (State f s' k' e m) |
---|
932 | |
---|
933 | | step_internal_function: ∀f,vargs,k,m,e,m1,m2. |
---|
934 | alloc_variables empty_env m ((fn_params f) @ (fn_vars f)) e m1 -> |
---|
935 | bind_parameters e m1 (fn_params f) vargs m2 -> |
---|
936 | step ge (Callstate (Internal f) vargs k m) |
---|
937 | E0 (State f (fn_body f) k e m2) |
---|
938 | |
---|
939 | | step_external_function: ∀id,targs,tres,vargs,k,m,vres,t. |
---|
940 | event_match (external_function id targs tres) vargs t vres -> |
---|
941 | step ge (Callstate (External id targs tres) vargs k m) |
---|
942 | t (Returnstate vres k m) |
---|
943 | |
---|
944 | | step_returnstate_0: ∀v,f,e,k,m. |
---|
945 | step ge (Returnstate v (Kcall (None ?) f e k) m) |
---|
946 | E0 (State f Sskip k e m) |
---|
947 | |
---|
948 | | step_returnstate_1: ∀v,f,e,k,m,m',psp,loc,ofs,ty. |
---|
949 | store_value_of_type ty m psp loc ofs v = Some ? m' -> |
---|
950 | step ge (Returnstate v (Kcall (Some ? 〈〈〈psp,loc〉, ofs〉, ty〉) f e k) m) |
---|
951 | E0 (State f Sskip k e m'). |
---|
952 | (* |
---|
953 | (** * Alternate big-step semantics *) |
---|
954 | |
---|
955 | (** ** Big-step semantics for terminating statements and functions *) |
---|
956 | |
---|
957 | (** The execution of a statement produces an ``outcome'', indicating |
---|
958 | how the execution terminated: either normally or prematurely |
---|
959 | through the execution of a [break], [continue] or [return] statement. *) |
---|
960 | |
---|
961 | ninductive outcome: Type := |
---|
962 | | Out_break: outcome (**r terminated by [break] *) |
---|
963 | | Out_continue: outcome (**r terminated by [continue] *) |
---|
964 | | Out_normal: outcome (**r terminated normally *) |
---|
965 | | Out_return: option val -> outcome. (**r terminated by [return] *) |
---|
966 | |
---|
967 | ninductive out_normal_or_continue : outcome -> Prop := |
---|
968 | | Out_normal_or_continue_N: out_normal_or_continue Out_normal |
---|
969 | | Out_normal_or_continue_C: out_normal_or_continue Out_continue. |
---|
970 | |
---|
971 | ninductive out_break_or_return : outcome -> outcome -> Prop := |
---|
972 | | Out_break_or_return_B: out_break_or_return Out_break Out_normal |
---|
973 | | Out_break_or_return_R: ∀ov. |
---|
974 | out_break_or_return (Out_return ov) (Out_return ov). |
---|
975 | |
---|
976 | Definition outcome_switch (out: outcome) : outcome := |
---|
977 | match out with |
---|
978 | | Out_break => Out_normal |
---|
979 | | o => o |
---|
980 | end. |
---|
981 | |
---|
982 | Definition outcome_result_value (out: outcome) (t: type) (v: val) : Prop := |
---|
983 | match out, t with |
---|
984 | | Out_normal, Tvoid => v = Vundef |
---|
985 | | Out_return None, Tvoid => v = Vundef |
---|
986 | | Out_return (Some v'), ty => ty <> Tvoid /\ v'=v |
---|
987 | | _, _ => False |
---|
988 | end. |
---|
989 | |
---|
990 | (** [exec_stmt ge e m1 s t m2 out] describes the execution of |
---|
991 | the statement [s]. [out] is the outcome for this execution. |
---|
992 | [m1] is the initial memory state, [m2] the final memory state. |
---|
993 | [t] is the trace of input/output events performed during this |
---|
994 | evaluation. *) |
---|
995 | |
---|
996 | ninductive exec_stmt: env -> mem -> statement -> trace -> mem -> outcome -> Prop := |
---|
997 | | exec_Sskip: ∀e,m. |
---|
998 | exec_stmt e m Sskip |
---|
999 | E0 m Out_normal |
---|
1000 | | exec_Sassign: ∀e,m,a1,a2,loc,ofs,v2,m'. |
---|
1001 | eval_lvalue e m a1 loc ofs -> |
---|
1002 | eval_expr e m a2 v2 -> |
---|
1003 | store_value_of_type (typeof a1) m loc ofs v2 = Some m' -> |
---|
1004 | exec_stmt e m (Sassign a1 a2) |
---|
1005 | E0 m' Out_normal |
---|
1006 | | exec_Scall_none: ∀e,m,a,al,vf,vargs,f,t,m',vres. |
---|
1007 | eval_expr e m a vf -> |
---|
1008 | eval_exprlist e m al vargs -> |
---|
1009 | Genv.find_funct ge vf = Some f -> |
---|
1010 | type_of_fundef f = typeof a -> |
---|
1011 | eval_funcall m f vargs t m' vres -> |
---|
1012 | exec_stmt e m (Scall None a al) |
---|
1013 | t m' Out_normal |
---|
1014 | | exec_Scall_some: ∀e,m,lhs,a,al,loc,ofs,vf,vargs,f,t,m',vres,m''. |
---|
1015 | eval_lvalue e m lhs loc ofs -> |
---|
1016 | eval_expr e m a vf -> |
---|
1017 | eval_exprlist e m al vargs -> |
---|
1018 | Genv.find_funct ge vf = Some f -> |
---|
1019 | type_of_fundef f = typeof a -> |
---|
1020 | eval_funcall m f vargs t m' vres -> |
---|
1021 | store_value_of_type (typeof lhs) m' loc ofs vres = Some m'' -> |
---|
1022 | exec_stmt e m (Scall (Some lhs) a al) |
---|
1023 | t m'' Out_normal |
---|
1024 | | exec_Sseq_1: ∀e,m,s1,s2,t1,m1,t2,m2,out. |
---|
1025 | exec_stmt e m s1 t1 m1 Out_normal -> |
---|
1026 | exec_stmt e m1 s2 t2 m2 out -> |
---|
1027 | exec_stmt e m (Ssequence s1 s2) |
---|
1028 | (t1 ** t2) m2 out |
---|
1029 | | exec_Sseq_2: ∀e,m,s1,s2,t1,m1,out. |
---|
1030 | exec_stmt e m s1 t1 m1 out -> |
---|
1031 | out <> Out_normal -> |
---|
1032 | exec_stmt e m (Ssequence s1 s2) |
---|
1033 | t1 m1 out |
---|
1034 | | exec_Sifthenelse_true: ∀e,m,a,s1,s2,v1,t,m',out. |
---|
1035 | eval_expr e m a v1 -> |
---|
1036 | is_true v1 (typeof a) -> |
---|
1037 | exec_stmt e m s1 t m' out -> |
---|
1038 | exec_stmt e m (Sifthenelse a s1 s2) |
---|
1039 | t m' out |
---|
1040 | | exec_Sifthenelse_false: ∀e,m,a,s1,s2,v1,t,m',out. |
---|
1041 | eval_expr e m a v1 -> |
---|
1042 | is_false v1 (typeof a) -> |
---|
1043 | exec_stmt e m s2 t m' out -> |
---|
1044 | exec_stmt e m (Sifthenelse a s1 s2) |
---|
1045 | t m' out |
---|
1046 | | exec_Sreturn_none: ∀e,m. |
---|
1047 | exec_stmt e m (Sreturn None) |
---|
1048 | E0 m (Out_return None) |
---|
1049 | | exec_Sreturn_some: ∀e,m,a,v. |
---|
1050 | eval_expr e m a v -> |
---|
1051 | exec_stmt e m (Sreturn (Some a)) |
---|
1052 | E0 m (Out_return (Some v)) |
---|
1053 | | exec_Sbreak: ∀e,m. |
---|
1054 | exec_stmt e m Sbreak |
---|
1055 | E0 m Out_break |
---|
1056 | | exec_Scontinue: ∀e,m. |
---|
1057 | exec_stmt e m Scontinue |
---|
1058 | E0 m Out_continue |
---|
1059 | | exec_Swhile_false: ∀e,m,a,s,v. |
---|
1060 | eval_expr e m a v -> |
---|
1061 | is_false v (typeof a) -> |
---|
1062 | exec_stmt e m (Swhile a s) |
---|
1063 | E0 m Out_normal |
---|
1064 | | exec_Swhile_stop: ∀e,m,a,v,s,t,m',out',out. |
---|
1065 | eval_expr e m a v -> |
---|
1066 | is_true v (typeof a) -> |
---|
1067 | exec_stmt e m s t m' out' -> |
---|
1068 | out_break_or_return out' out -> |
---|
1069 | exec_stmt e m (Swhile a s) |
---|
1070 | t m' out |
---|
1071 | | exec_Swhile_loop: ∀e,m,a,s,v,t1,m1,out1,t2,m2,out. |
---|
1072 | eval_expr e m a v -> |
---|
1073 | is_true v (typeof a) -> |
---|
1074 | exec_stmt e m s t1 m1 out1 -> |
---|
1075 | out_normal_or_continue out1 -> |
---|
1076 | exec_stmt e m1 (Swhile a s) t2 m2 out -> |
---|
1077 | exec_stmt e m (Swhile a s) |
---|
1078 | (t1 ** t2) m2 out |
---|
1079 | | exec_Sdowhile_false: ∀e,m,s,a,t,m1,out1,v. |
---|
1080 | exec_stmt e m s t m1 out1 -> |
---|
1081 | out_normal_or_continue out1 -> |
---|
1082 | eval_expr e m1 a v -> |
---|
1083 | is_false v (typeof a) -> |
---|
1084 | exec_stmt e m (Sdowhile a s) |
---|
1085 | t m1 Out_normal |
---|
1086 | | exec_Sdowhile_stop: ∀e,m,s,a,t,m1,out1,out. |
---|
1087 | exec_stmt e m s t m1 out1 -> |
---|
1088 | out_break_or_return out1 out -> |
---|
1089 | exec_stmt e m (Sdowhile a s) |
---|
1090 | t m1 out |
---|
1091 | | exec_Sdowhile_loop: ∀e,m,s,a,m1,m2,t1,t2,out,out1,v. |
---|
1092 | exec_stmt e m s t1 m1 out1 -> |
---|
1093 | out_normal_or_continue out1 -> |
---|
1094 | eval_expr e m1 a v -> |
---|
1095 | is_true v (typeof a) -> |
---|
1096 | exec_stmt e m1 (Sdowhile a s) t2 m2 out -> |
---|
1097 | exec_stmt e m (Sdowhile a s) |
---|
1098 | (t1 ** t2) m2 out |
---|
1099 | | exec_Sfor_start: ∀e,m,s,a1,a2,a3,out,m1,m2,t1,t2. |
---|
1100 | a1 <> Sskip -> |
---|
1101 | exec_stmt e m a1 t1 m1 Out_normal -> |
---|
1102 | exec_stmt e m1 (Sfor Sskip a2 a3 s) t2 m2 out -> |
---|
1103 | exec_stmt e m (Sfor a1 a2 a3 s) |
---|
1104 | (t1 ** t2) m2 out |
---|
1105 | | exec_Sfor_false: ∀e,m,s,a2,a3,v. |
---|
1106 | eval_expr e m a2 v -> |
---|
1107 | is_false v (typeof a2) -> |
---|
1108 | exec_stmt e m (Sfor Sskip a2 a3 s) |
---|
1109 | E0 m Out_normal |
---|
1110 | | exec_Sfor_stop: ∀e,m,s,a2,a3,v,m1,t,out1,out. |
---|
1111 | eval_expr e m a2 v -> |
---|
1112 | is_true v (typeof a2) -> |
---|
1113 | exec_stmt e m s t m1 out1 -> |
---|
1114 | out_break_or_return out1 out -> |
---|
1115 | exec_stmt e m (Sfor Sskip a2 a3 s) |
---|
1116 | t m1 out |
---|
1117 | | exec_Sfor_loop: ∀e,m,s,a2,a3,v,m1,m2,m3,t1,t2,t3,out1,out. |
---|
1118 | eval_expr e m a2 v -> |
---|
1119 | is_true v (typeof a2) -> |
---|
1120 | exec_stmt e m s t1 m1 out1 -> |
---|
1121 | out_normal_or_continue out1 -> |
---|
1122 | exec_stmt e m1 a3 t2 m2 Out_normal -> |
---|
1123 | exec_stmt e m2 (Sfor Sskip a2 a3 s) t3 m3 out -> |
---|
1124 | exec_stmt e m (Sfor Sskip a2 a3 s) |
---|
1125 | (t1 ** t2 ** t3) m3 out |
---|
1126 | | exec_Sswitch: ∀e,m,a,t,n,sl,m1,out. |
---|
1127 | eval_expr e m a (Vint n) -> |
---|
1128 | exec_stmt e m (seq_of_labeled_statement (select_switch n sl)) t m1 out -> |
---|
1129 | exec_stmt e m (Sswitch a sl) |
---|
1130 | t m1 (outcome_switch out) |
---|
1131 | |
---|
1132 | (** [eval_funcall m1 fd args t m2 res] describes the invocation of |
---|
1133 | function [fd] with arguments [args]. [res] is the value returned |
---|
1134 | by the call. *) |
---|
1135 | |
---|
1136 | with eval_funcall: mem -> fundef -> list val -> trace -> mem -> val -> Prop := |
---|
1137 | | eval_funcall_internal: ∀m,f,vargs,t,e,m1,m2,m3,out,vres. |
---|
1138 | alloc_variables empty_env m (f.(fn_params) ++ f.(fn_vars)) e m1 -> |
---|
1139 | bind_parameters e m1 f.(fn_params) vargs m2 -> |
---|
1140 | exec_stmt e m2 f.(fn_body) t m3 out -> |
---|
1141 | outcome_result_value out f.(fn_return) vres -> |
---|
1142 | eval_funcall m (Internal f) vargs t (Mem.free_list m3 (blocks_of_env e)) vres |
---|
1143 | | eval_funcall_external: ∀m,id,targs,tres,vargs,t,vres. |
---|
1144 | event_match (external_function id targs tres) vargs t vres -> |
---|
1145 | eval_funcall m (External id targs tres) vargs t m vres. |
---|
1146 | |
---|
1147 | Scheme exec_stmt_ind2 := Minimality for exec_stmt Sort Prop |
---|
1148 | with eval_funcall_ind2 := Minimality for eval_funcall Sort Prop. |
---|
1149 | |
---|
1150 | (** ** Big-step semantics for diverging statements and functions *) |
---|
1151 | |
---|
1152 | (** Coinductive semantics for divergence. |
---|
1153 | [execinf_stmt ge e m s t] holds if the execution of statement [s] |
---|
1154 | diverges, i.e. loops infinitely. [t] is the possibly infinite |
---|
1155 | trace of observable events performed during the execution. *) |
---|
1156 | |
---|
1157 | Coninductive execinf_stmt: env -> mem -> statement -> traceinf -> Prop := |
---|
1158 | | execinf_Scall_none: ∀e,m,a,al,vf,vargs,f,t. |
---|
1159 | eval_expr e m a vf -> |
---|
1160 | eval_exprlist e m al vargs -> |
---|
1161 | Genv.find_funct ge vf = Some f -> |
---|
1162 | type_of_fundef f = typeof a -> |
---|
1163 | evalinf_funcall m f vargs t -> |
---|
1164 | execinf_stmt e m (Scall None a al) t |
---|
1165 | | execinf_Scall_some: ∀e,m,lhs,a,al,loc,ofs,vf,vargs,f,t. |
---|
1166 | eval_lvalue e m lhs loc ofs -> |
---|
1167 | eval_expr e m a vf -> |
---|
1168 | eval_exprlist e m al vargs -> |
---|
1169 | Genv.find_funct ge vf = Some f -> |
---|
1170 | type_of_fundef f = typeof a -> |
---|
1171 | evalinf_funcall m f vargs t -> |
---|
1172 | execinf_stmt e m (Scall (Some lhs) a al) t |
---|
1173 | | execinf_Sseq_1: ∀e,m,s1,s2,t. |
---|
1174 | execinf_stmt e m s1 t -> |
---|
1175 | execinf_stmt e m (Ssequence s1 s2) t |
---|
1176 | | execinf_Sseq_2: ∀e,m,s1,s2,t1,m1,t2. |
---|
1177 | exec_stmt e m s1 t1 m1 Out_normal -> |
---|
1178 | execinf_stmt e m1 s2 t2 -> |
---|
1179 | execinf_stmt e m (Ssequence s1 s2) (t1 *** t2) |
---|
1180 | | execinf_Sifthenelse_true: ∀e,m,a,s1,s2,v1,t. |
---|
1181 | eval_expr e m a v1 -> |
---|
1182 | is_true v1 (typeof a) -> |
---|
1183 | execinf_stmt e m s1 t -> |
---|
1184 | execinf_stmt e m (Sifthenelse a s1 s2) t |
---|
1185 | | execinf_Sifthenelse_false: ∀e,m,a,s1,s2,v1,t. |
---|
1186 | eval_expr e m a v1 -> |
---|
1187 | is_false v1 (typeof a) -> |
---|
1188 | execinf_stmt e m s2 t -> |
---|
1189 | execinf_stmt e m (Sifthenelse a s1 s2) t |
---|
1190 | | execinf_Swhile_body: ∀e,m,a,v,s,t. |
---|
1191 | eval_expr e m a v -> |
---|
1192 | is_true v (typeof a) -> |
---|
1193 | execinf_stmt e m s t -> |
---|
1194 | execinf_stmt e m (Swhile a s) t |
---|
1195 | | execinf_Swhile_loop: ∀e,m,a,s,v,t1,m1,out1,t2. |
---|
1196 | eval_expr e m a v -> |
---|
1197 | is_true v (typeof a) -> |
---|
1198 | exec_stmt e m s t1 m1 out1 -> |
---|
1199 | out_normal_or_continue out1 -> |
---|
1200 | execinf_stmt e m1 (Swhile a s) t2 -> |
---|
1201 | execinf_stmt e m (Swhile a s) (t1 *** t2) |
---|
1202 | | execinf_Sdowhile_body: ∀e,m,s,a,t. |
---|
1203 | execinf_stmt e m s t -> |
---|
1204 | execinf_stmt e m (Sdowhile a s) t |
---|
1205 | | execinf_Sdowhile_loop: ∀e,m,s,a,m1,t1,t2,out1,v. |
---|
1206 | exec_stmt e m s t1 m1 out1 -> |
---|
1207 | out_normal_or_continue out1 -> |
---|
1208 | eval_expr e m1 a v -> |
---|
1209 | is_true v (typeof a) -> |
---|
1210 | execinf_stmt e m1 (Sdowhile a s) t2 -> |
---|
1211 | execinf_stmt e m (Sdowhile a s) (t1 *** t2) |
---|
1212 | | execinf_Sfor_start_1: ∀e,m,s,a1,a2,a3,t. |
---|
1213 | execinf_stmt e m a1 t -> |
---|
1214 | execinf_stmt e m (Sfor a1 a2 a3 s) t |
---|
1215 | | execinf_Sfor_start_2: ∀e,m,s,a1,a2,a3,m1,t1,t2. |
---|
1216 | a1 <> Sskip -> |
---|
1217 | exec_stmt e m a1 t1 m1 Out_normal -> |
---|
1218 | execinf_stmt e m1 (Sfor Sskip a2 a3 s) t2 -> |
---|
1219 | execinf_stmt e m (Sfor a1 a2 a3 s) (t1 *** t2) |
---|
1220 | | execinf_Sfor_body: ∀e,m,s,a2,a3,v,t. |
---|
1221 | eval_expr e m a2 v -> |
---|
1222 | is_true v (typeof a2) -> |
---|
1223 | execinf_stmt e m s t -> |
---|
1224 | execinf_stmt e m (Sfor Sskip a2 a3 s) t |
---|
1225 | | execinf_Sfor_next: ∀e,m,s,a2,a3,v,m1,t1,t2,out1. |
---|
1226 | eval_expr e m a2 v -> |
---|
1227 | is_true v (typeof a2) -> |
---|
1228 | exec_stmt e m s t1 m1 out1 -> |
---|
1229 | out_normal_or_continue out1 -> |
---|
1230 | execinf_stmt e m1 a3 t2 -> |
---|
1231 | execinf_stmt e m (Sfor Sskip a2 a3 s) (t1 *** t2) |
---|
1232 | | execinf_Sfor_loop: ∀e,m,s,a2,a3,v,m1,m2,t1,t2,t3,out1. |
---|
1233 | eval_expr e m a2 v -> |
---|
1234 | is_true v (typeof a2) -> |
---|
1235 | exec_stmt e m s t1 m1 out1 -> |
---|
1236 | out_normal_or_continue out1 -> |
---|
1237 | exec_stmt e m1 a3 t2 m2 Out_normal -> |
---|
1238 | execinf_stmt e m2 (Sfor Sskip a2 a3 s) t3 -> |
---|
1239 | execinf_stmt e m (Sfor Sskip a2 a3 s) (t1 *** t2 *** t3) |
---|
1240 | | execinf_Sswitch: ∀e,m,a,t,n,sl. |
---|
1241 | eval_expr e m a (Vint n) -> |
---|
1242 | execinf_stmt e m (seq_of_labeled_statement (select_switch n sl)) t -> |
---|
1243 | execinf_stmt e m (Sswitch a sl) t |
---|
1244 | |
---|
1245 | (** [evalinf_funcall ge m fd args t] holds if the invocation of function |
---|
1246 | [fd] on arguments [args] diverges, with observable trace [t]. *) |
---|
1247 | |
---|
1248 | with evalinf_funcall: mem -> fundef -> list val -> traceinf -> Prop := |
---|
1249 | | evalinf_funcall_internal: ∀m,f,vargs,t,e,m1,m2. |
---|
1250 | alloc_variables empty_env m (f.(fn_params) ++ f.(fn_vars)) e m1 -> |
---|
1251 | bind_parameters e m1 f.(fn_params) vargs m2 -> |
---|
1252 | execinf_stmt e m2 f.(fn_body) t -> |
---|
1253 | evalinf_funcall m (Internal f) vargs t. |
---|
1254 | |
---|
1255 | End SEMANTICS. |
---|
1256 | *) |
---|
1257 | (* * * Whole-program semantics *) |
---|
1258 | |
---|
1259 | (* * Execution of whole programs are described as sequences of transitions |
---|
1260 | from an initial state to a final state. An initial state is a [Callstate] |
---|
1261 | corresponding to the invocation of the ``main'' function of the program |
---|
1262 | without arguments and with an empty continuation. *) |
---|
1263 | |
---|
1264 | ninductive initial_state (p: program): state -> Prop := |
---|
1265 | | initial_state_intro: ∀b,f. |
---|
1266 | let ge := globalenv Genv ?? p in |
---|
1267 | let m0 := init_mem Genv ?? p in |
---|
1268 | find_symbol ?? ge (prog_main ?? p) = Some ? 〈Code,b〉 -> |
---|
1269 | find_funct_ptr ?? ge b = Some ? f -> |
---|
1270 | initial_state p (Callstate f (nil ?) Kstop m0). |
---|
1271 | |
---|
1272 | (* * A final state is a [Returnstate] with an empty continuation. *) |
---|
1273 | |
---|
1274 | ninductive final_state: state -> int -> Prop := |
---|
1275 | | final_state_intro: ∀r,m. |
---|
1276 | final_state (Returnstate (Vint r) Kstop m) r. |
---|
1277 | |
---|
1278 | (* * Execution of a whole program: [exec_program p beh] |
---|
1279 | holds if the application of [p]'s main function to no arguments |
---|
1280 | in the initial memory state for [p] has [beh] as observable |
---|
1281 | behavior. *) |
---|
1282 | |
---|
1283 | ndefinition exec_program : program → program_behavior → Prop ≝ λp,beh. |
---|
1284 | program_behaves (mk_transrel ?? step) (initial_state p) final_state (globalenv ??? p) beh. |
---|
1285 | (* |
---|
1286 | (** Big-step execution of a whole program. *) |
---|
1287 | |
---|
1288 | ninductive bigstep_program_terminates (p: program): trace -> int -> Prop := |
---|
1289 | | bigstep_program_terminates_intro: ∀b,f,m1,t,r. |
---|
1290 | let ge := Genv.globalenv p in |
---|
1291 | let m0 := Genv.init_mem p in |
---|
1292 | Genv.find_symbol ge p.(prog_main) = Some b -> |
---|
1293 | Genv.find_funct_ptr ge b = Some f -> |
---|
1294 | eval_funcall ge m0 f nil t m1 (Vint r) -> |
---|
1295 | bigstep_program_terminates p t r. |
---|
1296 | |
---|
1297 | ninductive bigstep_program_diverges (p: program): traceinf -> Prop := |
---|
1298 | | bigstep_program_diverges_intro: ∀b,f,t. |
---|
1299 | let ge := Genv.globalenv p in |
---|
1300 | let m0 := Genv.init_mem p in |
---|
1301 | Genv.find_symbol ge p.(prog_main) = Some b -> |
---|
1302 | Genv.find_funct_ptr ge b = Some f -> |
---|
1303 | evalinf_funcall ge m0 f nil t -> |
---|
1304 | bigstep_program_diverges p t. |
---|
1305 | |
---|
1306 | (** * Implication from big-step semantics to transition semantics *) |
---|
1307 | |
---|
1308 | Section BIGSTEP_TO_TRANSITIONS. |
---|
1309 | |
---|
1310 | Variable prog: program. |
---|
1311 | Let ge : genv := Genv.globalenv prog. |
---|
1312 | |
---|
1313 | Definition exec_stmt_eval_funcall_ind |
---|
1314 | (PS: env -> mem -> statement -> trace -> mem -> outcome -> Prop) |
---|
1315 | (PF: mem -> fundef -> list val -> trace -> mem -> val -> Prop) := |
---|
1316 | fun a b c d e f g h i j k l m n o p q r s t u v w x y => |
---|
1317 | conj (exec_stmt_ind2 ge PS PF a b c d e f g h i j k l m n o p q r s t u v w x y) |
---|
1318 | (eval_funcall_ind2 ge PS PF a b c d e f g h i j k l m n o p q r s t u v w x y). |
---|
1319 | |
---|
1320 | ninductive outcome_state_match |
---|
1321 | (e: env) (m: mem) (f: function) (k: cont): outcome -> state -> Prop := |
---|
1322 | | osm_normal: |
---|
1323 | outcome_state_match e m f k Out_normal (State f Sskip k e m) |
---|
1324 | | osm_break: |
---|
1325 | outcome_state_match e m f k Out_break (State f Sbreak k e m) |
---|
1326 | | osm_continue: |
---|
1327 | outcome_state_match e m f k Out_continue (State f Scontinue k e m) |
---|
1328 | | osm_return_none: ∀k'. |
---|
1329 | call_cont k' = call_cont k -> |
---|
1330 | outcome_state_match e m f k |
---|
1331 | (Out_return None) (State f (Sreturn None) k' e m) |
---|
1332 | | osm_return_some: ∀a,v,k'. |
---|
1333 | call_cont k' = call_cont k -> |
---|
1334 | eval_expr ge e m a v -> |
---|
1335 | outcome_state_match e m f k |
---|
1336 | (Out_return (Some v)) (State f (Sreturn (Some a)) k' e m). |
---|
1337 | |
---|
1338 | Lemma is_call_cont_call_cont: |
---|
1339 | ∀k. is_call_cont k -> call_cont k = k. |
---|
1340 | Proof. |
---|
1341 | destruct k; simpl; intros; contradiction || auto. |
---|
1342 | Qed. |
---|
1343 | |
---|
1344 | Lemma exec_stmt_eval_funcall_steps: |
---|
1345 | (∀e,m,s,t,m',out. |
---|
1346 | exec_stmt ge e m s t m' out -> |
---|
1347 | ∀f,k. exists S, |
---|
1348 | star step ge (State f s k e m) t S |
---|
1349 | /\ outcome_state_match e m' f k out S) |
---|
1350 | /\ |
---|
1351 | (∀m,fd,args,t,m',res. |
---|
1352 | eval_funcall ge m fd args t m' res -> |
---|
1353 | ∀k. |
---|
1354 | is_call_cont k -> |
---|
1355 | star step ge (Callstate fd args k m) t (Returnstate res k m')). |
---|
1356 | Proof. |
---|
1357 | apply exec_stmt_eval_funcall_ind; intros. |
---|
1358 | |
---|
1359 | (* skip *) |
---|
1360 | econstructor; split. apply star_refl. constructor. |
---|
1361 | |
---|
1362 | (* assign *) |
---|
1363 | econstructor; split. apply star_one. econstructor; eauto. constructor. |
---|
1364 | |
---|
1365 | (* call none *) |
---|
1366 | econstructor; split. |
---|
1367 | eapply star_left. econstructor; eauto. |
---|
1368 | eapply star_right. apply H4. simpl; auto. econstructor. reflexivity. traceEq. |
---|
1369 | constructor. |
---|
1370 | |
---|
1371 | (* call some *) |
---|
1372 | econstructor; split. |
---|
1373 | eapply star_left. econstructor; eauto. |
---|
1374 | eapply star_right. apply H5. simpl; auto. econstructor; eauto. reflexivity. traceEq. |
---|
1375 | constructor. |
---|
1376 | |
---|
1377 | (* sequence 2 *) |
---|
1378 | destruct (H0 f (Kseq s2 k)) as [S1 [A1 B1]]. inv B1. |
---|
1379 | destruct (H2 f k) as [S2 [A2 B2]]. |
---|
1380 | econstructor; split. |
---|
1381 | eapply star_left. econstructor. |
---|
1382 | eapply star_trans. eexact A1. |
---|
1383 | eapply star_left. constructor. eexact A2. |
---|
1384 | reflexivity. reflexivity. traceEq. |
---|
1385 | auto. |
---|
1386 | |
---|
1387 | (* sequence 1 *) |
---|
1388 | destruct (H0 f (Kseq s2 k)) as [S1 [A1 B1]]. |
---|
1389 | set (S2 := |
---|
1390 | match out with |
---|
1391 | | Out_break => State f Sbreak k e m1 |
---|
1392 | | Out_continue => State f Scontinue k e m1 |
---|
1393 | | _ => S1 |
---|
1394 | end). |
---|
1395 | exists S2; split. |
---|
1396 | eapply star_left. econstructor. |
---|
1397 | eapply star_trans. eexact A1. |
---|
1398 | unfold S2; inv B1. |
---|
1399 | congruence. |
---|
1400 | apply star_one. apply step_break_seq. |
---|
1401 | apply star_one. apply step_continue_seq. |
---|
1402 | apply star_refl. |
---|
1403 | apply star_refl. |
---|
1404 | reflexivity. traceEq. |
---|
1405 | unfold S2; inv B1; congruence || econstructor; eauto. |
---|
1406 | |
---|
1407 | (* ifthenelse true *) |
---|
1408 | destruct (H2 f k) as [S1 [A1 B1]]. |
---|
1409 | exists S1; split. |
---|
1410 | eapply star_left. eapply step_ifthenelse_true; eauto. eexact A1. traceEq. |
---|
1411 | auto. |
---|
1412 | |
---|
1413 | (* ifthenelse false *) |
---|
1414 | destruct (H2 f k) as [S1 [A1 B1]]. |
---|
1415 | exists S1; split. |
---|
1416 | eapply star_left. eapply step_ifthenelse_false; eauto. eexact A1. traceEq. |
---|
1417 | auto. |
---|
1418 | |
---|
1419 | (* return none *) |
---|
1420 | econstructor; split. apply star_refl. constructor. auto. |
---|
1421 | |
---|
1422 | (* return some *) |
---|
1423 | econstructor; split. apply star_refl. econstructor; eauto. |
---|
1424 | |
---|
1425 | (* break *) |
---|
1426 | econstructor; split. apply star_refl. constructor. |
---|
1427 | |
---|
1428 | (* continue *) |
---|
1429 | econstructor; split. apply star_refl. constructor. |
---|
1430 | |
---|
1431 | (* while false *) |
---|
1432 | econstructor; split. |
---|
1433 | apply star_one. eapply step_while_false; eauto. |
---|
1434 | constructor. |
---|
1435 | |
---|
1436 | (* while stop *) |
---|
1437 | destruct (H2 f (Kwhile a s k)) as [S1 [A1 B1]]. |
---|
1438 | set (S2 := |
---|
1439 | match out' with |
---|
1440 | | Out_break => State f Sskip k e m' |
---|
1441 | | _ => S1 |
---|
1442 | end). |
---|
1443 | exists S2; split. |
---|
1444 | eapply star_left. eapply step_while_true; eauto. |
---|
1445 | eapply star_trans. eexact A1. |
---|
1446 | unfold S2. inversion H3; subst. |
---|
1447 | inv B1. apply star_one. constructor. |
---|
1448 | apply star_refl. |
---|
1449 | reflexivity. traceEq. |
---|
1450 | unfold S2. inversion H3; subst. constructor. inv B1; econstructor; eauto. |
---|
1451 | |
---|
1452 | (* while loop *) |
---|
1453 | destruct (H2 f (Kwhile a s k)) as [S1 [A1 B1]]. |
---|
1454 | destruct (H5 f k) as [S2 [A2 B2]]. |
---|
1455 | exists S2; split. |
---|
1456 | eapply star_left. eapply step_while_true; eauto. |
---|
1457 | eapply star_trans. eexact A1. |
---|
1458 | eapply star_left. |
---|
1459 | inv H3; inv B1; apply step_skip_or_continue_while; auto. |
---|
1460 | eexact A2. |
---|
1461 | reflexivity. reflexivity. traceEq. |
---|
1462 | auto. |
---|
1463 | |
---|
1464 | (* dowhile false *) |
---|
1465 | destruct (H0 f (Kdowhile a s k)) as [S1 [A1 B1]]. |
---|
1466 | exists (State f Sskip k e m1); split. |
---|
1467 | eapply star_left. constructor. |
---|
1468 | eapply star_right. eexact A1. |
---|
1469 | inv H1; inv B1; eapply step_skip_or_continue_dowhile_false; eauto. |
---|
1470 | reflexivity. traceEq. |
---|
1471 | constructor. |
---|
1472 | |
---|
1473 | (* dowhile stop *) |
---|
1474 | destruct (H0 f (Kdowhile a s k)) as [S1 [A1 B1]]. |
---|
1475 | set (S2 := |
---|
1476 | match out1 with |
---|
1477 | | Out_break => State f Sskip k e m1 |
---|
1478 | | _ => S1 |
---|
1479 | end). |
---|
1480 | exists S2; split. |
---|
1481 | eapply star_left. apply step_dowhile. |
---|
1482 | eapply star_trans. eexact A1. |
---|
1483 | unfold S2. inversion H1; subst. |
---|
1484 | inv B1. apply star_one. constructor. |
---|
1485 | apply star_refl. |
---|
1486 | reflexivity. traceEq. |
---|
1487 | unfold S2. inversion H1; subst. constructor. inv B1; econstructor; eauto. |
---|
1488 | |
---|
1489 | (* dowhile loop *) |
---|
1490 | destruct (H0 f (Kdowhile a s k)) as [S1 [A1 B1]]. |
---|
1491 | destruct (H5 f k) as [S2 [A2 B2]]. |
---|
1492 | exists S2; split. |
---|
1493 | eapply star_left. apply step_dowhile. |
---|
1494 | eapply star_trans. eexact A1. |
---|
1495 | eapply star_left. |
---|
1496 | inv H1; inv B1; eapply step_skip_or_continue_dowhile_true; eauto. |
---|
1497 | eexact A2. |
---|
1498 | reflexivity. reflexivity. traceEq. |
---|
1499 | auto. |
---|
1500 | |
---|
1501 | (* for start *) |
---|
1502 | destruct (H1 f (Kseq (Sfor Sskip a2 a3 s) k)) as [S1 [A1 B1]]. inv B1. |
---|
1503 | destruct (H3 f k) as [S2 [A2 B2]]. |
---|
1504 | exists S2; split. |
---|
1505 | eapply star_left. apply step_for_start; auto. |
---|
1506 | eapply star_trans. eexact A1. |
---|
1507 | eapply star_left. constructor. eexact A2. |
---|
1508 | reflexivity. reflexivity. traceEq. |
---|
1509 | auto. |
---|
1510 | |
---|
1511 | (* for false *) |
---|
1512 | econstructor; split. |
---|
1513 | eapply star_one. eapply step_for_false; eauto. |
---|
1514 | constructor. |
---|
1515 | |
---|
1516 | (* for stop *) |
---|
1517 | destruct (H2 f (Kfor2 a2 a3 s k)) as [S1 [A1 B1]]. |
---|
1518 | set (S2 := |
---|
1519 | match out1 with |
---|
1520 | | Out_break => State f Sskip k e m1 |
---|
1521 | | _ => S1 |
---|
1522 | end). |
---|
1523 | exists S2; split. |
---|
1524 | eapply star_left. eapply step_for_true; eauto. |
---|
1525 | eapply star_trans. eexact A1. |
---|
1526 | unfold S2. inversion H3; subst. |
---|
1527 | inv B1. apply star_one. constructor. |
---|
1528 | apply star_refl. |
---|
1529 | reflexivity. traceEq. |
---|
1530 | unfold S2. inversion H3; subst. constructor. inv B1; econstructor; eauto. |
---|
1531 | |
---|
1532 | (* for loop *) |
---|
1533 | destruct (H2 f (Kfor2 a2 a3 s k)) as [S1 [A1 B1]]. |
---|
1534 | destruct (H5 f (Kfor3 a2 a3 s k)) as [S2 [A2 B2]]. inv B2. |
---|
1535 | destruct (H7 f k) as [S3 [A3 B3]]. |
---|
1536 | exists S3; split. |
---|
1537 | eapply star_left. eapply step_for_true; eauto. |
---|
1538 | eapply star_trans. eexact A1. |
---|
1539 | eapply star_trans with (s2 := State f a3 (Kfor3 a2 a3 s k) e m1). |
---|
1540 | inv H3; inv B1. |
---|
1541 | apply star_one. constructor. auto. |
---|
1542 | apply star_one. constructor. auto. |
---|
1543 | eapply star_trans. eexact A2. |
---|
1544 | eapply star_left. constructor. |
---|
1545 | eexact A3. |
---|
1546 | reflexivity. reflexivity. reflexivity. reflexivity. traceEq. |
---|
1547 | auto. |
---|
1548 | |
---|
1549 | (* switch *) |
---|
1550 | destruct (H1 f (Kswitch k)) as [S1 [A1 B1]]. |
---|
1551 | set (S2 := |
---|
1552 | match out with |
---|
1553 | | Out_normal => State f Sskip k e m1 |
---|
1554 | | Out_break => State f Sskip k e m1 |
---|
1555 | | Out_continue => State f Scontinue k e m1 |
---|
1556 | | _ => S1 |
---|
1557 | end). |
---|
1558 | exists S2; split. |
---|
1559 | eapply star_left. eapply step_switch; eauto. |
---|
1560 | eapply star_trans. eexact A1. |
---|
1561 | unfold S2; inv B1. |
---|
1562 | apply star_one. constructor. auto. |
---|
1563 | apply star_one. constructor. auto. |
---|
1564 | apply star_one. constructor. |
---|
1565 | apply star_refl. |
---|
1566 | apply star_refl. |
---|
1567 | reflexivity. traceEq. |
---|
1568 | unfold S2. inv B1; simpl; econstructor; eauto. |
---|
1569 | |
---|
1570 | (* call internal *) |
---|
1571 | destruct (H2 f k) as [S1 [A1 B1]]. |
---|
1572 | eapply star_left. eapply step_internal_function; eauto. |
---|
1573 | eapply star_right. eexact A1. |
---|
1574 | inv B1; simpl in H3; try contradiction. |
---|
1575 | (* Out_normal *) |
---|
1576 | assert (fn_return f = Tvoid /\ vres = Vundef). |
---|
1577 | destruct (fn_return f); auto || contradiction. |
---|
1578 | destruct H5. subst vres. apply step_skip_call; auto. |
---|
1579 | (* Out_return None *) |
---|
1580 | assert (fn_return f = Tvoid /\ vres = Vundef). |
---|
1581 | destruct (fn_return f); auto || contradiction. |
---|
1582 | destruct H6. subst vres. |
---|
1583 | rewrite <- (is_call_cont_call_cont k H4). rewrite <- H5. |
---|
1584 | apply step_return_0; auto. |
---|
1585 | (* Out_return Some *) |
---|
1586 | destruct H3. subst vres. |
---|
1587 | rewrite <- (is_call_cont_call_cont k H4). rewrite <- H5. |
---|
1588 | eapply step_return_1; eauto. |
---|
1589 | reflexivity. traceEq. |
---|
1590 | |
---|
1591 | (* call external *) |
---|
1592 | apply star_one. apply step_external_function; auto. |
---|
1593 | Qed. |
---|
1594 | |
---|
1595 | Lemma exec_stmt_steps: |
---|
1596 | ∀e,m,s,t,m',out. |
---|
1597 | exec_stmt ge e m s t m' out -> |
---|
1598 | ∀f,k. exists S, |
---|
1599 | star step ge (State f s k e m) t S |
---|
1600 | /\ outcome_state_match e m' f k out S. |
---|
1601 | Proof (proj1 exec_stmt_eval_funcall_steps). |
---|
1602 | |
---|
1603 | Lemma eval_funcall_steps: |
---|
1604 | ∀m,fd,args,t,m',res. |
---|
1605 | eval_funcall ge m fd args t m' res -> |
---|
1606 | ∀k. |
---|
1607 | is_call_cont k -> |
---|
1608 | star step ge (Callstate fd args k m) t (Returnstate res k m'). |
---|
1609 | Proof (proj2 exec_stmt_eval_funcall_steps). |
---|
1610 | |
---|
1611 | Definition order (x y: unit) := False. |
---|
1612 | |
---|
1613 | Lemma evalinf_funcall_forever: |
---|
1614 | ∀m,fd,args,T,k. |
---|
1615 | evalinf_funcall ge m fd args T -> |
---|
1616 | forever_N step order ge tt (Callstate fd args k m) T. |
---|
1617 | Proof. |
---|
1618 | cofix CIH_FUN. |
---|
1619 | assert (∀e,m,s,T,f,k. |
---|
1620 | execinf_stmt ge e m s T -> |
---|
1621 | forever_N step order ge tt (State f s k e m) T). |
---|
1622 | cofix CIH_STMT. |
---|
1623 | intros. inv H. |
---|
1624 | |
---|
1625 | (* call none *) |
---|
1626 | eapply forever_N_plus. |
---|
1627 | apply plus_one. eapply step_call_none; eauto. |
---|
1628 | apply CIH_FUN. eauto. traceEq. |
---|
1629 | (* call some *) |
---|
1630 | eapply forever_N_plus. |
---|
1631 | apply plus_one. eapply step_call_some; eauto. |
---|
1632 | apply CIH_FUN. eauto. traceEq. |
---|
1633 | |
---|
1634 | (* seq 1 *) |
---|
1635 | eapply forever_N_plus. |
---|
1636 | apply plus_one. econstructor. |
---|
1637 | apply CIH_STMT; eauto. traceEq. |
---|
1638 | (* seq 2 *) |
---|
1639 | destruct (exec_stmt_steps _ _ _ _ _ _ H0 f (Kseq s2 k)) as [S1 [A1 B1]]. |
---|
1640 | inv B1. |
---|
1641 | eapply forever_N_plus. |
---|
1642 | eapply plus_left. constructor. eapply star_trans. eexact A1. |
---|
1643 | apply star_one. constructor. reflexivity. reflexivity. |
---|
1644 | apply CIH_STMT; eauto. traceEq. |
---|
1645 | |
---|
1646 | (* ifthenelse true *) |
---|
1647 | eapply forever_N_plus. |
---|
1648 | apply plus_one. eapply step_ifthenelse_true; eauto. |
---|
1649 | apply CIH_STMT; eauto. traceEq. |
---|
1650 | (* ifthenelse false *) |
---|
1651 | eapply forever_N_plus. |
---|
1652 | apply plus_one. eapply step_ifthenelse_false; eauto. |
---|
1653 | apply CIH_STMT; eauto. traceEq. |
---|
1654 | |
---|
1655 | (* while body *) |
---|
1656 | eapply forever_N_plus. |
---|
1657 | eapply plus_one. eapply step_while_true; eauto. |
---|
1658 | apply CIH_STMT; eauto. traceEq. |
---|
1659 | (* while loop *) |
---|
1660 | destruct (exec_stmt_steps _ _ _ _ _ _ H2 f (Kwhile a s0 k)) as [S1 [A1 B1]]. |
---|
1661 | eapply forever_N_plus with (s2 := State f (Swhile a s0) k e m1). |
---|
1662 | eapply plus_left. eapply step_while_true; eauto. |
---|
1663 | eapply star_right. eexact A1. |
---|
1664 | inv H3; inv B1; apply step_skip_or_continue_while; auto. |
---|
1665 | reflexivity. reflexivity. |
---|
1666 | apply CIH_STMT; eauto. traceEq. |
---|
1667 | |
---|
1668 | (* dowhile body *) |
---|
1669 | eapply forever_N_plus. |
---|
1670 | eapply plus_one. eapply step_dowhile. |
---|
1671 | apply CIH_STMT; eauto. |
---|
1672 | traceEq. |
---|
1673 | |
---|
1674 | (* dowhile loop *) |
---|
1675 | destruct (exec_stmt_steps _ _ _ _ _ _ H0 f (Kdowhile a s0 k)) as [S1 [A1 B1]]. |
---|
1676 | eapply forever_N_plus with (s2 := State f (Sdowhile a s0) k e m1). |
---|
1677 | eapply plus_left. eapply step_dowhile. |
---|
1678 | eapply star_right. eexact A1. |
---|
1679 | inv H1; inv B1; eapply step_skip_or_continue_dowhile_true; eauto. |
---|
1680 | reflexivity. reflexivity. |
---|
1681 | apply CIH_STMT. eauto. |
---|
1682 | traceEq. |
---|
1683 | |
---|
1684 | (* for start 1 *) |
---|
1685 | assert (a1 <> Sskip). red; intros; subst. inv H0. |
---|
1686 | eapply forever_N_plus. |
---|
1687 | eapply plus_one. apply step_for_start; auto. |
---|
1688 | apply CIH_STMT; eauto. |
---|
1689 | traceEq. |
---|
1690 | |
---|
1691 | (* for start 2 *) |
---|
1692 | destruct (exec_stmt_steps _ _ _ _ _ _ H1 f (Kseq (Sfor Sskip a2 a3 s0) k)) as [S1 [A1 B1]]. |
---|
1693 | inv B1. |
---|
1694 | eapply forever_N_plus. |
---|
1695 | eapply plus_left. eapply step_for_start; eauto. |
---|
1696 | eapply star_right. eexact A1. |
---|
1697 | apply step_skip_seq. |
---|
1698 | reflexivity. reflexivity. |
---|
1699 | apply CIH_STMT; eauto. |
---|
1700 | traceEq. |
---|
1701 | |
---|
1702 | (* for body *) |
---|
1703 | eapply forever_N_plus. |
---|
1704 | apply plus_one. eapply step_for_true; eauto. |
---|
1705 | apply CIH_STMT; eauto. |
---|
1706 | traceEq. |
---|
1707 | |
---|
1708 | (* for next *) |
---|
1709 | destruct (exec_stmt_steps _ _ _ _ _ _ H2 f (Kfor2 a2 a3 s0 k)) as [S1 [A1 B1]]. |
---|
1710 | eapply forever_N_plus. |
---|
1711 | eapply plus_left. eapply step_for_true; eauto. |
---|
1712 | eapply star_trans. eexact A1. |
---|
1713 | apply star_one. |
---|
1714 | inv H3; inv B1; apply step_skip_or_continue_for2; auto. |
---|
1715 | reflexivity. reflexivity. |
---|
1716 | apply CIH_STMT; eauto. |
---|
1717 | traceEq. |
---|
1718 | |
---|
1719 | (* for body *) |
---|
1720 | destruct (exec_stmt_steps _ _ _ _ _ _ H2 f (Kfor2 a2 a3 s0 k)) as [S1 [A1 B1]]. |
---|
1721 | destruct (exec_stmt_steps _ _ _ _ _ _ H4 f (Kfor3 a2 a3 s0 k)) as [S2 [A2 B2]]. |
---|
1722 | inv B2. |
---|
1723 | eapply forever_N_plus. |
---|
1724 | eapply plus_left. eapply step_for_true; eauto. |
---|
1725 | eapply star_trans. eexact A1. |
---|
1726 | eapply star_left. inv H3; inv B1; apply step_skip_or_continue_for2; auto. |
---|
1727 | eapply star_right. eexact A2. |
---|
1728 | constructor. |
---|
1729 | reflexivity. reflexivity. reflexivity. reflexivity. |
---|
1730 | apply CIH_STMT; eauto. |
---|
1731 | traceEq. |
---|
1732 | |
---|
1733 | (* switch *) |
---|
1734 | eapply forever_N_plus. |
---|
1735 | eapply plus_one. eapply step_switch; eauto. |
---|
1736 | apply CIH_STMT; eauto. |
---|
1737 | traceEq. |
---|
1738 | |
---|
1739 | (* call internal *) |
---|
1740 | intros. inv H0. |
---|
1741 | eapply forever_N_plus. |
---|
1742 | eapply plus_one. econstructor; eauto. |
---|
1743 | apply H; eauto. |
---|
1744 | traceEq. |
---|
1745 | Qed. |
---|
1746 | |
---|
1747 | Theorem bigstep_program_terminates_exec: |
---|
1748 | ∀t,r. bigstep_program_terminates prog t r -> exec_program prog (Terminates t r). |
---|
1749 | Proof. |
---|
1750 | intros. inv H. unfold ge0, m0 in *. |
---|
1751 | econstructor. |
---|
1752 | econstructor. eauto. eauto. |
---|
1753 | apply eval_funcall_steps. eauto. red; auto. |
---|
1754 | econstructor. |
---|
1755 | Qed. |
---|
1756 | |
---|
1757 | Theorem bigstep_program_diverges_exec: |
---|
1758 | ∀T. bigstep_program_diverges prog T -> |
---|
1759 | exec_program prog (Reacts T) \/ |
---|
1760 | exists t, exec_program prog (Diverges t) /\ traceinf_prefix t T. |
---|
1761 | Proof. |
---|
1762 | intros. inv H. |
---|
1763 | set (st := Callstate f nil Kstop m0). |
---|
1764 | assert (forever step ge0 st T). |
---|
1765 | eapply forever_N_forever with (order := order). |
---|
1766 | red; intros. constructor; intros. red in H. elim H. |
---|
1767 | eapply evalinf_funcall_forever; eauto. |
---|
1768 | destruct (forever_silent_or_reactive _ _ _ _ _ _ H) |
---|
1769 | as [A | [t [s' [T' [B [C D]]]]]]. |
---|
1770 | left. econstructor. econstructor. eauto. eauto. auto. |
---|
1771 | right. exists t. split. |
---|
1772 | econstructor. econstructor; eauto. eauto. auto. |
---|
1773 | subst T. rewrite <- (E0_right t) at 1. apply traceinf_prefix_app. constructor. |
---|
1774 | Qed. |
---|
1775 | |
---|
1776 | End BIGSTEP_TO_TRANSITIONS. |
---|
1777 | |
---|
1778 | |
---|
1779 | |
---|
1780 | *) |
---|
1781 | |
---|
1782 | |
---|