source: src/Clight/toCminorCorrectness.ma @ 3036

Last change on this file since 3036 was 3036, checked in by garnier, 7 years ago

Fixing some problems, progress, etc

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