1 | (* |
---|
2 | include "Clight/toCminor.ma". |
---|
3 | include "Clight/CexecInd.ma". |
---|
4 | include "common/Globalenvs.ma". |
---|
5 | include "Clight/memoryInjections.ma". |
---|
6 | include "Clight/Clight_abstract.ma". |
---|
7 | include "Cminor/Cminor_abstract.ma". |
---|
8 | *) |
---|
9 | include "common/Measurable.ma". |
---|
10 | |
---|
11 | (* Expr simulation. Contains important definitions for statements, too. *) |
---|
12 | include "Clight/toCminorCorrectnessExpr.ma". |
---|
13 | |
---|
14 | (* When we characterise the local Clight variables, those that are stack |
---|
15 | allocated are given disjoint regions of the stack. *) |
---|
16 | lemma characterise_vars_disjoint : ∀globals,f,vartypes,stacksize,id,n,ty. |
---|
17 | characterise_vars globals f = 〈vartypes, stacksize〉 → |
---|
18 | lookup ?? vartypes id = Some ? 〈Stack n,ty〉 → |
---|
19 | ∀id',n',ty'. id ≠ id' → |
---|
20 | lookup ?? vartypes id' = Some ? 〈Stack n',ty'〉 → |
---|
21 | n' + sizeof ty' ≤ n ∨ n + sizeof ty ≤ n'. |
---|
22 | #globals * #ret #args #vars #body #vartypes #stacksize #id #n #ty |
---|
23 | whd in ⊢ (??%? → ?); |
---|
24 | generalize in match vartypes; -vartypes |
---|
25 | generalize in match stacksize; -stacksize |
---|
26 | elim (args@vars) |
---|
27 | [ #stacksize #vartypes #CHAR #L @⊥ whd in CHAR:(??%?); destruct |
---|
28 | elim globals in L; |
---|
29 | [ normalize #L destruct |
---|
30 | | * * #id' #r #ty' #tl #IH |
---|
31 | whd in match (foldr ?????); |
---|
32 | #L cases (lookup_add_cases ??????? L) |
---|
33 | [ * #E1 #E2 destruct |
---|
34 | | @IH |
---|
35 | ] |
---|
36 | ] |
---|
37 | | * #id1 #ty1 #tl #IH #stacksize #vartypes |
---|
38 | whd in match (foldr ?????); |
---|
39 | (* Avoid writing out the definition again *) |
---|
40 | letin ih ≝ (foldr ? (Prod ??) ?? tl) in IH ⊢ %; |
---|
41 | lapply (refl ? ih) whd in match ih; -ih |
---|
42 | cases (foldr ? (Prod ??) ?? tl) in ⊢ (???% → %); |
---|
43 | #vartypes' #stack' #FOLD #IH |
---|
44 | whd in ⊢ (??(match % with [_⇒?])? → ?); |
---|
45 | cases (orb ??) |
---|
46 | #CHAR whd in CHAR:(??%?); destruct |
---|
47 | #L cases (lookup_add_cases ??????? L) |
---|
48 | [ 1,3: * #E1 #E2 destruct |
---|
49 | #id' #n' #ty' #NE >lookup_add_miss /2/ |
---|
50 | #L' %1 -L -IH |
---|
51 | generalize in match vartypes' in FOLD L' ⊢ %; -vartypes' |
---|
52 | generalize in match stack'; -stack' |
---|
53 | elim tl |
---|
54 | [ #stack' #vartypes2 whd in ⊢ (??%? → ?); #F destruct #L' @⊥ |
---|
55 | elim globals in L'; |
---|
56 | [ normalize #E destruct |
---|
57 | | * * #id2 #r2 #ty2 #tl2 #IH whd in match (foldr ?????); |
---|
58 | #L cases (lookup_add_cases ??????? L) |
---|
59 | [ * #E1 #E2 destruct |
---|
60 | | @IH |
---|
61 | ] |
---|
62 | ] |
---|
63 | | * #id2 #ty2 #tl2 #IH #stack' #vartypes' |
---|
64 | whd in ⊢ (??%? → ?); cases (foldr ? (Prod ??) ???) in IH ⊢ %; |
---|
65 | #vartypes2 #stack2 #IH |
---|
66 | whd in ⊢ (??%? → ?); |
---|
67 | cases (orb ??) |
---|
68 | [ #E whd in E:(??%?); destruct #L cases (lookup_add_cases ??????? L) |
---|
69 | [ * #E1 #E2 destruct // |
---|
70 | | #L'' lapply (IH ?? (refl ??) L'') /2/ |
---|
71 | ] |
---|
72 | | #E whd in E:(??%?); destruct #L cases (lookup_add_cases ??????? L) |
---|
73 | [ * #E1 #E2 destruct |
---|
74 | | #L'' lapply (IH ?? (refl ??) L'') /2/ |
---|
75 | ] |
---|
76 | ] |
---|
77 | ] |
---|
78 | | -L #L #id' #n' #ty' #NE #L' |
---|
79 | cases (lookup_add_cases ??????? L') |
---|
80 | [ * #E1 #E2 destruct |
---|
81 | %2 -IH -L' |
---|
82 | generalize in match vartypes' in FOLD L; -vartypes' |
---|
83 | generalize in match stack'; -stack' |
---|
84 | elim tl |
---|
85 | [ #stack' #vartypes' whd in ⊢ (??%? → ?); #F destruct #L @⊥ |
---|
86 | elim globals in L; |
---|
87 | [ normalize #E destruct |
---|
88 | | * * #id1 #r1 #ty1 #tl1 #IH whd in match (foldr ?????); |
---|
89 | #L cases (lookup_add_cases ??????? L) |
---|
90 | [ * #E1 #E2 destruct |
---|
91 | | @IH |
---|
92 | ] |
---|
93 | ] |
---|
94 | | * #id1 #ty1 #tl1 #IH #stack' #vartypes' |
---|
95 | whd in ⊢ (??%? → ?); cases (foldr ? (Prod ??) ???) in IH ⊢ %; |
---|
96 | #vartypes2 #stack2 #IH |
---|
97 | whd in ⊢ (??%? → ?); |
---|
98 | cases (orb ??) |
---|
99 | #E whd in E:(??%?); destruct |
---|
100 | #L cases (lookup_add_cases ??????? L) |
---|
101 | [ 1,3: * #E1 #E2 destruct // |
---|
102 | | 2,4: #L' lapply (IH ?? (refl ??) L') /2/ |
---|
103 | ] |
---|
104 | ] |
---|
105 | | @(IH … (refl ??) L … NE) |
---|
106 | ] |
---|
107 | | -L #L #id' #n' #ty' #NE #L' |
---|
108 | cases (lookup_add_cases ??????? L') |
---|
109 | [ * #E1 #E2 destruct |
---|
110 | | @(IH … (refl ??) L … NE) |
---|
111 | ] |
---|
112 | ] |
---|
113 | ] qed. |
---|
114 | |
---|
115 | (* And everything is in the stack frame. *) |
---|
116 | |
---|
117 | lemma characterise_vars_in_range : ∀globals,f,vartypes,stacksize,id,n,ty. |
---|
118 | characterise_vars globals f = 〈vartypes, stacksize〉 → |
---|
119 | lookup ?? vartypes id = Some ? 〈Stack n,ty〉 → |
---|
120 | n + sizeof ty ≤ stacksize. |
---|
121 | #globals * #ret #args #vars #body whd in match (characterise_vars ??); |
---|
122 | elim (args@vars) |
---|
123 | [ #vartypes #stacksize #id #n #ty #FOLD #L @⊥ |
---|
124 | whd in FOLD:(??%?); destruct elim globals in L; |
---|
125 | [ #E normalize in E; destruct |
---|
126 | | * * #id' #r' #ty' #tl' #IH |
---|
127 | whd in match (foldr ?????); #L cases (lookup_add_cases ??????? L) |
---|
128 | [ * #E1 #E2 destruct |
---|
129 | | @IH |
---|
130 | ] |
---|
131 | ] |
---|
132 | | * #id' #ty' #tl #IH #vartypes #stacksize #id #n #ty |
---|
133 | whd in match (foldr ?????); cases (foldr ? (Prod ??) ???) in IH ⊢ %; |
---|
134 | #vartypes' #stackspace' #IH |
---|
135 | whd in ⊢ (??(match % with [_⇒?])? → ?); |
---|
136 | cases (orb ??) whd in ⊢ (??%? → ?); |
---|
137 | #E destruct #L cases (lookup_add_cases ??????? L) |
---|
138 | [ 1,3: * #E1 #E2 destruct // |
---|
139 | | 2,4: #L' lapply (IH … (refl ??) L') /2/ |
---|
140 | ] |
---|
141 | ] qed. |
---|
142 | |
---|
143 | |
---|
144 | |
---|
145 | (* Put knowledge that Globals are global into a more useful form than the |
---|
146 | one used for the invariant. *) |
---|
147 | (* XXX superfluous lemma ? Commenting it for now. |
---|
148 | if not superfluous : move to toCminorCorrectnessExpr.ma, after |
---|
149 | [characterise_vars_localid] *) |
---|
150 | (* |
---|
151 | lemma characterise_vars_global : ∀globals,f,vartypes,stacksize. |
---|
152 | characterise_vars globals f = 〈vartypes, stacksize〉 → |
---|
153 | ∀id,r,ty. lookup' vartypes id = OK ? 〈Global r,ty〉 → |
---|
154 | Exists ? (λx.x = 〈〈id,r〉,ty〉) globals ∧ |
---|
155 | ¬ Exists ? (λx. \fst x = id) (fn_params f @ fn_vars f). |
---|
156 | #globals #f #vartypes #stacksize #CHAR #id #r #ty #L |
---|
157 | cases (characterise_vars_src … CHAR id ?) |
---|
158 | [ * #r' * #ty' >L |
---|
159 | * #E1 destruct (E1) #EX |
---|
160 | % |
---|
161 | [ @EX |
---|
162 | | % #EX' cases (characterise_vars_localid … CHAR EX') |
---|
163 | #ty' whd in ⊢ (% → ?); >L * |
---|
164 | ] |
---|
165 | | * #ty' whd in ⊢ (% → ?); >L * |
---|
166 | | whd >(opt_eq_from_res ???? L) % #E destruct |
---|
167 | ] qed. *) |
---|
168 | |
---|
169 | (* Show how the global environments match up. *) |
---|
170 | |
---|
171 | lemma map_partial_All_to_All2 : ∀A,B,P,f,l,H,l'. |
---|
172 | map_partial_All A B P f l H = OK ? l' → |
---|
173 | All2 ?? (λa,b. ∃p. f a p = OK ? b) l l'. |
---|
174 | #A #B #P #f #l |
---|
175 | elim l |
---|
176 | [ #H #l' #MAP normalize in MAP; destruct // |
---|
177 | | #h #t #IH * #p #H #l' |
---|
178 | whd in ⊢ (??%? → ?); |
---|
179 | lapply (refl ? (f h p)) whd in match (proj1 ???); |
---|
180 | cases (f h p) in ⊢ (???% → %); |
---|
181 | [ #b #E #MAP cases (bind_inversion ????? MAP) |
---|
182 | #tl' * #MAP' #E' normalize in E'; destruct |
---|
183 | % [ %{p} @E | @IH [ @H | @MAP' ] ] |
---|
184 | | #m #_ #X normalize in X; destruct |
---|
185 | ] |
---|
186 | ] qed. |
---|
187 | |
---|
188 | |
---|
189 | definition clight_cminor_matching : clight_program → matching ≝ |
---|
190 | λp. |
---|
191 | let tmpuniverse ≝ universe_for_program p in |
---|
192 | let fun_globals ≝ map ?? (λidf. 〈\fst idf,Code,type_of_fundef (\snd idf)〉) (prog_funct ?? p) in |
---|
193 | let var_globals ≝ map ?? (λv. 〈\fst (\fst v), \snd (\fst v), \snd (\snd v)〉) (prog_vars ?? p) in |
---|
194 | let globals ≝ fun_globals @ var_globals in |
---|
195 | mk_matching |
---|
196 | ?? (list init_data × type) (list init_data) |
---|
197 | (λvs,f_clight,f_cminor. ∃H1,H2. translate_fundef tmpuniverse globals H1 f_clight H2 = OK ? f_cminor) |
---|
198 | (λv,w. \fst v = w). |
---|
199 | |
---|
200 | lemma clight_to_cminor_varnames : ∀p,p'. |
---|
201 | clight_to_cminor p = OK ? p' → |
---|
202 | prog_var_names … p = prog_var_names … p'. |
---|
203 | * #vars #fns #main * #vars' #fns' #main' |
---|
204 | #TO cases (bind_inversion ????? TO) #fns'' * #MAP #E |
---|
205 | whd in E:(??%%); destruct |
---|
206 | -MAP normalize |
---|
207 | elim vars |
---|
208 | [ // |
---|
209 | | * * #id #r * #d #t #tl #IH normalize >IH // |
---|
210 | ] qed. |
---|
211 | |
---|
212 | lemma clight_to_cminor_matches : ∀p,p'. |
---|
213 | clight_to_cminor p = OK ? p' → |
---|
214 | match_program (clight_cminor_matching p) p p'. |
---|
215 | * #vars #fns #main * #vars' #fns' #main' |
---|
216 | #TO cases (bind_inversion ????? TO) #fns'' * #MAP #E |
---|
217 | whd in E:(??%%); destruct |
---|
218 | % |
---|
219 | [ -MAP whd in match (m_V ?); whd in match (m_W ?); |
---|
220 | elim vars |
---|
221 | [ // |
---|
222 | | * * #id #r * #init #ty #tl #IH % |
---|
223 | [ % // |
---|
224 | | @(All2_mp … IH) * * #a #b * #c #d * * #e #f #g * /2/ |
---|
225 | ] |
---|
226 | ] |
---|
227 | | @(All2_mp … (map_partial_All_to_All2 … MAP)) -MAP |
---|
228 | * #id #f * #id' #f' * #H #F cases (bind_inversion ????? F) #f'' * #TRANSF #E |
---|
229 | normalize in E; destruct |
---|
230 | <(clight_to_cminor_varnames … TO) |
---|
231 | % whd |
---|
232 | % [2: % [2: @TRANSF | skip ] | skip ] |
---|
233 | | % |
---|
234 | ] qed. |
---|
235 | |
---|
236 | (* --------------------------------------------------------------------------- *) |
---|
237 | (* Clight to Cminor makes use of fresh symbol generators, which store the list |
---|
238 | * of symbols they generate. We need to maintain as an invariant that these grow |
---|
239 | * in a monotonic and consistent fashion. *) |
---|
240 | (* --------------------------------------------------------------------------- *) |
---|
241 | |
---|
242 | (* The two following definitions and two lemmas are duplicated from switchRemoval.ma. |
---|
243 | * TODO: factorise this in frontend_misc, if they turn out not to be useless *) |
---|
244 | definition fresher_than_or_equal : universe SymbolTag → universe SymbolTag → Prop ≝ |
---|
245 | λu1,u2. |
---|
246 | match u1 with |
---|
247 | [ mk_universe p1 ⇒ |
---|
248 | match u2 with |
---|
249 | [ mk_universe p2 ⇒ p2 ≤ p1 ] ]. |
---|
250 | |
---|
251 | definition fte ≝ fresher_than_or_equal. |
---|
252 | |
---|
253 | lemma transitive_fte : ∀u1,u2,u3. fte u1 u2 → fte u2 u3 → fte u1 u3. |
---|
254 | * #u1 * #u2 * #u3 normalize /2 by transitive_le/ |
---|
255 | qed. |
---|
256 | |
---|
257 | lemma reflexive_fte : ∀u. fte u u. |
---|
258 | * // qed. |
---|
259 | |
---|
260 | (* Express that the [first] tmpgen generates "newer" ids than an other one. *) |
---|
261 | definition tmpgen_fresher_than ≝ |
---|
262 | λvars. λgen1, gen2 : tmpgen vars. |
---|
263 | fresher_than_or_equal (tmp_universe … gen1) (tmp_universe … gen2). |
---|
264 | |
---|
265 | (* Map a predicate on all the /keys/ of an environment, i.e. on a set |
---|
266 | * of identifiers. *) |
---|
267 | definition env_domain_P : cl_env → ∀P:(ident → Prop). Prop ≝ |
---|
268 | λe, P. |
---|
269 | match e with |
---|
270 | [ an_id_map m ⇒ |
---|
271 | fold ?? (λkey,elt,acc. P (an_identifier ? key) ∧ acc) m True |
---|
272 | ]. |
---|
273 | |
---|
274 | (* Property for an identifier to be out of the set |
---|
275 | * of identifiers represented by an universe. *) |
---|
276 | definition ident_below_universe ≝ |
---|
277 | λi: ident. |
---|
278 | λu: universe SymbolTag. |
---|
279 | match i with |
---|
280 | [ an_identifier id ⇒ |
---|
281 | match u with |
---|
282 | [ mk_universe id_u ⇒ |
---|
283 | id < id_u |
---|
284 | ] |
---|
285 | ]. |
---|
286 | |
---|
287 | (* Property of the domain of an environment to be disjoint of the set |
---|
288 | * of identifiers represented by an universe. *) |
---|
289 | definition env_below_freshgen : env → ∀vars. tmpgen vars → Prop ≝ |
---|
290 | λe, vars, tmpgen. |
---|
291 | env_domain_P e (λid. ident_below_universe id (tmp_universe … tmpgen)). |
---|
292 | |
---|
293 | (* The property of interest for the proof. Identifiers generated from an |
---|
294 | * universe above the environment are not in the said environment. *) |
---|
295 | lemma lookup_fails_outside_of_env : |
---|
296 | ∀env, vars, ty, gen, id, gen'. |
---|
297 | alloc_tmp vars ty gen = 〈id, gen'〉 → |
---|
298 | env_below_freshgen env vars gen → |
---|
299 | lookup ?? env id = None ?. |
---|
300 | @cthulhu |
---|
301 | qed. |
---|
302 | |
---|
303 | (* The property of being above an environment is conserved by fresh ident |
---|
304 | * generation *) |
---|
305 | lemma alloc_tmp_env_invariant : |
---|
306 | ∀env, vars, ty, gen, id, gen'. |
---|
307 | alloc_tmp vars ty gen = 〈id, gen'〉 → |
---|
308 | env_below_freshgen env vars gen → |
---|
309 | env_below_freshgen env vars gen'. |
---|
310 | @cthulhu |
---|
311 | qed. |
---|
312 | |
---|
313 | (* --------------------------------------------------------------------------- *) |
---|
314 | (* Additional invariants not contain in clight_cminor_data *) |
---|
315 | (* --------------------------------------------------------------------------- *) |
---|
316 | |
---|
317 | (* Fresh variable ident generator *) |
---|
318 | (* tmp_gen : tmpgen alloc_type; *) |
---|
319 | |
---|
320 | (* Temporary variables generated during conversion are well-allocated. *) |
---|
321 | definition tmp_vars_well_allocated ≝ |
---|
322 | λtmpenv: list (ident × type). |
---|
323 | λcm_env. |
---|
324 | λcm_m. |
---|
325 | λcl_m. |
---|
326 | λE: embedding. |
---|
327 | ∀local_variable. |
---|
328 | ∀H:present ?? cm_env local_variable. |
---|
329 | ∀ty. Exists ? (λx. x = 〈local_variable, ty〉) tmpenv → |
---|
330 | ∀v. val_typ v (typ_of_type ty) → |
---|
331 | ∃cm_m'. storev (typ_of_type ty) cm_m (lookup_present ?? cm_env local_variable H) v = Some ? cm_m' ∧ |
---|
332 | memory_inj E cl_m cm_m'. |
---|
333 | |
---|
334 | (* wrap the above invariant into a clight_cminor_data-eating prop *) |
---|
335 | (* |
---|
336 | definition tmp_vars_well_allocated' ≝ |
---|
337 | λcl_f, cl_ge, cm_ge, INV. |
---|
338 | λframe_data: clight_cminor_data cl_f cl_ge cm_ge INV. |
---|
339 | λtmp_gen: tmpgen (alloc_type … frame_data). |
---|
340 | ∀vars_v, cl_m_v, cm_env_v, cm_m_v. |
---|
341 | vars_v = alloc_type … frame_data → |
---|
342 | cl_m_v = cl_m … frame_data → |
---|
343 | cm_env_v = cm_env … frame_data → |
---|
344 | cm_m_v = cm_m … frame_data → |
---|
345 | ∀local_variable. |
---|
346 | ∀H:present ?? cm_env_v local_variable. |
---|
347 | ∀ty. Exists ? (λx. x = 〈local_variable, ty〉) (tmp_env … tmp_gen) → |
---|
348 | ∀v. val_typ v (typ_of_type ty) → |
---|
349 | ∃cm_m'. storev (typ_of_type ty) cm_m_v (lookup_present ?? cm_env_v local_variable H) v = Some ? cm_m' ∧ |
---|
350 | memory_inj (Em … frame_data) cl_m_v cm_m'. *) |
---|
351 | |
---|
352 | (* --------------------------------------------------------------------------- *) |
---|
353 | (* A measure on Clight states that is decreasing along execution sequences *) |
---|
354 | (* --------------------------------------------------------------------------- *) |
---|
355 | |
---|
356 | (* statements *) |
---|
357 | let rec measure_Clight_statement (s : statement) : ℕ ≝ |
---|
358 | match s with |
---|
359 | [ Sskip ⇒ 0 |
---|
360 | | Ssequence s1 s2 ⇒ |
---|
361 | measure_Clight_statement s1 + measure_Clight_statement s2 + 1 |
---|
362 | | Sifthenelse e s1 s2 => |
---|
363 | measure_Clight_statement s1 + measure_Clight_statement s2 + 1 |
---|
364 | | Swhile e s => |
---|
365 | measure_Clight_statement s + 1 |
---|
366 | | Sdowhile e s => |
---|
367 | measure_Clight_statement s + 1 |
---|
368 | | Sfor s1 e s2 s3 => |
---|
369 | measure_Clight_statement s1 + |
---|
370 | measure_Clight_statement s2 + |
---|
371 | measure_Clight_statement s3 + 1 |
---|
372 | | Sswitch e ls => |
---|
373 | measure_Clight_ls ls + 1 |
---|
374 | | Slabel l s => |
---|
375 | measure_Clight_statement s + 1 |
---|
376 | | Scost cl s => |
---|
377 | measure_Clight_statement s + 1 |
---|
378 | | _ => 1 |
---|
379 | ] |
---|
380 | and measure_Clight_ls (ls : labeled_statements) : ℕ := |
---|
381 | match ls with |
---|
382 | [ LSdefault s => |
---|
383 | measure_Clight_statement s |
---|
384 | | LScase sz i s ls => |
---|
385 | measure_Clight_statement s + |
---|
386 | measure_Clight_ls ls |
---|
387 | ]. |
---|
388 | |
---|
389 | (* continuations *) |
---|
390 | let rec measure_Clight_cont (cont : cl_cont) : ℕ ≝ |
---|
391 | match cont with |
---|
392 | [ Kstop => 0 |
---|
393 | | Kseq s k => |
---|
394 | measure_Clight_statement s + |
---|
395 | measure_Clight_cont k + 1 |
---|
396 | | Kwhile e s k => |
---|
397 | measure_Clight_statement s + |
---|
398 | measure_Clight_cont k + 1 |
---|
399 | | Kdowhile e s k => |
---|
400 | measure_Clight_statement s + |
---|
401 | measure_Clight_cont k + 1 |
---|
402 | | Kfor2 e s1 s2 k => |
---|
403 | measure_Clight_statement s1 + |
---|
404 | measure_Clight_statement s2 + |
---|
405 | measure_Clight_cont k + 1 |
---|
406 | | Kfor3 e s1 s2 k => |
---|
407 | measure_Clight_statement s1 + |
---|
408 | measure_Clight_statement s2 + |
---|
409 | measure_Clight_cont k + 1 |
---|
410 | | Kswitch k => |
---|
411 | measure_Clight_cont k + 1 |
---|
412 | | Kcall retaddr f e k => |
---|
413 | measure_Clight_statement (fn_body f) + |
---|
414 | measure_Clight_cont k + 1 |
---|
415 | ]. |
---|
416 | |
---|
417 | (* Shamelessly copying Compcert. *) |
---|
418 | definition measure_Clight : Clight_state → ℕ × ℕ ≝ |
---|
419 | λstate. |
---|
420 | match state with |
---|
421 | [ State f s k e m ⇒ |
---|
422 | 〈measure_Clight_statement s + measure_Clight_cont k + 1, measure_Clight_statement s + 1〉 |
---|
423 | | Callstate fb fd args k m ⇒ 〈0, 0〉 |
---|
424 | | Returnstate res k m ⇒ 〈0, 0〉 |
---|
425 | | Finalstate r ⇒ 〈0, 0〉 |
---|
426 | ]. |
---|
427 | |
---|
428 | (* Stuff on lexicographic orders *) |
---|
429 | definition lexicographic : ∀A:Type[0]. (A → A → Prop) → A × A → A × A → Prop ≝ |
---|
430 | λA,Ord, x, y. |
---|
431 | let 〈xa, xb〉 ≝ x in |
---|
432 | let 〈ya, yb〉 ≝ y in |
---|
433 | Ord xa ya ∨ (xa = ya ∧ Ord xb yb). |
---|
434 | |
---|
435 | definition lex_lt ≝ lexicographic nat lt. |
---|
436 | |
---|
437 | (* --------------------------------------------------------------------------- *) |
---|
438 | (* Simulation relations *) |
---|
439 | (* --------------------------------------------------------------------------- *) |
---|
440 | |
---|
441 | definition CMcast : ∀t,t'. CMexpr t → t = t' → CMexpr t'. |
---|
442 | #t #t' #e #H destruct (H) @e |
---|
443 | qed. |
---|
444 | |
---|
445 | lemma CMcast_identity : ∀t. ∀e: CMexpr t. CMcast t t e (refl ??) = e. |
---|
446 | #H1 #H2 @refl qed. |
---|
447 | |
---|
448 | (* relate Clight continuations and Cminor ones. *) |
---|
449 | inductive clight_cminor_cont_rel : |
---|
450 | ∀cl_ge, cm_ge. |
---|
451 | ∀INV: clight_cminor_inv cl_ge cm_ge. (* stuff on global variables and functions (matching between CL and CM) *) |
---|
452 | ∀cl_fd: clight_fundef. (* current Clight function *) |
---|
453 | fundef internal_function → (* current Cminor function *) |
---|
454 | cl_env → (* Clight local environment *) |
---|
455 | cm_env → (* Cminor local environment *) |
---|
456 | mem → (* Cminor memory state *) |
---|
457 | ∀alloc_type:var_types. (* map vars to alloc type *) |
---|
458 | ∀tmpenv:list (ident×type). (* list of generated variables *) |
---|
459 | (*tmpgen alloc_type → (* input freshgen *) |
---|
460 | tmpgen alloc_type → (* output freshgen *) *) (* bad idea *) |
---|
461 | option typ → (* optional target type - arg. uniform over a given function *) |
---|
462 | cl_cont → (* CL cont *) |
---|
463 | cm_cont → (* CM cont *) |
---|
464 | stack → (* CM stack *) |
---|
465 | Prop ≝ |
---|
466 | (* Stop continuation *) |
---|
467 | | ClCm_cont_stop: |
---|
468 | ∀cl_ge, cm_ge, INV, cl_f, cm_f, target_type. |
---|
469 | ∀cl_env, cm_env, cm_m, alloc_type, tmpenv. (*, stmt_univ, stmt_univ'.*) |
---|
470 | ∀cm_stack. |
---|
471 | cm_stack = SStop → |
---|
472 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env cm_m alloc_type tmpenv (* stmt_univ stmt_univ' *) target_type Kstop Kend cm_stack |
---|
473 | |
---|
474 | (* Seq continuation *) |
---|
475 | | ClCm_cont_seq: |
---|
476 | ∀cl_ge, cm_ge, INV, cl_f, cm_f, target_type. |
---|
477 | ∀stack. |
---|
478 | ∀alloc_type. |
---|
479 | ∀tmpenv. |
---|
480 | ∀cl_s: statement. |
---|
481 | ∀cm_s: stmt. |
---|
482 | ∀cl_env: cl_env. |
---|
483 | ∀cm_env: cm_env. |
---|
484 | ∀cm_m: mem. |
---|
485 | ∀cl_k': cl_cont. |
---|
486 | ∀cm_k': cm_cont. |
---|
487 | ∀stmt_univ, stmt_univ'. |
---|
488 | ∀lbl_univ, lbl_univ'. |
---|
489 | ∀lbls. |
---|
490 | ∀flag. |
---|
491 | ∀Htranslate_inv. |
---|
492 | translate_statement alloc_type stmt_univ lbl_univ lbls flag target_type cl_s = OK ? «〈stmt_univ',lbl_univ',cm_s〉, Htranslate_inv» → |
---|
493 | (* ---- invariant on label existence ---- *) |
---|
494 | lset_inclusion ? (labels_of cm_s) (labels_of (f_body cm_f)) → |
---|
495 | (* ---- invariant on fresh variables ---- *) |
---|
496 | lset_inclusion ? (tmp_env alloc_type stmt_univ') tmpenv → |
---|
497 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ'*) target_type cl_k' cm_k' stack → |
---|
498 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ'*) target_type (ClKseq cl_s cl_k') (Kseq cm_s cm_k') stack |
---|
499 | |
---|
500 | (* While continuation *) |
---|
501 | | ClCm_cont_while: |
---|
502 | (* Inductive family parameters *) |
---|
503 | ∀cl_ge, cm_ge, INV, cl_f, cm_f, target_type. |
---|
504 | ∀stack. |
---|
505 | ∀alloc_type. |
---|
506 | ∀tmpenv. |
---|
507 | ∀cl_env. |
---|
508 | ∀cm_env. |
---|
509 | ∀cm_m. |
---|
510 | (* sub-continuations *) |
---|
511 | ∀cl_k': cl_cont. |
---|
512 | ∀cm_k': cm_cont. |
---|
513 | (* elements of the source while statement *) |
---|
514 | ∀sz,sg. |
---|
515 | ∀cl_ty. |
---|
516 | ∀cl_cond_desc. |
---|
517 | ∀cl_body. |
---|
518 | ∀Heq: ASTint sz sg = typ_of_type cl_ty. |
---|
519 | (* elements of the converted while statement *) |
---|
520 | ∀cm_cond: CMexpr (ASTint sz sg). |
---|
521 | ∀cm_body. |
---|
522 | ∀entry,exit: identifier Label. |
---|
523 | (* universes used to generate fresh labels and variables *) |
---|
524 | ∀stmt_univ, stmt_univ'. |
---|
525 | ∀lbl_univ, lbl_univ', lbl_univ''. |
---|
526 | ∀lbls: lenv. |
---|
527 | ∀Htranslate_inv. |
---|
528 | (* relate CL and CM expressions *) |
---|
529 | ∀Hexpr_vars:expr_vars ? cm_cond (local_id alloc_type). |
---|
530 | translate_expr alloc_type (Expr cl_cond_desc cl_ty) ≃ OK ? («cm_cond, Hexpr_vars») → |
---|
531 | (* Parameters and results to find_label_always *) |
---|
532 | ∀sInv: stmt_inv cm_f cm_env (f_body cm_f). |
---|
533 | ∀Hlabel_declared: Exists (identifier Label) (λl'.l'=entry) (labels_of (f_body cm_f)). |
---|
534 | ∀Hinv. |
---|
535 | (* Specify how the labels for the while-replacing gotos are produced *) |
---|
536 | mklabels lbl_univ = 〈〈entry, exit〉, lbl_univ'〉 → |
---|
537 | translate_statement alloc_type stmt_univ lbl_univ' lbls (ConvertTo entry exit) target_type cl_body = OK ? «〈stmt_univ',lbl_univ'',cm_body〉, Htranslate_inv» → |
---|
538 | (* ---- Invariant on label existence ---- *) |
---|
539 | lset_inclusion ? (labels_of cm_body) (labels_of (f_body cm_f)) → |
---|
540 | (* ---- invariant on fresh variables ---- *) |
---|
541 | lset_inclusion ? (tmp_env alloc_type stmt_univ') tmpenv → |
---|
542 | find_label_always entry (f_body cm_f) Kend Hlabel_declared cm_f cm_env sInv I = |
---|
543 | «〈(*St_label entry*) |
---|
544 | (St_seq |
---|
545 | (St_ifthenelse ?? cm_cond (St_seq cm_body (St_goto entry)) St_skip) |
---|
546 | (St_label exit St_skip)), cm_k'〉, Hinv» → |
---|
547 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv (* stmt_univ stmt_univ' *) target_type cl_k' cm_k' stack → |
---|
548 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv (* stmt_univ stmt_univ' *) target_type |
---|
549 | (Kwhile (Expr cl_cond_desc cl_ty) cl_body cl_k') |
---|
550 | (Kseq (St_goto entry) (Kseq (St_label exit St_skip) cm_k')) stack |
---|
551 | |
---|
552 | | ClCm_cont_call_store: |
---|
553 | ∀cl_ge, cm_ge, INV, (* callee fn *) cl_fd, cm_fd, (* caller *) cl_f, cm_f, target_type, target_type'. |
---|
554 | ∀stack. |
---|
555 | ∀alloc_type,alloc_type'. |
---|
556 | ∀tmp_env,tmp_env'. |
---|
557 | ∀cl_env,cl_env'. |
---|
558 | ∀cm_env,cm_env'. |
---|
559 | ∀cm_m. |
---|
560 | (* sub-continuations *) |
---|
561 | ∀cl_k': cl_cont. |
---|
562 | ∀cm_k': cm_cont. |
---|
563 | (* CL return addr *) |
---|
564 | ∀CL_lvalue_block,CL_lvalue_offset,lhs_ty. |
---|
565 | ∀CM_lvalue_ptr. |
---|
566 | (* CM stack content *) |
---|
567 | ∀stackptr. |
---|
568 | ∀fInv. |
---|
569 | ∀tmp_var, ret_var. |
---|
570 | ∀Htmp_var_present. |
---|
571 | ∀Hret_present. |
---|
572 | ∀Hstmt_inv. |
---|
573 | (* TODO: loads of invariants *) |
---|
574 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env' cm_env' cm_m alloc_type' tmp_env' (* stmt_univ stmt_univ' *) target_type' cl_k' cm_k' stack → |
---|
575 | clight_cminor_cont_rel cl_ge cm_ge INV cl_fd cm_fd cl_env cm_env cm_m alloc_type tmp_env (*stmt_univ stmt_univ*) target_type |
---|
576 | (Kcall (Some ? 〈CL_lvalue_block, CL_lvalue_offset, lhs_ty〉) cl_f cl_env cl_k') |
---|
577 | Kend (* cm_k' is on the Cminor stack, below *) |
---|
578 | (Scall (Some ? 〈ret_var,typ_of_type lhs_ty〉) cm_f stackptr |
---|
579 | (update_present SymbolTag val cm_env' tmp_var Htmp_var_present (Vptr CM_lvalue_ptr)) Hret_present |
---|
580 | (stmt_inv_update cm_f cm_env' (f_body cm_f) tmp_var (Vptr CM_lvalue_ptr) fInv Htmp_var_present) |
---|
581 | (Kseq |
---|
582 | (St_store (typ_of_type lhs_ty) (Id ASTptr tmp_var) |
---|
583 | (Id (typ_of_type lhs_ty) ret_var)) cm_k') Hstmt_inv stack) |
---|
584 | |
---|
585 | | ClCm_cont_call_nostore: |
---|
586 | ∀cl_ge, cm_ge, INV, (* callee *) cl_fd, cm_fd, (* caller *) cl_f, cm_f, target_type, target_type'. |
---|
587 | ∀stack. |
---|
588 | ∀alloc_type,alloc_type'. |
---|
589 | ∀tmpenv, tmpenv'. |
---|
590 | ∀cl_env,cl_env'. |
---|
591 | ∀cm_env,cm_env'. |
---|
592 | ∀cm_m. |
---|
593 | (* sub-continuations *) |
---|
594 | ∀cl_k': cl_cont. |
---|
595 | ∀cm_k': cm_cont. |
---|
596 | (* CM stack content *) |
---|
597 | ∀cl_lhs, cm_lhs. |
---|
598 | match cl_lhs with |
---|
599 | [ None ⇒ match cm_lhs with [ None ⇒ True | _ ⇒ False ] |
---|
600 | | Some cl_location ⇒ |
---|
601 | match cm_lhs with |
---|
602 | [ None ⇒ False |
---|
603 | | Some cm_location ⇒ |
---|
604 | ∃CL_lvalue_block, CL_lvalue_offset, lhs_ty, ret_var. |
---|
605 | cl_location = 〈CL_lvalue_block,CL_lvalue_offset, lhs_ty〉 ∧ |
---|
606 | cm_location = 〈ret_var, typ_of_type lhs_ty〉 |
---|
607 | ] |
---|
608 | ] → |
---|
609 | ∀Hret_present. |
---|
610 | ∀Hstmt_inv. |
---|
611 | ∀stackptr. |
---|
612 | ∀fInv. |
---|
613 | (* ∀stmt_univ.*) |
---|
614 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env' cm_env' cm_m alloc_type' tmpenv' (* stmt_univ stmt_univ' *) target_type' cl_k' cm_k' stack → |
---|
615 | clight_cminor_cont_rel cl_ge cm_ge INV cl_fd cm_fd cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ*) target_type |
---|
616 | (Kcall cl_lhs cl_f cl_env cl_k') |
---|
617 | Kend |
---|
618 | (Scall cm_lhs cm_f stackptr cm_env Hret_present fInv cm_k' Hstmt_inv stack). |
---|
619 | |
---|
620 | lemma translate_fundef_internal : |
---|
621 | ∀ge1, ge2. |
---|
622 | ∀INV: clight_cminor_inv ge1 ge2. |
---|
623 | ∀u, cl_f, cm_fundef. |
---|
624 | ∀H1, H2. |
---|
625 | translate_fundef u (globals ?? INV) H1 (CL_Internal cl_f) H2 = OK ? cm_fundef → |
---|
626 | ∃cm_f. cm_fundef = Internal ? cm_f ∧ |
---|
627 | translate_function u (globals ge1 ge2 INV) cl_f H1 H2 = OK ? cm_f. |
---|
628 | #ge1 #ge2 #INV #u #cl_f #cm_fd #H1 #H2 |
---|
629 | whd in ⊢ ((??%?) → ?); cases (translate_function u (globals ge1 ge2 INV) cl_f H1 H2) |
---|
630 | normalize nodelta |
---|
631 | [ 2: #er #Habsurd destruct (Habsurd) |
---|
632 | | 1: #cm_f #Heq destruct (Heq) %{cm_f} @conj @refl ] |
---|
633 | qed. |
---|
634 | |
---|
635 | lemma translate_fundef_external : |
---|
636 | ∀ge1, ge2. |
---|
637 | ∀INV: clight_cminor_inv ge1 ge2. |
---|
638 | ∀u, id, tl, ty. |
---|
639 | ∀H1, H2. |
---|
640 | translate_fundef u (globals ?? INV) H1 (CL_External id tl ty) H2 = |
---|
641 | OK ? (External ? (mk_external_function id (signature_of_type tl ty))). |
---|
642 | #ge1 #ge2 #INV #u #id #tl #ty #H1 #H2 @refl |
---|
643 | qed. |
---|
644 | |
---|
645 | (* Definition of the simulation relation on states. The orders of the parameters is dictated by |
---|
646 | * the necessity of performing an inversion on the continuation sim relation without having to |
---|
647 | * play the usual game of lapplying all previous dependent arguments. *) |
---|
648 | |
---|
649 | inductive clight_cminor_rel : ∀cl_ge, cm_ge. clight_cminor_inv cl_ge cm_ge → Clight_state → Cminor_state → Prop ≝ |
---|
650 | (* --------------------------------------------------------------------------- *) |
---|
651 | (* normal state *) |
---|
652 | (* --------------------------------------------------------------------------- *) |
---|
653 | | CMR_normal : |
---|
654 | (* Clight and Cminor global envs *) |
---|
655 | ∀cl_ge, cm_ge. |
---|
656 | (* Relates globals to globals and functions to functions. *) |
---|
657 | ∀INV: clight_cminor_inv cl_ge cm_ge. |
---|
658 | (* ---- Statements ---- *) |
---|
659 | (* Clight statement *) |
---|
660 | ∀cl_s: statement. |
---|
661 | (* Cminor statement *) |
---|
662 | ∀cm_s: stmt. |
---|
663 | (* ---- Continuations ---- *) |
---|
664 | (* Clight continuation *) |
---|
665 | ∀cl_k: cl_cont. |
---|
666 | (* Cminor continuation *) |
---|
667 | ∀cm_k: cm_cont. |
---|
668 | (* Cminor stack *) |
---|
669 | ∀cm_st: stack. |
---|
670 | (* Clight enclosing function *) |
---|
671 | ∀cl_f: function. |
---|
672 | (* Cminor enclosing function *) |
---|
673 | ∀cm_f: internal_function. |
---|
674 | (* optional return type of the function *) |
---|
675 | ∀rettyp. |
---|
676 | (* mapping from variables to their Cminor alloc type *) |
---|
677 | ∀alloc_type. |
---|
678 | (* Clight env/mem *) |
---|
679 | ∀cl_env, cl_m. |
---|
680 | (* Cminor env/mem *) |
---|
681 | ∀cm_env, cm_m. |
---|
682 | (* Stack pointer (block containing Cminor locals), related size *) |
---|
683 | ∀stackptr, stacksize. |
---|
684 | (* ---- Cminor invariants ---- *) |
---|
685 | ∀fInv: stmt_inv cm_f cm_env (f_body cm_f). |
---|
686 | ∀sInv: stmt_inv cm_f cm_env cm_s. |
---|
687 | ∀kInv: cont_inv cm_f cm_env cm_k. |
---|
688 | (* ---- relate return type variable to actual return type ---- *) |
---|
689 | rettyp = opttyp_of_type (fn_return cl_f) → |
---|
690 | (* ---- relate Clight and Cminor functions ---- *) |
---|
691 | ∀func_univ: universe SymbolTag. |
---|
692 | ∀Hfresh_globals: globals_fresh_for_univ ? (globals ?? INV) func_univ. |
---|
693 | ∀Hfresh_function: fn_fresh_for_univ cl_f func_univ. |
---|
694 | translate_function func_univ (globals ?? INV) cl_f Hfresh_globals Hfresh_function = OK ? cm_f → |
---|
695 | (* ---- relate Clight and Cminor statements ---- *) |
---|
696 | (* fresh var generators *) |
---|
697 | ∀stmt_univ,stmt_univ' : tmpgen alloc_type. |
---|
698 | (* fresh label generators *) |
---|
699 | ∀lbl_univ,lbl_univ' : labgen. |
---|
700 | (* map old labels to new labels *) |
---|
701 | ∀lbls : lenv. |
---|
702 | (* specify where to goto when encountering a continue or a break *) |
---|
703 | ∀flag : convert_flag. |
---|
704 | (* Invariant on translation produced by [translate_statement] *) |
---|
705 | ∀Htranslate_inv. |
---|
706 | translate_statement alloc_type stmt_univ lbl_univ lbls flag rettyp cl_s = OK ? «〈stmt_univ',lbl_univ',cm_s〉, Htranslate_inv» → |
---|
707 | (* ---- invariant on label existence ---- *) |
---|
708 | lset_inclusion ? (labels_of cm_s) (labels_of (f_body cm_f)) → |
---|
709 | (* ---- relate Clight continuation to Cminor continuation ---- *) |
---|
710 | ∀tmpenv. |
---|
711 | lset_inclusion ? (tmp_env ? stmt_univ') tmpenv → |
---|
712 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ'*) rettyp cl_k cm_k cm_st → |
---|
713 | (* ---- state invariants for memory and environments ---- *) |
---|
714 | (* Embedding *) |
---|
715 | ∀Em: embedding. |
---|
716 | (* locals are properly allocated *) |
---|
717 | tmp_vars_well_allocated tmpenv cm_env cm_m cl_m Em → |
---|
718 | (* specify how alloc_type is built *) |
---|
719 | characterise_vars (globals ?? INV) cl_f = 〈alloc_type, stacksize〉 → |
---|
720 | (* spec. Clight env at alloc time *) |
---|
721 | (∃m,m'. exec_alloc_variables empty_env m (fn_params cl_f @ fn_vars cl_f) = 〈cl_env,m'〉) → |
---|
722 | (* memory injection *) |
---|
723 | memory_inj Em cl_m cm_m → |
---|
724 | (* map CL env to CM env *) |
---|
725 | memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type → |
---|
726 | (* Force embedding to compute identity on functions *) |
---|
727 | (∀b. block_region b = Code → Em b = Some ? 〈b, zero_offset〉) → |
---|
728 | (* Make explicit the fact that locals in CL are mapped to a single CM block *) |
---|
729 | (∀b1.∀delta. Em b1=Some ? 〈stackptr,delta〉 → |
---|
730 | mem block b1 (blocks_of_env cl_env)) → |
---|
731 | (* The fresh name generator is compatible with the clight environment *) |
---|
732 | env_below_freshgen cl_env alloc_type stmt_univ → |
---|
733 | clight_cminor_rel cl_ge cm_ge INV |
---|
734 | (ClState cl_f cl_s cl_k cl_env cl_m) |
---|
735 | (CmState cm_f cm_s cm_env fInv sInv cm_m stackptr cm_k kInv cm_st) |
---|
736 | (* --------------------------------------------------------------------------- *) |
---|
737 | (* return state *) |
---|
738 | (* --------------------------------------------------------------------------- *) |
---|
739 | | CMR_return : |
---|
740 | (* Clight and Cminor global envs *) |
---|
741 | ∀cl_ge, cm_ge. |
---|
742 | (* Relates globals to globals and functions to functions. *) |
---|
743 | ∀INV: clight_cminor_inv cl_ge cm_ge. |
---|
744 | (* ---- Continuations and functions ---- *) |
---|
745 | (* Clight continuation *) |
---|
746 | ∀cl_k: cl_cont. |
---|
747 | (* Cminor continuation *) |
---|
748 | ∀cm_k: cm_cont. |
---|
749 | (* Cminor stack *) |
---|
750 | ∀cm_st: stack. |
---|
751 | (* Clight enclosing function *) |
---|
752 | ∀cl_f: function. |
---|
753 | (* Cminor enclosing function *) |
---|
754 | ∀cm_f: internal_function. |
---|
755 | (* mapping from variables to their Cminor alloc type *) |
---|
756 | ∀alloc_type. |
---|
757 | (* Clight env/mem *) |
---|
758 | ∀cl_env, cl_m. |
---|
759 | (* Cminor env/mem *) |
---|
760 | ∀cm_env, cm_m. |
---|
761 | (* Stack pointer (block containing Cminor locals), related size *) |
---|
762 | ∀stackptr, stacksize. |
---|
763 | (* fresh label generator *) |
---|
764 | ∀stmt_univ: tmpgen alloc_type. |
---|
765 | ∀tmpenv. |
---|
766 | lset_inclusion ? (tmp_env ? stmt_univ) tmpenv → |
---|
767 | (* ---- state invariants for memory and environments ---- *) |
---|
768 | (* Embedding *) |
---|
769 | ∀Em: embedding. |
---|
770 | (* locals are properly allocated *) |
---|
771 | tmp_vars_well_allocated tmpenv cm_env cm_m cl_m Em → |
---|
772 | (* specify how alloc_type is built *) |
---|
773 | characterise_vars (globals ?? INV) cl_f = 〈alloc_type, stacksize〉 → |
---|
774 | (* spec. Clight env at alloc time *) |
---|
775 | (∃m,m'. exec_alloc_variables empty_env m (fn_params cl_f @ fn_vars cl_f) = 〈cl_env,m'〉) → |
---|
776 | (* memory injection *) |
---|
777 | memory_inj Em cl_m cm_m → |
---|
778 | (* map CL env to CM env *) |
---|
779 | memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type → |
---|
780 | (* Force embedding to compute identity on functions *) |
---|
781 | (∀b. block_region b = Code → Em b = Some ? 〈b, zero_offset〉) → |
---|
782 | (* Make explicit the fact that locals in CL are mapped to a single CM block *) |
---|
783 | (∀b1.∀delta. Em b1=Some ? 〈stackptr,delta〉 → |
---|
784 | mem block b1 (blocks_of_env cl_env)) → |
---|
785 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ*) (None ?) cl_k cm_k cm_st → |
---|
786 | clight_cminor_rel cl_ge cm_ge INV |
---|
787 | (ClReturnstate Vundef cl_k cl_m) |
---|
788 | (CmReturnstate (None val) cm_m cm_st) |
---|
789 | (* --------------------------------------------------------------------------- *) |
---|
790 | (* call state *) |
---|
791 | (* --------------------------------------------------------------------------- *) |
---|
792 | | CMR_call : |
---|
793 | (* Clight and Cminor global envs *) |
---|
794 | ∀cl_ge, cm_ge. |
---|
795 | (* Relates globals to globals and functions to functions. *) |
---|
796 | ∀INV: clight_cminor_inv cl_ge cm_ge. |
---|
797 | (* ------- Continuations and functions for the current stack frame -------- *) |
---|
798 | (* Clight continuation *) |
---|
799 | ∀cl_k: cl_cont. |
---|
800 | (* Cminor stack *) |
---|
801 | ∀cm_st: stack. |
---|
802 | (* Clight called fundef *) |
---|
803 | ∀cl_fundef. |
---|
804 | (* Cminor called fundef *) |
---|
805 | ∀cm_fundef. |
---|
806 | (* block of Clight and Cminor function *) |
---|
807 | (* XXX why do I need that already ? *) |
---|
808 | ∀fblock: block. |
---|
809 | (* optional return type of the function *) |
---|
810 | ∀target_type. |
---|
811 | (* Clight env/mem *) |
---|
812 | ∀cl_env, cl_m. |
---|
813 | (* Cminor env/mem *) |
---|
814 | ∀cm_env, cm_m. |
---|
815 | (* specify fblock; as a consequence of these and INV we can deduce that |
---|
816 | cm_fundef is the translation of cl_fundef *) |
---|
817 | ∀fun_id. |
---|
818 | find_funct_id clight_fundef cl_ge (Vptr (mk_pointer fblock zero_offset)) = Some ? 〈cl_fundef,fun_id〉 → |
---|
819 | find_funct_id (fundef internal_function) cm_ge (Vptr (mk_pointer fblock zero_offset)) = Some ? 〈cm_fundef,fun_id〉 → |
---|
820 | ∀tmpenv. |
---|
821 | (*match cl_fundef with |
---|
822 | [ CL_Internal _ ⇒*) |
---|
823 | (* specify continuation *) |
---|
824 | clight_cminor_cont_rel cl_ge cm_ge INV cl_fundef cm_fundef cl_env cm_env cm_m (empty_map …) tmpenv target_type cl_k Kend cm_st |
---|
825 | (* ∨ |
---|
826 | (∃cl_blo, cl_off, cl_ty. (* Clight return loscation + type *) |
---|
827 | ∃cm_loc_ident, cm_return_ident. (* Cminor locals storing the lvalues *) |
---|
828 | ∃sInv, fInv, kInv. (* Invariants required by the stack construction *) |
---|
829 | present ?? cm_env cm_loc_ident ∧ |
---|
830 | present ?? cm_env cm_return_ident ∧ |
---|
831 | (clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env cm_m alloc_type target_type |
---|
832 | (Kcall (Some ? 〈cl_blo, cl_off, cl_ty〉) cl_f cl_env cl_k) |
---|
833 | cm_k (Scall (Some ? 〈cm_return_ident,typ_of_type cl_ty〉) cm_f stackptr cm_env sInv fInv |
---|
834 | (Kseq (St_store (typ_of_type cl_ty) (Id ? cm_loc_ident) (Id ? cm_return_ident)) cm_k) |
---|
835 | kInv cm_st))) *) |
---|
836 | (*| CL_External cl_id cl_argtypes cl_rettype ⇒ |
---|
837 | match cm_fundef with |
---|
838 | [ Internal _ ⇒ False |
---|
839 | | External cm_f_ext ⇒ True ] |
---|
840 | (* match cm_f_ext with |
---|
841 | [ mk_external_function cm_id sig ⇒ |
---|
842 | cl_fun_id = cl_id ∧ cm_fun_id = cm_id ∧ cl_fun_id = cm_fun_id |
---|
843 | ] *) |
---|
844 | ]*) → |
---|
845 | (* ---- state invariants for memory and environments ---- *) |
---|
846 | (* Embedding *) |
---|
847 | ∀Em: embedding. |
---|
848 | (* memory injection *) |
---|
849 | memory_inj Em cl_m cm_m → |
---|
850 | (* Force embedding to compute identity on functions *) |
---|
851 | (∀b. block_region b = Code → Em b = Some ? 〈b, zero_offset〉) → |
---|
852 | ∀cl_args_values, cm_args_values. |
---|
853 | All2 val val (λcl_val:val.λcm_val:val.value_eq Em cl_val cm_val) cl_args_values cm_args_values → |
---|
854 | clight_cminor_rel cl_ge cm_ge INV |
---|
855 | (ClCallstate fun_id cl_fundef cl_args_values cl_k cl_m) |
---|
856 | (CmCallstate fun_id cm_fundef cm_args_values cm_m cm_st) |
---|
857 | (* --------------------------------------------------------------------------- *) |
---|
858 | (* special while state *) |
---|
859 | (* --------------------------------------------------------------------------- *) |
---|
860 | | CMR_while: |
---|
861 | ∀cl_ge,cm_ge,INV,cl_f,cm_f. |
---|
862 | ∀cl_env, cl_m, cm_env, cm_m, stackptr, stacksize. |
---|
863 | ∀alloc_type. |
---|
864 | ∀cl_k, cm_k. |
---|
865 | ∀sz,sg, cl_ty, cl_cond_desc. |
---|
866 | ∀cl_body. |
---|
867 | ∀entry_label, exit_label. |
---|
868 | ∀cm_cond: CMexpr (ASTint sz sg). |
---|
869 | ∀cm_body. |
---|
870 | ∀cm_stack. |
---|
871 | ∀rettyp. |
---|
872 | ∀kInv: cont_inv cm_f cm_env cm_k. |
---|
873 | ∀fInv: stmt_inv cm_f cm_env (f_body cm_f). |
---|
874 | ∀sInv: stmt_inv cm_f cm_env |
---|
875 | ((*St_label entry_label*) |
---|
876 | (St_seq |
---|
877 | (St_ifthenelse sz sg cm_cond (St_seq cm_body (St_goto entry_label)) St_skip) |
---|
878 | (St_label exit_label St_skip))). |
---|
879 | (* Constrain the CL type *) |
---|
880 | ∀Heq_ty: ASTint sz sg = typ_of_type cl_ty. |
---|
881 | (* ---- relate return type variable to actual return type ---- *) |
---|
882 | rettyp = opttyp_of_type (fn_return cl_f) → |
---|
883 | (* ---- relate Clight and Cminor functions ---- *) |
---|
884 | ∀func_univ: universe SymbolTag. |
---|
885 | ∀Hfresh_globals: globals_fresh_for_univ ? (globals ?? INV) func_univ. |
---|
886 | ∀Hfresh_function: fn_fresh_for_univ cl_f func_univ. |
---|
887 | translate_function func_univ (globals ?? INV) cl_f Hfresh_globals Hfresh_function = OK ? cm_f → |
---|
888 | (* ---- relate continuations ---- *) |
---|
889 | ∀stmt_univ,stmt_univ',lbl_univ,lbl_univ',lbl_univ'',lbls. |
---|
890 | ∀tmpenv'. |
---|
891 | lset_inclusion ? (tmp_env ? stmt_univ') tmpenv' → |
---|
892 | clight_cminor_cont_rel cl_ge cm_ge INV (CL_Internal cl_f) (Internal … cm_f) cl_env cm_env cm_m alloc_type tmpenv' rettyp cl_k cm_k cm_stack → |
---|
893 | (* Invariants *) |
---|
894 | ∀Em: embedding. |
---|
895 | tmp_vars_well_allocated tmpenv' cm_env cm_m cl_m Em → (* locals are properly allocated *) |
---|
896 | characterise_vars (globals ?? INV) cl_f = 〈alloc_type, stacksize〉 → (* specify how alloc_type is built *) |
---|
897 | (∃m,m'. exec_alloc_variables empty_env m (fn_params cl_f @ fn_vars cl_f) = 〈cl_env,m'〉) → (* spec. Clight env *) |
---|
898 | memory_inj Em cl_m cm_m → (* memory injection *) |
---|
899 | memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type → (* map CL env to CM env *) |
---|
900 | (∀b. block_region b = Code → Em b = Some ? 〈b, zero_offset〉) → (* Force embedding to compute identity on functions *) |
---|
901 | (* Make explicit the fact that locals in CL are mapped to a single CM block *) |
---|
902 | (∀b1.∀delta. Em b1 = Some ? 〈stackptr,delta〉 → |
---|
903 | mem block b1 (blocks_of_env cl_env)) → |
---|
904 | (* The fresh name generator is compatible with the clight environment *) |
---|
905 | env_below_freshgen cl_env alloc_type stmt_univ → |
---|
906 | (* Expression translation and related hypotheses *) |
---|
907 | ∀Hcond_tr:expr_vars ? cm_cond (local_id alloc_type). (* invariant after converting conditional expr *) |
---|
908 | (* translate_expr alloc_type (Expr cl_cond_desc cl_ty) = OK ? «CMcast ?? cm_cond Heq_ty, Hcond_tr » → *) |
---|
909 | translate_expr alloc_type (Expr cl_cond_desc cl_ty) ≃ OK ? «cm_cond, Hcond_tr » → |
---|
910 | (* Label consistency *) |
---|
911 | Exists ? (λl':identifier Label.l'=entry_label) (labels_of (f_body cm_f)) → |
---|
912 | Exists ? (λl':identifier Label.l'=exit_label) (labels_of (f_body cm_f)) → |
---|
913 | (* Statement translation *) |
---|
914 | ∀Htranslate_inv. |
---|
915 | mklabels lbl_univ = 〈〈entry_label, exit_label〉, lbl_univ'〉 → |
---|
916 | translate_statement alloc_type stmt_univ lbl_univ' lbls |
---|
917 | (ConvertTo entry_label exit_label) rettyp cl_body |
---|
918 | = OK ? «〈stmt_univ',lbl_univ'',cm_body〉,Htranslate_inv» → |
---|
919 | (* ---- invariant on label existence ---- *) |
---|
920 | lset_inclusion ? (labels_of cm_body) (labels_of (f_body cm_f)) → |
---|
921 | (* Express the fact that the label points where it ought to *) |
---|
922 | ∀Hlabel_exists. |
---|
923 | ∀Hinv1, Hinv2. |
---|
924 | find_label_always entry_label (f_body cm_f) Kend Hlabel_exists cm_f cm_env fInv Hinv1 |
---|
925 | = «〈(*St_label entry_label*) |
---|
926 | (St_seq |
---|
927 | (St_ifthenelse sz sg cm_cond (St_seq cm_body (St_goto entry_label)) |
---|
928 | St_skip) |
---|
929 | (St_label exit_label St_skip)), |
---|
930 | cm_k〉, |
---|
931 | Hinv2» → |
---|
932 | (clight_cminor_rel cl_ge cm_ge INV |
---|
933 | (ClState cl_f (Swhile (Expr cl_cond_desc cl_ty) cl_body) cl_k cl_env cl_m) |
---|
934 | (CmState cm_f |
---|
935 | ( (*St_label entry_label*) |
---|
936 | (St_seq |
---|
937 | (St_ifthenelse sz sg cm_cond (St_seq cm_body (St_goto entry_label)) St_skip) |
---|
938 | (St_label exit_label St_skip))) |
---|
939 | cm_env fInv sInv cm_m stackptr cm_k kInv cm_stack)). |
---|
940 | |
---|
941 | |
---|
942 | (* |
---|
943 | | CMR_call_nostore : |
---|
944 | (* call to a function with no return value, or which returns in a local variable in Cminor *) |
---|
945 | ∀cl_ge, cm_ge. (* cl_f, cm_f.*) |
---|
946 | ∀INV: clight_cminor_inv cl_ge cm_ge. |
---|
947 | ∀alloc_type, cl_env, cl_m, cm_env, cm_m, cm_stack, stackptr. |
---|
948 | (* TODO: put the actual invariants on memory and etc. here *) |
---|
949 | ∀func_univ: universe SymbolTag. |
---|
950 | ∀cl_f, cm_f. |
---|
951 | ∀Hglobals_fresh: globals_fresh_for_univ type (globals cl_ge cm_ge INV) func_univ. |
---|
952 | ∀Hfundef_fresh: fd_fresh_for_univ (CL_Internal cl_f) func_univ. |
---|
953 | ∀rettyp. |
---|
954 | ∀cl_k, cm_k. |
---|
955 | ∀fblock. |
---|
956 | rettyp = opttyp_of_type (fn_return cl_f) ∧ |
---|
957 | find_funct clight_fundef cl_ge (Vptr (mk_pointer fblock zero_offset)) = Some ? (CL_Internal cl_f) → |
---|
958 | find_funct (fundef internal_function) cm_ge (Vptr (mk_pointer fblock zero_offset)) = Some ? (Internal ? cm_f) → |
---|
959 | translate_function func_univ (globals ?? INV) cl_f Hglobals_fresh Hfundef_fresh = OK ? cm_f → |
---|
960 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env alloc_type rettyp cl_k cm_k cm_stack → |
---|
961 | ∀fun_id. |
---|
962 | ∀cl_retval, cm_retval. |
---|
963 | ∀sInv, fInv, kInv. |
---|
964 | ∀cl_args_values, cm_args_values. |
---|
965 | All2 val val (λcl_val:val.λcm_val:val.value_eq Em cl_val cm_val) cl_args_values cm_args_values → |
---|
966 | (* TODO: return_value_rel … INV frame_data cl_retval cm_retval →*) |
---|
967 | clight_cminor_rel cl_ge cm_ge INV |
---|
968 | (ClCallstate fun_id (CL_Internal cl_f) cl_args_values cl_k cl_m) |
---|
969 | (CmCallstate fun_id (Internal ? cm_f) cm_args_values cm_m cm_stack) |
---|
970 | |
---|
971 | | CMR_call_store : |
---|
972 | (* call to a function which returns to some location in memory in Cminor *) |
---|
973 | ∀cl_ge, cm_ge. |
---|
974 | ∀INV: clight_cminor_inv cl_ge cm_ge. |
---|
975 | ∀alloc_type, cl_env, cl_m, cm_env, cm_m, cm_stack, stackptr. |
---|
976 | (* TODO: put the actual invariants on memory and etc. here *) |
---|
977 | ∀func_univ: universe SymbolTag. |
---|
978 | ∀cl_f, cm_f. |
---|
979 | ∀Hglobals_fresh: globals_fresh_for_univ type (globals cl_ge cm_ge INV) func_univ. |
---|
980 | ∀Hfundef_fresh: fd_fresh_for_univ (CL_Internal cl_f) func_univ. |
---|
981 | ∀rettyp. |
---|
982 | ∀cl_k, cm_k. |
---|
983 | ∀fblock. |
---|
984 | rettyp = opttyp_of_type (fn_return cl_f) → |
---|
985 | find_funct clight_fundef cl_ge (Vptr (mk_pointer fblock zero_offset)) = Some ? (CL_Internal cl_f) → |
---|
986 | find_funct (fundef internal_function) cm_ge (Vptr (mk_pointer fblock zero_offset)) = Some ? (Internal ? cm_f) → |
---|
987 | translate_function func_univ (globals ?? INV) cl_f Hglobals_fresh Hfundef_fresh = OK ? cm_f → |
---|
988 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env alloc_type rettyp cl_k cm_k cm_stack → |
---|
989 | ∀fun_id. |
---|
990 | ∀cl_rettyp, cl_retval, cl_rettrace, cm_retval. |
---|
991 | ∀cl_lhs, cm_lhs, Hinvariant_on_cm_lhs. |
---|
992 | (* Explain where the lhs of the post-return assign comes from *) |
---|
993 | exec_lvalue cl_ge cl_env cl_m cl_lhs = OK ? 〈cl_retval, cl_rettrace〉 → |
---|
994 | translate_dest alloc_type cl_lhs = OK ? (MemDest ? «cm_lhs, Hinvariant_on_cm_lhs») → |
---|
995 | (* TODO: Explain that the actual variable used to store the ret val is fresh and has the |
---|
996 | * right type, etc *) |
---|
997 | ∀cm_ret_var. |
---|
998 | ∀sInv, fInv, kInv. |
---|
999 | ∀cl_args_values, cm_args_values. |
---|
1000 | All2 val val (λcl_val:val.λcm_val:val.value_eq Em cl_val cm_val) cl_args_values cm_args_values → |
---|
1001 | (* TODO: return_value_rel … INV frame_data cl_retval cm_retval →*) |
---|
1002 | ∀cm_stack. |
---|
1003 | clight_cminor_rel cl_ge cm_ge INV |
---|
1004 | (ClCallstate fun_id (CL_Internal cl_f) |
---|
1005 | cl_args_values (Kcall (Some ? 〈cl_retval,cl_rettyp〉) cl_f cl_env cl_k) cl_m) |
---|
1006 | (CmCallstate fun_id (Internal ? cm_f) |
---|
1007 | cm_args_values cm_m (Scall cm_retval cm_f stackptr cm_env sInv fInv |
---|
1008 | (Kseq (St_store (typ_of_type cl_rettyp) cm_lhs |
---|
1009 | (Id (typ_of_type cl_rettyp) cm_ret_var)) cm_k) |
---|
1010 | kInv cm_stack)) |
---|
1011 | *) |
---|
1012 | |
---|
1013 | definition clight_normal : Clight_state → bool ≝ |
---|
1014 | λs. match Clight_classify s with [ cl_other ⇒ true | cl_jump ⇒ true | _ ⇒ false ]. |
---|
1015 | |
---|
1016 | definition cminor_normal : Cminor_state → bool ≝ |
---|
1017 | λs. match Cminor_classify s with [ cl_other ⇒ true | cl_jump ⇒ true | _ ⇒ false ]. |
---|
1018 | |
---|
1019 | definition cl_pre : preclassified_system ≝ |
---|
1020 | mk_preclassified_system |
---|
1021 | clight_fullexec |
---|
1022 | (λg. Clight_labelled) |
---|
1023 | (λg. Clight_classify) |
---|
1024 | (λx,y,H. an_identifier ? one). (* XXX TODO *) |
---|
1025 | |
---|
1026 | definition cm_pre : preclassified_system ≝ |
---|
1027 | mk_preclassified_system |
---|
1028 | Cminor_fullexec |
---|
1029 | (λg. Cminor_labelled) |
---|
1030 | (λg. Cminor_classify) |
---|
1031 | (λx,y,H. an_identifier ? one). (* XXX TODO *) |
---|
1032 | |
---|
1033 | (* --------------------------------------------------------------------------- *) |
---|
1034 | (* General purpose auxilliary lemmas. *) |
---|
1035 | (* --------------------------------------------------------------------------- *) |
---|
1036 | |
---|
1037 | lemma invert_assert : |
---|
1038 | ∀b. ∀P. assert b P → b = true ∧ P. |
---|
1039 | * #P whd in ⊢ (% → ?); #H |
---|
1040 | [ @conj try @refl @H |
---|
1041 | | @False_ind @H ] |
---|
1042 | qed. |
---|
1043 | |
---|
1044 | lemma res_to_io : |
---|
1045 | ∀A,B:Type[0]. ∀C. |
---|
1046 | ∀x: res A. ∀y. |
---|
1047 | match x with |
---|
1048 | [ OK v ⇒ Value B C ? v |
---|
1049 | | Error m ⇒ Wrong … m ] = return y → |
---|
1050 | x = OK ? y. |
---|
1051 | #A #B #C * |
---|
1052 | [ #x #y normalize nodelta whd in ⊢ ((???%) → ?); #Heq destruct (Heq) @refl |
---|
1053 | | #err #y normalize nodelta whd in ⊢ ((???%) → ?); #Heq destruct (Heq) ] |
---|
1054 | qed. |
---|
1055 | |
---|
1056 | lemma jmeq_absorb : ∀A:Type[0]. ∀a,b: A. ∀P:Prop. (a = b → P) → a ≃ b → P. |
---|
1057 | #A #a #b #P #H #Heq lapply (jmeq_to_eq ??? Heq) #Heq' @H @Heq' qed. |
---|
1058 | |
---|
1059 | (* wrap up some trivial bit of reasoning to alleviate strange destruct behaviour *) |
---|
1060 | lemma pair_eq_split : |
---|
1061 | ∀A,B:Type[0]. ∀a1,a2:A. ∀b1,b2:B. |
---|
1062 | 〈a1,b1〉 = 〈a2, b2〉 → |
---|
1063 | a1 = a2 ∧ b1 = b2. |
---|
1064 | #A #B #a1 #a2 #b1 #b2 #Heq destruct (Heq) @conj try @refl |
---|
1065 | qed. |
---|
1066 | |
---|
1067 | lemma ok_eq_ok_destruct : |
---|
1068 | ∀A:Type[0]. ∀a,b:A. OK ? a = OK ? b → a = b. |
---|
1069 | #H1 #H2 #H3 #H4 destruct @refl qed. |
---|
1070 | |
---|
1071 | lemma sigma_eq_destruct : ∀A:Type[0]. ∀a,b:A. ∀P: A → Prop. ∀Ha: P a. ∀Hb: P b. «a, Ha» = «b,Hb» → a = b ∧ Ha ≃ Hb. |
---|
1072 | #A #a #b #P #Ha #Hb #Heq destruct (Heq) |
---|
1073 | @conj try % |
---|
1074 | qed. |
---|
1075 | |
---|
1076 | (* inverting find_funct and find_funct_ptr *) |
---|
1077 | lemma find_funct_inversion : |
---|
1078 | ∀F: Type[0]. ∀ge: genv_t F. ∀v: val. ∀res: F. |
---|
1079 | find_funct F ge v = Some ? res → |
---|
1080 | (∃ptr. v = Vptr ptr ∧ |
---|
1081 | (poff ptr) = zero_offset ∧ |
---|
1082 | block_region (pblock ptr) = Code ∧ |
---|
1083 | (∃p. block_id (pblock ptr) = neg p ∧ |
---|
1084 | lookup_opt … p (functions … ge) = Some ? res)). |
---|
1085 | #F #ge #v #res |
---|
1086 | cases v |
---|
1087 | [ | #sz #i | | #ptr ] |
---|
1088 | whd in ⊢ ((??%?) → ?); |
---|
1089 | #Heq destruct (Heq) |
---|
1090 | %{ptr} @conj try @conj try @conj try @refl |
---|
1091 | lapply Heq -Heq |
---|
1092 | @(eq_offset_elim … (poff ptr) zero_offset) // |
---|
1093 | normalize nodelta |
---|
1094 | [ 1,3,5: #_ #Habsurd destruct (Habsurd) ] |
---|
1095 | #Heq destruct (Heq) |
---|
1096 | whd in ⊢ ((??%?) → ?); |
---|
1097 | cases ptr #blo #off cases (block_region blo) normalize nodelta |
---|
1098 | [ 1,3: #Habsurd destruct (Habsurd) ] |
---|
1099 | [ // ] |
---|
1100 | cases (block_id blo) normalize nodelta |
---|
1101 | [ #Habsurd destruct (Habsurd) | #p #Habsurd destruct (Habsurd) ] |
---|
1102 | #p #Hlookup %{p} @conj try @refl assumption |
---|
1103 | qed. |
---|
1104 | |
---|
1105 | lemma find_funct_id_inversion : |
---|
1106 | ∀F: Type[0]. ∀ge: genv_t F. ∀ptr. ∀f. ∀id. |
---|
1107 | find_funct_id F ge ptr = Some ? 〈f, id〉 → |
---|
1108 | ∃H:(find_funct F ge ptr = Some ? f). |
---|
1109 | id = symbol_of_function_val' F ge ptr f H. |
---|
1110 | #F #ge #ptr #f #id |
---|
1111 | whd in match (find_funct_id ???); |
---|
1112 | generalize in match (refl ??); |
---|
1113 | generalize in ⊢ |
---|
1114 | (∀_:(???%). |
---|
1115 | (??(match % |
---|
1116 | with |
---|
1117 | [ _ ⇒ λ_. ? |
---|
1118 | | _ ⇒ λ_.λ_. ? ] ?)?) → ?); |
---|
1119 | #o cases o |
---|
1120 | normalize nodelta |
---|
1121 | [ #H #Habsurd destruct (Habsurd) |
---|
1122 | | #f #Hfind #Heq destruct (Heq) %{Hfind} |
---|
1123 | cases (find_funct_inversion ???? Hfind) #ptr * |
---|
1124 | * * #Hptr lapply Hfind -Hfind >Hptr #Hfind |
---|
1125 | #Hoff #Hblock * #id * #Hblock_id #Hlookup_opt |
---|
1126 | normalize nodelta @refl |
---|
1127 | ] qed. |
---|
1128 | |
---|
1129 | (* We should be able to prove that ty = ty' with some more hypotheses, if needed. *) |
---|
1130 | lemma translate_dest_id_inversion : |
---|
1131 | ∀var_types, e, var_id, H. |
---|
1132 | translate_dest var_types e = return IdDest var_types ? var_id H → |
---|
1133 | e = Expr (Evar var_id) (typeof e). |
---|
1134 | @cthulhu |
---|
1135 | (* |
---|
1136 | #vars #e #var_id #ty #H |
---|
1137 | cases e #ed #ty' |
---|
1138 | cases ed |
---|
1139 | [ #sz #i | #id | #e1 | #e1 | #op #e1 |#op #e1 #e2 | #cast_ty #e1 |
---|
1140 | | #cond #iftrue #iffalse | #e1 #e2 | #e1 #e2 | #sizeofty | #e1 #field | #cost #e1 ] |
---|
1141 | whd in ⊢ ((??%%) → ?); |
---|
1142 | #Heq |
---|
1143 | [ 1,4,5,6,7,8,9,10,11,13: destruct (Heq) |
---|
1144 | | 3,12: cases (bind_inversion ????? Heq) * #H1 #H2 #H3 cases H3 |
---|
1145 | #_ whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) ] |
---|
1146 | lapply Heq -Heq |
---|
1147 | change with (bind2_eq ????? ) in ⊢ ((??%?) → ?); #Heq |
---|
1148 | cases (bind2_eq_inversion ?????? Heq) |
---|
1149 | #alloctype |
---|
1150 | (* * #alloctype *) * #typ' * |
---|
1151 | cases alloctype |
---|
1152 | [ #r | #n | ] normalize nodelta #Hlookup' |
---|
1153 | [ 1,2: whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) ] |
---|
1154 | whd in ⊢ ((??%%) → ?); #Heq' destruct (Heq') |
---|
1155 | @refl*) |
---|
1156 | qed. |
---|
1157 | |
---|
1158 | |
---|
1159 | (* Note: duplicate in switchRemoval.ma *) |
---|
1160 | lemma fresh_elim : ∀u. ∃fv',u'. fresh SymbolTag u = 〈fv', u'〉. #u /3 by ex_intro/ qed. |
---|
1161 | |
---|
1162 | lemma fresh_elim_lab : ∀u. ∃fv',u'. fresh Label u = 〈fv', u'〉. #u /3 by ex_intro/ qed. |
---|
1163 | |
---|
1164 | |
---|
1165 | lemma breakup_dependent_match_on_pairs : |
---|
1166 | ∀A,B,C: Type[0]. |
---|
1167 | ∀term: A × B. |
---|
1168 | ∀F: ∀x,y. 〈x, y〉 = term → C. |
---|
1169 | ∀z:C. |
---|
1170 | match term |
---|
1171 | return λx.x = term → ? with |
---|
1172 | [ mk_Prod x y ⇒ λEq. F x y Eq ] (refl ? term) = z → |
---|
1173 | ∃xa,xb,H. term = 〈xa, xb〉 ∧ |
---|
1174 | F xa xb H = z. |
---|
1175 | #A #B #C * #xa #xb #F #z normalize nodelta #H %{xa} %{xb} %{(refl ??)} @conj try @conj |
---|
1176 | // qed. |
---|
1177 | |
---|
1178 | (* --------------------------------------------------------------------------- *) |
---|
1179 | (* Extending simulation results on expressions to particular cases *) |
---|
1180 | (* --------------------------------------------------------------------------- *) |
---|
1181 | |
---|
1182 | lemma translate_expr_sigma_welltyped : ∀vars, cl_expr, cm_expr. |
---|
1183 | translate_expr_sigma vars cl_expr = OK ? cm_expr → |
---|
1184 | dpi1 ?? (pi1 ?? cm_expr) = typ_of_type (typeof cl_expr). |
---|
1185 | #vars #cl_expr * * #typ #cm_expr normalize nodelta #Hexpr_vars |
---|
1186 | whd in ⊢ ((??%?) → ?); #H |
---|
1187 | cases (bind_inversion ????? H) -H * #cm_expr' #Hexpr_vars' * |
---|
1188 | #Htranslate_expr |
---|
1189 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) @refl |
---|
1190 | qed. |
---|
1191 | |
---|
1192 | lemma translate_exprlist_sigma_welltyped : |
---|
1193 | ∀vars, cl_exprs, cm_exprs. |
---|
1194 | mmap_sigma ??? (translate_expr_sigma vars) cl_exprs = OK ? cm_exprs → |
---|
1195 | All2 ?? (λcl, cm. dpi1 ?? cm = typ_of_type (typeof cl)) cl_exprs (pi1 ?? cm_exprs). |
---|
1196 | #vars #cl_exprs |
---|
1197 | elim cl_exprs |
---|
1198 | [ * #cm_exprs #Hall whd in ⊢ ((??%?) → ?); #Heq destruct (Heq) @I |
---|
1199 | | #hd #tl #Hind * #cm_exprs #Hall #H |
---|
1200 | cases (bind_inversion ????? H) -H |
---|
1201 | * * #cm_typ #cm_expr normalize nodelta |
---|
1202 | #Hexpr_vars_cm * #Htranslate_hd |
---|
1203 | lapply (translate_expr_sigma_welltyped … Htranslate_hd) |
---|
1204 | #Heq_cm_typ #H |
---|
1205 | cases (bind_inversion ????? H) -H |
---|
1206 | #cm_tail lapply (Hind cm_tail) cases cm_tail |
---|
1207 | #cm_tail_expr #Hall_tail -Hind #Hind * #Heq_cm_tail normalize nodelta |
---|
1208 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) whd @conj |
---|
1209 | [ @Heq_cm_typ |
---|
1210 | | @Hind assumption ] |
---|
1211 | ] qed. |
---|
1212 | |
---|
1213 | lemma translate_dest_MemDest_simulation : |
---|
1214 | ∀cl_f : function. |
---|
1215 | ∀cl_ge : genv_t clight_fundef. |
---|
1216 | ∀cm_ge : genv_t (fundef internal_function). |
---|
1217 | ∀INV : clight_cminor_inv cl_ge cm_ge. |
---|
1218 | ∀alloc_type. |
---|
1219 | ∀cl_env, cl_m, cm_env, cm_m, stackptr. |
---|
1220 | ∀Em. |
---|
1221 | ∀stacksize : ℕ. |
---|
1222 | ∀alloc_hyp : characterise_vars (globals ?? INV) cl_f = 〈alloc_type, stacksize〉. |
---|
1223 | ∀cl_cm_env_hyp : ∃m,m'. exec_alloc_variables empty_env m (fn_params cl_f @ fn_vars cl_f) = 〈cl_env,m'〉. |
---|
1224 | ∀injection : memory_inj Em cl_m cm_m. |
---|
1225 | ∀matching : memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type. |
---|
1226 | (* decorrelate goal from input using some eqs *) |
---|
1227 | ∀cl_expr. ∀cm_expr. |
---|
1228 | ∀cl_block, cl_offset, trace. |
---|
1229 | ∀Hyp_present. |
---|
1230 | translate_dest alloc_type cl_expr = OK ? (MemDest … cm_expr) → |
---|
1231 | exec_lvalue cl_ge cl_env cl_m cl_expr = OK ? 〈〈cl_block, cl_offset〉, trace〉 → |
---|
1232 | ∃cm_val. eval_expr cm_ge ASTptr cm_expr cm_env Hyp_present stackptr cm_m = OK ? 〈trace, cm_val〉 ∧ |
---|
1233 | value_eq Em (Vptr (mk_pointer cl_block cl_offset)) cm_val. |
---|
1234 | #cl_f #cl_ge #cm_ge #INV #alloc_type |
---|
1235 | #cl_env #cl_m #cm_env #cm_m #stackptr #Em #stacksize #alloc_hyp #cl_env_hyp #injection #matching |
---|
1236 | #cl_expr * #cm_expr #Hexpr_vars #cl_block #cl_offset #trace #Hyp_present |
---|
1237 | whd in match (translate_dest ??); cases cl_expr #cl_desc #cl_typ normalize nodelta |
---|
1238 | cases cl_desc normalize nodelta |
---|
1239 | [ #sz #i | #id | #e1 | #e1 | #op #e1 |#op #e1 #e2 | #cast_ty #e1 |
---|
1240 | | #cond #iftrue #iffalse | #e1 #e2 | #e1 #e2 | #sizeofty | #e1 #field | #cost #e1 ] |
---|
1241 | #Htranslate |
---|
1242 | [ 2: |
---|
1243 | | *: cases (bind_inversion ????? Htranslate) -Htranslate * #cm_expr' #Hexpr_vars' * |
---|
1244 | #Htranslate_addr |
---|
1245 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) #Hexec_lvalue |
---|
1246 | cases (eval_expr_sim cl_ge cm_ge INV cl_f alloc_type stacksize alloc_hyp … cl_env_hyp … injection … matching) |
---|
1247 | #_ #Hsim |
---|
1248 | @(Hsim ??? Hexpr_vars … Htranslate_addr ??? ? Hexec_lvalue) ] |
---|
1249 | cases (bind2_eq_inversion ?????? Htranslate) -Htranslate * |
---|
1250 | [ #r | #n | ] |
---|
1251 | * #cl_type * #Heq_lookup normalize nodelta |
---|
1252 | whd in ⊢ ((??%%) → ?); [3: cases (typ_eq ??) #Htyp whd in ⊢ (??%% → ?); ] #Heq destruct (Heq) |
---|
1253 | whd in ⊢ ((??%?) → ?); |
---|
1254 | @(match lookup SymbolTag block cl_env id |
---|
1255 | return λx. (lookup SymbolTag block cl_env id = x) → ? |
---|
1256 | with |
---|
1257 | [ None ⇒ ? |
---|
1258 | | Some loc ⇒ ? |
---|
1259 | ] (refl ? (lookup SymbolTag block cl_env id ))) normalize nodelta |
---|
1260 | #Hlookup_eq |
---|
1261 | [ 2,4: #Heq destruct (Heq) whd in match (eval_expr ???????); |
---|
1262 | [ 2: %{(Vptr (mk_pointer stackptr (shift_offset (bitsize_of_intsize I16) zero_offset (repr I16 n))))} |
---|
1263 | @conj try @refl |
---|
1264 | lapply (matching id) |
---|
1265 | >Hlookup_eq normalize nodelta |
---|
1266 | >(opt_to_res_inversion ???? Heq_lookup) normalize nodelta |
---|
1267 | #Hembed %4 whd in ⊢ (??%?); >Hembed @refl |
---|
1268 | | 1: whd in match (eval_constant ????); |
---|
1269 | lapply (matching id) |
---|
1270 | >Hlookup_eq normalize nodelta |
---|
1271 | >(opt_to_res_inversion ???? Heq_lookup) normalize nodelta |
---|
1272 | @False_ind |
---|
1273 | ] |
---|
1274 | | 1,3: #Hfind_symbol |
---|
1275 | cases (bind_inversion ????? Hfind_symbol) -Hfind_symbol #block * |
---|
1276 | whd in ⊢ ((??%%) → ?); #Hfind_symbol |
---|
1277 | lapply (opt_to_res_inversion ???? Hfind_symbol) #Hfind_symbol_eq |
---|
1278 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
1279 | whd in match (eval_expr ???????); |
---|
1280 | whd in match (eval_constant ????); |
---|
1281 | lapply (matching id) |
---|
1282 | [ >Hlookup_eq normalize nodelta >Hfind_symbol_eq normalize nodelta |
---|
1283 | #Hembed |
---|
1284 | <(eq_sym … INV id) >Hfind_symbol_eq normalize nodelta |
---|
1285 | %{(Vptr |
---|
1286 | (mk_pointer cl_block |
---|
1287 | (shift_offset (bitsize_of_intsize I16) zero_offset (repr I16 O))))} |
---|
1288 | @conj try @refl |
---|
1289 | %4 whd in ⊢ (??%?); >Hembed try @refl |
---|
1290 | | (* A stack variable is not in the local environment but in the global one. *) |
---|
1291 | (* we have a contradiction somewhere in the context *) |
---|
1292 | lapply (variable_not_in_env_but_in_vartypes_is_global ??????? |
---|
1293 | cl_env_hyp alloc_hyp Hlookup_eq … Heq_lookup) |
---|
1294 | * #r #Habsurd destruct (Habsurd) |
---|
1295 | ] |
---|
1296 | ] qed. |
---|
1297 | |
---|
1298 | (* lift simulation result to eval_exprlist *) |
---|
1299 | |
---|
1300 | lemma eval_exprlist_simulation : |
---|
1301 | ∀cl_f. |
---|
1302 | ∀cl_ge : genv_t clight_fundef. |
---|
1303 | ∀cm_ge : genv_t (fundef internal_function). |
---|
1304 | ∀INV : clight_cminor_inv cl_ge cm_ge. |
---|
1305 | ∀alloc_type. |
---|
1306 | ∀cl_env, cl_m, cm_env, cm_m, stackptr. |
---|
1307 | ∀Em. |
---|
1308 | ∀stacksize : ℕ. |
---|
1309 | ∀alloc_hyp : characterise_vars (globals ?? INV) cl_f = 〈alloc_type, stacksize〉. |
---|
1310 | ∀cl_env_hyp : ∃m,m'. exec_alloc_variables empty_env m (fn_params cl_f @ fn_vars cl_f) = 〈cl_env,m'〉. |
---|
1311 | ∀injection : memory_inj Em cl_m cm_m. |
---|
1312 | ∀matching : memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type. |
---|
1313 | ∀cl_exprs,cm_exprs. |
---|
1314 | ∀cl_results,trace. |
---|
1315 | exec_exprlist cl_ge cl_env cl_m cl_exprs = OK ? 〈cl_results, trace〉 → |
---|
1316 | mmap_sigma ??? (translate_expr_sigma alloc_type) cl_exprs = OK ? cm_exprs → |
---|
1317 | ∀H:All ? (λx:𝚺t:typ.expr t. |
---|
1318 | match x with |
---|
1319 | [ mk_DPair ty e ⇒ |
---|
1320 | (expr_vars ty e |
---|
1321 | (λid:ident.λty:typ.present SymbolTag val cm_env id)) ]) cm_exprs. |
---|
1322 | ∃cm_results. |
---|
1323 | trace_map_inv … (λe. match e return λe. |
---|
1324 | match e with |
---|
1325 | [ mk_DPair _ _ ⇒ ? ] → ? |
---|
1326 | with |
---|
1327 | [ mk_DPair ty e ⇒ λp. eval_expr cm_ge ? e cm_env p stackptr cm_m ]) cm_exprs H = OK ? 〈trace, cm_results〉 ∧ |
---|
1328 | All2 ?? (λcl_val, cm_val. value_eq Em cl_val cm_val) cl_results cm_results. |
---|
1329 | #f #cl_ge #cm_ge #INV |
---|
1330 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #Em #stacksize #alloc_hyp #cl_env_hyp #injection #matching |
---|
1331 | #cl_exprs |
---|
1332 | elim cl_exprs |
---|
1333 | [ #cm_exprs #cl_results #trace |
---|
1334 | whd in ⊢ ((??%?) → ?); |
---|
1335 | #Heq destruct (Heq) |
---|
1336 | whd in ⊢ ((??%?) → ?); |
---|
1337 | #Heq destruct (Heq) #H %{[]} |
---|
1338 | @conj try @refl try @I |
---|
1339 | | #cl_hd #cl_tl #Hind #cm_exprs #cl_results #trace |
---|
1340 | #Heq cases (bind_inversion ????? Heq) -Heq |
---|
1341 | * #hd_val #hd_trace * #Hexec_expr_cl |
---|
1342 | #Heq cases (bind_inversion ????? Heq) -Heq |
---|
1343 | * #cl_tl_vals #cl_tl_trace * #Hexec_expr_tl |
---|
1344 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
1345 | #Htranslate |
---|
1346 | lapply (translate_exprlist_sigma_welltyped … Htranslate) |
---|
1347 | #Htype_eq_all #Hall |
---|
1348 | cases (bind_inversion ????? Htranslate) -Htranslate |
---|
1349 | * * #cmtype #cmexpr normalize nodelta |
---|
1350 | #Hexpr_vars_local_cm * #Htranslate_expr_sigma #Htranslate |
---|
1351 | cases (bind_inversion ????? Htranslate) -Htranslate |
---|
1352 | * #cm_tail #Hexpr_vars_local_cm_tail * #Htranslate_tail |
---|
1353 | normalize nodelta |
---|
1354 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
1355 | cases Htype_eq_all -Htype_eq_all #Hcm_type_eq #Htype_eq_all |
---|
1356 | lapply (Hind cm_tail cl_tl_vals cl_tl_trace Hexec_expr_tl) |
---|
1357 | [ assumption ] -Hind #Hind |
---|
1358 | lapply (Hind Htranslate_tail (proj2 ?? Hall)) -Hind |
---|
1359 | * #cm_results_tl * #Hcm_exec_tl #Hvalues_eq_tl |
---|
1360 | cases (eval_expr_sim cl_ge cm_ge INV f alloc_type stacksize alloc_hyp ?? cl_env_hyp ?? Em injection stackptr matching) |
---|
1361 | #Hsim #_ |
---|
1362 | cases (bind_inversion ????? Htranslate_expr_sigma) |
---|
1363 | * #cmexpr' #Hexpr_vars_local_cm' * #Htranslate |
---|
1364 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
1365 | lapply (Hsim cl_hd cmexpr ??????) -Hsim try assumption |
---|
1366 | [ @(proj1 ?? Hall) ] |
---|
1367 | * #cm_val_hd * #Heval_expr_cm #Hvalue_eq |
---|
1368 | %{(cm_val_hd :: cm_results_tl)} @conj |
---|
1369 | [ 2: @conj try assumption |
---|
1370 | | 1: whd in ⊢ (??%?); normalize nodelta >Heval_expr_cm |
---|
1371 | normalize nodelta >Hcm_exec_tl @refl |
---|
1372 | ] |
---|
1373 | ] qed. |
---|
1374 | |
---|
1375 | (* --------------------------------------------------------------------------- *) |
---|
1376 | (* Putting the memory injection at work. *) |
---|
1377 | (* --------------------------------------------------------------------------- *) |
---|
1378 | |
---|
1379 | (* A) Non-interference of local variables with memory injections *) |
---|
1380 | |
---|
1381 | (* Needed property: |
---|
1382 | * A local variable allocated via the temporary variable generator should not interfere |
---|
1383 | * with the memory injection. In particular, we need to show that: |
---|
1384 | * 1) we can successfuly store stuff of the right type inside (where the type is specified |
---|
1385 | * at generation time, and should be in the current context) |
---|
1386 | * 2) after the store, we can build a consistent memory state and more generally, a |
---|
1387 | * correct [clight_cminor_data] invariant record. Cf. toCminorCorrectnessExpr.ma |
---|
1388 | *) |
---|
1389 | |
---|
1390 | (* A.1) memory matchings survives memory injection *) |
---|
1391 | |
---|
1392 | lemma offset_plus_0' : ∀o:offset. offset_plus zero_offset o = o. |
---|
1393 | #o cases o #b >offset_plus_0 @refl |
---|
1394 | qed. |
---|
1395 | |
---|
1396 | (* |
---|
1397 | lemma store_value_of_type_memory_matching_to_matching : |
---|
1398 | ∀cl_ge, cm_ge, cl_en, cm_en, INV, sp, vars, cl_m, cl_m',cm_m,cm_m'. |
---|
1399 | ∀E: embedding. |
---|
1400 | ∀blo, blo', delta, off. |
---|
1401 | E blo = Some ? 〈blo', delta〉 → |
---|
1402 | ∀cl_val, cm_val, ty. |
---|
1403 | value_eq E cl_val cm_val → |
---|
1404 | storen cl_m (mk_pointer blo off) (fe_to_be_values ty cl_val) = Some ? cl_m' → |
---|
1405 | storen cm_m (mk_pointer blo (offset_plus off delta)) (fe_to_be_values ty cm_val) = Some ? cm_m' → |
---|
1406 | (lookup' vars var_id = OK (var_type×type) 〈Global r,type_of_var〉) |
---|
1407 | memory_inj E cl_m' cm_m' → |
---|
1408 | memory_matching E cl_ge cm_ge cl_m cm_m cl_en cm_en INV sp vars → |
---|
1409 | memory_matching E cl_ge cm_ge cl_m' cm_m' cl_en cm_en INV sp vars. |
---|
1410 | #cl_ge #cm_ge #cl_en #cm_en #INV #sp #vars #cl_m #cl_m' #cm_m #cm_m' #E |
---|
1411 | #blo #blo' #delta #off #Hembed #cl_val #cm_val #ty #Hvalue_eq #Hstoren_cl #Hstoren_cm |
---|
1412 | #Hinj #Hmatching #id |
---|
1413 | lapply (Hmatching id) |
---|
1414 | cases (lookup ?? cl_en id) normalize nodelta |
---|
1415 | [ 1: #H @H |
---|
1416 | | 2: #bl cases (lookup ?? vars id) normalize nodelta |
---|
1417 | [ 1: #H @H |
---|
1418 | | 2: * #var_type #cl_type normalize nodelta |
---|
1419 | cases var_type normalize nodelta |
---|
1420 | [ #r #H @H |
---|
1421 | | #b #H @H |
---|
1422 | | #H #v lapply H -H |
---|
1423 | @(eq_block_elim … bl blo) |
---|
1424 | [ #Heq destruct (Heq) |
---|
1425 | @(eq_offset_elim … off zero_offset) |
---|
1426 | [ (* We actually load exactly where we wrote, but with a potentially different type. *) |
---|
1427 | #Heq destruct (Heq) #H |
---|
1428 | ] |
---|
1429 | ] |
---|
1430 | ] qed.*) |
---|
1431 | |
---|
1432 | |
---|
1433 | lemma alloc_tmp_in_genlist : |
---|
1434 | ∀vartypes. ∀g1, g2, g3. |
---|
1435 | ∀id1, ty1, id2, ty2. |
---|
1436 | alloc_tmp vartypes ty1 g1 = 〈id1, g2〉 → |
---|
1437 | alloc_tmp vartypes ty2 g2 = 〈id2, g3〉 → |
---|
1438 | Exists (identifier SymbolTag×type) |
---|
1439 | (λx:identifier SymbolTag×type.x=〈id2,ty2〉) (tmp_env ? g3). |
---|
1440 | #vartypes #g1 #g2 #g3 |
---|
1441 | #id1 #ty1 #id2 #ty2 #Halloc1 #Halloc2 |
---|
1442 | lapply (breakup_dependent_match_on_pairs ?????? Halloc1) * #id1' * #u' * #Hfg1 |
---|
1443 | * #Hfresh_eq generalize in match (fresh_map_add ????????); #ugly |
---|
1444 | generalize in ⊢ ((??(????(?????%))?) → ?); #ugly2 |
---|
1445 | #Heq destruct (Heq) |
---|
1446 | lapply (breakup_dependent_match_on_pairs ?????? Halloc2) * #id2' * #u'' * #Hfg2 |
---|
1447 | * #Hfresh_eq' generalize in match (fresh_map_add ????????); #ugly' |
---|
1448 | generalize in ⊢ ((??(????(?????%))?) → ?); #ugly2' |
---|
1449 | #Heq destruct (Heq) %1 @refl |
---|
1450 | qed. (* this last lemma has to be refitted. *) |
---|
1451 | |
---|
1452 | lemma store_value_of_type_success_by_value : |
---|
1453 | ∀ty, m, m', b, o, v. |
---|
1454 | store_value_of_type ty m b o v = Some ? m' → |
---|
1455 | access_mode ty = By_value (typ_of_type ty) ∧ |
---|
1456 | storev (typ_of_type ty) m (Vptr (mk_pointer b o)) v = Some ? m'. |
---|
1457 | #ty #m #m' #b #o #v |
---|
1458 | cases ty |
---|
1459 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
1460 | | #structname #fieldspec | #unionname #fieldspec | #id ] |
---|
1461 | whd in ⊢ ((??%?) → ?); |
---|
1462 | [ 1,4,5,6,7: #Habsurd destruct (Habsurd) ] |
---|
1463 | #H @conj try @refl @H |
---|
1464 | qed. |
---|
1465 | |
---|
1466 | (* Some boilerplate to avoid performing a case analysis on exprs in the middle of |
---|
1467 | * the proof. *) |
---|
1468 | lemma translate_dest_not_Evar_id : |
---|
1469 | ∀vars, ed, ty. |
---|
1470 | (∀id. ed ≠ Evar id) → |
---|
1471 | translate_dest vars (Expr ed ty) = |
---|
1472 | (do e1' ← translate_addr vars (Expr ed ty); |
---|
1473 | OK ? (MemDest … e1')). |
---|
1474 | #vars * |
---|
1475 | [ #sz #i | #id | #e1 | #e1 | #op #e1 |#op #e1 #e2 | #cast_ty #e1 |
---|
1476 | | #cond #iftrue #iffalse | #e1 #e2 | #e1 #e2 | #sizeofty | #e1 #field | #cost #e1 ] |
---|
1477 | #ty #H |
---|
1478 | [ 2: @False_ind @(absurd … (refl ??) (H ?)) ] |
---|
1479 | @refl |
---|
1480 | qed. |
---|
1481 | |
---|
1482 | lemma expr_is_Evar_id_dec : |
---|
1483 | ∀ed. (∀id. ed ≠ Evar id) ∨ (∃id. ed = Evar id). |
---|
1484 | * |
---|
1485 | [ #sz #i | #id | #e1 | #e1 | #op #e1 |#op #e1 #e2 | #cast_ty #e1 |
---|
1486 | | #cond #iftrue #iffalse | #e1 #e2 | #e1 #e2 | #sizeofty | #e1 #field | #cost #e1 ] |
---|
1487 | [ 2: %2 %{id} @refl |
---|
1488 | | *: %1 #id % #Habsurd destruct (Habsurd) ] |
---|
1489 | qed. |
---|
1490 | |
---|
1491 | lemma mk_offset_offv_id : ∀o. mk_offset (offv o) = o. |
---|
1492 | * #x @refl qed. |
---|
1493 | |
---|
1494 | lemma find_funct_to_find_funct_id : |
---|
1495 | ∀F, ge, ptr, fundef. |
---|
1496 | ∀H:find_funct ? ge ptr = Some ? fundef. |
---|
1497 | find_funct_id F ge ptr = Some ? 〈fundef, symbol_of_function_val' F ge ptr fundef H〉. |
---|
1498 | #F #ge #ptr #fundef #Hfind whd in match (find_funct_id ???); |
---|
1499 | generalize in ⊢ (??(?%)?); |
---|
1500 | generalize in ⊢ |
---|
1501 | ((???%) → (?? |
---|
1502 | (match % |
---|
1503 | (* return λ_. (??%?) → ?*) |
---|
1504 | with |
---|
1505 | [ _ ⇒ λ_. ? |
---|
1506 | | _ ⇒ λ_.λ_. ? ] ?) |
---|
1507 | ?)); |
---|
1508 | #o cases o normalize nodelta |
---|
1509 | [ #H @False_ind >Hfind in H; #Habsurd destruct (Habsurd) |
---|
1510 | | #f #Hfind' |
---|
1511 | cut (f = fundef) |
---|
1512 | [ >Hfind in Hfind'; #Heq destruct (Heq) @refl ] |
---|
1513 | #Heq destruct (Heq) |
---|
1514 | @refl |
---|
1515 | ] qed. |
---|
1516 | |
---|
1517 | lemma eval_bool_of_val_to_Cminor : |
---|
1518 | ∀E. ∀ty. ∀v1,v2. ∀b. |
---|
1519 | value_eq E v1 v2 → |
---|
1520 | exec_bool_of_val v1 ty = return b → |
---|
1521 | eval_bool_of_val v2 = return b. |
---|
1522 | #E #ty #v1 #v2 #b #Hvalue_eq |
---|
1523 | whd in ⊢ ((??%%) → (??%%)); |
---|
1524 | @(value_eq_inversion … Hvalue_eq) normalize nodelta |
---|
1525 | [ #Habsurd destruct (Habsurd) ] |
---|
1526 | [ #vsz #vi cases ty |
---|
1527 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
1528 | | #structname #fieldspec | #unionname #fieldspec | #id ] normalize nodelta |
---|
1529 | [ 2: | *: #Habsurd destruct (Habsurd) ] |
---|
1530 | @(intsize_eq_elim_elim … vsz sz) |
---|
1531 | [ 1: #H #Habsurd destruct (Habsurd) |
---|
1532 | | 2: #Heq destruct (Heq) normalize nodelta #H @H ] |
---|
1533 | | cases ty |
---|
1534 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
1535 | | #structname #fieldspec | #unionname #fieldspec | #id ] normalize nodelta |
---|
1536 | #H destruct (H) @refl |
---|
1537 | | #p1 #p2 #Htranslate |
---|
1538 | cases ty |
---|
1539 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
1540 | | #structname #fieldspec | #unionname #fieldspec | #id ] normalize nodelta |
---|
1541 | #H destruct (H) @refl |
---|
1542 | ] qed. |
---|
1543 | |
---|
1544 | lemma let_prod_as_inversion : |
---|
1545 | ∀A,B,C: Type[0]. |
---|
1546 | ∀expr: A × B. |
---|
1547 | ∀body: ∀a:A. ∀b:B. 〈a,b〉 = expr → res C. |
---|
1548 | ∀result: C. |
---|
1549 | (let 〈a,b〉 as E ≝ expr in body a b E) = return result → |
---|
1550 | ∃x,y. ∃E. 〈x,y〉 = expr ∧ |
---|
1551 | body x y E = return result. |
---|
1552 | #A #B #C * #a #b #body #res normalize nodelta #Heq |
---|
1553 | %{a} %{b} %{(refl ??)} @conj try @refl @Heq |
---|
1554 | qed. |
---|
1555 | |
---|
1556 | (* move this to frontend_misc *) |
---|
1557 | lemma lset_inclusion_Exists : ∀A, l1, l2, P. |
---|
1558 | Exists A P l1 → lset_inclusion A l1 l2 → Exists A P l2. |
---|
1559 | #A #l1 #l2 #P #Hexists whd in ⊢ (% → ?); |
---|
1560 | lapply Hexists |
---|
1561 | generalize in match l2; |
---|
1562 | elim l1 |
---|
1563 | [ #l2 @False_ind |
---|
1564 | | #hd #tl #Hind #l2 * |
---|
1565 | [ 2: #HA * #Hhd #Htl @Hind try assumption |
---|
1566 | | 1: #H * #Hmem #_ elim l2 in Hmem; |
---|
1567 | [ @False_ind |
---|
1568 | | #hd2 #tl2 #Hind * |
---|
1569 | [ #Heq destruct (Heq) %1 @H |
---|
1570 | | #Hneq %2 @Hind @Hneq ] |
---|
1571 | ] |
---|
1572 | ] |
---|
1573 | ] qed. |
---|
1574 | |
---|
1575 | axiom load_value_after_free_list_inversion : |
---|
1576 | ∀ty, m, blocks, b, o, v. |
---|
1577 | load_value_of_type ty (free_list m blocks) b o = Some ? v → |
---|
1578 | load_value_of_type ty m b o = Some ? v. |
---|
1579 | |
---|
1580 | (* Make explicit the contents of [exec_bind_parameters ????] *) |
---|
1581 | lemma exec_alloc_bind_params_same_length : |
---|
1582 | ∀e,m,m',params,vars. |
---|
1583 | exec_bind_parameters e m params vars = OK ? m' → |
---|
1584 | (params = [ ] ∧ vars = [ ]) ∨ |
---|
1585 | ∃id,ty,tl_pa,v,tl_vars,b,mi. |
---|
1586 | params = 〈id,ty〉 :: tl_pa ∧ |
---|
1587 | vars = v :: tl_vars ∧ |
---|
1588 | lookup ?? e id = Some ? b ∧ |
---|
1589 | store_value_of_type ty m b zero_offset v = Some ? mi ∧ |
---|
1590 | exec_bind_parameters e mi tl_pa tl_vars = OK ? m'. |
---|
1591 | #e #m #m' #params cases params |
---|
1592 | [ #vars whd in ⊢ ((??%?) → ?); cases vars normalize nodelta |
---|
1593 | [ #Heq destruct (Heq) %1 @conj try @refl |
---|
1594 | | #hd_pa #tl_pa #Habsurd destruct (Habsurd) ] |
---|
1595 | | * #id #ty #tl_pa #vars |
---|
1596 | whd in ⊢ ((??%?) → ?); |
---|
1597 | cases vars normalize nodelta |
---|
1598 | [ #Habsurd destruct (Habsurd) |
---|
1599 | | #hd_val #tl_val #H |
---|
1600 | cases (bind_inversion ????? H) -H |
---|
1601 | #blo * #HA #H |
---|
1602 | cases (bind_inversion ????? H) -H |
---|
1603 | #m'' * #HB #Hexec_bind %2 |
---|
1604 | %{id} %{ty} %{tl_pa} %{hd_val} %{tl_val} %{blo} %{m''} |
---|
1605 | @conj try @conj try @conj try @conj try @refl |
---|
1606 | try @(opt_to_res_inversion ???? HA) |
---|
1607 | try @(opt_to_res_inversion ???? HB) |
---|
1608 | @Hexec_bind |
---|
1609 | ] |
---|
1610 | ] qed. |
---|
1611 | |
---|
1612 | (* Axiom-fest, with all the lemmas we need but won't have time to prove. Most of them are not too hard. *) |
---|
1613 | |
---|
1614 | (* The way we have of stating this is certainly not the most synthetic. The property we really need is that |
---|
1615 | * stmt_univ' is fresher than stmt_univ, which sould be trivially provable by a simple induction. *) |
---|
1616 | axiom env_below_freshgen_preserved_by_translation : |
---|
1617 | ∀cl_env, alloc_type, stmt_univ, lbl_univ, lbls, flag, rettyp, s, stmt_univ', lbl_univ', cm_s, H. |
---|
1618 | env_below_freshgen cl_env alloc_type stmt_univ → |
---|
1619 | translate_statement alloc_type stmt_univ lbl_univ lbls flag rettyp s = return «〈stmt_univ', lbl_univ', cm_s〉, H» → |
---|
1620 | env_below_freshgen cl_env alloc_type stmt_univ'. |
---|
1621 | |
---|
1622 | axiom tmp_vars_well_allocated_preserved_by_inclusion : |
---|
1623 | ∀cm_env, cm_m, cl_m, Em, tmpenv, tmpenv'. |
---|
1624 | lset_inclusion ? tmpenv tmpenv' → |
---|
1625 | tmp_vars_well_allocated tmpenv' cm_env cm_m cl_m Em → |
---|
1626 | tmp_vars_well_allocated tmpenv cm_env cm_m cl_m Em. |
---|
1627 | |
---|
1628 | axiom translation_entails_ident_inclusion : |
---|
1629 | ∀alloc_type, stmt_univ, lbl_univ, lbls, flag, rettyp, stmt_univ'. |
---|
1630 | ∀cl_s, cm_s, labgen, Htrans_inv. |
---|
1631 | translate_statement alloc_type stmt_univ lbl_univ lbls flag rettyp cl_s = return «〈stmt_univ',labgen,cm_s〉,Htrans_inv» → |
---|
1632 | lset_inclusion ? (tmp_env … stmt_univ) (tmp_env … stmt_univ'). |
---|
1633 | |
---|
1634 | (* Same remarks as above apply here too. *) |
---|
1635 | (* |
---|
1636 | lemma tmp_vars_well_allocated_preserved_by_translation : |
---|
1637 | ∀cm_env, alloc_type, stmt_univ, lbl_univ, lbls, flag, rettyp, stmt_univ'. |
---|
1638 | ∀Em, cm_m, cl_m, cl_s, cm_s, labgen, Htrans_inv. |
---|
1639 | translate_statement alloc_type stmt_univ lbl_univ lbls flag rettyp cl_s = return «〈stmt_univ',labgen,cm_s〉,Htrans_inv» → |
---|
1640 | tmp_vars_well_allocated (tmp_env alloc_type stmt_univ') cm_env cm_m cl_m Em → |
---|
1641 | tmp_vars_well_allocated (tmp_env alloc_type stmt_univ) cm_env cm_m cl_m Em. |
---|
1642 | #cm_env #alloc_type #stmt_univ #lbl_univ #lbls #flag #rettyp #stmt_univ' #Em #cm_m #cl_m #cl_s #cm_s |
---|
1643 | #labgen #Htrans_inv #Htranslate_statement #H #id #Hpresent #ty #Hexists |
---|
1644 | @H lapply (translation_entails_ident_inclusion … Htranslate_statement) |
---|
1645 | #H |
---|
1646 | @H23*) |
---|
1647 | |
---|
1648 | axiom tmp_vars_well_allocated_conserved_by_frame_free : |
---|
1649 | ∀alloc_type, tmpenv, cl_env, cm_env, cm_m, cl_m, stackptr. |
---|
1650 | ∀Em, cl_ge, cm_ge, INV. |
---|
1651 | ∀Hmatching:memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type. |
---|
1652 | tmp_vars_well_allocated tmpenv cm_env cm_m cl_m Em -> |
---|
1653 | tmp_vars_well_allocated tmpenv cm_env (free cm_m stackptr) (free_list cl_m (blocks_of_env cl_env)) Em. |
---|
1654 | |
---|
1655 | axiom generated_id_not_in_env : |
---|
1656 | ∀id, blo, tmp, ty. |
---|
1657 | ∀env: cl_env. |
---|
1658 | ∀alloc_type. |
---|
1659 | ∀freshgen, freshgen': tmpgen alloc_type. |
---|
1660 | env_below_freshgen env alloc_type freshgen → |
---|
1661 | lookup ?? env id = Some ? blo → |
---|
1662 | alloc_tmp alloc_type ty freshgen = 〈tmp, freshgen'〉 → |
---|
1663 | tmp ≠ id. |
---|
1664 | |
---|
1665 | (* This should just be lifting a lemma from positive maps to identifier maps. |
---|
1666 | * Sadly, the way things are designed requires a boring induction. *) |
---|
1667 | axiom update_lookup_opt_other : |
---|
1668 | ∀b,a,t,H. |
---|
1669 | ∀b'. b ≠ b' → |
---|
1670 | lookup SymbolTag val t b' = lookup SymbolTag val (update_present SymbolTag val t b H a) b'. |
---|
1671 | |
---|
1672 | |
---|
1673 | (* NOTE: this axiom is way more general than what we need. In practice, cm_m' is cm_m after a store. *) |
---|
1674 | axiom clight_cminor_cont_rel_parametric_in_mem : |
---|
1675 | ∀cl_ge, cm_ge, INV, cl_f, cm_f, cl_env, cm_env, cm_m, cm_m', alloc_type, tmpenv, (*stmt_univ, stmt_univ', *) rettyp, cl_k, cm_k, cm_st. |
---|
1676 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ'*) rettyp cl_k cm_k cm_st → |
---|
1677 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env cm_m' alloc_type tmpenv (*stmt_univ stmt_univ'*) rettyp cl_k cm_k cm_st. |
---|
1678 | |
---|
1679 | (* Same remark as above. *) |
---|
1680 | axiom well_allocated_preserved_by_parallel_stores : |
---|
1681 | ∀tmpenv, cm_env, cm_m, cm_m', cl_m, cl_m', Em. |
---|
1682 | |
---|
1683 | (* TODO: proper hypotheses (the following, commented out do not exactly fit) |
---|
1684 | (storen cm_m (mk_pointer cl_blo (mk_offset (offv zero_offset))) (fe_to_be_values (typ_of_type (typeof rhs)) cm_rhs_val) |
---|
1685 | =Some mem cm_mem_after_store_lhs) |
---|
1686 | storev (typ_of_type ty) cl_m (Vptr (mk_pointer cl_blo zero_offset)) cl_rhs_val = Some ? cl_m') *) |
---|
1687 | |
---|
1688 | tmp_vars_well_allocated tmpenv cm_env cm_m cl_m Em → |
---|
1689 | tmp_vars_well_allocated tmpenv cm_env cm_m' cl_m' Em. |
---|
1690 | |
---|
1691 | (* Same remark as above. Moreover, this should be provable from memory injections. *) |
---|
1692 | axiom memory_matching_preserved_by_parallel_stores : |
---|
1693 | ∀Em, cl_ge, cm_ge, cl_m, cl_m', cm_m, cm_m', cl_env, cm_env, INV, stackptr, alloc_type. |
---|
1694 | memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type → |
---|
1695 | memory_matching Em cl_ge cm_ge cl_m' cm_m' cl_env cm_env INV stackptr alloc_type. |
---|
1696 | |
---|
1697 | axiom clight_cminor_cont_rel_parametric_in_cm_env : |
---|
1698 | ∀cl_ge, cm_ge, INV, cl_f, cm_f, cl_env, cm_env, cm_m, alloc_type, tmpenv, (*stmt_univ, stmt_univ',*) rettyp, cl_k, cm_k, cm_st, var_id, v. |
---|
1699 | ∀Hpresent:present SymbolTag val cm_env var_id. |
---|
1700 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env cm_env cm_m alloc_type tmpenv (*stmt_univ stmt_univ'*) rettyp cl_k cm_k cm_st -> |
---|
1701 | clight_cminor_cont_rel cl_ge cm_ge INV cl_f cm_f cl_env |
---|
1702 | (update_present SymbolTag val cm_env var_id Hpresent v) cm_m |
---|
1703 | alloc_type tmpenv (*stmt_univ stmt_univ'*) rettyp cl_k cm_k cm_st. |
---|
1704 | |
---|
1705 | axiom tmp_vars_well_allocated_preserved_by_local_store : |
---|
1706 | ∀Em, cl_value, cm_value, lhs_ty, cl_m, cl_m', cm_m, cl_blo, tmpenv, cm_env, var_id. |
---|
1707 | ∀Hpresent:present SymbolTag val cm_env var_id. |
---|
1708 | value_eq Em cl_value cm_value → |
---|
1709 | store_value_of_type' lhs_ty cl_m 〈cl_blo, zero_offset〉 cl_value = Some ? cl_m' → |
---|
1710 | tmp_vars_well_allocated tmpenv cm_env cm_m cl_m Em → |
---|
1711 | tmp_vars_well_allocated tmpenv |
---|
1712 | (update_present ?? cm_env var_id Hpresent cm_value) cm_m |
---|
1713 | cl_m' Em. |
---|
1714 | |
---|
1715 | axiom memory_inj_preserved_by_local_store : |
---|
1716 | ∀Em, cl_ge, cm_ge, cl_m, cl_m', cm_m, cl_env, cm_env, INV, stackptr, alloc_type. |
---|
1717 | memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type -> |
---|
1718 | memory_inj Em cl_m cm_m -> |
---|
1719 | memory_inj Em cl_m' cm_m. |
---|
1720 | |
---|
1721 | axiom memory_matching_preserved_by_local_store : |
---|
1722 | ∀Em, cl_ge, cm_ge, cl_m, cl_m', cm_m, cl_env, cm_env, INV, stackptr, alloc_type, cl_value, cm_value. |
---|
1723 | ∀cl_blo, var_id, lhs_ty. |
---|
1724 | ∀Hpresent:present SymbolTag val cm_env var_id. |
---|
1725 | value_eq Em cl_value cm_value → |
---|
1726 | store_value_of_type' lhs_ty cl_m 〈cl_blo, zero_offset〉 cl_value = Some ? cl_m' → |
---|
1727 | memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env INV stackptr alloc_type → |
---|
1728 | memory_matching Em cl_ge cm_ge cl_m' cm_m cl_env |
---|
1729 | (update_present SymbolTag val cm_env var_id Hpresent cm_value) INV stackptr alloc_type. |
---|
1730 | |
---|
1731 | lemma alloc_tmp_monotonic : |
---|
1732 | ∀alloc_type, ty, univ, univ', v. |
---|
1733 | alloc_tmp alloc_type ty univ = 〈v, univ'〉 → |
---|
1734 | lset_inclusion ? (tmp_env ? univ) (tmp_env ? univ'). |
---|
1735 | #alloc_type #ty #univ #univ' #v cases univ |
---|
1736 | #u #env #Hfresh #Hyp #Halloc |
---|
1737 | cases (breakup_dependent_match_on_pairs ?????? Halloc) -Halloc |
---|
1738 | #v * #u' * #Heq * #Heq' normalize nodelta #Heq'' |
---|
1739 | destruct (Heq'') |
---|
1740 | @cons_preserves_inclusion @reflexive_lset_inclusion |
---|
1741 | qed. |
---|
1742 | |
---|
1743 | (* TODO: move *) |
---|
1744 | lemma extract_pair' : ∀A,B,C. ∀u:A×B. ∀Q:A → B → C. ∀x. |
---|
1745 | ((let 〈a,b〉 ≝ u in Q a b) = x) → |
---|
1746 | ∃a,b. 〈a,b〉 = u ∧ Q a b = x. |
---|
1747 | #A #B #C * #a #b #Q #x normalize #E1 %{a} %{b} % try @refl @E1 qed. |
---|
1748 | |
---|
1749 | lemma pair_as_elim: |
---|
1750 | ∀A,B,C: Type[0]. |
---|
1751 | ∀p. |
---|
1752 | ∀T: ∀a:A. ∀b:B. 〈a,b〉 = p → C. |
---|
1753 | ∀P: A×B → C → Prop. |
---|
1754 | (∀lft, rgt. ∀E:〈lft,rgt〉 = p. P 〈lft,rgt〉 (T lft rgt E)) → |
---|
1755 | P p (let 〈lft, rgt〉 as E ≝ p in T lft rgt E). |
---|
1756 | #A #B #C * /2/ |
---|
1757 | qed. |
---|
1758 | |
---|
1759 | (* TODO: move *) |
---|
1760 | lemma alloc_low_bound : ∀m,l,h,m',b. |
---|
1761 | alloc m l h = 〈m',b〉 → |
---|
1762 | low_bound m' b = l. |
---|
1763 | * #contents #next #next_ok #l #h #m' #b #E |
---|
1764 | whd in E:(??%%); destruct |
---|
1765 | whd in ⊢ (??%?); >update_block_s |
---|
1766 | % |
---|
1767 | qed. |
---|
1768 | |
---|
1769 | lemma alloc_high_bound : ∀m,l,h,m',b. |
---|
1770 | alloc m l h = 〈m',b〉 → |
---|
1771 | high_bound m' b = h. |
---|
1772 | * #contents #next #next_ok #l #h #m' #b #E |
---|
1773 | whd in E:(??%%); destruct |
---|
1774 | whd in ⊢ (??%?); >update_block_s |
---|
1775 | % |
---|
1776 | qed. |
---|
1777 | |
---|
1778 | (* Weaker version of Zlt_to_Zle *) |
---|
1779 | lemma Zlt_Zle : ∀x,y:Z. x < y → x ≤ y. |
---|
1780 | #x #y #H |
---|
1781 | @(transitive_Zle … (Zsucc_le x)) @Zlt_to_Zle @H |
---|
1782 | qed. |
---|
1783 | |
---|
1784 | axiom unZoo : ∀off:Z. |
---|
1785 | off < Z_two_power_nat 16 → |
---|
1786 | Zoo (offset_of_Z off) = off. |
---|
1787 | |
---|
1788 | lemma le_to_Zle : ∀x,y:nat. le x y → Zle x y. |
---|
1789 | #x #y #H @(le_ind ????? H) |
---|
1790 | [ // |
---|
1791 | | #m #H1 #H2 >Zsucc_pos @(transitive_Zle … (Zsucc_le m)) assumption |
---|
1792 | ] qed. |
---|
1793 | |
---|
1794 | lemma lt_to_Zlt : ∀x,y:nat. lt x y → Zlt x y. |
---|
1795 | #x #y whd in ⊢ (% → ?); #H |
---|
1796 | <(Zpred_Zsucc x) @Zle_to_Zlt |
---|
1797 | <Zsucc_pos |
---|
1798 | @le_to_Zle assumption |
---|
1799 | qed. |
---|
1800 | |
---|
1801 | lemma Zlt_Zsucc : ∀z:Z. z < Zsucc z. |
---|
1802 | /2/ |
---|
1803 | qed. |
---|
1804 | |
---|
1805 | lemma Zle_Zlt_Zsucc : ∀x,y:Z. x ≤ y → x < Zsucc y. |
---|
1806 | /2/ |
---|
1807 | qed. |
---|
1808 | |
---|
1809 | theorem Zle_to_Zlt_to_Zlt: ∀n,m,p:Z. n ≤ m → m < p → n < p. |
---|
1810 | #n #m #p #Hle #Hlt lapply (Zlt_to_Zle … Hlt) |
---|
1811 | @Zlt_to_Zle_to_Zlt @Zle_Zlt_Zsucc assumption |
---|
1812 | qed. |
---|
1813 | |
---|
1814 | |
---|
1815 | (* This roughly corresponds to lemma 69 of Leroy and Blazy *) |
---|
1816 | (* |
---|
1817 | lemma alloc_vars_rel : ∀vartypes, cl_m, cm_m, stacksize, cm_m1, cm_frame. |
---|
1818 | ∀Em. memory_inj Em cl_m cm_m → |
---|
1819 | Z_of_nat stacksize < Z_two_power_nat 16 → |
---|
1820 | alloc cm_m O (Z_of_nat stacksize) = 〈cm_m1,cm_frame〉 → |
---|
1821 | ∀L, cl_env, cl_m1. |
---|
1822 | exec_alloc_variables empty_env cl_m L = 〈cl_env,cl_m1〉 → |
---|
1823 | (∀v,ty. Exists … (λx.x = 〈v,ty〉) L → ∃c. lookup' vartypes v = return 〈c,ty〉 ∧ |
---|
1824 | match c with |
---|
1825 | [ Local ⇒ True |
---|
1826 | | Stack off ⇒ |
---|
1827 | le O off ∧ le (sizeof ty + off) stacksize ∧ |
---|
1828 | (∀v',off',t'. v≠v' → lookup' vartypes v' = return 〈Stack off',t'〉 → le (off' + sizeof t') off ∨ le (off + sizeof ty) off') |
---|
1829 | | Global _ ⇒ False |
---|
1830 | ]) → |
---|
1831 | ∃Em'. memory_inj Em' cl_m1 cm_m1 ∧ |
---|
1832 | embedding_compatible Em Em' ∧ |
---|
1833 | ∀v. Exists … (λx.\fst x = v) L → |
---|
1834 | ∃b,c,t. lookup … cl_env v = Some ? b ∧ |
---|
1835 | lookup' vartypes v = return 〈c,t〉 ∧ |
---|
1836 | match c with |
---|
1837 | [ Local ⇒ Em' b = None ? |
---|
1838 | | Stack off ⇒ Em' b = Some ? 〈cm_frame, offset_of_Z (Z_of_nat off)〉 |
---|
1839 | | Global _ ⇒ False |
---|
1840 | ]. |
---|
1841 | #vartypes #cl_m #cm_m #stacksize #cm_m1 #cm_frame #Em #Inj #stack_ok #cm_alloc #L |
---|
1842 | cut (block_implementable_bv cm_m1 cm_frame) |
---|
1843 | [ whd >(alloc_low_bound … cm_alloc) >(alloc_high_bound … cm_alloc) % % // |
---|
1844 | cases stacksize // ] #cm_bi |
---|
1845 | lapply (alloc_memory_inj_m2 … Inj cm_alloc cm_bi) |
---|
1846 | lapply (alloc_valid_new_block … cm_alloc) #cm_frame_valid |
---|
1847 | cut (∀b:block. ∀delta':offset. |
---|
1848 | Em b=Some (block×offset) 〈cm_frame,delta'〉 → |
---|
1849 | ∀v,off,ty. lookup' vartypes v = OK ? 〈Stack off, ty〉 → |
---|
1850 | high_bound cl_m b+Zoo delta'≤O+Zoo (offset_of_Z off) |
---|
1851 | ∨ sizeof ty+Zoo (offset_of_Z off)≤low_bound cl_m b+Zoo delta') |
---|
1852 | [ #b #delta' #E @⊥ lapply (mi_nodangling … Inj … E) #V |
---|
1853 | @(absurd … V) @(new_block_invalid_before_alloc … cm_alloc) ] |
---|
1854 | |
---|
1855 | generalize in match Em; -Em generalize in match empty_env; elim L |
---|
1856 | [ #cl_env #Em #_ #Inj #cl_env' #cl_m1 #cl_alloc |
---|
1857 | whd in cl_alloc:(??%%); destruct #H |
---|
1858 | %{Em} % [ % [ @Inj | // ] | #v * ] |
---|
1859 | | * #v #ty #tl #IH |
---|
1860 | #cl_env #Em #Hexisting #Inj #cl_env' #cl_m1 |
---|
1861 | whd in ⊢ (??%? → ?); @pair_elim #cl_m2 #cl_b #cl_alloc #cl_alloc' #H |
---|
1862 | cases (H v ty ?) [2: %1 % ] * |
---|
1863 | [ #r * #L * |
---|
1864 | | #off * #L * * #off_low #off_high #other |
---|
1865 | lapply (alloc_memory_inj_m1_to_m2 … (offset_of_Z off) cm_frame_valid … cm_bi … cl_alloc … Inj) |
---|
1866 | [ #b #delta' #NE #E @(Hexisting … E … L) |
---|
1867 | | cases (alloc_properties … cm_alloc) #_ #U #i #LOW #HIGH @U |
---|
1868 | [ /2/ |
---|
1869 | | @(transitive_Zle … HIGH) >unZoo |
---|
1870 | [ <eq_plus_Zplus /2/ |
---|
1871 | | @(Zlt_to_Zle_to_Zlt ? (sizeof ty + off)) |
---|
1872 | [ <eq_plus_Zplus @lt_to_Zlt whd in ⊢ (??%); /2/ |
---|
1873 | | @(transitive_Zlt … stacksize) [ <eq_plus_Zplus @(lt_to_Zlt … off_high) | // ] |
---|
1874 | ] |
---|
1875 | ] |
---|
1876 | ] |
---|
1877 | | >unZoo |
---|
1878 | [ <eq_plus_Zplus >(alloc_high_bound … cm_alloc) |
---|
1879 | *) |
---|
1880 | (* |
---|
1881 | lemma lset_inclusion_Exists : |
---|
1882 | ∀A. ∀l1, l2: lset A. |
---|
1883 | lset_inclusion ? l1 l2 → |
---|
1884 | ∀P. Exists ? P l1 → Exists ? P l2. |
---|
1885 | #A #l1 elim l1 |
---|
1886 | [ #l2 #Hincl #P @False_ind |
---|
1887 | | #hd #tl #Hind #l2 * #Hmem #Hincl2 #P * |
---|
1888 | [ 2: #Htl @Hind assumption ] |
---|
1889 | lapply P -P |
---|
1890 | lapply Hincl2 -Hincl2 |
---|
1891 | lapply Hmem -Hmem elim l2 |
---|
1892 | [ @False_ind ] |
---|
1893 | #hd2 #tl2 #Hind2 * |
---|
1894 | [ #Heq destruct (Heq) |
---|
1895 | #Hincl2 #P #H %1 @H |
---|
1896 | | #Hmem #Hincl2 #P #H %2 |
---|
1897 | elim tl2 in Hmem; |
---|
1898 | [ @False_ind |
---|
1899 | | #hd2' #tl2' #Hind3 * |
---|
1900 | [ #Heq destruct (Heq) %1 assumption |
---|
1901 | | #Hmem' %2 @Hind3 @Hmem' ] |
---|
1902 | ] |
---|
1903 | ] |
---|
1904 | ] qed. *) |
---|
1905 | |
---|
1906 | (* --------------------------------------------------------------------------- *) |
---|
1907 | (* Main simulation results *) |
---|
1908 | (* --------------------------------------------------------------------------- *) |
---|
1909 | |
---|
1910 | (* Conjectured simulation results |
---|
1911 | |
---|
1912 | We split these based on the start state: |
---|
1913 | |
---|
1914 | 1. ‘normal’ states take some [S n] normal steps and simulates them by [S m] |
---|
1915 | normal steps in Cminor; |
---|
1916 | 2. call and return steps are simulated by a call/return step plus [m] normal |
---|
1917 | steps (to copy stack allocated parameters / results); and |
---|
1918 | 3. lone cost label steps are simulated by a lone cost label step |
---|
1919 | |
---|
1920 | These should allow us to maintain enough structure to identify the Cminor |
---|
1921 | subtrace corresponding to a measurable Clight subtrace. |
---|
1922 | *) |
---|
1923 | (* WIP |
---|
1924 | include "common/ExtraMonads.ma". |
---|
1925 | |
---|
1926 | lemma clight_cminor_call : |
---|
1927 | ∀g,g'. |
---|
1928 | ∀INV:clight_cminor_inv g g'. |
---|
1929 | ∀s1,s1'. |
---|
1930 | clight_cminor_rel g g' INV s1 s1' → |
---|
1931 | Clight_classify s1 = cl_call → |
---|
1932 | ∀s2,tr2,s3,tr3. |
---|
1933 | step … (pcs_exec cl_pre) g s1 = Value … 〈tr2,s2〉 → |
---|
1934 | step … (pcs_exec cl_pre) g s2 = Value … 〈tr3,s3〉 → |
---|
1935 | Clight_labelled s2 → |
---|
1936 | after_n_steps 1 ?? (pcs_exec cm_pre) g' s1' (λs.cminor_normal s) (λtr2',s2'. |
---|
1937 | tr2 = tr2' ∧ |
---|
1938 | bool_to_Prop (Cminor_labelled s2') ∧ |
---|
1939 | ∃m. |
---|
1940 | after_n_steps m ?? (pcs_exec cm_pre) g' s2' (λs.cminor_normal s) (λtr3',s3'. |
---|
1941 | tr3 = tr3' ∧ |
---|
1942 | clight_cminor_rel g g' INV s2 s2') |
---|
1943 | ). |
---|
1944 | #Xg #Xg' #XINV #Xs1 #Xs1' * |
---|
1945 | [ #g #g' #INV #cl_s #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize #fInv #sInv #kInv #Erettyp #func_univ #Hfresh_globals #Hfresh_function #Htranslate_fn #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls #flag #Htranslate_inv #Htranslate_s #Hlbls_inc #tmpenv #Htmpenv #CONT #Em #HtmpEm #CHAR #ALLOC #INJ #MATCH #HEm_fn #HEm_env #Henv_below |
---|
1946 | #CL whd in CL:(??%?); destruct |
---|
1947 | | #g #g' #INV #cl_k #cm_k #cm_st #cl_f #cm_f #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize #stmt_univ #tmpenv #Htmpenv #Em #HEm_tmp #CHAR #ALLOC #INJ #MATCH #HEm_fn #HEm_env #CONT |
---|
1948 | #CL whd in CL:(??%?); destruct |
---|
1949 | | #g #g' #INV #cl_k #cm_st #cl_fd #cm_fd #fblock #target_type #cl_env #cl_m #cm_env #cm_m #fid #Hfind_cl #Hfind_cm #tmpenv #CONT #Em #INJ #HEm_fn #cl_args #cm_args #Hargs |
---|
1950 | #CL #s2 #tr2 #s3 #tr3 #STEP1 #STEP2 #CS2 |
---|
1951 | |
---|
1952 | (* Note that cm_fd is the translation of cl_fd *) |
---|
1953 | cases (trans_fn … INV … Hfind_cl) |
---|
1954 | #func_univ * #cm_fd' * #Hglobals_fresh * #Hfundef_fresh * #Htranslate |
---|
1955 | >Hfind_cm #E destruct |
---|
1956 | |
---|
1957 | (* Must be a CL_Internal function *) |
---|
1958 | cases cl_fd in Hfundef_fresh Htranslate Hfind_cl CONT STEP1; |
---|
1959 | [ #cl_f |
---|
1960 | | #ext #ext_argtys #ext_retty |
---|
1961 | ] |
---|
1962 | #Hfundef_fresh #Htranslate #Hfind_cl #CONT #STEP1 |
---|
1963 | [2: cases (bindIO_inversion ??????? STEP1) -STEP1 #vs * #_ #STEP1 |
---|
1964 | whd in STEP1:(??%%); destruct ] |
---|
1965 | -cl_fd |
---|
1966 | (* and the Cminor one must be Internal *) |
---|
1967 | @('bind_inversion Htranslate) #cm_f #Htranslate' #E |
---|
1968 | whd in E:(??%%); destruct |
---|
1969 | |
---|
1970 | (* Invert function translation *) |
---|
1971 | (* NB: if you want to examine the proof state in here, you probably want to |
---|
1972 | turn off the pretty printer - it doesn't cope well with a large proof |
---|
1973 | term. *) |
---|
1974 | @('bind_inversion Htranslate') * * #lbls #Ilbls #ul #Hbuild_label_env |
---|
1975 | whd in ⊢ (??%? → ?); |
---|
1976 | @pair_as_elim #vartypes #stacksize #Hcharacterise |
---|
1977 | letin uv ≝ (mk_tmpgen ?? [ ] ??) #H |
---|
1978 | @('bind_inversion H) -H #s0 #Htranslate_statement #H |
---|
1979 | @('bind_inversion H) -H * * #fgens #s1 #Is #Halloc_params |
---|
1980 | letin cm_params ≝ (map ??? (fn_params cl_f)) |
---|
1981 | whd in ⊢ (??%? → ?); |
---|
1982 | letin cm_vars ≝ (map ??? (?@fn_vars cl_f)) #H |
---|
1983 | @('bind_inversion H) -H #D #Hcheck_distinct_env |
---|
1984 | whd in ⊢ (??%% → ?); generalize in ⊢ (??(??(???????%))? → ?); |
---|
1985 | (* It's safe to use the pretty printer again. *) |
---|
1986 | #cm_Sinv #H destruct |
---|
1987 | |
---|
1988 | (* Invert Clight STEP1 *) |
---|
1989 | cases (extract_pair' ?????? STEP1) -STEP1 #cl_env * #cl_m1 * #ALLOC #STEP1 |
---|
1990 | cases (bindIO_inversion ??????? STEP1) -STEP1 #cl_m2 * #BIND #STEP1 |
---|
1991 | whd in STEP1:(??%%); destruct |
---|
1992 | |
---|
1993 | whd whd in ⊢ (??%?); |
---|
1994 | @pair_elim #cm_m1 #cm_frame #CM_ALLOC |
---|
1995 | |
---|
1996 | (〈vartypes,stacksize〉=characterise_vars (globals g g' INV) cl_f) |
---|
1997 | We need to build an extended memory injection to reflect the new allocations; |
---|
1998 | then the bind functions put the correct local variables in; |
---|
1999 | then after execution the appropriate number of Cminor steps the stored values |
---|
2000 | match. |
---|
2001 | |
---|
2002 | Oh, and there are the locals too. |
---|
2003 | |
---|
2004 | |
---|
2005 | alloc_memory_inj_m2 shows that embedding is fine after the Cminor alloc |
---|
2006 | |
---|
2007 | ∀Em. memory_inj Em cl_m cm_m → |
---|
2008 | (∀b. block_region b = Code → Em' b = Some ? 〈b,zero_offset〉) → |
---|
2009 | exec_alloc_variables empty_env cl_m (fn_params cl_f@fn_vars cl_f) = 〈cl_env,cl_m1〉 → |
---|
2010 | alloc cm_m O (f_stacksize cm_f) = 〈cm_m1,cm_frame〉 → |
---|
2011 | ∃Em'. |
---|
2012 | memory_inj Em' cl_m1 cm_m1 ∧ |
---|
2013 | (∀b. block_region b = Code → Em' b = Some ? 〈b,zero_offset〉) ∧ |
---|
2014 | (∀v,v'. value_eq Em v v' → value_eq Em' v v') ∧ |
---|
2015 | (∀b1.∀delta. Em' b1=Some ? 〈cm_frame,delta〉 → |
---|
2016 | mem block b1 (blocks_of_env cl_env)). |
---|
2017 | |
---|
2018 | ∀b. Em b = Em' b ∨ (Em b = None ? ∧ ∃off. Em' b = Some ? 〈cm_frame,off〉). |
---|
2019 | |
---|
2020 | |
---|
2021 | translate_function func_univ (globals … INV) cl_f H1 H2 = return cm_f → |
---|
2022 | All2 … (λcl,cm.value_eq Em cl cm) cl_args cm_args → |
---|
2023 | exec_bind_parameters cl_env cl_m1 (fn_params cl_f) cl_args = return cl_m2 → |
---|
2024 | ∃cm_en,Hcm_args_present. |
---|
2025 | bind_params cm_args (f_params cm_f) = return «cm_en, Hcm_args_present» ∧ |
---|
2026 | |
---|
2027 | |
---|
2028 | *) |
---|
2029 | |
---|
2030 | (* |
---|
2031 | lemma clight_cminor_call_return : |
---|
2032 | ∀g1, g2. |
---|
2033 | ∀INV:clight_cminor_inv g1 g2. |
---|
2034 | ∀s1,s1'. |
---|
2035 | clight_cminor_rel g1 g2 INV s1 s1' → |
---|
2036 | match Clight_classify s1 with |
---|
2037 | [ cl_call ⇒ true |
---|
2038 | | cl_return ⇒ true |
---|
2039 | | _ ⇒ false ] → |
---|
2040 | ∀s2,tr. step … (pcs_exec cl_pre) g1 s1 = Value … 〈tr, s2〉 → |
---|
2041 | ∃m. after_n_steps m ?? (pcs_exec cm_pre) g2 s1' (λs.cminor_normal s) (λtr',s2'. |
---|
2042 | tr = tr' ∧ |
---|
2043 | clight_cminor_rel g1 g2 INV s2 s2' ∧ |
---|
2044 | (m = 0 → lex_lt (measure_Clight s2) (measure_Clight s1)) |
---|
2045 | ). |
---|
2046 | #g1 #g2 #INV #s1 #s1' #Hstate_rel #Hclight_class |
---|
2047 | inversion Hstate_rel |
---|
2048 | [ 1: (* normal *) |
---|
2049 | #cl_ge #cm_ge #INV' #cl_s |
---|
2050 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2051 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
2052 | (* introduce everything *) |
---|
2053 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2054 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2055 | #flag #Htrans_inv #Htrans_stmt #Hincl #HA #HB #HC |
---|
2056 | #HE #HF #HG #HI #HJ #HK |
---|
2057 | @(jmeq_absorb ?????) #H1 @(jmeq_absorb ?????) #H2 |
---|
2058 | destruct (H1 H2) |
---|
2059 | @(jmeq_absorb ?????) #H3 @(jmeq_absorb ?????) #H4 @(jmeq_absorb ?????) #H5 |
---|
2060 | destruct (H3 H4 H5) |
---|
2061 | @False_ind @Hclight_class |
---|
2062 | | 5: |
---|
2063 | #cl_ge #cm_ge #INV' #cl_s |
---|
2064 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2065 | #alloc_type #cl_k #cm_k #sz #sg #cl_ty #cl_cond_desc #cl_body #entry_lab #exit_lab |
---|
2066 | #cm_cond #cm_body #cm_stack #rettyp' #kInv |
---|
2067 | (* introduce everything *) |
---|
2068 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2069 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2070 | #lbl1 #lbl2 #Em #Htmp_vars #Hcharac #Hexec #Hinj #Hmatching #Hem #Hframe #Hcond_tr |
---|
2071 | #Htransl #Hex1 #Hex2 #Htransinv #Hmklabs #Htranstmt #Hincl |
---|
2072 | #Hlabdecl #Hinv1 #Hinv2 #Hfindlab |
---|
2073 | @(jmeq_absorb ?????) #H1 @(jmeq_absorb ?????) #H2 |
---|
2074 | destruct (H1 H2) |
---|
2075 | @(jmeq_absorb ?????) #H3 @(jmeq_absorb ?????) #H4 @(jmeq_absorb ?????) #H5 |
---|
2076 | destruct (H3 H4 H5) |
---|
2077 | @False_ind @Hclight_class |
---|
2078 | | 2: |
---|
2079 | #cl_ge #cm_ge #INV' #cl_f #cm_f #cl_k #cm_k #alloc_type |
---|
2080 | #cl_env #cl_m #cm_env #cm_m #cm_st #stackptr #stacksize |
---|
2081 | #stmt_univ #Em #Htmp_vars_well_allocated #Halloc_hyp #Hcl_env_hyp |
---|
2082 | #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Hcont_rel |
---|
2083 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2084 | destruct (HA HB) |
---|
2085 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE #_ |
---|
2086 | destruct (HC HD HE) |
---|
2087 | inversion Hcont_rel |
---|
2088 | [ #kcl_ge #kcm_ge #kINV #kcl_f #kcm_f #ktarget_type #kcl_env #kcm_env #kalloc_type #kstack #Hkstack |
---|
2089 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2090 | destruct (HA HB) |
---|
2091 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2092 | destruct (HC HD HE) |
---|
2093 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH |
---|
2094 | @(jmeq_absorb ?????) #HI @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK @(jmeq_absorb ?????) #HL |
---|
2095 | destruct (HF HG HH HI HJ HK HL) #_ |
---|
2096 | #s2 #tr |
---|
2097 | whd in ⊢ ((??%?) → ?); #Habsurd destruct (Habsurd) |
---|
2098 | | (* Kseq *) |
---|
2099 | #kcl_ge #kcm_ge #kINV #kcl_f #kcm_f #ktarget_type #kstack #kalloc_type #kcl_s #kcm_s |
---|
2100 | #kcl_env #kcm_env #kcl_k' #kcm_k' #kstmt_univ #kstmt_univ' #klbl_univ #klbl_univ' #klbls #kflag |
---|
2101 | * * * * #kHstmt_inv #kHlabels_translated #kHtmps_preserved |
---|
2102 | #kHreturn_ok #kHlabel_wf #kHeq_translate #kHlabel_inclusion #kHcont_rel #_ |
---|
2103 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2104 | destruct (HA HB) |
---|
2105 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2106 | destruct (HC HD HE) |
---|
2107 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH @(jmeq_absorb ?????) #HI |
---|
2108 | @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK @(jmeq_absorb ?????) #HL |
---|
2109 | destruct (HF HG HH HI HJ HK HL) #_ |
---|
2110 | #s2 #tr |
---|
2111 | whd in ⊢ ((??%?) → ?); #Habsurd destruct (Habsurd) |
---|
2112 | | (* *) |
---|
2113 | #kcl_ge #kcm_ge #kINV #kcl_f #kcm_f #ktarget_type #kstack #kalloc_type #kcl_env #kcm_env |
---|
2114 | #kcl_k' #kcm_k' #ksz #ksg #kcl_ty #kcl_cond_desc #kcl_body #kHeq_ty #kcm_cond #kcm_body |
---|
2115 | #kentry #kexit #kstmt_univ #kstmt_univ' #klbl_univ #klbl_univ' #klbl_univ'' |
---|
2116 | #klbls #kHtranslate_inv #kHexpr_vars #kHtranslate_expr #kfInv #kHlabel_declared |
---|
2117 | #kHinv #kHmklabels #kHeq_translate #kHlabel_inclusion #kHfind_label |
---|
2118 | (* |
---|
2119 | * * * * #kHentry_declared * * * * |
---|
2120 | * * * #kHcond_vars_declared #Hnoise #Hnoise' #Hnoise'' |
---|
2121 | #kHcont_inv #kHmklabels #kHeq_translate |
---|
2122 | #kHfind_label *) #kHcont_rel #_ |
---|
2123 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2124 | destruct (HA HB) |
---|
2125 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2126 | destruct (HC HD HE) |
---|
2127 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH |
---|
2128 | @(jmeq_absorb ?????) #HI @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK |
---|
2129 | @(jmeq_absorb ?????) #HL |
---|
2130 | destruct (HF HG HH HI HJ HK HL) #_ |
---|
2131 | #s2 #tr |
---|
2132 | whd in ⊢ ((??%?) → ?); #Habsurd destruct (Habsurd) |
---|
2133 | ] |
---|
2134 | | 3: |
---|
2135 | #cl_ge #cm_ge #INV' #alloc_type |
---|
2136 | #cl_env #cl_m #cm_env #cm_m #cm_st #stackptr #func_univ |
---|
2137 | #cl_f #cm_f #Hglobals_fresh #Hfundef_fresh |
---|
2138 | #rettyp #cl_k #cm_k #fblock * |
---|
2139 | #Hrettyp #Hfind_funct_cl #Hfind_func_cm #Htranslate_function #Hcont_rel |
---|
2140 | #fun_id #cl_retval #cm_retval #sInv #fInv #kInv #cl_args #cm_args |
---|
2141 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2142 | destruct (HA HB) |
---|
2143 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2144 | destruct (HC HD HE) #_ |
---|
2145 | #s2 #tr whd in ⊢ ((??%?) → ?); |
---|
2146 | @(match (exec_alloc_variables empty_env cl_m (fn_params cl_f@fn_vars cl_f)) |
---|
2147 | return λx. (x = (exec_alloc_variables empty_env cl_m (fn_params cl_f@fn_vars cl_f))) → ? |
---|
2148 | with |
---|
2149 | [ mk_Prod new_cl_env cl_m_alloc ⇒ ? |
---|
2150 | ] (refl ? (exec_alloc_variables empty_env cl_m (fn_params cl_f@fn_vars cl_f)))) |
---|
2151 | #Hexec_alloc_variables normalize nodelta |
---|
2152 | #Hstep |
---|
2153 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
2154 | #cl_m_init * #Hexec_bind_parameters |
---|
2155 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
2156 | %{1} whd whd in ⊢ (??%?); |
---|
2157 | (* Alloc big chunk of data of size (f_stacksize cm_f) *) |
---|
2158 | @(match (alloc cm_m 0 (f_stacksize cm_f)) |
---|
2159 | return λx. (alloc cm_m 0 (f_stacksize cm_f) = x) → ? |
---|
2160 | with |
---|
2161 | [ mk_Prod new_cm_mem new_cm_stackptr ⇒ ? |
---|
2162 | ] (refl ? (alloc cm_m 0 (f_stacksize cm_f)))) |
---|
2163 | #H_cm_alloc normalize nodelta |
---|
2164 | (* Initialise CM /parameters/ *) |
---|
2165 | |
---|
2166 | |
---|
2167 | %{(S (times 3 (|fn_vars|)))} -Hclight_class |
---|
2168 | lapply (exec_alloc_bind_params_same_length … Hexec_bind_parameters) |
---|
2169 | elim cl_args in Hstate_rel Hexec_alloc; |
---|
2170 | [ #Hstate_rel whd in ⊢ ((??%%) → ?); |
---|
2171 | |
---|
2172 | whd in match (exec_bind_parameters ????); |
---|
2173 | |
---|
2174 | exec_alloc_variables empty_env cl_m (fn_params cl_f@fn_vars cl_f) = 〈cl_env, cl_m'〉 |
---|
2175 | |
---|
2176 | |
---|
2177 | lapply (let_prod_as_inversion ?????? Hstep) |
---|
2178 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH |
---|
2179 | @(jmeq_absorb ?????) #HI @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK |
---|
2180 | @(jmeq_absorb ?????) #HL |
---|
2181 | destruct (HF HG HH HI HJ HK HL) #_ |
---|
2182 | #s2 #tr |
---|
2183 | |
---|
2184 | |
---|
2185 | #Em #Htmp_vars_well_allocated #Halloc_hyp #Hcl_env_hyp |
---|
2186 | #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Hcont_rel |
---|
2187 | ] qed. *) |
---|
2188 | |
---|
2189 | lemma clight_cminor_normal : |
---|
2190 | ∀g1,g2. |
---|
2191 | ∀INV:clight_cminor_inv g1 g2. |
---|
2192 | ∀s1,s1'. |
---|
2193 | clight_cminor_rel g1 g2 INV s1 s1' → |
---|
2194 | clight_normal s1 → |
---|
2195 | ¬ pcs_labelled cl_pre g1 s1 → |
---|
2196 | ∀s2,tr. step … (pcs_exec cl_pre) g1 s1 = Value … 〈tr,s2〉 → |
---|
2197 | ∃m. after_n_steps m ?? (pcs_exec cm_pre) g2 s1' (λs.cminor_normal s) (λtr',s2'. |
---|
2198 | tr = tr' ∧ |
---|
2199 | clight_cminor_rel g1 g2 INV s2 s2' ∧ |
---|
2200 | (m = 0 → lex_lt (measure_Clight s2) (measure_Clight s1)) |
---|
2201 | ). |
---|
2202 | #Xg1 #Xg2 #XINV #Xs1 #Xs1' * |
---|
2203 | [ 1: (* Normal state *) |
---|
2204 | (* ---------------------------------------------------------------------- *) |
---|
2205 | #cl_ge #cm_ge #INV' #cl_s |
---|
2206 | (* case analysis on Clight statement *) |
---|
2207 | cases cl_s |
---|
2208 | [ 1: | 2: #lhs #rhs | 3: #retv #func #args | 4: #stm1 #stm2 | 5: #cond #iftrue #iffalse | 6: #cond #body |
---|
2209 | | 7: #cond #body | 8: #init #cond #step #body | 9,10: | 11: #retval | 12: #cond #switchcases | 13: #lab #body |
---|
2210 | | 14: #lab | 15: #cost #body ] |
---|
2211 | (* |
---|
2212 | [ 11: (* Return case *) |
---|
2213 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2214 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
2215 | (* introduce everything *) |
---|
2216 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2217 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2218 | #flag #Htrans_inv #Htranslate #Hlabel_inclusion #Hcont_rel |
---|
2219 | #Em #Htmp_vars_well_allocated #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id |
---|
2220 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2221 | destruct (HA HB) |
---|
2222 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE #_ |
---|
2223 | destruct (HC HD HE) |
---|
2224 | whd in Htranslate:(??%?); |
---|
2225 | cases retval in Htranslate; normalize nodelta |
---|
2226 | [ cases rettyp in Htrans_inv Hcont_rel; |
---|
2227 | [ 2: #opttyp normalize nodelta #Htrans_inv #_ |
---|
2228 | #Habsurd destruct (Habsurd) |
---|
2229 | | 1: #Htrans_inv #Hcont_rel normalize nodelta #Heq destruct (Heq) |
---|
2230 | #s2 #tr whd in ⊢ ((??%?) → ?); |
---|
2231 | cases (fn_return cl_f) |
---|
2232 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
2233 | | #structname #fieldspec | #unionname #fieldspec | #id ] |
---|
2234 | normalize nodelta |
---|
2235 | [ 1: |
---|
2236 | | *: #Habsurd destruct (Habsurd) ] |
---|
2237 | whd in ⊢ ((??%?) → ?); |
---|
2238 | #Heq destruct (Heq) |
---|
2239 | %{1} whd @conj try @conj |
---|
2240 | [ 3: #Habsurd destruct (Habsurd) |
---|
2241 | | 1: @refl ] |
---|
2242 | @CMR_return |
---|
2243 | *) |
---|
2244 | [ 6: (* While *) |
---|
2245 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2246 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
2247 | (* introduce everything *) |
---|
2248 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2249 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2250 | #flag * * * * #Hstmt_inv_cm cases cond #cond_desc #cond_ty |
---|
2251 | (* early case analysis to avoid dependency hell *) |
---|
2252 | cases cond_ty |
---|
2253 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
2254 | | #structname #fieldspec | #unionname #fieldspec | #id ] |
---|
2255 | #Hlabels_translated #Htmps_preserved |
---|
2256 | #Hreturn_ok #Hlabel_wf #Htranslate #Hlabel_inclusion #tmpenv #Htmpenv |
---|
2257 | #Hcont_rel |
---|
2258 | #Em #Htmp_vars_well_allocated |
---|
2259 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id |
---|
2260 | #Hframe_spec #Henv_below #Hclight_normal #Hnot_labeleld |
---|
2261 | lapply Htranslate -Htranslate |
---|
2262 | [ 1: generalize in match (conj ????); #Hugly_inv |
---|
2263 | | 2: generalize in match (conj ????); #Hugly_inv |
---|
2264 | | 3: generalize in match (conj ????); #Hugly_inv |
---|
2265 | | 4: generalize in match (conj ????); #Hugly_inv |
---|
2266 | | 5: generalize in match (conj ????); #Hugly_inv |
---|
2267 | | 6: generalize in match (conj ????); #Hugly_inv |
---|
2268 | | 7: generalize in match (conj ????); #Hugly_inv |
---|
2269 | | 8: generalize in match (conj ????); #Hugly_inv ] |
---|
2270 | #Htranslate |
---|
2271 | cases (bind_inversion ????? Htranslate) -Htranslate |
---|
2272 | whd in match (typeof ?); whd in match (typ_of_type ?); * |
---|
2273 | #cm_cond #Hexpr_vars_cond * #Htranslate_cond normalize nodelta |
---|
2274 | [ 3,4,5,8: whd in ⊢ ((??%%) → ?); #Habsurd destruct (Habsurd) ] |
---|
2275 | #Htranslate normalize nodelta |
---|
2276 | lapply (let_prod_as_inversion ?????? Htranslate) -Htranslate |
---|
2277 | * * #entry_label #exit_label * #lbl_univ0 * #Hmk_label_eq * |
---|
2278 | #Hmk_label_eq_bis normalize nodelta #Htranslate |
---|
2279 | cases (bind_inversion ????? Htranslate) -Htranslate |
---|
2280 | * * * #stmt_univ0 #lbl_univ1 #cm_body |
---|
2281 | #Htrans_inv * #Htrans_body normalize nodelta |
---|
2282 | [ generalize in ⊢ ((??(??(????%))?) → ?); |
---|
2283 | #Htrans_inv' |
---|
2284 | | generalize in ⊢ ((??(??(????%))?) → ?); |
---|
2285 | #Htrans_inv' |
---|
2286 | | generalize in ⊢ ((??(??(????%))?) → ?); |
---|
2287 | #Htrans_inv' |
---|
2288 | | generalize in ⊢ ((??(??(????%))?) → ?); |
---|
2289 | #Htrans_inv' ] |
---|
2290 | whd in ⊢ ((???%) → ?); |
---|
2291 | #Heq destruct (Heq) |
---|
2292 | #s2 #tr whd in ⊢ ((??%?) → ?); |
---|
2293 | #Hstep |
---|
2294 | cases (bindIO_inversion ??????? Hstep) -Hstep * #cond_val #cond_trace |
---|
2295 | * #Hcl_exec_cond #Hstep |
---|
2296 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
2297 | #cl_cond_bool * #Hcl_bool_of_val whd in ⊢ ((??%%) → ?); |
---|
2298 | cases cl_cond_bool in Hcl_bool_of_val; |
---|
2299 | [ 1,3,5,7: (* cond = true: continue looping *) |
---|
2300 | #Hcl_bool_of_val normalize nodelta |
---|
2301 | #Heq destruct (Heq) |
---|
2302 | %{4} whd whd in ⊢ (??%?); normalize nodelta |
---|
2303 | [ generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
2304 | | generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
2305 | | generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
2306 | | generalize in match (proj1 ???); #Hpresent_ifthenelse ] |
---|
2307 | (* Exhibit simulation of condition evaluation *) |
---|
2308 | lapply (eval_expr_sim … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) * #Hsim #_ |
---|
2309 | [ lapply (Hsim (Expr cond_desc Tvoid) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) |
---|
2310 | | lapply (Hsim (Expr cond_desc (Tint sz sg)) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) |
---|
2311 | | lapply (Hsim (Expr cond_desc (Tstruct structname fieldspec)) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) |
---|
2312 | | lapply (Hsim (Expr cond_desc (Tunion unionname fieldspec)) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) ] |
---|
2313 | * #cm_val_cond * #Hcm_eval_cond #Hvalue_eq >Hcm_eval_cond |
---|
2314 | whd in match (m_bind ?????); |
---|
2315 | >(eval_bool_of_val_to_Cminor … Hvalue_eq … Hcl_bool_of_val) |
---|
2316 | normalize nodelta whd |
---|
2317 | [ generalize in match (proj1 ???); #Hnoise' |
---|
2318 | generalize in match (conj ????); #Hnoise'' |
---|
2319 | | generalize in match (proj1 ???); #Hnoise' |
---|
2320 | generalize in match (conj ????); #Hnoise'' |
---|
2321 | | generalize in match (proj1 ???); #Hnoise' |
---|
2322 | generalize in match (conj ????); #Hnoise'' |
---|
2323 | | generalize in match (proj1 ???); #Hnoise' |
---|
2324 | generalize in match (conj ????); #Hnoise'' ] |
---|
2325 | @conj try @conj |
---|
2326 | [ 3,6,9,12: #Habsurd destruct (Habsurd) |
---|
2327 | | 1,4,7,10: normalize >append_nil @refl |
---|
2328 | | 2,5,8,11: |
---|
2329 | cut (lset_inclusion (identifier Label) (labels_of cm_body) (labels_of (f_body cm_f))) |
---|
2330 | [ 1,3,5,7: |
---|
2331 | lapply Hlabel_inclusion |
---|
2332 | @transitive_lset_inclusion |
---|
2333 | @cons_preserves_inclusion |
---|
2334 | @lset_inclusion_union %1 |
---|
2335 | @lset_inclusion_union %1 |
---|
2336 | @lset_inclusion_union %1 |
---|
2337 | @reflexive_lset_inclusion ] |
---|
2338 | #Hlabels_of_body |
---|
2339 | cut (Exists (identifier Label) (λl'.l'=entry_label) (labels_of (f_body cm_f))) |
---|
2340 | [ 1,3,5,7: @(lset_inclusion_Exists ????? Hlabel_inclusion) |
---|
2341 | %1 @refl ] |
---|
2342 | #Hentry_exists |
---|
2343 | cut (Exists (identifier Label) (λl'.l'=exit_label) (labels_of (f_body cm_f))) |
---|
2344 | [ 1,3,5,7: @(lset_inclusion_Exists ????? Hlabel_inclusion) |
---|
2345 | %2 @Exists_append_r %1 @refl ] |
---|
2346 | #Hexit_exists |
---|
2347 | @(CMR_normal … Htrans_body) try assumption |
---|
2348 | @(ClCm_cont_while … (sym_eq … Hmk_label_eq) … Htrans_body) try assumption |
---|
2349 | try @refl |
---|
2350 | [ 1,4,7,10: @eq_to_jmeq assumption |
---|
2351 | | 2,5,8,11: |
---|
2352 | @conj try assumption @conj @conj try assumption @conj @conj try assumption |
---|
2353 | try @conj try assumption try @conj try assumption |
---|
2354 | try @conj try assumption try @conj try assumption |
---|
2355 | | *: (* find_label_always *) |
---|
2356 | (* TODO /!\ implement necessary invariant on label lookup *) |
---|
2357 | @cthulhu |
---|
2358 | ] |
---|
2359 | ] |
---|
2360 | | 2,4,6,8: (* cond = false: stop looping *) |
---|
2361 | #Hcl_bool_of_val normalize nodelta #Heq destruct (Heq) |
---|
2362 | %{5} whd whd in ⊢ (??%?); normalize nodelta |
---|
2363 | [ generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
2364 | | generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
2365 | | generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
2366 | | generalize in match (proj1 ???); #Hpresent_ifthenelse ] |
---|
2367 | (* Exhibit simulation of condition evaluation *) |
---|
2368 | lapply (eval_expr_sim … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) * #Hsim #_ |
---|
2369 | [ lapply (Hsim (Expr cond_desc Tvoid) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) |
---|
2370 | | lapply (Hsim (Expr cond_desc (Tint sz sg)) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) |
---|
2371 | | lapply (Hsim (Expr cond_desc (Tstruct structname fieldspec)) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) |
---|
2372 | | lapply (Hsim (Expr cond_desc (Tunion unionname fieldspec)) … Htranslate_cond ?? Hpresent_ifthenelse Hcl_exec_cond) ] |
---|
2373 | * #cm_val_cond * #Hcm_eval_cond #Hvalue_eq >Hcm_eval_cond |
---|
2374 | whd in match (m_bind ?????); |
---|
2375 | >(eval_bool_of_val_to_Cminor … Hvalue_eq … Hcl_bool_of_val) normalize nodelta whd |
---|
2376 | [ generalize in match (proj2 ???); #Hnoise' |
---|
2377 | generalize in match (proj2 ???); #Hnoise'' |
---|
2378 | | generalize in match (proj2 ???); #Hnoise' |
---|
2379 | generalize in match (proj2 ???); #Hnoise'' |
---|
2380 | | generalize in match (proj2 ???); #Hnoise' |
---|
2381 | generalize in match (proj2 ???); #Hnoise'' |
---|
2382 | | generalize in match (proj2 ???); #Hnoise' |
---|
2383 | generalize in match (proj2 ???); #Hnoise'' ] |
---|
2384 | @conj try @conj try @conj |
---|
2385 | [ 1,4,7,10: normalize >append_nil >append_nil @refl |
---|
2386 | | 2,5,8,11: |
---|
2387 | @(CMR_normal … Htranslate_function … DoNotConvert) try assumption |
---|
2388 | try @refl try @(env_below_freshgen_preserved_by_translation … Henv_below Htrans_body) |
---|
2389 | | *: #Habsurd destruct (Habsurd) ] |
---|
2390 | ] |
---|
2391 | | 3: (* Call *) |
---|
2392 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2393 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
2394 | (* introduce everything *) |
---|
2395 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2396 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2397 | #flag * * * * #Hstmt_inv #Hlabels_translated #Htmps_preserved #Hreturn_ok #Hlabel_wf |
---|
2398 | (* generalize away ugly proof *) |
---|
2399 | generalize in ⊢ (∀_:(???(??(????%))).?); #Hugly |
---|
2400 | #Htranslate #Hlabel_inclusion #tmpenv #Htmpenv #Hcont_rel #Em |
---|
2401 | #Htmp_vars_well_allocated |
---|
2402 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id |
---|
2403 | #Hframe_spec #Henv_below #Hclight_normal #Hnot_labeleld |
---|
2404 | (* back to unfolding Clight execution *) |
---|
2405 | cases (bind_inversion ????? Htranslate) -Htranslate * |
---|
2406 | #ef #Hexpr_vars_ef * #Htranslate_ef normalize nodelta #Htranslate |
---|
2407 | cases (bind_inversion ????? Htranslate) -Htranslate * |
---|
2408 | #ef' #Hexpr_vars_local_ef' * #Htyp_should_eq_ef |
---|
2409 | cases (typ_should_eq_inversion (typ_of_type (typeof func)) ASTptr … Htyp_should_eq_ef) |
---|
2410 | -Htyp_should_eq_ef #Htyp_equality_ef |
---|
2411 | #Heq_ef_ef' #Htranslate |
---|
2412 | cases (bind_inversion ????? Htranslate) -Htranslate * |
---|
2413 | #cm_args #Hall_variables_from_args_local * |
---|
2414 | whd in ⊢ ((???%) → ?); #Hargs_spec |
---|
2415 | @(match retv |
---|
2416 | return λx. retv = x → ? |
---|
2417 | with |
---|
2418 | [ None ⇒ λHretv. ? |
---|
2419 | | Some lhs ⇒ λHretv. ? |
---|
2420 | ] (refl ? retv)) |
---|
2421 | normalize nodelta |
---|
2422 | [ 2: (* return something *) |
---|
2423 | #Hdest cases (bind_inversion ????? Hdest) -Hdest #dest * |
---|
2424 | inversion dest normalize nodelta |
---|
2425 | [ (* register dest *) #var_id #His_local @(jmeq_absorb ?????) #Hdest |
---|
2426 | #Htranslate_dest whd in ⊢ ((???%) → ?); #Heq destruct (Heq) |
---|
2427 | (* make explicit the nature of lhs, allowing to prove that no trace is emitted *) |
---|
2428 | lapply (translate_dest_id_inversion … Htranslate_dest) #Hlhs_eq |
---|
2429 | | * #cm_expr #Hexpr_vars_cm #Hdest #Htranslate_dest #Hgensym |
---|
2430 | lapply (breakup_dependent_match_on_pairs ?????? Hgensym) -Hgensym |
---|
2431 | * #ret_var * #new_gensym * #Heq_alloc_tmp * #_ #Hgensym |
---|
2432 | lapply (breakup_dependent_match_on_pairs ?????? Hgensym) -Hgensym |
---|
2433 | * #tmp_var * #new_gensym' * #Heq_alloc_tmp' * #_ |
---|
2434 | generalize in ⊢ ((??(?? (????%) )?) → ?); #Hstmt_inv_after_gensym |
---|
2435 | whd in ⊢ ((???%) → ?); #Heq destruct (Heq) |
---|
2436 | ] |
---|
2437 | | 1: (* return void *) |
---|
2438 | generalize in ⊢ ((??(??(????%))?) → ?); #Hugly2 |
---|
2439 | whd in ⊢ ((???%) → ?); #Heq destruct (Heq) ] |
---|
2440 | (* Now, execute the Clight call *) |
---|
2441 | #s2 #tr #Htranslate |
---|
2442 | cases (bindIO_inversion ??????? Htranslate) -Htranslate * |
---|
2443 | #CL_callee_val #CL_callee_trace * #Hexec_CL_callee normalize nodelta |
---|
2444 | whd in ⊢ ((???%) → ?); #Htranslate |
---|
2445 | cases (bindIO_inversion ??????? Htranslate) -Htranslate * |
---|
2446 | #CL_args #CL_args_trace * #Hexec_CL_args #Htranslate |
---|
2447 | cases (bindIO_inversion ??????? Htranslate) -Htranslate |
---|
2448 | * #CL_callee_fundef #CL_callee_id * #Hfind_funct |
---|
2449 | (* We've got the CL fundef. Extract a function pointer out of it. *) |
---|
2450 | lapply (opt_to_io_Value ?????? Hfind_funct) -Hfind_funct #Hfind_funct |
---|
2451 | cases (find_funct_inversion ???? Hfind_funct) |
---|
2452 | #CL_callee_ptr * * * #HCL_callee_eq destruct (HCL_callee_eq) |
---|
2453 | (* Done. Now stash the resulting properties of this pointer in the context. *) |
---|
2454 | #HCL_callee_ptr_offset_eq_zero #HCL_callee_ptr_region_eq_Code |
---|
2455 | (* Some more properties, that should stay hidden. XXX we discard them, this should not hinder the proof *) |
---|
2456 | * #block_id * #Hblock_id_neg #Hlookup -Hlookup -Hblock_id_neg -block_id |
---|
2457 | (* Now, break up a safety check for the type of the function and finally, execute the |
---|
2458 | * CL lvalue supposed to store the result of the function call. This will yield a pointer |
---|
2459 | * that will be stored in the Callstate, until the function call returns and we store te |
---|
2460 | * result inside it. Of course, this does not apply to the case wich returns void. *) |
---|
2461 | #Htranslate |
---|
2462 | cases (bindIO_inversion ??????? Htranslate) -Htranslate #Htype_of_fundef * |
---|
2463 | #Hassert_type_eq |
---|
2464 | [ 1,2: (* Cases where we return something. *) |
---|
2465 | #Htranslate |
---|
2466 | cases (bindIO_inversion ??????? Htranslate) -Htranslate * * |
---|
2467 | #CL_lvalue_block #CL_lvalue_offset #CL_lvalue_trace * |
---|
2468 | whd in ⊢ ((???%) → (??%%) → ?); |
---|
2469 | [ >Hlhs_eq #HCL_exec_lvalue |
---|
2470 | (* The trace is empty since we execute a variable *) |
---|
2471 | cut (CL_lvalue_trace = []) |
---|
2472 | [ lapply (res_to_io ????? HCL_exec_lvalue) |
---|
2473 | #H' whd in H':(??%?); cases (lookup ????) in H'; normalize nodelta |
---|
2474 | [ 2: #b #Heq destruct (Heq) @refl |
---|
2475 | | #H cases (bind_inversion ????? H) #H24 * #H27 #H28 |
---|
2476 | whd in H28:(???%); destruct (H28) @refl ] |
---|
2477 | ] #H destruct (H) |
---|
2478 | | #HCL_exec_lvalue ] |
---|
2479 | | 3: ] |
---|
2480 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
2481 | (* We have reached the final Clight state. Now execute the Cminor transalted code. *) |
---|
2482 | [ 1: (* Return to a variable *) |
---|
2483 | %{1} whd whd in ⊢ (??%?); normalize nodelta |
---|
2484 | | 2: (* Return to memory location. Need to create a tmp CM local variable to store the |
---|
2485 | * lvalue ptr (otherwise trace does not match CL). *) |
---|
2486 | %{5} whd whd in ⊢ (??%?); normalize nodelta |
---|
2487 | whd in match (eval_expr ???????); |
---|
2488 | whd in match (m_bind ?????); |
---|
2489 | (* Evalue Cminor lvalue. Need to feed some invariants to the simulation lemma, that |
---|
2490 | * we bake here and now. *) |
---|
2491 | cut (expr_vars ASTptr cm_expr |
---|
2492 | (λid:ident.λty:typ.present SymbolTag val cm_env id)) |
---|
2493 | [ cases sInv * * * * * * * #_ #H #_ #_ #_ @H ] #Hexpr_vars_cut |
---|
2494 | (* Apply simulation lemma for lvalues *) |
---|
2495 | lapply (translate_dest_MemDest_simulation … Htranslate_dest HCL_exec_lvalue) |
---|
2496 | try assumption try @refl |
---|
2497 | * #CM_lvalue * #HCM_eval_lvalue >HCM_eval_lvalue #Hvalue_eq_lvalues |
---|
2498 | normalize nodelta generalize in match (proj1 ???); #Htmp_var_present |
---|
2499 | (* Make explicit the fact that the CM lvalue is a pointer *) |
---|
2500 | cases (value_eq_ptr_inversion … Hvalue_eq_lvalues) #CM_lvalue_ptr * #HCM_value_ptr_eq #HCM_lvalue_ptr_trans |
---|
2501 | >HCM_value_ptr_eq |
---|
2502 | lapply (Htmp_vars_well_allocated … tmp_var Htmp_var_present (Tpointer (typeof lhs)) ? (Vptr CM_lvalue_ptr) ?) |
---|
2503 | [ 1: normalize cases CM_lvalue_ptr #b #o %3 |
---|
2504 | | 2: lapply (alloc_tmp_in_genlist … (sym_eq ??? Heq_alloc_tmp) (sym_eq ??? Heq_alloc_tmp')) |
---|
2505 | #Hexists' @(lset_inclusion_Exists … Hexists' Htmpenv) |
---|
2506 | ] |
---|
2507 | * #CM_mem_after_store * #Hstorev #Hnew_inj >Hstorev |
---|
2508 | whd in match (m_bind ?????); normalize nodelta |
---|
2509 | whd whd in ⊢ (??%?); normalize nodelta |
---|
2510 | | 3: %{1} whd whd in ⊢ (??%?); normalize nodelta |
---|
2511 | ] |
---|
2512 | (* cleanup ugliness *) |
---|
2513 | [ 1: generalize in match (proj2 (present ????) (expr_vars ???) (proj1 ???)); |
---|
2514 | | 2: generalize in match (proj2 (present ????) (expr_vars ???) (proj1 ???)); |
---|
2515 | | 3: generalize in match (proj2 True ??); ] |
---|
2516 | #Hexpr_vars_present_ef' |
---|
2517 | [ 1,3: |
---|
2518 | cases (eval_expr_sim … INV' … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) #Hsim_expr #_ |
---|
2519 | cut (expr_vars (typ_of_type (typeof func)) ef |
---|
2520 | (λid:ident.λty:typ.present SymbolTag val cm_env id)) |
---|
2521 | [ 1,3: lapply Heq_ef_ef' lapply Hexpr_vars_ef lapply ef >Htyp_equality_ef |
---|
2522 | #ef #Hexpr_vars_ef @(jmeq_absorb ?????) #Heq destruct (Heq) |
---|
2523 | @Hexpr_vars_present_ef' ] |
---|
2524 | #Hexpr_vars_present_ef |
---|
2525 | lapply (Hsim_expr … Htranslate_ef … Hexpr_vars_present_ef … Hexec_CL_callee) |
---|
2526 | -Hsim_expr * #cm_func_ptr_val * #Heval_func #Hvalue_eq_func |
---|
2527 | cut (eval_expr cm_ge ASTptr ef' cm_env Hexpr_vars_present_ef' |
---|
2528 | stackptr cm_m = OK (trace×val) 〈CL_callee_trace,cm_func_ptr_val〉) |
---|
2529 | [ 1,3: |
---|
2530 | lapply Heq_ef_ef' lapply Heval_func lapply Hexpr_vars_ef lapply Hexpr_vars_local_ef' |
---|
2531 | lapply Hexpr_vars_present_ef lapply ef lapply Hexpr_vars_present_ef' lapply ef' |
---|
2532 | <Htyp_equality_ef #ef' #HA #ef #HB #HC #HD #HE |
---|
2533 | @(jmeq_absorb ?????) #Heq destruct (Heq) @HE ] |
---|
2534 | -Heval_func #Heval_func >Heval_func |
---|
2535 | | 2: (* treat case 2 as special, since the type differs slightly *) |
---|
2536 | letin cm_env' ≝ (update_present SymbolTag val cm_env tmp_var Htmp_var_present (Vptr CM_lvalue_ptr)) |
---|
2537 | cut (memory_matching Em cl_ge cm_ge cl_m cm_m cl_env cm_env' INV' stackptr alloc_type) |
---|
2538 | (* cut (memory_matching Em cl_ge cm_ge cl_m CM_mem_after_store cl_env cm_env' INV' stackptr alloc_type) *) |
---|
2539 | [ (* Proving preservation of the memory matching under store in "new" cminor memory zone. |
---|
2540 | Use the property that the ident [tmp_var] is not in the clight env. *) |
---|
2541 | #id lapply (Hmatching id) |
---|
2542 | @(match (lookup ??? id) |
---|
2543 | return λx. (lookup ??? id = x) → ? |
---|
2544 | with |
---|
2545 | [ None ⇒ λHeq_lookup. ? |
---|
2546 | | Some blo ⇒ λHeq_lookup. ? |
---|
2547 | ] (refl ? (lookup ??? id))) |
---|
2548 | [ 1: #H @H ] normalize nodelta |
---|
2549 | cases (lookup ??? id) normalize nodelta |
---|
2550 | [ 1: #H @H ] * #var_ty #cl_ty cases var_ty normalize nodelta |
---|
2551 | [ #r #H @H |
---|
2552 | | #n #H @H |
---|
2553 | | #H #v #Hload_value_of_type lapply (H ? Hload_value_of_type) |
---|
2554 | * #v' * #Hlookup_cm #Hvalue_eq %{v'} @conj try @Hvalue_eq |
---|
2555 | lapply (alloc_tmp_env_invariant ?????? (sym_eq ??? Heq_alloc_tmp) Henv_below) #Henv_below' |
---|
2556 | lapply (generated_id_not_in_env ???????? Henv_below' … Heq_lookup (sym_eq ??? Heq_alloc_tmp')) |
---|
2557 | #Hneq <(update_lookup_opt_other … (Vptr CM_lvalue_ptr) … cm_env … Htmp_var_present … Hneq) |
---|
2558 | assumption ] ] #Hmatching' |
---|
2559 | cases (eval_expr_sim … INV' … Halloc_hyp ? cm_env' Hcl_env_hyp … Hinjection stackptr Hmatching') |
---|
2560 | #Hsim_expr #_ |
---|
2561 | generalize in match (proj2 ???); #Hall_present |
---|
2562 | generalize in match (proj1 ???); #Hret_present |
---|
2563 | generalize in match (proj2 ???); #Hstore_inv |
---|
2564 | generalize in match (conj ????); #Hstmt_inv |
---|
2565 | (* cut (eval_expr cm_ge ? ef' cm_env' ? stackptr cm_m = |
---|
2566 | (eval_expr cm_ge ASTptr ef' cm_env' ? stackptr cm_m)) try assumption try @refl |
---|
2567 | #Heval_expr_rewrite >Heval_expr_rewrite -Heval_expr_rewrite *) |
---|
2568 | lapply (Hsim_expr … Htranslate_ef … (Vptr CL_callee_ptr) CL_callee_trace ??) |
---|
2569 | try assumption |
---|
2570 | [ lapply Hexpr_vars_present_ef' lapply Heq_ef_ef' lapply Hexpr_vars_ef lapply Hexpr_vars_local_ef' |
---|
2571 | lapply ef >Htyp_equality_ef #ef #HA #HB @(jmeq_absorb ?????) #Heq destruct (Heq) #x @x ] |
---|
2572 | * #CM_callee_ptr * #Heval_func_cm #Hvalue_eq_func |
---|
2573 | (* And some more shuffling types around to match the goal *) |
---|
2574 | cut (eval_expr cm_ge ? ef' cm_env' Hexpr_vars_present_ef' stackptr cm_m = OK ? 〈CL_callee_trace,CM_callee_ptr〉) |
---|
2575 | [ lapply Heval_func_cm -Heval_func_cm |
---|
2576 | generalize in ⊢ ((??(?????%??)?) → ?); |
---|
2577 | lapply Heq_ef_ef' -Heq_ef_ef' |
---|
2578 | lapply Hexpr_vars_ef -Hexpr_vars_ef |
---|
2579 | lapply Hexpr_vars_local_ef' -Hexpr_vars_local_ef' |
---|
2580 | lapply Hexpr_vars_present_ef' |
---|
2581 | lapply ef >Htyp_equality_ef #ef0 #HA #HB #HC @(jmeq_absorb ?????) |
---|
2582 | #Heq destruct (Heq) #H1 #H2 @H2 ] |
---|
2583 | #Heval_cm_func >Heval_cm_func ] |
---|
2584 | whd in match (m_bind ?????); |
---|
2585 | lapply (trans_fn … INV' … Hfind_funct) |
---|
2586 | * #tmp_u * #cminor_fundef * #Hglobals_fresh_for_tmp_u * #Hfundef_fresh_for_tmp_u * |
---|
2587 | #Htranslate_fundef #Hfind_funct_cm |
---|
2588 | lapply (value_eq_ptr_inversion … Hvalue_eq_func) * #cm_func_ptr * #Hcm_func_ptr |
---|
2589 | whd in ⊢ ((??%?) → ?); |
---|
2590 | cases CL_callee_ptr in Hfind_funct Hfind_funct_cm HCL_callee_ptr_region_eq_Code HCL_callee_ptr_offset_eq_zero; |
---|
2591 | #cm_block #cm_off #Hfind_funct #Hfind_funct_cm #Hregion_is_code #Hpoff_eq_zero destruct (Hpoff_eq_zero) |
---|
2592 | whd in ⊢ ((??%?) → ?); |
---|
2593 | [ 1,2: >(HEm_fn_id … cm_block Hregion_is_code) |
---|
2594 | | 3: >(HEm_fn_id … cm_block Hregion_is_code) ] |
---|
2595 | normalize nodelta |
---|
2596 | cases cm_func_ptr in Hcm_func_ptr; #cm_block' #cm_off' |
---|
2597 | #Hcm_func_ptr #Heq destruct (Hcm_func_ptr Heq) |
---|
2598 | [ 1,2: >addition_n_0 >mk_offset_offv_id |
---|
2599 | | 3: ] |
---|
2600 | >Hfind_funct_cm |
---|
2601 | whd in match (opt_to_res ???); normalize nodelta |
---|
2602 | (* Again, isolate cases by type similarity *) |
---|
2603 | [ 1,2: |
---|
2604 | cut (All (𝚺t:typ.CMexpr t) |
---|
2605 | (λx:𝚺t:typ.expr t.( |
---|
2606 | match x with |
---|
2607 | [ mk_DPair ty e ⇒ |
---|
2608 | expr_vars ty e |
---|
2609 | (λid:ident |
---|
2610 | .λty0:typ.present SymbolTag val cm_env id)])) cm_args) |
---|
2611 | [ 1: cases sInv * * normalize nodelta * #_ #_ #Hall #_ #_ @Hall |
---|
2612 | | 3: cases sInv * * normalize nodelta * #_ #_ #Hall #_ #_ @Hall ] |
---|
2613 | #Hall |
---|
2614 | cases (eval_exprlist_simulation … Halloc_hyp Hcl_env_hyp Hinjection Hmatching ???? Hexec_CL_args Hargs_spec Hall) |
---|
2615 | #cm_values * #Hcm_exec_list #Hcl_cm_values_eq >Hcm_exec_list |
---|
2616 | | 3: |
---|
2617 | lapply (eval_exprlist_simulation … Halloc_hyp Hcl_env_hyp Hinjection ????? Hexec_CL_args Hargs_spec ?) |
---|
2618 | try assumption |
---|
2619 | * #cm_values * #Hcm_exec_list #Hcl_cm_values_eq >Hcm_exec_list |
---|
2620 | ] |
---|
2621 | whd in match (m_bind ?????); normalize nodelta whd @conj |
---|
2622 | [ 2,4,6: #Habsurd destruct (Habsurd) ] |
---|
2623 | @conj |
---|
2624 | [ 1,3,5: normalize try @refl >append_nil >append_nil @refl ] |
---|
2625 | [ 1: generalize in match (proj1 ? (expr_vars ???) (proj1 ???)); #Hugly_pres |
---|
2626 | | 2: generalize in match (proj1 ? (expr_vars ???) (proj1 ???)); #Hugly_pres |
---|
2627 | | 3: ] |
---|
2628 | [ 3: @(CMR_call … Hinjection … HEm_fn_id) try assumption |
---|
2629 | lapply (alloc_tmp_monotonic … (sym_eq ??? Heq_alloc_tmp)) #Hincl1 |
---|
2630 | lapply (alloc_tmp_monotonic … (sym_eq ??? Heq_alloc_tmp')) #Hincl2 |
---|
2631 | lapply (transitive_lset_inclusion … Hincl1 Hincl2) #Hincl3 |
---|
2632 | try /2 by transitive_lset_inclusion/ |
---|
2633 | lapply Htranslate_fundef -Htranslate_fundef |
---|
2634 | lapply Hfundef_fresh_for_tmp_u -Hfundef_fresh_for_tmp_u |
---|
2635 | #Hfundef_fresh_for_tmp_u #Htranslate_fundef |
---|
2636 | @ClCm_cont_call_store assumption |
---|
2637 | | 1,2: (* no return or return to CM local variable *) |
---|
2638 | @(CMR_call … Hinjection … HEm_fn_id) try assumption |
---|
2639 | @(ClCm_cont_call_nostore … Hcont_rel) try assumption |
---|
2640 | whd %{CL_lvalue_block} %{CL_lvalue_offset} %{(typeof lhs)} %{var_id} |
---|
2641 | % % |
---|
2642 | ] |
---|
2643 | | 1: (* Skip *) |
---|
2644 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2645 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
2646 | (* introduce everything *) |
---|
2647 | #fInv #sInv #kInv |
---|
2648 | #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2649 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2650 | #flag * * * * #Hstmt_inv #Hlabels_translated #Htmps_preserved |
---|
2651 | #Hreturn_ok #Hlabel_wf generalize in match (conj ????); #Hugly |
---|
2652 | whd in ⊢ ((??%?) → ?); #Heq_translate #Hlabel_inclusion |
---|
2653 | #tmpenv #Htmpenv #Hcont_rel |
---|
2654 | lapply Heq_translate -Heq_translate |
---|
2655 | lapply Hugly -Hugly |
---|
2656 | lapply Hlabel_wf -Hlabel_wf |
---|
2657 | lapply Hreturn_ok -Hreturn_ok |
---|
2658 | lapply Htmps_preserved -Htmps_preserved |
---|
2659 | lapply Hlabels_translated -Hlabels_translated |
---|
2660 | lapply Hstmt_inv -Hstmt_inv |
---|
2661 | lapply Htranslate_function -Htranslate_function |
---|
2662 | lapply Hfresh_globals -Hfresh_globals |
---|
2663 | lapply Hfresh_function -Hfresh_function |
---|
2664 | lapply Htarget_type -Htarget_type |
---|
2665 | lapply kInv -kInv |
---|
2666 | lapply sInv -sInv |
---|
2667 | lapply fInv -fInv |
---|
2668 | lapply stmt_univ -stmt_univ |
---|
2669 | lapply Htmpenv -Htmpenv |
---|
2670 | lapply stmt_univ' -stmt_univ' |
---|
2671 | lapply Hlabel_inclusion -Hlabel_inclusion |
---|
2672 | (* case analysis on continuation *) |
---|
2673 | inversion Hcont_rel |
---|
2674 | [ (* Kstop continuation *) |
---|
2675 | (* simplifying the goal using outcome of the inversion *) |
---|
2676 | #kcl_ge #kcm_ge #kINV #kcl_f #kcm_f #ktarget_type #kcl_env #kcm_env #kcm_m #kalloc_type #ktmpenv #kstack #Hkstack |
---|
2677 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2678 | destruct (HA HB) |
---|
2679 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2680 | destruct (HC HD HE) |
---|
2681 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH @(jmeq_absorb ?????) #HI |
---|
2682 | destruct (HF HG HH HI) |
---|
2683 | @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK @(jmeq_absorb ?????) #HL @(jmeq_absorb ?????) #HM |
---|
2684 | @(jmeq_absorb ?????) #HN |
---|
2685 | destruct (HJ HK HL HM HN) #_ |
---|
2686 | (* re-introduce everything *) |
---|
2687 | #Hlabel_inclusion |
---|
2688 | #stmt_univ' #Htmpenv #stmt_univ #fInv #sInv #kInv #Htarget_type #Hfresh_function #Hfresh_globals |
---|
2689 | #Htranslate_function #Hstmt_inv #Hlabels_translated #Htmps_preserved |
---|
2690 | #Hreturn_ok #Hlabel_wf |
---|
2691 | #Hugly generalize in match (conj ????); #Hugly' |
---|
2692 | (* reduce statement translation function *) |
---|
2693 | #Heq_translate |
---|
2694 | (* In this simple case, trivial translation *) |
---|
2695 | destruct (Heq_translate) |
---|
2696 | #Em #Htmp_vars_well_allocated |
---|
2697 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Henv_below |
---|
2698 | #Hclight_normal #Hnot_labeleld |
---|
2699 | (* unfold the clight execution *) |
---|
2700 | #s2 #tr whd in ⊢ ((??%?) → ?); |
---|
2701 | inversion (fn_return cl_f) normalize nodelta |
---|
2702 | [ | #sz #sg | #ptr_ty | #array_ty #array_sz | #domain #codomain |
---|
2703 | | #structname #fieldspec | #unionname #fieldspec | #id ] |
---|
2704 | #Hfn_return whd in ⊢ ((??%?) → ?); #Heq destruct (Heq) |
---|
2705 | %{1} whd @conj try @conj try @refl |
---|
2706 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
2707 | (* Use the memory injection stuff to produce a new memory injection *) |
---|
2708 | cut (memory_inj Em (free_list cl_m (blocks_of_env kcl_env)) (free kcm_m stackptr)) |
---|
2709 | [ @(freelist_memory_inj_m1_m2 Em cl_m kcm_m |
---|
2710 | (free_list cl_m (blocks_of_env kcl_env)) |
---|
2711 | (free kcm_m stackptr) Hinjection (blocks_of_env kcl_env) stackptr ? (refl ??) (refl ??)) |
---|
2712 | assumption ] |
---|
2713 | #Hinjection' |
---|
2714 | @(CMR_return … Kend … Halloc_hyp Hcl_env_hyp … Hinjection') try assumption |
---|
2715 | [ 2: #b lapply (Hmatching b) |
---|
2716 | cases (lookup ?? kcl_env b) normalize nodelta |
---|
2717 | [ 1: #H @H |
---|
2718 | | 2: #b' cases (lookup ?? kalloc_type b) normalize nodelta |
---|
2719 | [ 1: #H @H |
---|
2720 | | 2: * #kalloc_type #ty normalize nodelta |
---|
2721 | cases kalloc_type normalize nodelta try // |
---|
2722 | #H #v #Hload_after_free @H |
---|
2723 | @(load_value_after_free_list_inversion … Hload_after_free) |
---|
2724 | ] |
---|
2725 | ] |
---|
2726 | | 1: @(tmp_vars_well_allocated_conserved_by_frame_free … Hmatching … Htmp_vars_well_allocated) |
---|
2727 | | 3: @ClCm_cont_stop @Hkstack |
---|
2728 | ] |
---|
2729 | | (* Kseq *) |
---|
2730 | #kcl_ge #kcm_ge #kINV #kcl_f #kcm_f #ktarget_type #kstack #kalloc_type #ktmpenv #kcl_s #kcm_s |
---|
2731 | #kcl_env #kcm_env #kcm_m #kcl_k' #kcm_k' #kstmt_univ #kstmt_univ' #klbl_univ #klbl_univ' #klbls #kflag |
---|
2732 | * * * * #kHstmt_inv #kHlabels_translated #kHtmps_preserved |
---|
2733 | #kHreturn_ok #kHlabel_wf #kHeq_translate #kHlabel_inclusion #kHident_inclusion #kHcont_rel #_ |
---|
2734 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2735 | destruct (HA HB) |
---|
2736 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2737 | destruct (HC HD HE) |
---|
2738 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH @(jmeq_absorb ?????) #HI |
---|
2739 | destruct (HF HG HH HI) |
---|
2740 | @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK @(jmeq_absorb ?????) #HL @(jmeq_absorb ?????) #HM |
---|
2741 | @(jmeq_absorb ?????) #HN |
---|
2742 | destruct (HJ HK HL HM HN) #_ |
---|
2743 | #Hlabel_inclusion |
---|
2744 | #stmt_univ' #Htmpenv #stmt_univ #fInv #sInv #kInv #Htarget_type #Hfresh_function #Hfresh_globals |
---|
2745 | #Htranslate_function #Hstmt_inv #Hlabels_translated #Htmps_preserved #Hreturn_ok #Hlabel_wf |
---|
2746 | #Hugly generalize in match (conj ????); #Hugly' |
---|
2747 | (* In this simple case, trivial translation *) |
---|
2748 | #Heq_translate destruct (Heq_translate) #Em |
---|
2749 | #Htmp_vars_well_alloc |
---|
2750 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Henv_below |
---|
2751 | #Hclight_normal #Hnot_labeleld |
---|
2752 | #s2 #tr whd in ⊢ ((??%?) → ?); #Heq destruct (Heq) |
---|
2753 | %{1} whd @conj [ 2: #Habsurd destruct (Habsurd) ] @conj try @refl |
---|
2754 | (* close simulation *) |
---|
2755 | @(CMR_normal … kHeq_translate … kHcont_rel … Hinjection … Hmatching) try assumption |
---|
2756 | (* TODO Invariant on env_below_freshgen *) |
---|
2757 | @cthulhu |
---|
2758 | | (* Kwhile continuation *) |
---|
2759 | #kcl_ge #kcm_ge #kINV #kcl_f #kcm_f #ktarget_type #kstack #kalloc_type #ktmpenv #kcl_env #kcm_env #kcm_m |
---|
2760 | #kcl_k' #kcm_k' #ksz #ksg #kcl_ty #kcl_cond_desc #kcl_body #kHeq_ty #kcm_cond #kcm_body |
---|
2761 | #kentry #kexit #kstmt_univ #kstmt_univ' #klbl_univ #klbl_univ' #klbl_univ'' |
---|
2762 | #klbls #kHtranslate_inv #kHexpr_vars #kHtranslate_expr #kfInv #kHlabel_declared |
---|
2763 | #kHinv #kHmklabels #kHeq_translate #kHlabel_inclusion #kHident_inclusion #kHfind_label |
---|
2764 | (* |
---|
2765 | * * * * #kHentry_declared * * * * |
---|
2766 | * * * #kHcond_vars_declared #Hnoise #Hnoise' #Hnoise'' |
---|
2767 | #kHcont_inv #kHmklabels #kHeq_translate |
---|
2768 | #kHfind_label *) #kHcont_rel #_ |
---|
2769 | @(jmeq_absorb ?????) #HA @(jmeq_absorb ?????) #HB |
---|
2770 | destruct (HA HB) |
---|
2771 | @(jmeq_absorb ?????) #HC @(jmeq_absorb ?????) #HD @(jmeq_absorb ?????) #HE |
---|
2772 | destruct (HC HD HE) |
---|
2773 | @(jmeq_absorb ?????) #HF @(jmeq_absorb ?????) #HG @(jmeq_absorb ?????) #HH |
---|
2774 | @(jmeq_absorb ?????) #HI @(jmeq_absorb ?????) #HJ @(jmeq_absorb ?????) #HK |
---|
2775 | @(jmeq_absorb ?????) #HL @(jmeq_absorb ?????) #HM @(jmeq_absorb ?????) #HN |
---|
2776 | destruct (HF HG HH HI HJ HK HL HM HN) #_ |
---|
2777 | #Hlabel_inclusion |
---|
2778 | #stmt_univ' #Htmpenv #stmt_univ #fInv #sInv #kInv #Htarget_type #Hfresh_function #Hfresh_globals |
---|
2779 | #Htranslate_function #Hstmt_inv #Hlabels_translated #Htmps_preserved #Hreturn_ok #Hlabel_wf |
---|
2780 | #Hugly |
---|
2781 | generalize in match (conj ????); #Hugly' |
---|
2782 | (* In this simple case, trivial translation *) |
---|
2783 | #Heq_translate destruct (Heq_translate) |
---|
2784 | #Em #Htmp_vars_well_allocated |
---|
2785 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching |
---|
2786 | #HEm_fn_id #Hframe_spec #Henv_below |
---|
2787 | #Hclight_normal #Hnot_labeleld |
---|
2788 | #s2 #tr |
---|
2789 | whd in ⊢ ((??%?) → ?); #Heq destruct (Heq) |
---|
2790 | lapply kHfind_label -kHfind_label |
---|
2791 | generalize in ⊢ ((??(????%????)?) → ?); #Hlabel_exists |
---|
2792 | generalize in ⊢ ((???(????%)) → ?); #Hmore_invariant |
---|
2793 | #kHfind_label |
---|
2794 | (* Kwhile cont case *) |
---|
2795 | %{2} whd whd in ⊢ (??%?); normalize nodelta |
---|
2796 | generalize in match (proj2 ???); #Hmore_noise |
---|
2797 | generalize in match (proj1 ???); #Hmore_noise' |
---|
2798 | >kHfind_label normalize nodelta |
---|
2799 | whd @conj try @conj try @refl |
---|
2800 | generalize in match (proj1 ???); #Hvars_present_in_ifthenelse |
---|
2801 | generalize in match (proj2 ???); #Hcont_inv' |
---|
2802 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
2803 | (* go to a special simulation state for while loops *) |
---|
2804 | @(CMR_while … stacksize … Hcl_env_hyp … Hinjection … kHtranslate_expr … kHmklabels … kHeq_translate) |
---|
2805 | try assumption |
---|
2806 | [ 1: (* TODO: lemma on Henv_below. We need to thread freshgens through cont_rel. *) |
---|
2807 | @cthulhu |
---|
2808 | | 2: cases Hmore_invariant * * #_ * * * * #_ #_ * #_ #_ * * #_ #H |
---|
2809 | #_ #_ @H ] |
---|
2810 | | 4,5: (* Continuations for Scall. TODO *) |
---|
2811 | @cthulhu |
---|
2812 | ] |
---|
2813 | | 2: (* Assign *) |
---|
2814 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
2815 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
2816 | (* introduce everything *) |
---|
2817 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
2818 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
2819 | #flag * * * * #Hstmt_inv_cm #Hlabels_translated #Htmps_preserved |
---|
2820 | #Hreturn_ok #Hlabel_wf generalize in match (conj ????); #Hugly #Htranslate |
---|
2821 | #Hlabel_inclusion #tmpenv #Htmpenv #Hcont_rel |
---|
2822 | #Em #Htmp_vars_well_allocated |
---|
2823 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Henv_below |
---|
2824 | #Hclight_normal #Hnot_labeleld |
---|
2825 | lapply Htranslate -Htranslate |
---|
2826 | (* case-split on lhs in order to reduce lvalue production in Cminor *) |
---|
2827 | cases lhs #lhs_ed #lhs_ty |
---|
2828 | cases (expr_is_Evar_id_dec lhs_ed) |
---|
2829 | [ 2: * #var_id #Hlhs_ed destruct (Hlhs_ed) |
---|
2830 | #Htranslate_statement |
---|
2831 | cases (bind_inversion ????? Htranslate_statement) |
---|
2832 | * #cm_rhs #Hexpr_vars_rhs * #Htranslate_rhs #Htranslate_statement' |
---|
2833 | cases (bind_inversion ????? Htranslate_statement') -Htranslate_statement' |
---|
2834 | #lhs_dest * #Htranslate_lhs |
---|
2835 | cases (bind2_eq_inversion ?????? Htranslate_lhs) -Htranslate_lhs |
---|
2836 | #alloctype * #type_of_var * #Hlookup_var_success |
---|
2837 | cases alloctype in Hlookup_var_success; |
---|
2838 | normalize nodelta |
---|
2839 | [ 1: (* Global *) #r |
---|
2840 | #Hlookup_var_success whd in ⊢ ((???%) → ?); #Hlhs_dest_eq |
---|
2841 | destruct (Hlhs_dest_eq) normalize nodelta |
---|
2842 | generalize in match (conj ????); #Hinvariant |
---|
2843 | cases (type_eq_dec ??) |
---|
2844 | [ 2: #Hneq normalize nodelta whd in ⊢ ((??%%) → ?); |
---|
2845 | #Habsurd destruct (Habsurd) ] |
---|
2846 | normalize nodelta whd in match (typeof ?); #Heq_cl_types |
---|
2847 | whd in ⊢ ((???%) → ?); #Heq destruct (Heq) |
---|
2848 | #s2 #tr whd in ⊢ ((??%?) → ?); #Hstep |
---|
2849 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
2850 | * * #cl_blo #cl_off #cl_tr * whd in ⊢ ((??%?) → ?); |
---|
2851 | #Hexec_lvalue #Hstep |
---|
2852 | lapply (res_to_io ????? Hexec_lvalue) -Hexec_lvalue #Hexec_lvalue |
---|
2853 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
2854 | * #cl_rhs_val #cl_trace * #Hexec_rhs #Hstep |
---|
2855 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
2856 | #cl_mem_after_store_lhs * #Hstore |
---|
2857 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
2858 | lapply (opt_to_io_Value ?????? Hstore) -Hstore #Hstore |
---|
2859 | %{1} whd whd in ⊢ (??%?); normalize nodelta |
---|
2860 | generalize in match (proj1 ???); whd in ⊢ (% → ?); * |
---|
2861 | whd in match (eval_expr ???????); |
---|
2862 | whd in match (eval_constant ????); |
---|
2863 | whd in Hexec_lvalue:(??%?); |
---|
2864 | <(eq_sym … INV' var_id) |
---|
2865 | lapply (Hmatching … var_id) |
---|
2866 | cases (lookup ?? cl_env var_id) in Hexec_lvalue; normalize nodelta |
---|
2867 | [ 1: #Heq_find_sym cases (bind_inversion ????? Heq_find_sym) -Heq_find_sym |
---|
2868 | #global_b * #Hopt_to_res lapply (opt_to_res_inversion ???? Hopt_to_res) -Hopt_to_res |
---|
2869 | #Hfind_symbol >Hfind_symbol |
---|
2870 | normalize nodelta |
---|
2871 | whd in ⊢ ((???%) → ?); #Heq destruct (Heq) #Hembed_eq |
---|
2872 | whd in match (m_bind ?????); |
---|
2873 | cases (eval_expr_sim … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) #Hsim_expr #_ |
---|
2874 | lapply (Hsim_expr … Htranslate_rhs … (proj2 ?? (proj1 ?? (proj1 ?? sInv))) Hexec_rhs) |
---|
2875 | * #cm_rhs_val generalize in match (proj2 ???); |
---|
2876 | #Hexpr_vars_rhs * #Heval_expr_rhs #Hvalue_eq_rhs >Heval_expr_rhs |
---|
2877 | whd in match (m_bind ?????); whd in Hstore:(??%?); whd in Hstore:(??%?); |
---|
2878 | cases (store_value_of_type_success_by_value lhs_ty cl_m |
---|
2879 | cl_mem_after_store_lhs cl_blo zero_offset cl_rhs_val Hstore) |
---|
2880 | #Haccess_mode #Hstorev |
---|
2881 | lapply (storen_parallel_aux ??? Hinjection … Hvalue_eq_rhs … Hembed_eq ??? Hstorev) |
---|
2882 | * #cm_mem_after_store_lhs * #Hstoren #Hinj whd in Hstoren:(??%?); |
---|
2883 | whd in Hstoren:(??%?); whd in match (shift_offset ???); |
---|
2884 | >sign_ext_same_size >addition_n_0 |
---|
2885 | whd in match (storev ????); |
---|
2886 | lapply Hstoren whd in match (offset_plus ??); |
---|
2887 | >addition_n_0 -Hstoren |
---|
2888 | >Heq_cl_types #Hstoren >Hstoren |
---|
2889 | whd in match (opt_to_res ???); normalize nodelta |
---|
2890 | whd @conj try @conj try @refl |
---|
2891 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
2892 | generalize in match (conj ????); #Hinv_vars |
---|
2893 | @CMR_normal try assumption |
---|
2894 | [ 2: @refl | *: ] |
---|
2895 | [ 3: @(memory_matching_preserved_by_parallel_stores … Hmatching) |
---|
2896 | | 2: @(well_allocated_preserved_by_parallel_stores … Htmp_vars_well_allocated) |
---|
2897 | | 1: @(clight_cminor_cont_rel_parametric_in_mem … Hcont_rel) ] |
---|
2898 | | 2: #b #Heq destruct (Heq) |
---|
2899 | lapply (opt_to_res_inversion ???? Hlookup_var_success) #Hlookup_aux |
---|
2900 | >Hlookup_aux normalize nodelta @False_ind ] |
---|
2901 | | 2: (* Stack *) |
---|
2902 | #n #Hlookup_var_success |
---|
2903 | whd in ⊢ ((???%) → ?); #Heq destruct (Heq) |
---|
2904 | normalize nodelta whd in ⊢ ((???%) → ?); |
---|
2905 | cases (type_eq_dec ??) normalize nodelta #Htype_eq |
---|
2906 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
2907 | #Heq destruct (Heq) #s2 #tr #Hstep |
---|
2908 | cases (bindIO_inversion ??????? Hstep) |
---|
2909 | * * #cl_lvalue_block #cl_offset #cl_trace * #Hexec_lvalue |
---|
2910 | lapply (res_to_io ????? Hexec_lvalue) -Hexec_lvalue |
---|
2911 | whd in ⊢ ((??%?) → ?); |
---|
2912 | @(match lookup ?? cl_env var_id |
---|
2913 | return λx. (lookup ?? cl_env var_id = x) → ? |
---|
2914 | with |
---|
2915 | [ None ⇒ λH. ? |
---|
2916 | | Some cl_addr ⇒ λH. ? |
---|
2917 | ] (refl ? (lookup ?? cl_env var_id))) |
---|
2918 | normalize nodelta |
---|
2919 | [ (* Contradiction: a stack-allocated variable was necessarily in the environment. TODO *) |
---|
2920 | @cthulhu |
---|
2921 | | #Heq destruct (Heq) |
---|
2922 | lapply (Hmatching var_id) >H normalize nodelta |
---|
2923 | >(opt_to_res_inversion ???? Hlookup_var_success) normalize nodelta |
---|
2924 | #Hembedding_to_stack #Hexec_cl_rhs |
---|
2925 | cases (bindIO_inversion ??????? Hexec_cl_rhs) -Hexec_cl_rhs * |
---|
2926 | #cl_rhs_result #cl_rhs_trace * #Hcl_exec_expr_rhs #Hcl_exec_store |
---|
2927 | cases (bindIO_inversion ??????? Hcl_exec_store) -Hcl_exec_store #cl_mem_after_store |
---|
2928 | * #Hstore_value_of_type lapply (opt_to_io_Value ?????? Hstore_value_of_type) |
---|
2929 | -Hstore_value_of_type |
---|
2930 | #Hstore_value_of_type |
---|
2931 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
2932 | %{1} whd whd in ⊢ (??%?); normalize nodelta |
---|
2933 | whd in match (eval_expr ???????); |
---|
2934 | whd in match (eval_constant ????); |
---|
2935 | whd in match (m_bind ?????); |
---|
2936 | cases (eval_expr_sim … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) #Hsim_expr #_ |
---|
2937 | lapply (Hsim_expr … Htranslate_rhs … (proj2 ?? (proj1 ?? (proj1 ?? sInv))) Hcl_exec_expr_rhs) |
---|
2938 | * #cm_rhs_val generalize in match (proj2 ???); |
---|
2939 | #Hexpr_vars_rhs * #Heval_expr_rhs #Hvalue_eq_rhs >Heval_expr_rhs |
---|
2940 | normalize nodelta -Hsim_expr |
---|
2941 | whd in match (shift_offset ???); >sign_ext_same_size |
---|
2942 | >commutative_addition_n >addition_n_0 |
---|
2943 | whd in Hstore_value_of_type:(??%?); |
---|
2944 | cases (store_value_of_type_success_by_value ? cl_m |
---|
2945 | cl_mem_after_store ?? cl_rhs_result Hstore_value_of_type) |
---|
2946 | whd in match (typeof ?) in ⊢ ((??%%) → (??%?) → ?); |
---|
2947 | #Haccess_mode #Hstorev -Hstore_value_of_type |
---|
2948 | lapply (storen_parallel_aux ??? Hinjection … Hvalue_eq_rhs … Hembedding_to_stack ??? Hstorev) |
---|
2949 | * #cm_mem_after_store_lhs * #Hstoren #Hinj whd in Hstoren:(??%?); |
---|
2950 | >offset_plus_0 in Hstoren; #Hstorev' |
---|
2951 | whd in match (storev ????); |
---|
2952 | lapply Htype_eq whd in match (typeof ?) in ⊢ ((??%?) → ?); #Htype_eq' |
---|
2953 | <Htype_eq' >Hstorev' |
---|
2954 | whd in match (m_bind ?????); normalize nodelta |
---|
2955 | whd @conj try @conj try @refl |
---|
2956 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
2957 | @(CMR_normal … Halloc_hyp) try assumption |
---|
2958 | try @refl |
---|
2959 | try @(memory_matching_preserved_by_parallel_stores … Hmatching) |
---|
2960 | try @(well_allocated_preserved_by_parallel_stores … Htmp_vars_well_allocated) |
---|
2961 | @(clight_cminor_cont_rel_parametric_in_mem … Hcont_rel) |
---|
2962 | ] |
---|
2963 | | 3: (* Local *) |
---|
2964 | #Hlookup_var_success |
---|
2965 | cases (typ_eq ??) normalize nodelta #Htyp_eq |
---|
2966 | whd in ⊢ ((???%) → ?); |
---|
2967 | #Heq destruct (Heq) normalize nodelta -Htranslate_statement |
---|
2968 | #Htranslate |
---|
2969 | cases (bind_inversion ????? Htranslate) -Htranslate |
---|
2970 | * #cm_expr #Hexpr_vars * #Htyp_should_eq |
---|
2971 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
2972 | cases (typ_should_eq_inversion (typ_of_type (typeof rhs)) (typ_of_type lhs_ty) … Htyp_should_eq) |
---|
2973 | -Htyp_should_eq #Htyp_eq lapply Hexpr_vars_rhs lapply Hexpr_vars |
---|
2974 | -Hlabel_wf -Hreturn_ok -Hlabels_translated -Hstmt_inv_cm lapply sInv |
---|
2975 | lapply cm_expr -cm_expr <Htyp_eq #cm_expr #sInv #Hexpr_vars #Hexpr_vars' |
---|
2976 | @(jmeq_absorb ?????) #Heq destruct (Heq) |
---|
2977 | #s2 #tr whd in ⊢ ((??%?) → ?); #Hcl_exec |
---|
2978 | cases (bindIO_inversion ??????? Hcl_exec) |
---|
2979 | * * #cl_blo #cl_off #cl_trace * |
---|
2980 | whd in ⊢ ((???%) → ?); |
---|
2981 | #Hexec_lvalue lapply (res_to_io ????? Hexec_lvalue) -Hexec_lvalue |
---|
2982 | whd in ⊢ ((??%?) → ?); |
---|
2983 | @(match lookup ?? cl_env var_id |
---|
2984 | return λx. (lookup ?? cl_env var_id = x) → ? |
---|
2985 | with |
---|
2986 | [ None ⇒ λH. ? |
---|
2987 | | Some cl_addr ⇒ λH. ? |
---|
2988 | ] (refl ? (lookup ?? cl_env var_id))) |
---|
2989 | normalize nodelta |
---|
2990 | [ (* Contradiction: a register-allocated variable was necessarily in the environment *) |
---|
2991 | (* TODO, cf Hlookup_var_success or sInv *) |
---|
2992 | @cthulhu |
---|
2993 | | #Heq destruct (Heq) |
---|
2994 | lapply (Hmatching var_id) >H normalize nodelta |
---|
2995 | >(opt_to_res_inversion ???? Hlookup_var_success) normalize nodelta |
---|
2996 | #Hpresent_in_local #Hexec_cl_rhs |
---|
2997 | cases (bindIO_inversion ??????? Hexec_cl_rhs) -Hexec_cl_rhs * |
---|
2998 | #cl_rhs_result #cl_rhs_trace * #Hcl_exec_expr_rhs #Hcl_exec_store |
---|
2999 | cases (bindIO_inversion ??????? Hcl_exec_store) -Hcl_exec_store #cl_mem_after_store |
---|
3000 | * #Hstore_value_of_type lapply (opt_to_io_Value ?????? Hstore_value_of_type) |
---|
3001 | -Hstore_value_of_type #Hstore_value_of_type |
---|
3002 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
3003 | %{1} whd whd in ⊢ (??%?); normalize nodelta |
---|
3004 | cases (eval_expr_sim … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) #Hsim_expr #_ |
---|
3005 | lapply (Hsim_expr … Htranslate_rhs … (proj2 ?? (proj1 ?? (proj1 ?? sInv))) Hcl_exec_expr_rhs) |
---|
3006 | * #cm_rhs_val generalize in match (proj2 ???); |
---|
3007 | #Hexpr_vars_rhs * #Heval_expr_rhs #Hvalue_eq_rhs >Heval_expr_rhs |
---|
3008 | normalize nodelta -Hsim_expr whd @conj try @conj try @refl |
---|
3009 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
3010 | generalize in match (proj1 ???); #Hpresent |
---|
3011 | generalize in match (conj ????); #Hstmt_vars |
---|
3012 | @(CMR_normal … Halloc_hyp) try assumption try @refl |
---|
3013 | [ 4: @(memory_matching_preserved_by_local_store … Hvalue_eq_rhs Hstore_value_of_type Hmatching) |
---|
3014 | | 3: @(memory_inj_preserved_by_local_store … Hmatching Hinjection) |
---|
3015 | | 2: @(tmp_vars_well_allocated_preserved_by_local_store … Hvalue_eq_rhs Hstore_value_of_type Htmp_vars_well_allocated) |
---|
3016 | | 1: @(clight_cminor_cont_rel_parametric_in_cm_env … Hpresent Hcont_rel) ] |
---|
3017 | ] |
---|
3018 | ] |
---|
3019 | | 1: #Hnot_evar #Htranslate_statement |
---|
3020 | cases (bind_inversion ????? Htranslate_statement) -Htranslate_statement |
---|
3021 | * #cm_rhs #Hexpr_vars_rhs * #Htranslate_rhs #Htranslate_statement' |
---|
3022 | cases (bind_inversion ????? Htranslate_statement') -Htranslate_statement' #dest |
---|
3023 | lapply (translate_dest_not_Evar_id alloc_type ? lhs_ty Hnot_evar) |
---|
3024 | #Htranslate_dest * #Htranslate_dest' |
---|
3025 | >Htranslate_dest' in Htranslate_dest; #Haux lapply (sym_eq ??? Haux) -Haux #Haux |
---|
3026 | cases (bind_inversion ????? Haux) -Haux |
---|
3027 | * #translated_dest #Hexpr_vars_dest * #Htranslate_addr |
---|
3028 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) normalize nodelta |
---|
3029 | cases (type_eq_dec ??) |
---|
3030 | [ 2: #Hneq normalize nodelta whd in ⊢ ((??%%) → ?); |
---|
3031 | #Habsurd destruct (Habsurd) ] |
---|
3032 | normalize nodelta whd in match (typeof ?); #Heq_cl_types |
---|
3033 | whd in ⊢ ((???%) → ?); #Heq destruct (Heq) |
---|
3034 | #s2 #tr whd in ⊢ ((??%?) → ?); #Hstep |
---|
3035 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
3036 | * * #cl_blo #cl_off #cl_tr * whd in ⊢ ((??%?) → ?); |
---|
3037 | #Hexec_lvalue #Hstep |
---|
3038 | lapply (translate_dest_MemDest_simulation … |
---|
3039 | INV' ???????? Halloc_hyp Hcl_env_hyp Hinjection Hmatching ?????? |
---|
3040 | Htranslate_dest' Hexec_lvalue) |
---|
3041 | [ 1: @(proj1 ?? (proj1 ?? (proj1 ?? sInv))) ] |
---|
3042 | * #cm_val_dest * #Heval_cm_dest #Hvalue_eq_dest |
---|
3043 | %{1} whd whd in ⊢ (??%?); normalize nodelta |
---|
3044 | >Heval_cm_dest |
---|
3045 | whd in match (m_bind ?????); |
---|
3046 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
3047 | * #val #trace * #Hexec_expr #Hstep |
---|
3048 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
3049 | #cl_mem_after_store * #Hopt_store |
---|
3050 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
3051 | lapply (opt_to_io_Value ?????? Hopt_store) -Hopt_store |
---|
3052 | #Hstore_value_of_type whd in Hstore_value_of_type:(??%?); |
---|
3053 | cases (eval_expr_sim … Halloc_hyp … Hcl_env_hyp … Hinjection … Hmatching) #Hsim_expr #_ |
---|
3054 | lapply (Hsim_expr … Htranslate_rhs … (proj2 ?? (proj1 ?? (proj1 ?? sInv))) Hexec_expr) |
---|
3055 | * #cm_rhs_val generalize in match (proj2 ???); |
---|
3056 | #Hexpr_vars_rhs * #Heval_expr_rhs #Hvalue_eq_rhs >Heval_expr_rhs |
---|
3057 | normalize nodelta -Hsim_expr |
---|
3058 | cases (store_value_of_type_success_by_value ? cl_m |
---|
3059 | cl_mem_after_store ?? val Hstore_value_of_type) |
---|
3060 | whd in match (typeof ?) in ⊢ ((??%%) → (??%?) → ?); |
---|
3061 | #Haccess_mode #Hstorev -Hstore_value_of_type |
---|
3062 | cases (value_eq_ptr_inversion … Hvalue_eq_dest) * #cm_blo #cm_off * #Hcm_val_dest destruct (Hcm_val_dest) |
---|
3063 | whd in ⊢ ((??%?) → ?); #Hembed |
---|
3064 | cases (some_inversion ????? Hembed) -Hembed |
---|
3065 | * #cm_blo' #cm_off' * #Hembed normalize nodelta #Heq destruct (Heq) |
---|
3066 | lapply (storen_parallel_aux ??? Hinjection … Hvalue_eq_rhs … Hembed ??? Hstorev) |
---|
3067 | * #cm_mem_after_store_lhs * #Hstoren #Hinj whd in Hstoren:(??%?); |
---|
3068 | whd in match (storev ????); |
---|
3069 | lapply Hstoren |
---|
3070 | (* make the types match *) |
---|
3071 | generalize in match (conj ????); #Hstmt_vars' >Heq_cl_types |
---|
3072 | #Hstoren >Hstoren |
---|
3073 | whd in match (m_bind ?????); normalize nodelta whd @conj try @conj try @refl |
---|
3074 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
3075 | @(CMR_normal … Halloc_hyp) try assumption try @refl |
---|
3076 | [ 3: @(memory_matching_preserved_by_parallel_stores … Hmatching) |
---|
3077 | | 2: @(well_allocated_preserved_by_parallel_stores … Htmp_vars_well_allocated) |
---|
3078 | | 1: @(clight_cminor_cont_rel_parametric_in_mem … Hcont_rel) ] |
---|
3079 | ] |
---|
3080 | | 4: (* Seq *) |
---|
3081 | #cm_s #cl_k #cm_k #cm_st #cl_f #cm_f #rettyp |
---|
3082 | #alloc_type #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize |
---|
3083 | (* introduce everything *) |
---|
3084 | #fInv #sInv #kInv #Htarget_type #func_univ #Hfresh_globals #Hfresh_function #Htranslate_function |
---|
3085 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbls |
---|
3086 | #flag * * * * #Hstmt_inv_cm #Hlabels_translated #Htmps_preserved |
---|
3087 | #Hreturn_ok #Hlabel_wf generalize in match (conj ????); #Hugly #Htranslate #Hlabel_inclusion |
---|
3088 | #tmpenv #Htmpenv #Hcont_rel |
---|
3089 | #Em #Htmp_vars_well_allocated |
---|
3090 | #Halloc_hyp #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Henv_below |
---|
3091 | #Hclight_normal #Hnot_labeleld |
---|
3092 | cases (bind_inversion ????? Htranslate) -Htranslate |
---|
3093 | * * * #tmp_gen #labgen #cm_s1 #Htrans_inv * #Htrans_stm1 normalize nodelta |
---|
3094 | #Htranslate cases (bind_inversion ????? Htranslate) -Htranslate |
---|
3095 | * * * #tmp_gen' #labgen' #cm_s2 #Htrans_inv' * #Htrans_stm2 normalize nodelta |
---|
3096 | whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
3097 | #s2 #tr whd in ⊢ ((??%?) → ?); #Heq destruct (Heq) |
---|
3098 | %{1} whd @conj try @conj try @refl |
---|
3099 | [ 2: #Habsurd destruct (Habsurd) ] |
---|
3100 | @(CMR_normal … Htrans_stm1) try assumption |
---|
3101 | [ 1: lapply Hlabel_inclusion |
---|
3102 | @transitive_lset_inclusion @lset_inclusion_union %1 |
---|
3103 | @reflexive_lset_inclusion |
---|
3104 | | 2: lapply (translation_entails_ident_inclusion … Htrans_stm2) #H |
---|
3105 | @(transitive_lset_inclusion … (translation_entails_ident_inclusion … Htrans_stm2)) |
---|
3106 | assumption |
---|
3107 | | 3: @(ClCm_cont_seq … Htrans_stm2) |
---|
3108 | [ 1: lapply Hlabel_inclusion @transitive_lset_inclusion @lset_inclusion_union %2 |
---|
3109 | @reflexive_lset_inclusion |
---|
3110 | | 2: assumption |
---|
3111 | | 3: assumption ] |
---|
3112 | ] |
---|
3113 | | *: (* Other statements *) @cthulhu ] |
---|
3114 | | 2: (* Return state *) |
---|
3115 | #cl_ge #cm_ge #INV' #cl_k #cm_k #cm_st #cl_f #cm_f #alloc_type |
---|
3116 | #cl_env #cl_m #cm_env #cm_mt #stackptr #stacksize |
---|
3117 | #stmt_univ #tmpenv #Htmpenv #Em #Htmp_vars_wa #Hcharac #Hexec_alloc #Hinj #Hmatch #Hem_fn_id #Hframe #Hcont |
---|
3118 | #Hclight_normal #Hnot_labeleld |
---|
3119 | whd in Hclight_normal:%; |
---|
3120 | @False_ind @Hclight_normal |
---|
3121 | | 3: (* Call state *) |
---|
3122 | #cl_ge #cm_ge #INV' #cl_k #cm_st #cl_fundef #cm_fundef |
---|
3123 | #fblock #target_type #cl_env #cl_m #cm_env #cm_m |
---|
3124 | #fn_id #Hfind_cl #Hfind_cm |
---|
3125 | #tmpenv #Hcont_rel |
---|
3126 | #Em #Hinj #Hem_fn_id |
---|
3127 | #cl_args_values #cm_args_values #Hall2 |
---|
3128 | #Hclight_normal #Hnot_labeleld |
---|
3129 | whd in Hclight_normal:%; |
---|
3130 | @False_ind @Hclight_normal |
---|
3131 | | 4: (* Intermediary While state *) |
---|
3132 | (* ---------------------------------------------------------------------- *) |
---|
3133 | #cl_ge #cm_ge #INV' |
---|
3134 | #cl_f #cm_f #cl_env #cl_m #cm_env #cm_m #stackptr #stacksize #alloc_type |
---|
3135 | #cl_k #cm_k #sz #sg #cl_cond_ty #cl_cond_desc #cl_body #entry_label #exit_label #cm_cond #cm_body |
---|
3136 | #cm_stack #rettyp #kInv #fInv #sInv #Heq_ty #Hrettyp_eq #func_univ #Hfresh_globals #Hfresh_function |
---|
3137 | #Htranslate_function #Hcont_rel |
---|
3138 | #stmt_univ #stmt_univ' #lbl_univ #lbl_univ' #lbl_univ'' #tmpenv #Htmpenv #Hcont_rel |
---|
3139 | #Em #Htmp_vars_well_allocated |
---|
3140 | #Hcharacterise #Hcl_env_hyp #Hinjection #Hmatching #HEm_fn_id #Hframe_spec #Henv_below |
---|
3141 | #Hexpr_vars #Htranslate_expr #Hentry_ex #Hexit_ex #Htranslate_inv #Hmk_labels #Htranslate_statement |
---|
3142 | #Hlabel_inclusion #Hlabel_exists #Hinv1 #Hinv2 #Hfind_label |
---|
3143 | #Hclight_normal #Hnot_labeleld |
---|
3144 | #s2 #tr whd in ⊢ ((??%?) → ?); #Hstep |
---|
3145 | (* execute clight condition *) |
---|
3146 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
3147 | * #cl_cond_val #cl_cond_trace * #Hcl_exec_cond #Hstep |
---|
3148 | cases (bindIO_inversion ??????? Hstep) -Hstep |
---|
3149 | #cl_cond_bool * #Hcl_bool_of_val whd in ⊢ ((??%%) → ?); #Heq destruct (Heq) |
---|
3150 | (* The numbers of steps to execute in Cminor depends on the outcome of the condition |
---|
3151 | evaluation *) |
---|
3152 | cases cl_cond_bool in Hcl_bool_of_val; |
---|
3153 | [ (* cond = true: continue looping *) |
---|
3154 | #Hcl_bool_of_val |
---|
3155 | %{3} whd whd in ⊢ (??%?); normalize nodelta |
---|
3156 | generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
3157 | (* Exhibit simulation of condition evaluation *) |
---|
3158 | lapply (eval_expr_sim … Hcharacterise … Hcl_env_hyp … Hinjection … Hmatching) * #Hsim #_ |
---|
3159 | (* The type of Hsim forces us to wrap cm_cond into a dummy cast. *) |
---|
3160 | lapply (Hsim (Expr cl_cond_desc cl_cond_ty) (CMcast ?? cm_cond ?)) |
---|
3161 | [ >Heq_ty @refl ] -Hsim |
---|
3162 | whd in match (typeof ?); #Hsim |
---|
3163 | lapply (Hsim ??????) |
---|
3164 | [ 2: <Heq_ty >CMcast_identity assumption |
---|
3165 | | 1: assumption |
---|
3166 | | 6: <Heq_ty >CMcast_identity assumption |
---|
3167 | | 5: lapply Htranslate_expr lapply Hexpr_vars lapply cm_cond -cm_cond |
---|
3168 | >Heq_ty #cm_cond #Hexpr_vars @(jmeq_absorb ?????) #Hsol @Hsol |
---|
3169 | | *: ] |
---|
3170 | * #cm_val_cond * #Hcm_eval_cond #Hvalue_eq -Hsim |
---|
3171 | cut (eval_expr cm_ge (ASTint sz sg) cm_cond cm_env Hpresent_ifthenelse stackptr cm_m = OK ? 〈tr, cm_val_cond〉) |
---|
3172 | [ lapply Hpresent_ifthenelse |
---|
3173 | <(CMcast_identity (ASTint sz sg) cm_cond) #foo |
---|
3174 | lapply Hcm_eval_cond whd in match (eq_ind_r ??????); normalize nodelta cases Heq_ty |
---|
3175 | #H @H ] |
---|
3176 | #Heval >Heval |
---|
3177 | whd in match (m_bind ?????); |
---|
3178 | >(eval_bool_of_val_to_Cminor … Hvalue_eq … Hcl_bool_of_val) |
---|
3179 | normalize nodelta whd |
---|
3180 | generalize in match (proj1 ???); #Hnoise' |
---|
3181 | generalize in match (conj ????); #Hnoise'' @conj try @conj |
---|
3182 | [ 3: #Habsurd destruct (Habsurd) |
---|
3183 | | 1: normalize >append_nil @refl |
---|
3184 | | 2: @(CMR_normal … Htranslate_function … Htranslate_statement) try assumption |
---|
3185 | @(ClCm_cont_while … Htranslate_inv … Hmk_labels … Htranslate_statement) try assumption |
---|
3186 | ] |
---|
3187 | | (* cond = false: stop looping *) |
---|
3188 | #Hcl_bool_of_val |
---|
3189 | %{4} whd whd in ⊢ (??%?); normalize nodelta |
---|
3190 | generalize in match (proj1 ???); #Hpresent_ifthenelse |
---|
3191 | (* Exhibit simulation of condition evaluation *) |
---|
3192 | lapply (eval_expr_sim … Hcharacterise … Hcl_env_hyp … Hinjection … Hmatching) * #Hsim #_ |
---|
3193 | lapply (Hsim (Expr cl_cond_desc cl_cond_ty) (CMcast ?? cm_cond ?)) |
---|
3194 | [ >Heq_ty @refl ] -Hsim |
---|
3195 | whd in match (typeof ?); #Hsim |
---|
3196 | lapply (Hsim ??????) |
---|
3197 | [ 2: <Heq_ty >CMcast_identity assumption |
---|
3198 | | 1: assumption |
---|
3199 | | 6: <Heq_ty >CMcast_identity assumption |
---|
3200 | | 5: lapply Htranslate_expr lapply Hexpr_vars lapply cm_cond -cm_cond |
---|
3201 | >Heq_ty #cm_cond #Hexpr_vars @(jmeq_absorb ?????) #Hsol @Hsol |
---|
3202 | | *: ] |
---|
3203 | * #cm_val_cond * #Hcm_eval_cond #Hvalue_eq -Hsim |
---|
3204 | cut (eval_expr cm_ge (ASTint sz sg) cm_cond cm_env Hpresent_ifthenelse stackptr cm_m = OK ? 〈tr, cm_val_cond〉) |
---|
3205 | [ lapply Hpresent_ifthenelse |
---|
3206 | <(CMcast_identity (ASTint sz sg) cm_cond) #foo |
---|
3207 | lapply Hcm_eval_cond whd in match (eq_ind_r ??????); normalize nodelta cases Heq_ty |
---|
3208 | #H @H ] |
---|
3209 | #Heval >Heval |
---|
3210 | whd in match (m_bind ?????); |
---|
3211 | >(eval_bool_of_val_to_Cminor … Hvalue_eq … Hcl_bool_of_val) |
---|
3212 | normalize nodelta whd |
---|
3213 | generalize in match (proj1 ???); #Hnoise' |
---|
3214 | generalize in match (proj2 ???); #Hnoise'' |
---|
3215 | generalize in match (conj ????); #Hnoise''' |
---|
3216 | whd @conj try @conj |
---|
3217 | [ 3: #Habsurd destruct (Habsurd) |
---|
3218 | | 1: normalize >append_nil >append_nil @refl |
---|
3219 | | 2: @(CMR_normal … DoNotConvert) try assumption |
---|
3220 | try @refl |
---|
3221 | @(env_below_freshgen_preserved_by_translation … Htranslate_statement) |
---|
3222 | assumption |
---|
3223 | ] |
---|
3224 | ] |
---|
3225 | |
---|
3226 | ] qed. |
---|
3227 | |
---|
3228 | |
---|
3229 | (* TODO: move to globalenvs *) |
---|
3230 | (* The hypotheses are a little strong - we don't need to know that the size of |
---|
3231 | the initialisation data is the same. *) |
---|
3232 | lemma find_funct_id_match: |
---|
3233 | ∀M:matching. |
---|
3234 | ∀initV,initW. (∀v,w. match_var_entry M v w → size_init_data_list (initV (\snd v)) = size_init_data_list (initW (\snd w))) → |
---|
3235 | ∀p: program (m_A M) (m_V M). ∀p': program (m_B M) (m_W M). |
---|
3236 | ∀MATCH:match_program … M p p'. |
---|
3237 | ∀v. ∀f: m_A M (prog_var_names … p). ∀id. |
---|
3238 | find_funct_id … (globalenv … initV p) v = Some ? 〈f,id〉 → |
---|
3239 | ∃tf : m_B M (prog_var_names … p'). |
---|
3240 | find_funct_id … (globalenv … initW p') v = Some ? 〈tf,id〉 ∧ match_fundef M ? f (tf⌈m_B M ? ↦ m_B M (prog_var_names … p)⌉). |
---|
3241 | [ 2: >(matching_vars … (mp_vars … MATCH)) % ] |
---|
3242 | #M #initV #initW #varsOK #p #p' #MP * [ | #sz #i | | #p ] #f #id |
---|
3243 | [ 1,2,3: #FF whd in FF:(??%?); destruct ] |
---|
3244 | #FFI cases (find_funct_id_ptr ????? FFI) #b * * #E destruct #FS #FFPI |
---|
3245 | cases (find_funct_ptr_id_inv ????? FFPI) #FFP #SFB |
---|
3246 | cases (find_funct_ptr_match M initV initW … MP ? f FFP) |
---|
3247 | #f' * #FFP' #MF %{f'} % |
---|
3248 | [ @find_funct_ptr_id_conv |
---|
3249 | @(make_find_funct_ptr_id ???? id FFP' ?) |
---|
3250 | whd in ⊢ (??%?); >(symbols_match … initV … MP) [ @SFB | @varsOK ] |
---|
3251 | | @MF |
---|
3252 | ] qed. |
---|
3253 | |
---|
3254 | lemma clight_cminor_inv_exists : ∀p,p'. |
---|
3255 | clight_to_cminor p = OK … p' → |
---|
3256 | clight_cminor_inv (make_global … clight_fullexec p) (make_global … Cminor_fullexec p'). |
---|
3257 | #p #p' #COMPILE |
---|
3258 | lapply (clight_to_cminor_matches … COMPILE) #MATCHES -COMPILE |
---|
3259 | % |
---|
3260 | [2: #sym lapply (find_symbol_match (clight_cminor_matching p) ????? MATCHES) |
---|
3261 | [4: #H @sym_eq @H | #X #Y * #id #r #v1 #v2 * % | skip | skip ] |
---|
3262 | |3: #v #f #id #FF cases (find_funct_id_match … MATCHES … FF) |
---|
3263 | [ #f' * #FF' whd in ⊢ (% → ?); * #H1 * #H2 #Efd |
---|
3264 | % [2: %{f'} %{H1} %{H2} % [ >Efd |
---|
3265 | -Efd -H1 -H2 -FF' -FF |
---|
3266 | generalize in ⊢ (??(??(match % with [_⇒?]))?); |
---|
3267 | >(matching_vars … (mp_vars … MATCHES)) -MATCHES |
---|
3268 | #E @(streicherK ???? E) % |
---|
3269 | | @FF' |
---|
3270 | ] |
---|
3271 | | skip |
---|
3272 | ] |
---|
3273 | | skip |
---|
3274 | | #X #Y * #id' #r #v1 #v2 * % |
---|
3275 | ] |
---|
3276 | | skip |
---|
3277 | ] qed. |
---|
3278 | |
---|
3279 | (* TODO: move to common/Pointers.ma *) |
---|
3280 | axiom offset_plus_zero : ∀o. |
---|
3281 | offset_plus o zero_offset = o. |
---|
3282 | |
---|
3283 | (* TODO: move to memory model *) |
---|
3284 | lemma valid_block_dec: ∀m,b. (valid_block m b) + (¬valid_block m b). |
---|
3285 | #m * #b |
---|
3286 | whd in ⊢ (?%(?%)); |
---|
3287 | lapply (refl ? (Zltb b (nextblock m))) |
---|
3288 | cases (Zltb b (nextblock m)) in ⊢ (???% → ?); |
---|
3289 | #H |
---|
3290 | [ %1 @Zltb_true_to_Zlt assumption |
---|
3291 | | %2 @Zltb_false_to_not_Zlt assumption |
---|
3292 | ] qed. |
---|
3293 | |
---|
3294 | definition equal_embedding : mem → block → option (block × offset) ≝ |
---|
3295 | λm,b. match valid_block_dec m b with |
---|
3296 | [ inl _ ⇒ Some ? 〈b,zero_offset〉 |
---|
3297 | | inr _ ⇒ None ? |
---|
3298 | ]. |
---|
3299 | |
---|
3300 | lemma valid_pointer_valid_block : ∀m,b,o. |
---|
3301 | valid_pointer m (mk_pointer b o) → |
---|
3302 | valid_block m b. |
---|
3303 | #m #b #o #VP |
---|
3304 | cases (andb_Prop_true … VP) #H |
---|
3305 | cases (andb_Prop_true … H) #B #_ #_ |
---|
3306 | whd @(Zltb_true_to_Zlt … B) |
---|
3307 | qed. |
---|
3308 | |
---|
3309 | lemma valid_block_dec_true : ∀m,b. |
---|
3310 | valid_block m b → |
---|
3311 | ∃H. valid_block_dec m b = inl … H. |
---|
3312 | #m * #b #H whd in ⊢ (??(λ_.??%?)); whd in H; |
---|
3313 | generalize in ⊢ (??(λ_.??(?%)?)); |
---|
3314 | >(Zlt_to_Zltb_true … H) in ⊢ (???% → ??(λ_.??(match % with [_⇒?|_⇒?]?)?)); |
---|
3315 | #E % [2: % | skip ] |
---|
3316 | qed. |
---|
3317 | |
---|
3318 | lemma not_Zlt_to_Zltb_false : ∀x,y. |
---|
3319 | ¬(Zlt x y) → |
---|
3320 | Zltb x y = false. |
---|
3321 | #x #y #N lapply (Zltb_true_to_Zlt x y) |
---|
3322 | cases (Zltb x y) // |
---|
3323 | #H @⊥ @(absurd … (H (refl ??))) @N |
---|
3324 | qed. |
---|
3325 | |
---|
3326 | lemma valid_block_dec_false : ∀m,b. |
---|
3327 | ¬valid_block m b → |
---|
3328 | ∃H. valid_block_dec m b = inr … H. |
---|
3329 | #m * #b #H whd in ⊢ (??(λ_.??%?)); whd in H; |
---|
3330 | generalize in ⊢ (??(λ_.??(?%)?)); |
---|
3331 | >(not_Zlt_to_Zltb_false … H) in ⊢ (???% → ??(λ_.??(match % with [_⇒?|_⇒?]?)?)); |
---|
3332 | #E % [2: % | skip ] |
---|
3333 | qed. |
---|
3334 | |
---|
3335 | (* TODO: move to memoryInjections.ma? *) |
---|
3336 | lemma equal_value_eq : ∀m,ty,b,o,v. |
---|
3337 | (∀p. load_value_of_type ty m b o = Some ? (Vptr p) → valid_pointer m p) → |
---|
3338 | load_value_of_type ty m b o = Some ? v → |
---|
3339 | value_eq (equal_embedding m) v v. |
---|
3340 | #m #ty #b #o * // |
---|
3341 | * #b' #o' #H1 #H2 @vptr_eq |
---|
3342 | whd in ⊢ (??%?); whd in match (equal_embedding ??); |
---|
3343 | cases (valid_block_dec_true … (valid_pointer_valid_block m b' o' ?)) |
---|
3344 | [2: @H1 @H2 ] |
---|
3345 | #H3 #E >E whd in ⊢ (??%?); |
---|
3346 | >offset_plus_zero % |
---|
3347 | qed. |
---|
3348 | |
---|
3349 | lemma equal_embedding_elim : ∀m,b,b',o. ∀P:block → offset → Prop. |
---|
3350 | equal_embedding m b = Some ? 〈b',o〉 → |
---|
3351 | (valid_block m b → P b zero_offset) → |
---|
3352 | P b' o. |
---|
3353 | #m * #b #b' #o #P |
---|
3354 | whd in ⊢ (??%? → ?); |
---|
3355 | cases (valid_block_dec ??) #H #E |
---|
3356 | whd in E:(??%%); destruct |
---|
3357 | /2/ |
---|
3358 | qed. |
---|
3359 | |
---|
3360 | lemma pointer_translation_elim : ∀m,p,p'. ∀P:pointer → Prop. |
---|
3361 | pointer_translation p (equal_embedding m) = Some ? p' → |
---|
3362 | P p → |
---|
3363 | P p'. |
---|
3364 | #m * #b #o * #b' #o' #P whd in ⊢ (??%? → ?); |
---|
3365 | whd in match (equal_embedding m b); |
---|
3366 | cases (valid_block_dec ??) |
---|
3367 | #H #E whd in E:(??%?); [ >offset_plus_zero in E; #E ] destruct |
---|
3368 | // |
---|
3369 | qed. |
---|
3370 | |
---|
3371 | lemma pointer_translation_elim' : ∀m,b,o,b',o'. ∀P:block → offset → Prop. |
---|
3372 | pointer_translation (mk_pointer b o) (equal_embedding m) = Some ? (mk_pointer b' o') → |
---|
3373 | P b o → |
---|
3374 | P b' o'. |
---|
3375 | #m #b #o #b' #o' #P whd in ⊢ (??%? → ?); |
---|
3376 | whd in match (equal_embedding m b); |
---|
3377 | cases (valid_block_dec ??) |
---|
3378 | #H #E whd in E:(??%?); [ >offset_plus_zero in E; #E ] destruct |
---|
3379 | // |
---|
3380 | qed. |
---|
3381 | |
---|
3382 | lemma equal_memory_injection : ∀m. |
---|
3383 | (∀b. valid_block m b → block_implementable_bv m b) → |
---|
3384 | (∀ty,b,o,p. load_value_of_type ty m b o = Some ? (Vptr p) → valid_pointer m p) → |
---|
3385 | memory_inj (equal_embedding m) m m. |
---|
3386 | #m #addr_ok #contents_ok % |
---|
3387 | [ whd #b1 #off1 #b2 #off2 #ty #v1 #Hvalid #Htrans |
---|
3388 | @(pointer_translation_elim' … Htrans) |
---|
3389 | #Hload |
---|
3390 | %{v1} destruct %{Hload} @(equal_value_eq … Hload) @contents_ok |
---|
3391 | | #b #H whd in ⊢ (??%?); |
---|
3392 | cases (valid_block_dec_false … H) #H' #E >E % |
---|
3393 | | * #b #o #p' #Hv #Ht @(pointer_translation_elim … Ht) |
---|
3394 | @Hv |
---|
3395 | | #b #b' #off #Hem @(equal_embedding_elim … Hem) // |
---|
3396 | | #b #b' #o' #Hem @(equal_embedding_elim … Hem) // |
---|
3397 | | whd #b1 #b2 #b1' #b2' #delta1 #delta2 #NE #Hem1 #Hem2 |
---|
3398 | @(equal_embedding_elim … Hem1) |
---|
3399 | @(equal_embedding_elim … Hem2) |
---|
3400 | #_ #_ @eq_block_elim [ #E @⊥ @(absurd … E NE) | // ] |
---|
3401 | | #b whd whd in match (equal_embedding m b); |
---|
3402 | cases (valid_block_dec m b) #H whd // |
---|
3403 | % [ % @addr_ok assumption | cases (addr_ok … H) #_ * #_ #H' >Zplus_z_OZ @H' ] |
---|
3404 | ] qed. |
---|
3405 | |
---|
3406 | axiom init_mem_good : ∀F,V,i,p,m. |
---|
3407 | init_mem F V i p = OK … m → |
---|
3408 | (∀b. valid_block m b → block_implementable_bv m b) ∧ |
---|
3409 | (∀ty,b,o,p. load_value_of_type ty m b o = Some ? (Vptr p) → valid_pointer m p). |
---|
3410 | |
---|
3411 | lemma init_clight_cminor : ∀p,p',s. |
---|
3412 | make_initial_state … clight_fullexec p = OK … s → |
---|
3413 | clight_to_cminor p = OK … p' → |
---|
3414 | ∃INV:clight_cminor_inv (make_global … clight_fullexec p) (make_global … Cminor_fullexec p'). |
---|
3415 | ∃s'. |
---|
3416 | make_initial_state … Cminor_fullexec p' = OK … s' ∧ |
---|
3417 | clight_cminor_rel (make_global … clight_fullexec p) (make_global … Cminor_fullexec p') INV s s'. |
---|
3418 | #p #p' #s #INIT #COMPILE |
---|
3419 | lapply (clight_to_cminor_matches … COMPILE) #MATCHES |
---|
3420 | |
---|
3421 | %{(clight_cminor_inv_exists … COMPILE)} |
---|
3422 | |
---|
3423 | lapply (find_funct_ptr_match (clight_cminor_matching p) (fst ??) (λx.x) … MATCHES) |
---|
3424 | lapply (find_symbol_match (clight_cminor_matching p) (fst ??) (λx.x) … MATCHES) |
---|
3425 | [ #v #w * // ] |
---|
3426 | lapply (init_mem_match (clight_cminor_matching p) (fst ??) (λx.x) … MATCHES) |
---|
3427 | [ #v #w * // ] |
---|
3428 | cases p in INIT COMPILE MATCHES ⊢ %; #vars #fns #main #INIT #COMPILE #MATCHES |
---|
3429 | cases (bind_inversion ????? INIT) -INIT #m * #INITMEM #INIT |
---|
3430 | cases (bind_inversion ????? INIT) -INIT #b * #FINDSYM #INIT |
---|
3431 | cases (bind_inversion ????? INIT) -INIT #fd * #FFP #INIT |
---|
3432 | whd in INIT:(??%%); destruct |
---|
3433 | whd in match (m_A ??); whd in match (m_B ??); whd in match (m_V ?); whd in match (m_W ?); |
---|
3434 | #M_initmem #M_findsym #M_ffp |
---|
3435 | cases (M_ffp … FFP) -M_ffp #f' * #FFP' #Mf' |
---|
3436 | %{(Callstate main f' [ ] m SStop)} % |
---|
3437 | [ whd in ⊢ (??%?); normalize in M_initmem:(??(?%%%?)(?%%%?)); >M_initmem >INITMEM |
---|
3438 | whd in ⊢ (??%?); lapply (M_findsym main) <(mp_main … MATCHES) |
---|
3439 | whd in match (m_A ??); whd in match (m_B ??); |
---|
3440 | change with (make_global p') in match (globalenv ????); #E >E |
---|
3441 | >FINDSYM |
---|
3442 | whd in ⊢ (??%?); >FFP' |
---|
3443 | whd in ⊢ (??%?); % |
---|
3444 | | @(CMR_call … b (Some ? (ASTint I32 Signed)) (empty_map …) ? (empty_map …) … (ClCm_cont_stop …)) |
---|
3445 | [ @find_funct_ptr_id_conv @make_find_funct_ptr_id |
---|
3446 | [ @FFP |
---|
3447 | | @(symbol_for_block_fn … FINDSYM FFP) |
---|
3448 | ] |
---|
3449 | | @find_funct_ptr_id_conv @make_find_funct_ptr_id |
---|
3450 | [ @FFP' |
---|
3451 | | @(symbol_for_block_fn … FFP') >M_findsym @FINDSYM |
---|
3452 | ] |
---|
3453 | | @([ ]) |
---|
3454 | | % |
---|
3455 | | whd @(equal_embedding m) |
---|
3456 | | cases (init_mem_good … INITMEM) #H1 #H2 @equal_memory_injection assumption |
---|
3457 | | (* This is a little too concrete... and the property is true but a little |
---|
3458 | strong (we always map function blocks in the embedding - even if there's |
---|
3459 | no function!) *) |
---|
3460 | #b #CODE cut (valid_block m b) |
---|
3461 | [ cases b in CODE ⊢ %; * [2,3:#z] #CODE whd in CODE:(??%?); destruct whd |
---|
3462 | lapply (nextblock_pos m) cases (nextblock m) [2,3,5,6:#z'] try * % |
---|
3463 | ] #VALID |
---|
3464 | whd in ⊢ (??%?); cases (valid_block_dec ??) |
---|
3465 | [ // |
---|
3466 | | #INVALID @⊥ @(absurd … VALID INVALID) |
---|
3467 | ] |
---|
3468 | | % |
---|
3469 | ] |
---|
3470 | ] qed. |
---|
3471 | |
---|