source: src/ERTL/ERTLtoERTLptrUtils.ma @ 2843

Last change on this file since 2843 was 2843, checked in by piccolo, 7 years ago

1) Fixed a litte bug in Joint.ma
2) ERTL to ERTLptr correctness proof in place

File size: 76.9 KB
Line 
1(**************************************************************************)
2(*       ___                                                              *)
3(*      ||M||                                                             *)
4(*      ||A||       A project by Andrea Asperti                           *)
5(*      ||T||                                                             *)
6(*      ||I||       Developers:                                           *)
7(*      ||T||         The HELM team.                                      *)
8(*      ||A||         http://helm.cs.unibo.it                             *)
9(*      \   /                                                             *)
10(*       \ /        This file is distributed under the terms of the       *)
11(*        v         GNU General Public License Version 2                  *)
12(*                                                                        *)
13(**************************************************************************)
14
15include "ERTL/ERTLToERTLptr.ma".
16include "common/StatusSimulation.ma".   
17include "joint/Traces.ma".
18include "ERTLptr/ERTLptr_semantics.ma".
19include "common/ExtraMonads.ma".
20
21
22definition ERTL_status ≝
23λprog : ertl_program.λstack_sizes.
24joint_abstract_status (mk_prog_params ERTL_semantics prog stack_sizes).
25
26definition ERTLptr_status ≝
27λprog : ertlptr_program.λstack_sizes.
28joint_abstract_status (mk_prog_params ERTLptr_semantics prog stack_sizes).
29
30definition sigma_map ≝  block → label → option label.
31definition lbl_funct ≝  block → label → (list label).
32definition regs_funct ≝ block → label → (list register).
33
34(*TO BE MOVED*)
35lemma match_reg_elim : ∀ A : Type[0]. ∀ P : A → Prop. ∀ r : region.
36∀f : (r = XData) → A. ∀g : (r = Code) → A. (∀ prf : r = XData.P (f prf)) →
37(∀ prf : r = Code.P (g prf)) →
38P ((match r return λx.(r = x → ?) with
39    [XData ⇒ f | Code ⇒ g])(refl ? r)).
40#A #P * #f #g #H1 #H2 normalize nodelta [ @H1 | @H2]
41qed.
42
43definition get_sigma :
44ertl_program → lbl_funct → sigma_map ≝
45λprog,f_lbls.λbl,searched.
46let globals ≝ prog_var_names … prog in
47let ge ≝ globalenv_noinit … prog in
48! bl ← code_block_of_block bl ;
49! 〈id,fn〉 ← res_to_opt … (fetch_internal_function … ge bl);
50!〈res,s〉 ← find ?? (joint_if_code … fn)
51                (λlbl.λ_. match split_on_last … (f_lbls bl lbl) with
52                          [None ⇒ eq_identifier … searched lbl
53                          |Some x ⇒ eq_identifier … searched (\snd x)
54                          ]);
55return res.
56
57definition sigma_pc_opt : 
58ertl_program →  lbl_funct →
59program_counter → option program_counter ≝
60λprog,f_lbls,pc.
61  let sigma ≝ get_sigma prog f_lbls in
62  let ertl_ptr_point ≝ point_of_pc ERTLptr_semantics pc in
63  if eqZb       (block_id (pc_block pc)) (-1) then (* check for dummy exit pc *)
64    return pc
65  else
66       ! ertl_point ← sigma (pc_block pc) ertl_ptr_point;
67       return pc_of_point
68                   ERTL_semantics (pc_block pc) ertl_point.
69
70definition sigma_stored_pc ≝
71λprog,f_lbls,pc. match sigma_pc_opt prog f_lbls pc with
72      [None ⇒ null_pc (pc_offset … pc) | Some x ⇒ x].
73     
74     
75definition sigma_beval : ertl_program → lbl_funct →
76  beval → beval ≝
77λprog,f_lbls,bv.
78match bv with
79[ BVpc pc prt ⇒ match sigma_pc_opt prog f_lbls pc with
80                 [None ⇒ BVundef | Some x ⇒ BVpc x prt]
81| _ ⇒ bv
82].
83
84definition sigma_is : ertl_program → lbl_funct →
85internal_stack → internal_stack ≝
86λprog,f_lbls,is.
87match is with
88[ empty_is ⇒ empty_is
89| one_is bv ⇒ one_is (sigma_beval prog f_lbls bv)
90| both_is bv1 bv2 ⇒
91  both_is (sigma_beval prog f_lbls bv1) (sigma_beval prog f_lbls bv2)
92].
93
94lemma sigma_is_empty : ∀prog,sigma.
95  sigma_is prog sigma empty_is = empty_is.
96#prog #sigma % qed.
97
98definition sigma_mem : ertl_program → lbl_funct →
99 bemem → bemem ≝
100 λprog,f_lbls,m.
101 mk_mem
102  (λb.
103    If Zltb (block_id b) (nextblock m) then with prf' do   
104      let l ≝ low_bound m b in
105      let h ≝ high_bound m b in
106      mk_block_contents l h
107      (λz.If Zleb l z ∧ Zltb z h then with prf'' do
108        sigma_beval prog f_lbls (contents (blocks m b) z)
109      else BVundef)
110    else empty_block OZ OZ)
111  (nextblock m)
112  (nextblock_pos m).
113
114include "common/ExtraIdentifiers.ma".
115
116
117definition sigma_register_env :
118ertl_program → lbl_funct →
119list register →
120register_env beval → register_env beval ≝
121λprog,f_lbls,ids,psd_env.
122let m' ≝  map ??? psd_env (λbv.sigma_beval prog f_lbls bv) in
123m' ∖ ids.
124
125
126definition sigma_frames_opt : ertl_program →
127lbl_funct → regs_funct →
128list (register_env beval × (Σb:block.block_region b=Code)) →
129option (list (register_env beval × (Σb:block.block_region b=Code))) ≝
130λprog,f_lbls,f_regs,frms.
131let globals ≝ prog_var_names … prog in
132let ge ≝ globalenv_noinit … prog in
133m_list_map ? ? ?
134(λx.let 〈reg_env,bl〉 ≝ x in
135    ! 〈id,fn〉 ← res_to_opt … (fetch_internal_function … ge bl);
136    return 〈sigma_register_env prog f_lbls
137                (added_registers ERTL globals fn (f_regs bl)) reg_env,bl〉) frms.
138               
139definition sigma_frames :   ertl_program →
140lbl_funct → regs_funct →
141option (list (register_env beval × (Σb:block.block_region b=Code))) →
142option (list (register_env beval × (Σb:block.block_region b=Code))) ≝
143λprog,f_lbls,f_regs,frms.
144! frames ← frms;
145sigma_frames_opt prog f_lbls f_regs frames.
146       
147include "common/BitVectorTrieMap.ma".
148
149definition sigma_hw_register_env :ertl_program →
150lbl_funct →  hw_register_env → hw_register_env ≝
151λprog,f_lbls,h_reg.mk_hw_register_env
152(map ? ? (sigma_beval prog f_lbls) 6 (reg_env … h_reg)) (other_bit … h_reg).
153
154definition sigma_regs :ertl_program →
155lbl_funct →  list register →
156(register_env beval)×hw_register_env→
157(register_env beval)×hw_register_env ≝
158λprog,f_lbls,ids,regs.let 〈x,y〉≝ regs in
159      〈sigma_register_env prog f_lbls ids x,
160       sigma_hw_register_env prog f_lbls y〉.
161
162definition dummy_state : state ERTL_semantics ≝
163mk_state ERTL_semantics
164   (None ?) empty_is BBundef 〈empty_map ? ?,mk_hw_register_env … (Stub …) BBundef〉 empty.
165
166definition sigma_state : ertl_program →
167lbl_funct → regs_funct → list register →
168state ERTLptr_semantics → state ERTL_semantics ≝
169λprog,f_lbls,f_regs,restr,st.
170mk_state ERTL_semantics
171  (sigma_frames prog f_lbls f_regs (st_frms ERTLptr_semantics st))
172  (sigma_is prog f_lbls (istack … st))
173  (carry … st)
174  (sigma_regs prog f_lbls restr (regs … st))
175  (sigma_mem prog f_lbls (m … st)).
176   
177definition dummy_state_pc : state_pc ERTL_semantics ≝
178mk_state_pc ? dummy_state (null_pc one) (null_pc one).
179
180definition sigma_state_pc : ertl_program → lbl_funct → regs_funct →
181state_pc ERTLptr_semantics → state_pc ERTL_semantics ≝
182λprog,f_lbls,f_regs,st.
183let ge ≝ globalenv_noinit … prog in
184let globals ≝ prog_var_names … prog in
185match fetch_internal_function … ge (pc_block (pc … st)) with
186  [ OK y ⇒ let 〈i,fn〉 ≝ y in
187           let added ≝ added_registers ERTL globals fn
188                                          (f_regs (pc_block (pc … st))) in
189           mk_state_pc ?
190           (sigma_state prog f_lbls f_regs added st)
191               (pc … st) (sigma_stored_pc prog f_lbls (last_pop … st))
192  | Error e ⇒ dummy_state_pc
193  ].
194
195
196lemma ps_reg_retrieve_ok :  ∀prog : ertl_program.
197∀f_lbls : lbl_funct. ∀r,restr.
198preserving1 ?? res_preserve1 …
199     (sigma_regs prog f_lbls restr)
200     (sigma_beval prog f_lbls)
201     (λregs.ps_reg_retrieve regs r)
202     (λregs.ps_reg_retrieve regs r).
203#prog #f_lbls #r #restr * #psd_r #hw_r whd in match ps_reg_retrieve;
204whd in match reg_retrieve; normalize nodelta @opt_to_res_preserve1
205whd in match sigma_regs; whd in match sigma_register_env; normalize nodelta
206>lookup_set_minus @if_elim [ #_ @opt_preserve_none1] #id_r_not_in
207>(lookup_map ?? RegisterTag ???) #bv #H @('bind_inversion H) -H #bv1
208#bv1_spec whd in ⊢ (??%? → ?); #EQ destruct %{bv1} % // >bv1_spec %
209qed.
210
211lemma hw_reg_retrieve_ok : ∀prog : ertl_program.
212∀f_lbls : lbl_funct. ∀r,restr.
213preserving1 ?? res_preserve1 …
214    (sigma_regs prog f_lbls restr)
215    (sigma_beval prog f_lbls)
216    (λregs.hw_reg_retrieve regs r)
217    (λregs.hw_reg_retrieve regs r).
218#prog #f_lbls #r #restr * #psd_r * #hw_r #b whd in match hw_reg_retrieve;
219whd in match hwreg_retrieve; normalize nodelta whd in match sigma_regs;
220whd in match sigma_hw_register_env; normalize nodelta
221change with (sigma_beval prog f_lbls BVundef) in ⊢ (???????(??(?????%))?);
222#bv >lookup_map whd in ⊢ (???% → ?); #EQ destruct
223%{(lookup beval 6 (bitvector_of_register r) hw_r BVundef)}
224% //
225qed.
226
227
228lemma ps_reg_store_ok : ∀prog : ertl_program.
229∀f_lbls : lbl_funct. ∀r,restr.
230¬(r ∈ (set_from_list RegisterTag restr)) →
231preserving21 ?? res_preserve1 …
232   (sigma_beval prog f_lbls)
233   (sigma_regs prog f_lbls restr)
234   (sigma_regs prog f_lbls restr)
235   (ps_reg_store r)
236   (ps_reg_store r).
237#prog #f_lbls #r #restr #Hreg whd in match ps_reg_store; normalize nodelta
238#bv * #psd_r #hw_r @mfr_return_eq1
239whd in match reg_store; whd in match sigma_regs; normalize nodelta
240whd in match sigma_register_env; normalize nodelta >map_add
241  >add_set_minus [% | assumption]
242qed.
243(* 
244   lapply(update_ok_to_lookup ?????? x_spec) * * #_ #EQpsd #_
245  lapply x_spec -x_spec lapply EQpsd -EQpsd whd in match sigma_register_env;
246  normalize nodelta >lookup_set_minus @if_elim [ #_ * #H @⊥ @H %]
247  #id_not_in #_ >update_set_minus [2: assumption] #H @('bind_inversion H) -H
248  #x0 >map_update_commute #H @('bind_inversion H) -H #x1 #x1_spec
249  whd in ⊢ (??%% → ??%% → ?); #EQ1 #EQ2 destruct %{x1} % //
250| #x * #psd_r' #hw_r' whd in match sigma_regs; normalize nodelta
251  whd in ⊢ (???% → ?); #EQ destruct %{〈x,hw_r〉} % //
252]
253qed.*)
254
255
256lemma hw_reg_store_ok : ∀prog : ertl_program.
257∀f_lbls : lbl_funct. ∀r,restr.
258preserving21 ?? res_preserve1 …
259   (sigma_beval prog f_lbls)
260   (sigma_regs prog f_lbls restr)
261   (sigma_regs prog f_lbls restr)
262   (hw_reg_store r)
263   (hw_reg_store r).
264#prog #sigma #r #restr whd in match hw_reg_store; normalize nodelta
265#bv * #psd_r * #hw_r #b whd in match hwreg_store; whd in match sigma_regs;
266normalize nodelta
267whd in match sigma_hw_register_env; normalize nodelta <insert_map * #psd_r'
268* #hw_r' #b' whd in ⊢ (???% → ?); #EQ destruct % [2: % [%] % |]
269qed.
270
271definition move_dst_not_fresh : list register →  move_dst → Prop ≝
272λrestr,mv.match mv with
273  [PSD r ⇒ bool_to_Prop (¬(r ∈ (set_from_list RegisterTag restr)))
274  | _ ⇒ True
275  ].
276
277lemma ertl_eval_move_ok : ∀prog : ertl_program.
278∀f_lbls : lbl_funct. ∀ restr,pm.
279move_dst_not_fresh restr (\fst pm) →
280preserving1 ?? res_preserve1 …
281     (sigma_regs prog f_lbls restr)
282     (sigma_regs prog f_lbls restr)
283     (λregs.ertl_eval_move regs pm)
284     (λregs.ertl_eval_move regs pm).
285#prog #sigma #restr * #mv_dst #arg_dst #Hpm #pm whd in match ertl_eval_move;
286normalize nodelta @mfr_bind1 [@(sigma_beval prog sigma)
287| cases arg_dst normalize nodelta
288  [2: #b change with (return sigma_beval prog sigma (BVByte b)) in ⊢ (???????%?);
289      @mfr_return1]
290  * #r normalize nodelta [@ps_reg_retrieve_ok| @hw_reg_retrieve_ok]
291| #bv cases mv_dst in Hpm; #r #Hpm normalize nodelta [@ps_reg_store_ok assumption
292                                                     | @hw_reg_store_ok
293                                                     ]
294]
295qed.
296
297lemma ps_arg_retrieve_ok : ∀prog : ertl_program.
298∀f_lbls : lbl_funct. ∀a,restr.
299preserving1 ?? res_preserve1 …
300    (sigma_regs prog f_lbls restr)
301    (sigma_beval prog f_lbls)
302    (λregs.ps_arg_retrieve regs a)
303    (λregs.ps_arg_retrieve regs a).
304#prog #sigma #a #restr whd in match ps_arg_retrieve; normalize nodelta cases a -a
305normalize nodelta [#r | #b ] #regs
306[ @ps_reg_retrieve_ok
307| change with (return sigma_beval prog sigma (BVByte b)) in ⊢ (???????%?);
308  @mfr_return1
309]
310qed.
311
312lemma pop_ok :
313∀prog : ertl_program.∀f_lbls : lbl_funct.
314∀f_regs : regs_funct.∀restr.
315preserving1 ?? res_preserve1 ????
316   (sigma_state prog f_lbls f_regs restr)
317   (λx.let 〈bv,st〉 ≝ x in
318      〈sigma_beval prog f_lbls bv,
319       sigma_state prog f_lbls f_regs restr st〉)
320   (pop ERTL_semantics)
321   (pop ERTLptr_semantics).
322#prog #f_lbls #f_regs #id whd in match pop; normalize nodelta #st @mfr_bind1
323[@(λx.let 〈bv,is〉 ≝ x in
324     〈sigma_beval prog f_lbls bv,
325      sigma_is prog f_lbls is 〉)
326| whd in match is_pop; normalize nodelta whd in match sigma_state;
327  normalize nodelta cases(istack ? st) normalize nodelta
328  [@res_preserve_error1
329  |2,3: #bv1 [2: #bv2] * #bv3 #is1 whd in ⊢ (??%% → ?); #EQ destruct
330        % [2,4: % [1,3: %|*: %] |*:]
331  ]
332| * #bv #is normalize nodelta @mfr_return_eq1 %   
333]
334qed.
335
336lemma push_ok :
337∀prog : ertl_program.
338∀f_lbls : lbl_funct.
339∀f_regs : regs_funct.∀restr.
340preserving21 ?? res_preserve1 …
341     (sigma_state prog f_lbls f_regs restr)
342     (sigma_beval prog f_lbls)
343     (sigma_state prog f_lbls f_regs restr)
344     (push ERTL_semantics)
345     (push ERTLptr_semantics).
346#prog #f_lbls #f_regs #restr whd in match push; normalize nodelta #st #bv @mfr_bind1
347[ @(sigma_is prog f_lbls)
348| whd in match is_push; normalize nodelta whd in match sigma_state; normalize nodelta
349 cases (istack ? st) [2,3: #bv [2: #bv']]  whd in match sigma_is in ⊢ (???????%?);
350 normalize nodelta [@res_preserve_error1] @mfr_return_eq1 %
351| #is @mfr_return_eq1 %
352]
353qed.
354
355lemma be_opaccs_ok :
356∀prog : ertl_program. ∀f_lbls : lbl_funct. ∀ op.
357preserving21 ?? res_preserve1 ??????
358    (sigma_beval prog f_lbls)
359    (sigma_beval prog f_lbls)
360    (λx.let 〈bv1,bv2〉 ≝ x in
361           〈sigma_beval prog f_lbls bv1,
362            sigma_beval prog f_lbls bv2〉)
363    (be_opaccs op)
364    (be_opaccs op).
365#prog #sigma #op #bv #bv1
366whd in match be_opaccs; normalize nodelta @mfr_bind1
367[ @(λx.x)
368| cases bv
369  [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
370  whd in match Byte_of_val; normalize nodelta
371  try @res_preserve_error1 [ #x whd in ⊢ (???% → ?); #EQ destruct %{x} % //]
372  whd in match sigma_beval; normalize nodelta cases (sigma_pc_opt ? ? ?)
373  normalize nodelta [2: #pc] @res_preserve_error1
374| #by @mfr_bind1
375  [ @(λx.x)
376  | cases bv1
377    [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
378    whd in match Byte_of_val; normalize nodelta
379    try @res_preserve_error1 [ #x whd in ⊢ (???% → ?); #EQ destruct %{x} % //]
380    whd in match sigma_beval; normalize nodelta cases (sigma_pc_opt ? ? ?)
381    normalize nodelta [2: #pc] @res_preserve_error1
382 | #by1 * #bv2 #bv3 cases(opaccs eval op by by1) #by' #by1' normalize nodelta
383   whd in ⊢ (??%% → ?); #EQ destruct % [2: % [%] % |]
384qed.
385
386lemma be_op1_ok : ∀prog : ertl_program.  ∀f_lbls : lbl_funct.
387∀ op.
388preserving1 ?? res_preserve1 …
389     (sigma_beval prog f_lbls)
390     (sigma_beval prog f_lbls)
391     (be_op1 op)
392     (be_op1 op).
393#prog #sigma #o #bv whd in match be_op1; normalize nodelta @mfr_bind1
394[ @(λx.x)
395| cases bv
396  [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
397  whd in match Byte_of_val; whd in match sigma_beval; normalize nodelta
398  try @res_preserve_error1 [ @mfr_return_eq1 %]
399  cases(sigma_pc_opt prog sigma pc1) [2: #pc2] normalize nodelta
400  @res_preserve_error1
401| #by @mfr_return_eq1 %
402]
403qed.
404
405
406lemma be_op2_ok : ∀prog : ertl_program. ∀f_lbls : lbl_funct.
407∀ b,op.
408preserving21 ?? res_preserve1 …
409     (sigma_beval prog f_lbls)
410     (sigma_beval prog f_lbls)
411     (λx.let 〈bv,b〉≝ x in 〈sigma_beval prog f_lbls bv,b〉)
412     (be_op2 b op)
413     (be_op2 b op).
414#prog #sigma #b #op #bv #bv1 whd in match be_op2; normalize nodelta
415cases bv
416[ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
417normalize nodelta [@res_preserve_error1] whd in match sigma_beval;
418normalize nodelta
419cases bv1
420[1,2,8,9,15,16,22,23,29,30,36,37:
421|3,10,17,24,31,38: #ptr1' #ptr2' #p'
422|4,11,18,25,32,39: #by'
423|5,12,19,26,33,40: #p'
424|6,13,20,27,34,41: #ptr' #p'
425|7,14,21,28,35,42: #pc1' #p1'
426]
427normalize nodelta try @res_preserve_error1
428[4,5,8,13,16,20,21,22,23,24,25,26 : @res_preserve_error11 %
429   [2,4,6,8,10,12,14,16,18,20,22,24: cases(sigma_pc_opt ???) try % #pc2 %
430   |*:]
431|*: cases op normalize nodelta
432    try @res_preserve_error1 try( @mfr_return_eq1 %)
433    [1,2,12,13,16,17,18: @if_elim #_ try @res_preserve_error1
434                         try( @mfr_return_eq1 %)
435                         [ @if_elim #_ @mfr_return_eq1 %
436                         | cases(ptype ptr) normalize nodelta
437                           [2: @res_preserve_error1] @mfr_bind1
438                           [ @(λx.x)
439                           | whd in match Bit_of_val; normalize nodelta
440                             cases b [#bo|| #bo #ptr'' #p'' #bit_v]
441                             normalize nodelta [2,3: @res_preserve_error1]
442                             @mfr_return_eq1 %
443                           | #bi cases(op2 ?????) #by #bi1 normalize nodelta
444                             @mfr_return_eq1 %
445                           ]
446                         | cases(ptype ptr) normalize nodelta @res_preserve_error1
447                         ]
448    |3,4,5,6,7,8: @mfr_bind1
449        [1,4,7,10,13,16: @(λx.x)
450        |2,5,8,11,14,17: whd in match Bit_of_val; normalize nodelta
451                         cases b [1,4,7,10,13,16: #bo|
452                                 |2,5,8,11,14,17:
453                                 |3,6,9,12,15,18: #bo #ptr'' #p'' #bit_v
454                                 ] normalize nodelta try @res_preserve_error1
455                                 @mfr_return_eq1 %
456       |3,6,9,12,15,18: #bi try(@mfr_return_eq1 %) cases(op2 ?????) #by #bi1 normalize nodelta
457                        @mfr_return_eq1 %
458       ]
459    |*: whd in match be_add_sub_byte; normalize nodelta
460        [1,2,3: cases(ptype ptr) normalize nodelta [2,4,6: @res_preserve_error1]
461                cases p * [2,4,6: #p_no] #prf normalize nodelta
462                [@res_preserve_error1
463                |2,3: cases b [1,4: #bo|2,5: |3,6:  #bo #ptr'' #p'' #bit_v]
464                      normalize nodelta [1,2,3,4: @res_preserve_error1]
465                      @if_elim #_ [2,4: @res_preserve_error1]
466                      @If_elim #INUTILE [2,4: @res_preserve_error1]
467                      @pair_elim #a1 #a2 #_ normalize nodelta
468                      @mfr_return_eq1 %
469                |*: @mfr_bind1
470                  [1,4,7: @(λx.x)
471                  |2,5,8: whd in match Bit_of_val; normalize nodelta
472                          [@mfr_return_eq1 %] cases b
473                          [1,4: #bo|2,5: |3,6:  #bo #ptr'' #p'' #bit_v]
474                          normalize nodelta [3,4,5,6: @res_preserve_error1]
475                          @mfr_return_eq1 %
476                  |3,6,9: * normalize nodelta [1,3,5: @res_preserve_error1]
477                          cases(op2 ?????) #a1 #a2 normalize nodelta
478                          @mfr_return_eq1 %
479                  ]
480               ]
481         |*: cases(ptype ptr') normalize nodelta [2,4: @res_preserve_error1]
482             cases p' * [2,4: #part_no] #prf normalize nodelta
483             [ @res_preserve_error1
484             | cases b [#bo|| #bo #ptr'' #p'' #bit_v]
485               normalize nodelta [1,2: @res_preserve_error1] @if_elim #_
486               [2: @res_preserve_error1] @If_elim #INUTILE [2: @res_preserve_error1]
487               @pair_elim #a1 #a2 #_ normalize nodelta @mfr_return_eq1 %
488             |*: @mfr_bind1
489                [1,4: @(λx.x)
490                |2,5: whd in match Bit_of_val; normalize nodelta [ @mfr_return_eq1 %]
491                      cases b [#bo|| #bo #ptr'' #p'' #bit_v] normalize nodelta
492                      [2,3: @res_preserve_error1] @mfr_return_eq1 %
493                |3,6: * normalize nodelta [1,3: @res_preserve_error1]   
494                      cases(op2 ?????) #a1 #a2 normalize nodelta
495                      @mfr_return_eq1 %
496                ]
497              ]
498          ]
499      ]
500]
501qed.
502
503lemma pointer_of_address_ok : ∀prog : ertl_program.∀f_lbls : lbl_funct.
504preserving1 … res_preserve1 …
505     (λx.let 〈bv1,bv2〉 ≝ x in〈sigma_beval prog f_lbls bv1,
506           sigma_beval prog f_lbls bv2〉)
507     (λx.x)
508     pointer_of_address pointer_of_address.
509#prog #sigma * #bv1 #bv2 whd in match pointer_of_address;
510whd in match pointer_of_bevals; normalize nodelta
511cases bv1 normalize nodelta
512[ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
513try @res_preserve_error1
514[ cases bv2 [ | | #ptr1' #ptr2' #p' | #by' | #p' | #ptr' #p' | #pc1' #p1']
515  normalize nodelta
516  [1,2,3,4,5: @res_preserve_error1
517  | @if_elim #_ [ @mfr_return_eq1 % | @res_preserve_error1]
518  ]
519] whd in match sigma_beval; normalize nodelta cases(sigma_pc_opt ???)
520  [2,4: #pc4] normalize nodelta @res_preserve_error1
521qed.
522
523lemma beloadv_ok : ∀prog : ertl_program. ∀f_lbls : lbl_funct.
524∀ptr.
525preserving1 … opt_preserve1 …
526     (sigma_mem prog f_lbls)
527     (sigma_beval prog f_lbls)
528     (λm.beloadv m ptr)
529     (λm.beloadv m ptr).
530#prog #sigma #ptr #mem whd in match beloadv; whd in match do_if_in_bounds;
531normalize nodelta @if_elim [2: #_ @opt_preserve_none1]
532whd in match sigma_mem in ⊢ (% → ?); normalize nodelta #Hzlb
533@if_elim [2: #_ @opt_preserve_none1] whd in match sigma_mem in ⊢ (% → ?);
534normalize nodelta @If_elim [2: >Hzlb * #H @⊥ @H %] #_ @andb_elim @if_elim
535[2: #_ *] #Hzleb #Hzlb' >Hzlb normalize nodelta >Hzlb' normalize nodelta
536@mfr_return_eq1 whd in match sigma_mem; normalize nodelta >Hzlb
537@If_elim [2: * #H @⊥ @H %] * >Hzleb >Hzlb' @If_elim [2: * #H @⊥ @H %]
538* %
539qed.
540
541lemma bestorev_ok : ∀prog : ertl_program.∀f_lbls : lbl_funct.
542∀ptr.
543preserving21 … opt_preserve1 …
544    (sigma_mem prog f_lbls)
545    (sigma_beval prog f_lbls)
546    (sigma_mem prog f_lbls)
547    (λm.bestorev m ptr)
548    (λm.bestorev m ptr).
549#prog #sigma #ptr #mem #bv whd in match bestorev; whd in match do_if_in_bounds;
550normalize nodelta @if_elim [2: #_ @opt_preserve_none1]
551whd in match sigma_mem in ⊢ (% → ?); normalize nodelta #Hzlb
552@if_elim [2: #_ @opt_preserve_none1] @andb_elim @if_elim [2: #_ *]
553whd in match sigma_mem in ⊢ (% → % → ?); normalize nodelta >Hzlb
554@If_elim [2: * #H @⊥ @H %] * #Hzleb #Hzlb' normalize nodelta >Hzleb
555>Hzlb' normalize nodelta @mfr_return_eq1 whd in ⊢ (???%); @eq_f @mem_ext_eq
556[ #bl normalize nodelta % [%]
557  [ whd in match sigma_mem; normalize nodelta >Hzlb @If_elim [2: * #H @⊥ @H %] *
558    whd in match update_block; normalize nodelta @if_elim
559    [ @eq_block_elim [2: #_ *] #EQbl * >EQbl >Hzlb @If_elim [2: * #H @⊥ @H %]
560      * whd in match low_bound; normalize nodelta @if_elim [ #_ %]
561      @eq_block_elim #_ * %
562    | @eq_block_elim [#_ *] * #Hbl * @If_elim
563      [ #Hzlb'' >Hzlb'' @If_elim [2: * #H @⊥ @H %] * whd in match low_bound;
564        normalize nodelta @if_elim [2: #_ %] @eq_block_elim [2: #_ *] #H @⊥ @Hbl
565        assumption
566      | #Hzlb'' >Hzlb'' @If_elim [*] #_ %
567      ]
568   ]
569 | whd in match update_block; whd in match sigma_mem; normalize nodelta
570   @if_elim @eq_block_elim [2,3: #_ * |4: *] #Hbl #_ @If_elim
571   [3,4: >Hbl >Hzlb * [2: #H @⊥ @H %] @If_elim [2: * #H @⊥ @H %] *
572        whd in match high_bound; normalize nodelta @if_elim [#_ %]
573        @eq_block_elim [ #_ *] * #H @⊥ @H %
574   | #Hzlb'' >Hzlb'' @If_elim [2: * #H @⊥ @H %] * whd in match high_bound;
575     normalize nodelta @if_elim [2: #_ %] @eq_block_elim [2: #_ *]
576     #H @⊥ @Hbl assumption
577  | #Hzlb'' >Hzlb'' @If_elim [*] #_ %
578  ]
579 | #z whd in match update_block; whd in match sigma_mem; normalize nodelta
580   @if_elim @eq_block_elim [2,3: #_ * |4: *] #Hbl #_
581   [ @If_elim #Hzlb'' >Hzlb'' [2: @If_elim * #_ %] @If_elim @andb_elim
582     @if_elim [2: #_ *] #Hzleb' #Hzlb'''
583     [ @If_elim [2: * #H @⊥ @H %] * whd in match low_bound; normalize nodelta
584       @If_elim @andb_elim @if_elim [2: #_ *] @if_elim
585       [1,3,5: @eq_block_elim [2,4,6: #_ *] #H @⊥ @Hbl assumption] #_ >Hzleb' *
586       whd in match high_bound; normalize nodelta @if_elim
587       [1,3: @eq_block_elim [2,4: #_ *] #H @⊥ @Hbl assumption] #_ >Hzlb'''
588       [ * %] * #H @⊥ @H %
589     | @If_elim * [2: #H @⊥ @H %] whd in match low_bound; normalize nodelta
590       @if_elim [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_
591       >Hzleb' whd in match high_bound; normalize nodelta @if_elim
592       [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_ >Hzlb'''
593       @If_elim [2: #_ %] *
594     | @If_elim [2: * #H @⊥ @H %] whd in match low_bound; normalize nodelta @if_elim
595       [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_ #_
596       whd in match low_bound in Hzleb'; normalize nodelta in Hzleb';
597       whd in match high_bound; normalize nodelta @if_elim
598       [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_ @If_elim [2: #_ %]
599       @andb_elim @if_elim [2: #_ *] #H >H in Hzleb'; *
600     ]
601   | whd in ⊢ (??%?); @if_elim @eqZb_elim [2,3: #_ * |4: *] #Hz *
602       [ >Hzlb @If_elim [2: * #H @⊥ @H %] * @If_elim @andb_elim @if_elim
603          [2: #_ *] #Hzleb' #Hzlb'' >Hbl >Hzlb @If_elim [2,4,6: * #H @⊥ @H %] #_
604          whd in match low_bound; normalize nodelta @eq_block_elim
605          [2,4,6: * #H @⊥ @H %] #_ normalize nodelta whd in match high_bound;
606          normalize nodelta @eq_block_elim [2,4,6: * #H @⊥ @H %]
607          #_ normalize nodelta
608          [1,2: >Hzleb' >Hzlb'' @If_elim [2,3: * #H @⊥ @H %]
609                #_ [2: %] whd in ⊢ (???(???%)); @if_elim [2: #_ %]
610                @eqZb_elim [2: #_ *] #H @⊥ @Hz assumption
611          | @If_elim [2: #_ %] @andb_elim @if_elim [2: #_ *] #H >H in Hzleb'; *
612          ]
613       | >Hbl >Hzlb @If_elim [2: * #H @⊥ @H %] * whd in match low_bound;
614         normalize nodelta @eq_block_elim [2: * #H @⊥ @H %] #_ normalize nodelta
615         whd in match high_bound; normalize nodelta @eq_block_elim [2: * #H @⊥ @H %]
616         normalize nodelta >Hz >Hzleb >Hzlb' @If_elim [2: * #H @⊥ @H %] #_ #_
617         whd in ⊢ (???(???%)); @eqZb_elim [2: * #H @⊥ @H %] #_ %
618       ]
619    ]
620 ]
621| %
622]
623qed.
624
625
626lemma sp_ok : ∀prog : ertl_program.
627∀f_lbls : lbl_funct.
628∀f_regs : regs_funct.∀restr.
629   preserving1 … res_preserve1 …
630      (λst.sigma_state prog f_lbls f_regs restr st)
631      (λx.x)
632      (sp ERTL_semantics)
633      (sp ERTLptr_semantics).
634#prog #f_lbls #f_regs #restr #st whd in match sp; normalize nodelta
635whd in match (load_sp ??); whd in match (load_sp ??); whd in match sigma_state;
636normalize nodelta whd in match sigma_regs; normalize nodelta
637cases(regs ? st) #psd_r #hw_r normalize nodelta
638inversion(pointer_of_address ?) normalize nodelta [2: #e #_ @res_preserve_error1]
639#pt #EQ lapply(jmeq_to_eq ??? EQ) -EQ whd in match hwreg_retrieve; normalize nodelta
640whd in match sigma_hw_register_env; normalize nodelta
641change with (sigma_beval prog f_lbls BVundef) in ⊢ (??(?(???(?????%)(?????%)))? → ?);
642>lookup_map >lookup_map
643cases(lookup beval 6 (bitvector_of_register RegisterSPL) (reg_env hw_r) BVundef)
644[ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
645whd in match pointer_of_address; whd in match pointer_of_bevals; normalize nodelta
646[1,2,3,4,5: #ABS destruct
647| cases(lookup beval 6 (bitvector_of_register RegisterSPH) (reg_env hw_r) BVundef)
648  [ | | #ptr1' #ptr2' #p' | #by' | #p' | #ptr' #p' | #pc1' #p1']
649  whd in match sigma_beval; normalize nodelta
650  [1,2,3,4,5: #ABS destruct
651  | @if_elim [2: #_ #ABS destruct] #H whd in ⊢ (??%? → ?); #EQ destruct
652    normalize nodelta @match_reg_elim #INUTILE
653    [ @mfr_return_eq1 % | @res_preserve_error1 ]
654  | cases (sigma_pc_opt ? ? ?) normalize nodelta [2: #x] #EQ destruct
655  ]
656| whd in match sigma_beval; normalize nodelta cases(sigma_pc_opt ? ? ?)
657 normalize nodelta [2: #x] #EQ destruct
658]
659qed.
660
661lemma set_sp_ok :  ∀prog : ertl_program.
662∀f_lbls : lbl_funct.
663∀f_regs : regs_funct.∀restr.∀ptr,st.
664set_sp ? ptr (sigma_state prog f_lbls f_regs restr st) =
665sigma_state prog f_lbls f_regs restr (set_sp ? ptr st).
666#prog #f_lbls #f_regs #restr #ptr #st whd in match set_sp; whd in match sigma_state;
667normalize nodelta @eq_f2 [2: %] whd in match (save_sp ???);
668whd in match (save_sp ???); whd in match sigma_regs; normalize nodelta
669cases(regs ? st) #psd_env #hw_regs normalize nodelta @eq_f
670whd in match hwreg_store_sp; normalize nodelta whd in match sigma_hw_register_env;
671normalize nodelta whd in match hwreg_store; normalize nodelta @eq_f2 [2: %]
672>insert_map @eq_f >insert_map %
673qed.
674
675(*TO BE MOVED IN TranslateUtils.ma *)
676include "utilities/listb_extra.ma".
677lemma not_in_added_registers : ∀p : graph_params.
678∀globals : list ident.∀fn,f_regs,r.
679(∀lbl. code_has_label p globals (joint_if_code … fn) lbl →
680       ¬(bool_to_Prop (r ∈ (f_regs lbl)))) →
681¬ (r ∈ (set_from_list RegisterTag (added_registers p globals fn f_regs))).
682#p #globals #fn #f_regs #r #H whd in match added_registers; normalize nodelta
683@foldi_ind [@I] #lbl #labels_fn #stmt #regs * #lbl_not_in_fn #EQstmt #IH
684lapply(Prop_notb … IH) -IH * #IH
685lapply(H lbl ?)
686 [whd in match code_has_label; whd in match code_has_point; normalize nodelta
687  whd in match (stmt_at ????); >EQstmt @I]
688* #H1 @notb_elim @if_elim [2: #_ @I] #ABS
689lapply(mem_list_as_set … ABS) #ABS' cases(Exists_append … ABS') #ABS''
690[ @H1 @Exists_memb lapply ABS'' elim (f_regs lbl) [ *] #hd #tl #IH whd in ⊢ (% → %);
691  * [ #EQ >EQ % %] #H %2 @IH @H
692| @IH @list_as_set_mem assumption
693]
694qed.
695
696lemma Exists_append1 : ∀A.∀l1,l2 : list A.∀a : A.In A l1 a → In A (l1@l2) a.
697#A #l1 elim l1 [#l2 #a *] #hd #tl #IH *
698[#a normalize * [#H % assumption | #H %2 >append_nil assumption]]
699#hd1 #tl1 #a normalize * [#H % assumption | #H %2 @IH assumption]
700qed.
701
702lemma Exists_append2 : ∀A.∀l1,l2 : list A.∀a : A.In A l2 a → In A (l1@l2) a.
703#A #l1 #l2 lapply l1 -l1 elim l2 [#l1 #a *] #hd #tl #IH *
704[#a normalize * [#H %1 assumption| #H %2 assumption]]
705#hd1 #tl1 #a normalize *
706[ #H %2 >append_cons @Exists_append1 >H elim tl1 [% %] #hd2 #tl2 #H1 normalize %2 //
707| #H %2 >append_cons @IH assumption]
708qed.
709
710lemma append_All : ∀A : Type[0]. ∀ P : A → Prop. ∀l1,l2 : list A.
711All ? P (l1 @ l2) → All ? P l1 ∧ All ? P l2.
712#A #P #l1 elim l1
713[ #l2 change with l2 in ⊢ (???% → ?); #H % //]
714#a #tl #IH #l2 change with (P a ∧ All A P (tl @ l2)) in ⊢ (% → ?);
715* #H1 #H2 lapply(IH … H2) * #H3 #H4 % // whd % //
716qed.
717
718include alias "common/PositiveMap.ma".
719
720lemma added_register_pm : ∀A,B. ∀m : positive_map A.
721∀f : Pos → list B.∀b.
722let added ≝ fold A (list B) (λp.λ_.λacc.(f p)@acc) m [ ] in
723All B (λx.x≠b) added →
724(∀i. lookup_opt unit i (domain_of_pm A m) ≠ None ? → All B (λx.x≠b) (f i)).
725#A #B #m #f #b normalize nodelta @pm_fold_ind
726[ #_ #i normalize * #H @⊥ @H %
727| #p #ps #a #lst #H #H1 #H2 #H3 #i cases(decidable_eq_pos i p)
728  [1,3: #EQ destruct(EQ) #_ cases(append_All … H3) //
729  |*: #Hi >lookup_opt_insert_miss [2,4: assumption] @H2
730      cases(append_All … H3) //
731  ]
732]
733qed.
734
735lemma decidable_In : ∀A.∀l : list A. ∀a : A. (∀a'.decidable (a = a')) → 
736decidable (In A l a).
737#A #l elim l [ #a #_ %2 % *] #hd #tl #IH #a #DEC cases(IH a DEC)
738[ #H % %2 assumption | * #H cases (DEC hd)
739[ #H1 %1 %1 assumption | * #H1 %2 % * [ #H2 @H1 assumption | #H2 @H assumption]]
740qed.
741
742lemma In_all : ∀A.∀l : list A. ∀ a : A.¬In A l a → All A (λx.x≠a) l.
743#A #l elim l [ #a #_ @I] #hd #tl #IH #a * #H % [2: @IH % #H1 @H %2 assumption]
744% #H1 @H % >H1 %
745qed.
746
747lemma All_In : ∀A.∀l : list A. ∀ a : A.All A (λx.x≠a) l → ¬In A l a.
748#A #l elim l [#a #_ % *] #hd #tl #IH #a ** #H1 #H2 % *
749[ #H3 @H1 >H3 % | cases(IH a H2) #H3 #H4 @H3 assumption]
750qed.
751
752lemma added_register_aux : ∀tag,A,B.∀m : identifier_map tag A.
753∀f : identifier tag → list B.(∀b,b' : B.decidable (b=b')) →
754let added ≝ foldi A (list B) tag (λl.λ_.λacc. (f l)@acc) m [ ] in
755∀i,a,b.lookup tag A m i = Some ? a → In B (f i) b → In B added b.
756#tag #A #B * #m #f #DEC * #i #a #b whd in ⊢ (??%? → ?); normalize nodelta
757#H #H1
758cases(decidable_In ? (foldi A (list B) tag
759            (λl.λ_.λacc.(f l)@acc)
760              (an_id_map tag A m) []) b (DEC b)) [//]
761#H3 @⊥ lapply(In_all ??? H3) -H3 #H3
762lapply(added_register_pm ?? m ?? H3 i ?)
763[cases(domain_of_pm_present ? m i) #H4 #_ @H4 >H % #EQ destruct]
764lapply H1 elim (f ?) [*] #hd #tl #IH * [#EQ * >EQ * #H4 #_ @H4 %]
765#H4 * #_ @IH assumption
766qed.
767
768lemma in_added_registers : ∀p : graph_params.
769∀globals : list ident.∀fn,f_regs,r.
770∀lbl.code_has_label p globals (joint_if_code … fn) lbl →
771 In ? (f_regs lbl) r →
772In ? (added_registers p globals fn f_regs) r.
773#p #globals #fn #f_regs #r #lbl whd in match code_has_label;
774whd in match code_has_point; normalize nodelta whd in match (stmt_at ????);
775inversion(lookup LabelTag ???) [ #_ *] #stmt #EQstmt #_
776#H @(added_register_aux …  EQstmt H)
777* #p * #p' cases(decidable_eq_pos p p') [ #EQ destruct % % | * #H1 %2 % #EQ destruct @H1 %]
778qed.
779
780
781include alias "basics/lists/listb.ma".
782
783(*
784definition get_internal_function_from_ident :
785∀ p: sem_params. ∀ globals : list ident . ∀ge : genv_t (joint_function p globals).
786ident → option (joint_closed_internal_function p globals) ≝
787λp,globals,ge,id.
788! bl  ← (find_symbol (joint_function p globals) ge id);
789! bl' ← (code_block_of_block bl);
790! 〈f,fn〉 ← res_to_opt … (fetch_internal_function ? ge bl');
791return fn.
792
793lemma get_internal_function_from_ident_ok :
794∀p : sem_params. ∀globals : list ident. ∀ge : genv_t (joint_function p globals).
795∀bl,f,fn. fetch_internal_function ? ge bl = return 〈f,fn〉 →
796get_internal_function_from_ident p globals ge f= return fn.
797#p #globals #ge #bl #f #fn #EQf
798@('bind_inversion EQf) * #f1 * #fn1 whd in match fetch_function;
799normalize nodelta #H lapply(opt_eq_from_res ???? H) -H #H @('bind_inversion H) -H
800#f2 #EQf2 #H @('bind_inversion H) -H #fn2 #EQfn2 whd in ⊢ (??%% → ??%% → ?);
801#EQ1 #EQ2 destruct whd in match get_internal_function_from_ident; normalize nodelta
802>(symbol_of_block_rev … EQf2) >m_return_bind
803cut(code_block_of_block bl = return bl)
804 [ whd in match code_block_of_block; normalize nodelta @match_reg_elim
805   [ >(pi2 ?? bl) #ABS destruct] elim bl #bl1 #EQ #prf % ] #EQbl >EQbl
806>m_return_bind >EQf %
807qed.
808*)
809
810lemma eval_seq_no_pc_no_call_ok :
811∀prog : ertl_program.
812let trans_prog ≝ ertl_to_ertlptr prog in
813∀f_lbls : lbl_funct. ∀f_regs : regs_funct.
814∀stack_size.
815∀bl.∀id.
816∀fn : joint_closed_internal_function ERTL (prog_var_names … prog).∀seq.
817(∀l. code_has_label … (joint_if_code … fn) l → 
818(All … (λreg.bool_to_Prop(¬(reg ∈ (f_regs bl l))))
819       (get_used_registers_from_seq … (functs … ERTL) seq)))  →
820   preserving1 ?? res_preserve1 ????
821      (sigma_state prog f_lbls f_regs (added_registers … fn (f_regs bl)))
822      (sigma_state prog f_lbls f_regs (added_registers … fn (f_regs bl)))
823      (eval_seq_no_pc ERTL_semantics
824             (globals (mk_prog_params ERTL_semantics prog stack_size))
825             (ev_genv (mk_prog_params ERTL_semantics prog stack_size)) id seq)
826      (eval_seq_no_pc ERTLptr_semantics
827             (globals (mk_prog_params ERTLptr_semantics trans_prog stack_size))
828             (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_size))
829             id (seq_embed … seq)).
830#prog #f_lbls #f_regs #stack_size #bl #f #fn #seq #fresh_regs
831cases seq in fresh_regs;
832[ #c #_ #st @mfr_return1
833| #pm #fesh_regs #st whd in match pair_reg_move; normalize nodelta
834  @mfr_bind1
835  [ 2: change with (ertl_eval_move ??) in ⊢ (???????%%); @ertl_eval_move_ok
836       whd in match move_dst_not_fresh; normalize nodelta cases pm in fesh_regs;
837       * [#r1 | #R1] #m_src [2: #_ @I] normalize nodelta #fresh_regs
838       @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
839       whd in ⊢ (% → %); * #H #_ @Prop_notb @H
840  | | #regs  @mfr_return_eq1 %
841  ]
842| #r #fresh_regs #st @mfr_bind1
843  [2:  @pop_ok |
844  | * #bv #st whd in match acca_store; normalize nodelta @mfr_bind1
845    [2: @ps_reg_store_ok       
846        @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
847       whd in ⊢ (% → %); * #H #_ @Prop_notb @H
848    ]
849  ]
850| #r #_ #st @mfr_bind1
851  [2: whd in match acca_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
852  | #bv @push_ok
853  ]
854| #i
855  #i_spec
856  change with ((dpl_reg ERTL) → ?)
857  #dpl
858  change with ((dph_reg ERTL) → ?)
859  #dph #fresh_regs #st @mfr_bind1
860  [ @(sigma_state prog f_lbls f_regs (added_registers … fn (f_regs bl)))
861  | whd in match dpl_store; normalize nodelta @mfr_bind1
862    [2: @opt_safe_elim #bl #EQbl
863       @opt_safe_elim #bl'
864       >(find_symbol_transf …
865          (λvars.transf_fundef … (λfn.(b_graph_translate … fn))) prog i) in ⊢ (%→?);
866       >EQbl #EQ destruct whd in match sigma_state; normalize nodelta       
867       change with (sigma_beval prog f_lbls (BVptr …))
868                                               in ⊢ (???????(?????%?)?);
869       @ps_reg_store_ok
870              @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
871       whd in ⊢ (% → %); * #H #_ @Prop_notb @H |
872    | #regs  @mfr_return_eq1 %
873    ]
874  | #st1 @opt_safe_elim #bl #EQbl @opt_safe_elim #bl'   
875   >(find_symbol_transf …
876          (λvars.transf_fundef … (λfn.(b_graph_translate … fn))) prog i) in ⊢ (%→?);
877    >EQbl #EQ destruct whd in match dph_store; normalize nodelta @mfr_bind1
878    [2: whd in match sigma_state; normalize nodelta       
879       change with (sigma_beval prog f_lbls (BVptr …))
880                                               in ⊢ (???????(?????%?)?);
881      @ps_reg_store_ok @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
882       whd in ⊢ (% → %); * #_ * #H #_ @Prop_notb @H |
883    | #regs  @mfr_return_eq1 %
884    ]
885  ]     
886| #op #a #b #arg1 #arg2 #fresh_regs #st @mfr_bind1
887  [2: whd in match acca_arg_retrieve; whd in match sigma_state; normalize nodelta
888     @ps_arg_retrieve_ok |
889  | #bv1 @mfr_bind1
890   [2: whd in match accb_arg_retrieve; whd in match sigma_state; normalize nodelta
891      @ps_arg_retrieve_ok |
892   | #bv2 @mfr_bind1
893     [2: @be_opaccs_ok |
894     | * #bv3 #bv4 normalize nodelta @mfr_bind1
895       [ @(sigma_state prog f_lbls f_regs (added_registers … fn (f_regs bl)))
896       | whd in match acca_store; normalize nodelta @mfr_bind1
897         [2: @ps_reg_store_ok @not_in_added_registers #lbl #Hlbl
898             lapply(fresh_regs lbl Hlbl) whd in ⊢ (% → %); * #H #_ @Prop_notb @H |
899         | #regs  @mfr_return_eq1 %
900         ]
901       | #st1 whd in match accb_store; normalize nodelta @mfr_bind1
902         [2: whd in match sigma_state; normalize nodelta
903            @ps_reg_store_ok @not_in_added_registers #lbl #Hlbl
904            lapply(fresh_regs lbl Hlbl) whd in ⊢ (% → %); * #_ * #H #_ @Prop_notb @H |
905         | #regs  @mfr_return_eq1 %
906         ]         
907       ]
908     ]
909   ]
910  ] 
911| #op #r1 #r2 #fresh_regs #st @mfr_bind1
912  [ @(sigma_beval prog f_lbls)
913  | whd in match acca_retrieve; normalize nodelta @ps_reg_retrieve_ok
914  | #bv1 @mfr_bind1
915    [ @(sigma_beval prog f_lbls)
916    | @be_op1_ok
917    | #bv2 whd in match acca_store; normalize nodelta @mfr_bind1
918      [2: whd in match sigma_state; normalize nodelta @ps_reg_store_ok
919          @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
920       whd in ⊢ (% → %); * #H #_ @Prop_notb @H |
921      | #regs  @mfr_return_eq1 %
922      ]
923    ]
924  ]
925| #op2 #r1 #r2 #arg #fresh_regs #st @mfr_bind1
926  [2: whd in match acca_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
927  | #bv @mfr_bind1
928    [2: whd in match snd_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
929    | #bv1 @mfr_bind1
930      [2: @be_op2_ok |
931      | * #bv2 #b @mfr_bind1
932        [ @(sigma_state prog f_lbls f_regs (added_registers … fn (f_regs bl)))
933        | whd in match acca_store; normalize nodelta @mfr_bind1
934          [2: whd in match sigma_state; normalize nodelta @ps_reg_store_ok
935              @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
936              whd in ⊢ (% → %); * #H #_ @Prop_notb @H |
937          | #regs  @mfr_return_eq1 %
938          ]
939        | #st1 @mfr_return_eq1 %
940        ]
941      ]
942    ]
943  ]
944| #_ #st @mfr_return_eq1 %
945| #_ #st @mfr_return_eq1 %
946| #r1 #dpl #dph #fresh_regs #st @mfr_bind1
947  [2: whd in match dph_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
948  | #bv @mfr_bind1
949    [2: whd in match dpl_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
950    | #bv1 @mfr_bind1
951      [ @(λx.x)
952      | @(pointer_of_address_ok ? ? 〈bv1,bv〉)
953      | #ptr @mfr_bind1
954        [2: @opt_to_res_preserve1 @beloadv_ok |
955        | #bv2 whd in match acca_store; normalize nodelta @mfr_bind1
956          [2: whd in match sigma_state; normalize nodelta @ps_reg_store_ok
957          @not_in_added_registers #lbl #Hlbl lapply(fresh_regs lbl Hlbl)
958          whd in ⊢ (% → %); * #H #_ @Prop_notb @H |
959          | #regs  @mfr_return_eq1 %
960          ]
961        ] 
962      ]
963    ]
964  ] 
965| #dpl #dph #r #_ #st @mfr_bind1
966  [2: whd in match dph_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
967  | #bv @mfr_bind1
968    [2: whd in match dpl_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
969    | #bv1 @mfr_bind1
970      [ @(λx.x)
971      |  @(pointer_of_address_ok ? ? 〈bv1,bv〉)
972      | #ptr @mfr_bind1
973        [2: whd in match acca_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
974        | #bv2 @mfr_bind1
975          [2: @opt_to_res_preserve1 @bestorev_ok |
976          | #m @mfr_return_eq1 %
977          ]
978        ]
979      ]
980    ]
981  ]
982| #ext #fresh_regs #st whd in ⊢ (???????%%); whd in match (stack_sizes ????); cases (stack_size f)
983  normalize nodelta
984  [ @res_preserve_error1
985  | #n cases ext in fresh_regs; normalize nodelta
986    [1,2: #_ @mfr_bind1
987      [1,4: @(λx.x)
988      |2,5: @sp_ok
989      |3,6: #ptr @mfr_return_eq1 >set_sp_ok %
990      ]
991    | #r #fresh_regs whd in match ps_reg_store_status; normalize nodelta @mfr_bind1
992      [2: whd in match sigma_state; normalize nodelta
993          change with (sigma_beval prog f_lbls (BVByte ?))
994               in ⊢ (???????(??%?)?);
995          @ps_reg_store_ok  @not_in_added_registers #lbl #Hlbl
996          lapply(fresh_regs lbl Hlbl) whd in ⊢ (% → %); * #H #_ @Prop_notb @H |
997      | #regs @mfr_return_eq1 %
998      ]
999    ]
1000  ]     
1001]
1002#regs @mfr_return_eq1 %
1003qed.
1004
1005lemma partial_inj_sigma : ∀ prog : ertl_program.
1006∀f_lbls : lbl_funct.
1007let sigma ≝ get_sigma prog f_lbls in
1008∀id,lbl1,lbl2. sigma id lbl1 ≠ None ? → sigma id lbl1 = sigma id lbl2 → lbl1 = lbl2.
1009#prog #good #bl #lbl1 #lbl2 inversion(get_sigma … lbl1)
1010[#_ * #H @⊥ @H %] #lbl1' whd in match get_sigma; normalize nodelta
1011#H @('bind_inversion H) -H #bl' whd in match code_block_of_block; normalize nodelta
1012@match_reg_elim [#_ #ABS destruct] #prf #EQ destruct #H @('bind_inversion H) -H
1013* #id #fn #H lapply(res_eq_from_opt ??? H) -H #EQfn #H @('bind_inversion H) -H
1014* #lbl1'' #stmt1 #H1 whd in ⊢ (??%? → ?); #EQ destruct
1015#_ #H lapply(sym_eq ??? H) -H >m_return_bind >EQfn >m_return_bind
1016#H @('bind_inversion H) -H * #lbl2' #stmt2 #H2
1017whd in ⊢ (??%? → ?); #EQ destruct lapply(find_predicate ?????? H1)
1018lapply(find_predicate ?????? H2) cases(good ??) normalize nodelta
1019  [ normalize nodelta @eq_identifier_elim #EQ1 *
1020    @eq_identifier_elim #EQ2 * >EQ1 >EQ2 %
1021  | #lb #tl whd in match split_on_last; normalize nodelta whd in match (foldr ?????);
1022    cases( foldr label (option (list label×label)) … tl) normalize nodelta
1023    [2: * #x #lb1] @eq_identifier_elim #EQ1 * @eq_identifier_elim #EQ2 *
1024    >EQ1 >EQ2 %
1025  ]
1026qed.
1027
1028lemma pc_of_label_eq :
1029  ∀p,p'.let pars ≝ mk_sem_graph_params p p' in
1030  ∀globals,ge,bl,i_fn,lbl.
1031  fetch_internal_function ? ge bl = return i_fn →
1032  pc_of_label pars globals ge bl lbl =
1033    OK ? (pc_of_point ERTL_semantics bl lbl).
1034#p #p' #globals #ge #bl #i_fn #lbl #EQf
1035whd in match pc_of_label;
1036normalize nodelta >EQf >m_return_bind %
1037qed.
1038
1039lemma pop_ra_ok :
1040∀prog : ertl_program.
1041∀f_lbls : lbl_funct. ∀f_regs : regs_funct.
1042∀restr.
1043preserving1 … res_preserve1 …
1044     (sigma_state prog f_lbls f_regs restr)
1045     (λx.let 〈st,pc〉 ≝ x in
1046       〈sigma_state prog f_lbls f_regs restr st,
1047        sigma_stored_pc prog f_lbls pc〉)
1048     (pop_ra ERTL_semantics)
1049     (pop_ra ERTLptr_semantics).   
1050#prog #f_lbls #f_regs #restr1 #st whd in match pop_ra; normalize nodelta
1051@mfr_bind1
1052[ | @pop_ok ] * #bv #st1 @mfr_bind1 [ | @pop_ok] * #bv1 #st2 @mfr_bind1
1053[ @(sigma_stored_pc prog f_lbls)
1054| whd in match pc_of_bevals; normalize nodelta
1055  cases bv [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc #p]
1056  whd in match sigma_beval; normalize nodelta try @res_preserve_error1
1057  inversion(sigma_pc_opt ? ? ?) normalize nodelta [ #_ @res_preserve_error1]
1058  #sigma_pc #sigma_pc_spec normalize nodelta cases bv1
1059  [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1060  normalize nodelta try @res_preserve_error1
1061  inversion(sigma_pc_opt ? ? ?) normalize nodelta [#_ @res_preserve_error1]
1062  #sigma_pc1 #sigma_pc1_spec @if_elim [2: #_ @res_preserve_error1]
1063  @andb_elim @if_elim [2: #_ *] @andb_elim @if_elim [2: #_ *]
1064  #_ #H >H @eq_program_counter_elim [2: #_ *]
1065  #EQspc * @eq_program_counter_elim
1066  [#_ normalize nodelta @mfr_return_eq1 whd in match sigma_stored_pc; normalize nodelta
1067   >sigma_pc1_spec %] * #H1 @⊥ @H1 >EQspc in sigma_pc_spec; <sigma_pc1_spec
1068   whd in match sigma_pc_opt; normalize nodelta @if_elim
1069  [ #H2 #EQ lapply(sym_eq ??? EQ) -EQ @if_elim [#_  whd in ⊢ (??%% → ?); #EQ destruct %]
1070    #H3 #H @('bind_inversion H) -H #x #H4 whd in ⊢ (??%? → ?); #EQ destruct >H2 in H3; *
1071  | #H2 @if_elim
1072    [ #H3 #H @('bind_inversion H) -H #x1 #_ whd in match pc_of_point; normalize nodelta
1073      whd in ⊢ (??%? → ?); #EQ destruct >H3 in H2; *
1074    | #H3 lapply sigma_pc1_spec; whd in match sigma_pc_opt; normalize nodelta @if_elim
1075     [#H >H in H3; *] #_ #EQ >EQ @('bind_inversion EQ) -EQ * #x cases pc1 #bl1 #pos1
1076     whd in match (point_of_pc ??); #x_spec whd in match (pc_of_point ???);
1077     whd in match (offset_of_point ??); whd in ⊢ (??%? → ?); #EQ destruct
1078     #H @('bind_inversion H) -H * #lbl cases pc #bl #pos whd in match (point_of_pc ??);
1079     #lbl_spec whd in match pc_of_point; normalize nodelta
1080     whd in match (offset_of_point ??); whd in ⊢ (??%? → ?); #EQ destruct
1081     @eq_f cut(an_identifier LabelTag pos = an_identifier LabelTag pos1 → pos = pos1)
1082     [ #EQ destruct %] #APP @APP @(partial_inj_sigma prog f_lbls bl1 …)
1083     [ >lbl_spec % #EQ destruct] >x_spec >lbl_spec %
1084    ]
1085  ]
1086| #pc @mfr_return_eq1 %
1087]
1088qed.
1089
1090lemma pc_block_eq : ∀prog : ertl_program. ∀f_lbls,pc.
1091sigma_pc_opt prog f_lbls pc ≠ None ? →
1092 pc_block … pc = pc_block … (sigma_stored_pc prog f_lbls pc).
1093#prog #sigma * #bl #pos whd in match sigma_stored_pc; normalize nodelta
1094inversion(sigma_pc_opt ???) [ #_ * #H @⊥ @H %] #pc
1095whd in match sigma_pc_opt; normalize nodelta @if_elim
1096[#_ whd in ⊢ (??%? → ?); #EQ destruct #_ %] #_
1097#H @('bind_inversion H) -H * #lbl #_
1098 whd in ⊢ (??%? → ?); #EQ destruct
1099#_ %
1100qed.
1101
1102include "joint/extra_joint_semantics.ma".
1103
1104lemma pop_frame_ok : ∀prog : ertl_program.
1105let trans_prog ≝ ertl_to_ertlptr prog in
1106∀f_lbls : lbl_funct. ∀f_regs : regs_funct.
1107∀restr.
1108preserving1 ?? res_preserve1 ????
1109       (sigma_state prog f_lbls f_regs restr)
1110       (λx.let 〈st,pc〉 ≝ x in
1111           match fetch_internal_function ? (globalenv_noinit … prog)
1112                 (pc_block pc) with
1113                  [ OK y ⇒ let 〈id,f〉 ≝ y in
1114                           〈sigma_state prog f_lbls f_regs
1115                                 (added_registers ERTL (prog_var_names … prog) f
1116                             (f_regs (pc_block pc))) st,
1117                            sigma_stored_pc prog f_lbls pc〉
1118                  | Error e ⇒ 〈dummy_state,null_pc one〉
1119                  ])
1120       (ertl_pop_frame)
1121       (ertl_pop_frame).
1122#prog #f_lbls #f_regs #restr #st whd in match ertl_pop_frame; normalize nodelta
1123@mfr_bind1
1124[ @(λx.match sigma_frames_opt prog f_lbls f_regs x with [Some l ⇒ l | None ⇒ [ ]])
1125| @opt_to_res_preserve1 whd in match sigma_state; normalize nodelta
1126  cases(st_frms … st) [@opt_preserve_none1] #l whd in match sigma_frames;
1127  normalize  nodelta >m_return_bind #x #x_spec %{l} % [%] >x_spec %
1128| * normalize nodelta [@res_preserve_error1] * #loc_mem #bl #tl normalize nodelta
1129  inversion(sigma_frames_opt ????) normalize nodelta [ #_ @res_preserve_error1]
1130  #l whd in match sigma_frames_opt; whd in match m_list_map; normalize nodelta
1131  whd in match (foldr ?????); normalize nodelta inversion(fetch_internal_function ???)
1132  normalize nodelta [2: #e #_ #ABS destruct(ABS)] * #f #fn #EQfn
1133  #H @('bind_inversion H) -H #l1
1134  change with (sigma_frames_opt prog f_lbls f_regs tl = ? → ?) #EQl1
1135  whd in ⊢ (??%? → ?); #EQ destruct(EQ) @mfr_bind1
1136  [2: whd in match sigma_state; whd in match set_regs; whd in match set_frms;
1137     normalize nodelta
1138     cut( 〈sigma_register_env prog f_lbls
1139     (added_registers ERTL (prog_var_names (joint_function ERTL) ℕ prog) fn
1140      (f_regs bl))
1141     loc_mem,
1142    \snd  (sigma_regs prog f_lbls restr (regs ERTLptr_semantics st))〉 =
1143    sigma_regs prog f_lbls 
1144     (added_registers ERTL (prog_var_names (joint_function ERTL) ℕ prog) fn
1145      (f_regs bl)) (〈loc_mem,\snd  (regs ERTL_state st)〉)) [
1146      whd in match sigma_regs; normalize nodelta cases(regs … st) #x1 #x2
1147      %] #EQ >EQ -EQ <EQl1 in ⊢ (???????%?);
1148      change with (sigma_state prog f_lbls f_regs
1149    (added_registers ERTL (prog_var_names … prog) fn (f_regs bl))
1150      (mk_state ? (Some ? tl) (istack … st) (carry … st) (〈loc_mem,\snd (regs … st)〉)
1151      (m … st))) in ⊢ (???????(??%)?); @pop_ra_ok |
1152  | * #st1 #pc1 @if_elim normalize nodelta [2: #_ @res_preserve_error1]
1153   normalize nodelta @eq_block_elim [2: #_ *] #EQbl1 * @if_elim
1154   [2: >EQbl1 @eq_block_elim [#_ *] * #H @⊥ @H <pc_block_eq [%] %
1155       cases bl in EQbl1 EQfn; #p1 #p2 #EQ destruct lapply p2
1156       whd in match sigma_stored_pc; normalize nodelta cases(sigma_pc_opt ???)
1157       normalize nodelta [2: #pc2] #p2 [#_ #EQ destruct]
1158       >fetch_internal_function_no_zero [2: %] #EQ destruct
1159   |   @eq_block_elim [2: #_ *] #EQbl11 * @mfr_return_eq1 normalize nodelta
1160       cases bl in EQbl11 EQfn; #p1 #p2 #EQ destruct
1161       lapply p2 cases(pc_block pc1) #p11 #p22 #e #EQfn1 >EQfn1 %
1162   ]
1163  ]
1164]
1165qed.
1166
1167lemma fetch_ok_sigma_pc_ok :∀prog : ertl_program.
1168∀ f_lbls,f_regs,id,fn,st.
1169fetch_internal_function … (globalenv_noinit … prog)
1170(pc_block (pc … (sigma_state_pc prog f_lbls f_regs st))) = return 〈id,fn〉 →
1171pc … (sigma_state_pc prog f_lbls f_regs st) = pc … st.
1172#prog #f_lbls #f_regs #id #fn #st whd in match sigma_state_pc;
1173normalize nodelta cases(fetch_internal_function ?? (pc_block (pc … st)))
1174normalize nodelta [* #id1 #fn1 #_ %]
1175#e >fetch_internal_function_no_zero [2: %] whd in ⊢ (???% → ?); #EQ destruct(EQ)
1176qed.
1177
1178lemma fetch_ok_sigma_state_ok : ∀prog : ertl_program.
1179∀ f_lbls,f_regs,id,fn,st.
1180fetch_internal_function … (globalenv_noinit … prog)
1181(pc_block (pc … (sigma_state_pc prog f_lbls f_regs st))) = return 〈id,fn〉 →
1182let added ≝ (added_registers ERTL (prog_var_names … prog) fn
1183                                               (f_regs (pc_block (pc … st)))) in
1184st_no_pc … (sigma_state_pc prog f_lbls f_regs st) =
1185sigma_state prog f_lbls f_regs added (st_no_pc … st).
1186#prog #f_lbls #f_regs #id #fn #st #EQf whd in match sigma_state_pc;
1187normalize nodelta <(fetch_ok_sigma_pc_ok … EQf) >EQf %
1188qed.
1189
1190lemma fetch_ok_sigma_pc_block_ok : ∀prog : ertl_program.
1191∀ f_lbls,id,fn,pc.
1192fetch_internal_function … (globalenv_noinit … prog)
1193(pc_block (sigma_stored_pc prog f_lbls pc)) = return 〈id,fn〉 →
1194pc_block (sigma_stored_pc prog f_lbls pc) = pc_block pc.
1195#prog #f_lbls #id #fn #pc #EQf <pc_block_eq [%]
1196lapply EQf whd in match sigma_stored_pc; normalize nodelta
1197cases(sigma_pc_opt ???) normalize nodelta [2: #pc #_ % #EQ destruct(EQ)]
1198>fetch_internal_function_no_zero [2: %] whd in ⊢ (???% → ?); #EQ destruct(EQ)
1199qed.
1200
1201lemma fetch_stmt_ok_sigma_pc_ok : ∀prog : ertl_program.
1202∀ f_lbls,f_regs,id,fn,stmt,st.
1203fetch_statement ERTL_semantics (prog_var_names … prog)
1204    (globalenv_noinit … prog) (pc … (sigma_state_pc prog f_lbls f_regs st)) =
1205               return 〈id,fn,stmt〉 →
1206pc … (sigma_state_pc prog f_lbls f_regs st) = pc … st.
1207#prog #f_lbls #f_regs #id #fn #stmt #st #H @('bind_inversion H)
1208* #id1 #fn1 #EQfn1 #_ @(fetch_ok_sigma_pc_ok … EQfn1)
1209qed.
1210
1211lemma fetch_stmt_ok_sigma_state_ok : ∀prog : ertl_program.
1212∀ f_lbls,f_regs,id,fn,stmt,st.
1213fetch_statement ERTL_semantics (prog_var_names … prog)
1214    (globalenv_noinit … prog) (pc … (sigma_state_pc prog f_lbls f_regs st)) =
1215               return 〈id,fn,stmt〉 →
1216let added ≝ (added_registers ERTL (prog_var_names … prog) fn
1217                                               (f_regs (pc_block (pc … st)))) in
1218st_no_pc … (sigma_state_pc prog f_lbls f_regs st) =
1219sigma_state prog f_lbls f_regs added (st_no_pc … st).
1220#prog #f_lbls #f_regs #id #fn #stmt #st #H @('bind_inversion H) -H
1221* #id1 #fn1 #EQfn1 #H @('bind_inversion H) -H #stmt1 #_
1222whd in ⊢ (??%% → ?); #EQ destruct(EQ) @(fetch_ok_sigma_state_ok … EQfn1)
1223qed.
1224
1225lemma fetch_stmt_ok_sigma_pc_block_ok : ∀prog : ertl_program.
1226∀ f_lbls,id,fn,stmt,pc.
1227fetch_statement ERTL_semantics (prog_var_names … prog)
1228  (globalenv_noinit … prog) (sigma_stored_pc prog f_lbls pc) = return 〈id,fn,stmt〉 →
1229pc_block (sigma_stored_pc prog f_lbls pc) = pc_block pc.
1230#prog #f_lbls #id #fn #stmt #st #H @('bind_inversion H) -H
1231* #id1 #fn1 #EQfn1 #H @('bind_inversion H) -H #stmt1 #_
1232whd in ⊢ (??%% → ?); #EQ destruct(EQ) @(fetch_ok_sigma_pc_block_ok … EQfn1)
1233qed.
1234
1235lemma fetch_ok_sigma_last_pop_ok :∀prog : ertl_program.
1236∀ f_lbls,f_regs,id,fn,st.
1237fetch_internal_function … (globalenv_noinit … prog)
1238(pc_block (pc … (sigma_state_pc prog f_lbls f_regs st))) = return 〈id,fn〉 →
1239last_pop … (sigma_state_pc prog f_lbls f_regs st) =
1240sigma_stored_pc prog f_lbls (last_pop … st).
1241#prog #f_lbls #f_regs #id #fn #st whd in match sigma_state_pc; normalize nodelta
1242cases(fetch_internal_function ?? (pc_block (pc … st))) normalize nodelta
1243[ * #x #y #_ %] #e >fetch_internal_function_no_zero [2: %] whd in ⊢ (???% → ?);
1244#EQ destruct(EQ)
1245qed.
1246
1247lemma fetch_stmt_ok_sigma_last_pop_ok :∀prog : ertl_program.
1248∀ f_lbls,f_regs,id,fn,stmt,st.
1249fetch_statement ERTL_semantics (prog_var_names … prog)
1250    (globalenv_noinit … prog) (pc … (sigma_state_pc prog f_lbls f_regs st))
1251    = return 〈id,fn,stmt〉 →
1252last_pop … (sigma_state_pc prog f_lbls f_regs st) =
1253sigma_stored_pc prog f_lbls (last_pop … st).
1254#prog #f_lbls #f_regs #id #fn #stmt #st #H @('bind_inversion H) -H
1255* #id1 #fn1 #EQfn1 #H @('bind_inversion H) -H #stmt1 #_
1256whd in ⊢ (??%% → ?); #EQ destruct(EQ) @(fetch_ok_sigma_last_pop_ok … EQfn1)
1257qed.
1258
1259lemma excluded_middle_list :
1260∀A : Type[0]. ∀P : A → Prop.∀ l : list A. (∀a : A.In A l a → decidable … (P a)) →
1261All … P l ∨ Exists … (λa.¬(P a)) l.
1262#A #P #l elim l [#_  % %] #hd #tl #IH #Dec
1263cases IH [ cases(Dec hd ?)
1264            [ #H1 #H2 % whd % assumption
1265            | #H #_ %2 whd % assumption
1266            | % %
1267            ]
1268         | #H %2 whd %2 assumption
1269         | #a #H @Dec %2 assumption
1270         ]
1271qed.
1272
1273lemma code_block_of_block_eq : ∀bl : Σb.block_region b = Code.
1274code_block_of_block bl = return bl.
1275* #bl #prf whd in match code_block_of_block; normalize nodelta @match_reg_elim
1276[ >prf in ⊢ (% → ?); #ABS destruct(ABS)] #prf1 %
1277qed.
1278
1279lemma split_on_last_append : ∀A : Type[0]. ∀pre : list A.
1280∀ last : A. split_on_last ? (pre@[last]) = return 〈pre,last〉.
1281#A #pre elim pre [#last %] #a #tl #IH #last whd in ⊢ (??%?);lapply(IH last)
1282whd in ⊢ (??%? → ?); #EQ >EQ %
1283qed.
1284
1285include alias "common/Identifiers.ma".
1286
1287lemma get_sigma_idempotent :
1288∀prog : ertl_program.
1289∀ f_lbls,f_regs.
1290 ∀f_bl_r.
1291 b_graph_transform_program_props ERTL_semantics ERTLptr_semantics
1292     (λglobals,fn.«translate_data globals fn,(refl …)») prog f_bl_r f_lbls f_regs →
1293∀id,fn,bl,pt,stmt.
1294fetch_internal_function … (globalenv_noinit … prog) bl = return 〈id,fn〉 →
1295stmt_at ERTL (prog_var_names … prog) (joint_if_code … fn) pt = return stmt → 
1296f_lbls bl pt = [ ] → get_sigma prog f_lbls bl pt = return pt.
1297#prog #f_lbls #f_regs #f_bl_r #good #id #fn #bl #pt #stmt #EQfn #EQstmt #EQlabels
1298cases(b_graph_transform_program_fetch_internal_function … good … EQfn)
1299#init_data * #calling' ** #EQcalling' whd in ⊢ (% → ?); cases(f_bl_r ?)
1300[2,4: #x #y *] normalize nodelta #EQ destruct(EQ) * #_ #_ #_ #_ #_
1301#_ #fresh_labs #_ #_ #_ #H lapply(H … EQstmt) -H cases stmt in EQstmt;
1302[3: *
1303|2: * [#lbl || *] #EQstmt normalize nodelta * #bl * whd in ⊢ (% → ?);
1304   inversion (f_regs ??) [2,4: #x #y #_ #_ *] #EQregs normalize nodelta
1305   #EQ destruct(EQ) whd in ⊢ (%→?); * #pref * #mid ** #EQmid whd in ⊢ (% → ?);
1306   * #EQ1 #EQ2 destruct(EQ1 EQ2) whd in ⊢ (% → ?); #EQt_stmt
1307| * [#c | * [#c_id|#c_ptr] #args #dest | #r #lbl | #seq ] #nxt #EQstmt
1308  whd in ⊢ (% → ?); * #bl >if_merge_right [2,4,6,8,10: %] * whd in ⊢ (% → ?);
1309  inversion(f_regs ??) normalize nodelta
1310  [2,4,5,8,10: [1,2,4,5: #x #y] #_ [1,2,3,4: #_] *|6: #r * [2: #x #y] ]
1311  [1,2: #_] #EQregs [1,2: whd in ⊢ (% → ?); [*]] #EQ destruct(EQ) whd in ⊢ (% → ?);
1312  * #l1 * #mid1 * #mid2 * #l2 *** #EQmid1 whd in ⊢ (%→ ?);
1313  [ * #mid * #rest ** #EQ destruct(EQ) whd in ⊢ (% → ?); * #nxt1 *
1314    #EQlow change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ)
1315    whd in ⊢ (% → ?); * #mid3 * #rest1 ** #EQ destruct(EQ)
1316     whd in EQmid1 : (???%); destruct(EQmid1) whd in e0 : (???%); >EQlabels in e0;
1317    #e0 destruct(e0) ] * #EQ1 #EQ2 destruct(EQ1 EQ2) whd in EQmid1 : (???%);
1318     destruct(EQmid1) whd in ⊢ (% → ?); * #nxt1 * #EQt_stmt
1319     change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1320     * #_ #EQ destruct(EQ) ]
1321whd in match get_sigma; normalize nodelta >code_block_of_block_eq >m_return_bind
1322>EQfn >m_return_bind inversion(find ????)
1323[1,3,5,7,9,11: #EQfind @⊥ lapply(find_none ?????? EQfind EQstmt) >EQlabels
1324  normalize nodelta @eq_identifier_elim [1,3,5,7,9,11: #_ * |*: * #H #_ @H %]]
1325* #lbl #s #EQfind >m_return_bind lapply(find_predicate ?????? EQfind)
1326inversion(f_lbls ??)
1327[1,3,5,7,9,11: #_ normalize nodelta @eq_identifier_elim [2,4,6,8,10,12: #_ *] #EQ #_ >EQ %]
1328#lb #l @(list_elim_left … l …) normalize nodelta
1329[1,3,5,7,9,11: #_ #EQlb @eq_identifier_elim
1330               [1,3,5,7,9,11: #EQ destruct(EQ) #_ @⊥ |*: #_ *]
1331               lapply(fresh_labs lbl) >EQlb *** #H #_ #_ @H
1332               @(code_is_in_universe … (pi2 ?? fn)) whd in match code_has_label;
1333               whd in match code_has_point; normalize nodelta >EQstmt @I ]
1334#last #pre #_ #_ #EQlbl >(split_on_last_append … (lb::pre) last)
1335normalize nodelta @eq_identifier_elim
1336[2,4,6,8,10,12: #_ *] #EQ lapply EQlbl destruct(EQ) #EQlbl #_ @⊥
1337lapply(fresh_labs lbl) >EQlbl whd in ⊢ (% → ?); * #_ #H lapply(append_All … H) -H
1338* #_ whd in ⊢ (% → ?); *** #H #_ #_ @H -H @(code_is_in_universe … (pi2 ?? fn))
1339whd in match code_has_label; whd in match code_has_point; normalize nodelta
1340>EQstmt @I
1341qed.
1342
1343lemma append_absurd : ∀A : Type[0]. ∀l : list A. ∀ a : A.
1344l @ [a] = [ ] → False.
1345#A * [2: #x #y] #a normalize #EQ destruct
1346qed.
1347
1348lemma last_append_eq : ∀A : Type[0].∀l1,l2 : list A. ∀a1,a2: A.
1349l1 @ [a1] = l2 @ [a2] → a1 = a2.
1350#A #l1 elim l1 [ * [2: #hd #tl] #a1 #a2 normalize #EQ destruct [2: %]
1351@⊥ lapply(sym_eq ??? e0) -e0 #e0 @(append_absurd ??? e0)] #hd #tl #IH
1352* [ #a1 #a2 normalize #EQ destruct @⊥ @(append_absurd ??? e0)]
1353#hd1 #tl1 #a1 #a2 normalize #EQ destruct(EQ) @(IH tl1 a1 a2 e0)
1354qed.
1355
1356
1357lemma get_sigma_last :
1358∀prog : ertl_program.
1359∀ f_lbls,f_regs.
1360 ∀f_bl_r.
1361 b_graph_transform_program_props ERTL_semantics ERTLptr_semantics
1362     (λglobals,fn.«translate_data globals fn,(refl …)») prog f_bl_r f_lbls f_regs →
1363∀id,fn,bl,pt,stmt,pre,last.
1364fetch_internal_function … (globalenv_noinit … prog) bl = return 〈id,fn〉 →
1365stmt_at ERTL (prog_var_names … prog) (joint_if_code … fn) pt = return stmt → 
1366f_lbls bl pt = pre@[last] → get_sigma prog f_lbls bl last = return pt.
1367#prog #f_lbls #f_regs #f_bl_r #good #id #fn #bl #pt #stmt #pre #last
1368#EQfn #EQstmt #EQlabels
1369cases(b_graph_transform_program_fetch_internal_function … good … EQfn)
1370#init_data * #calling' ** #EQcalling' whd in ⊢ (% → ?); cases(f_bl_r ?)
1371[2: #x #y *] normalize nodelta #EQ destruct(EQ) * #_ #_ #_ #_ #pp_labs
1372#_ #fresh_labs #_ #_ #_ #H lapply(H … EQstmt) -H normalize nodelta
1373cases stmt in EQstmt; normalize nodelta
1374[3: *
1375|2: * [#lbl || *] #EQstmt whd in ⊢ (%→ ?); * #bl *
1376|*: * [#c | * [ #c_id | #c_ptr] #args #dest | #r #lbl | #seq ] #nxt #EQstmt
1377    >if_merge_right [2,4,6,8,10: %] whd in ⊢ (% → ?); * #bl *
1378]
1379whd in ⊢ (% → ?); inversion(f_regs ??) normalize nodelta
1380[2,4,6,8,9,12,14: [1,2,3,4,6,7: #x #y #_] #_ *|10: #r #tl #_] #EQregs
1381[ whd in ⊢ (% → ?); cases tl in EQregs; normalize nodelta [2: #x #y #_ *] #EQregs]
1382#EQbl destruct(EQbl) whd in ⊢ (%→?); [2,3: * #pref * #mid **|*: * #l1 * #mid1 * #mid2 * #l2 ***]
1383#EQmid1 whd in ⊢ (% → ?);
1384[1,2,4,5,6,7: * #EQ1 #EQ2 destruct(EQ1 EQ2) whd in EQmid1 : (??%%); destruct(EQmid1)               
1385[3,4,5,6: whd in ⊢ (% → ?); * #nxt1 * #EQt_stmt  #EQ destruct(EQ) ]
1386whd in ⊢ (% → ?); * [1,2,3,4: #e0] @⊥ >EQlabels in e0; #e0 @(append_absurd ??? e0)]
1387* #mid * #rest ** #EQ destruct(EQ) whd in ⊢ (% → ?); * #nxt1 * #_
1388change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1389* #mid3 * #rest1 ** #EQ destruct(EQ) whd in ⊢ (% → ?); * #nxt1 * #_
1390change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1391* #mid4 * #rest2 ** #EQ destruct(EQ)  whd in ⊢ (% → ?); * #nxt1 * #_
1392change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1393* #mid5 * #rest3 ** #EQ destruct(EQ) whd in ⊢ (% → ?); * #nxt1 * #_
1394change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1395* #EQ1 #EQ2 destruct(EQ1 EQ2) whd in ⊢ (% → ?); * #nxt1 * #EQcall
1396change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1397* #EQ1 #EQ2 destruct(EQ1 EQ2) whd in EQmid1 : (??%%); destruct(EQmid1)
1398>e0 in EQlabels; #EQlabels whd in match get_sigma; normalize nodelta
1399>code_block_of_block_eq >m_return_bind >EQfn >m_return_bind
1400inversion(find ????)
1401[ #EQfind @⊥ lapply(find_none ?????? EQfind EQstmt) >e0
1402  normalize nodelta @eq_identifier_elim [ #_ *] * #H #_ @H
1403  >(last_append_eq ????? EQlabels) % ]
1404* #lbl #s #EQfind >m_return_bind lapply(find_predicate ?????? EQfind)
1405inversion(f_lbls ??)
1406[ #EQlbl normalize nodelta @eq_identifier_elim [2: #_ *] #EQ destruct(EQ)
1407  lapply(last_append_eq ????? EQlabels) #EQ destruct(EQ) @⊥
1408  lapply(fresh_labs pt) >e0 * #_ * #_ * #_ *** #H #_ #_ @H -H
1409   @(code_is_in_universe … (pi2 ?? fn)) whd in match code_has_label;
1410  whd in match code_has_point; normalize nodelta whd in match (stmt_at ????);
1411  >(find_lookup ?????? EQfind) @I
1412]
1413#lb #labels #_  @(list_elim_left … (labels) …) -labels normalize nodelta
1414[2: #last1 #pre #_] #EQl [ >(split_on_last_append … (lb::pre) last1) ]
1415normalize nodelta @eq_identifier_elim [2,4: #_ *] #EQ destruct(EQ) #_
1416lapply(last_append_eq ????? EQlabels) #EQ destruct(EQ)
1417lapply pp_labs whd in match partial_partition; normalize nodelta * #_ #H
1418lapply(H lbl pt) >e0 whd in EQmid : (??%%); >EQl
1419#H [ >(H last1 ? ?) | >(H lb ? ?) ] [1,4: %
1420               |6: whd in match (memb ???); @if_elim [#_ @I]
1421                  #H lapply(Prop_notb ? H) * -H #H @⊥ @H cases lb #x normalize
1422                  @if_elim [#_ %] #H lapply(Prop_notb ? H) * -H #H @H >(eqb_n_n x) %
1423               |5: >(memb_append_l2 ? lb ? [lb] ?) /2 by /
1424               |*: >(memb_append_l2 ? last1 ? [last1] ?) /2 by /
1425                   @Exists_memb %2 elim pre [ % % | #hd #tl #IH %2 @IH]
1426               ]
1427qed.
1428
1429
1430lemma fetch_call_commute :
1431∀prog : ertl_program.
1432let trans_prog ≝ ertl_to_ertlptr prog in
1433∀ f_lbls,f_regs.
1434 ∀f_bl_r.
1435 b_graph_transform_program_props ERTL_semantics ERTLptr_semantics
1436     (λglobals,fn.«translate_data globals fn,(refl …)») prog f_bl_r f_lbls f_regs →
1437∀id,fn,c_id,c_args,c_dest,nxt,pc.
1438fetch_statement ERTL_semantics
1439    (prog_var_names … prog) (globalenv_noinit … prog) pc =
1440    return 〈id,fn, sequential ? ?(CALL ERTL_semantics ? c_id c_args c_dest) nxt〉 →
1441∃fn',pc'. sigma_stored_pc prog f_lbls pc' = pc ∧
1442fetch_statement ERTLptr_semantics
1443    (prog_var_names … trans_prog) (globalenv_noinit … trans_prog) pc' =
1444return 〈id,fn', sequential ? ?(CALL ERTLptr_semantics ? c_id c_args c_dest) nxt〉.
1445#prog #f_lbls #f_regs #f_bl_r #good #id #fn * [ #c_id | #c_ptr ] #c_args #c_dest
1446#nxt #pc #EQfetch lapply(fetch_statement_inv … EQfetch) * #EQfn #EQstmt
1447cases(b_graph_transform_program_fetch_internal_function … good … EQfn)
1448#init_data * #calling' ** #EQcalling' whd in ⊢ (% → ?); cases(f_bl_r ?)
1449[2,4: #x #y *] normalize nodelta #EQ destruct(EQ) * #_ #_ #_ #_ #_
1450#_ #_ #_ #_ #_ #H cases(H … EQstmt) -H #bl whd in ⊢ (% → ?); *
1451>if_merge_right [2,4: %] whd in match translate_step;
1452normalize nodelta whd in ⊢ (% → ?); inversion(f_regs ??) normalize nodelta
1453[|2,3:[ #x #y #_] #_ * |4: #r #tl #_ ] #EQregs
1454[ | cases tl in EQregs; [2: #x #y #_ *] #EQregs whd in ⊢ (% → ?);] #EQ destruct(EQ)
1455whd in ⊢ (% → ?); * #pre_l * #mid1 * #mid2 * #post_l *** #EQmid1 whd in ⊢ (% → ?);
1456[2: * #mid * #resg ** #EQ destruct(EQ) whd in ⊢ (% → ?);
1457  * #nxt1 * #EQlow change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ)
1458  whd in ⊢ (% → ?); * #mid3 * #rest1 ** #EQ destruct(EQ) * #nxt1 *
1459  #EQpush1 change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ)
1460  whd in ⊢ (% → ?); * #mid4 * #rest2 ** #EQ destruct(EQ) * #nxt1 * #EQhigh
1461  change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1462  * #mid5 * #rest3 ** #EQ destruct(EQ) * #nxt1 * #EQpush2
1463  change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ) whd in ⊢ (% → ?);
1464] * #EQ1 #EQ2 destruct(EQ1 EQ2) whd in EQmid1 : (??%%); destruct(EQmid1)
1465whd in ⊢ (% → ?); * #nxt1 * #EQcall #EQ destruct(EQ) whd in ⊢ (% → ?);
1466* #EQ destruct(EQ) change with nxt1 in ⊢ (??%? → ?); #EQ destruct(EQ)
1467%{calling'}
1468[  %{(pc_of_point ERTLptr_semantics (pc_block pc) mid1)}
1469|  %{pc}
1470] %
1471[1,3: whd in match sigma_stored_pc; whd in match sigma_pc_opt; normalize nodelta
1472      @eqZb_elim change with (pc_block pc) in match (pc_block ?) in ⊢ (% → ?);
1473      [1,3: #EQbl >fetch_internal_function_no_minus_one in EQfn; try assumption
1474            #EQ destruct(EQ)] #_ normalize nodelta
1475            [2: >(get_sigma_idempotent … good … EQfn EQstmt EQ)
1476            |*: change with (pc_block pc) in match (pc_block ?);
1477                >point_of_pc_of_point >(get_sigma_last … good … EQfn EQstmt e0)
1478            ] >m_return_bind normalize nodelta >pc_of_point_of_pc %
1479|*: whd in match fetch_statement; normalize nodelta >EQcalling' >m_return_bind
1480    [>point_of_pc_of_point ] >EQcall %
1481]
1482qed.
1483
1484
1485
1486lemma next_of_call_pc_ok : ∀prog : ertl_program.
1487let trans_prog ≝ ertl_to_ertlptr prog in
1488∀ f_lbls,f_regs.∀f_bl_r.
1489b_graph_transform_program_props ERTL_semantics ERTLptr_semantics
1490     (λglobals,fn.«translate_data globals fn,(refl …)») prog f_bl_r f_lbls f_regs →
1491∀pc,lb.
1492next_of_call_pc ERTL_semantics (prog_var_names … prog) (globalenv_noinit … prog)
1493  pc = return lb →
1494∃pc'. sigma_stored_pc prog f_lbls pc' = pc ∧ 
1495next_of_call_pc ERTLptr_semantics (prog_var_names … trans_prog)
1496             (globalenv_noinit … trans_prog) pc' =  return lb.
1497#prog #f_lbls #f_regs #f_bl_r #good #pc #lb whd in match next_of_call_pc;
1498normalize nodelta #H @('bind_inversion H) -H ** #id #fn
1499*  [ *[ #c | #c_id #c_arg #c_dest | #reg #lbl | #seq ] #prox | #fin | *]
1500#EQfetch normalize nodelta whd in ⊢ (??%% → ?); #EQ destruct(EQ)
1501cases(fetch_call_commute … good … EQfetch) #fn1 * #pc1 * #EQpc1 #EQt_fetch
1502%{pc1} % [assumption] >EQt_fetch %
1503qed.
1504
1505lemma next_of_call_pc_error : ∀pars.∀prog : program ? ℕ. ∀init,pc.
1506(block_id (pi1 … (pc_block pc)) = 0 ∨ block_id (pi1 … (pc_block pc)) = -1) →
1507next_of_call_pc pars (prog_var_names … prog) (globalenv … init prog)
1508  pc = Error ? [MSG BadFunction].
1509#pars #prg #init #pc * #EQ whd in match next_of_call_pc; normalize nodelta
1510whd in match fetch_statement; normalize nodelta
1511[ >fetch_internal_function_no_zero | >fetch_internal_function_no_minus_one]
1512//
1513qed.
1514
1515lemma next_of_call_pc_inv :  ∀pars.∀prog : program ? ℕ. ∀init.
1516∀pc,nxt.
1517next_of_call_pc pars (prog_var_names … prog)
1518(globalenv … init prog) pc = return nxt →
1519∃id,fn,c_id,c_args,c_dest.
1520fetch_statement pars
1521    (prog_var_names … prog) (globalenv … init prog) pc =
1522    return 〈id,fn, sequential ? ?(CALL pars ? c_id c_args c_dest) nxt〉.
1523#pars #prog #init #pc #nxt whd in match next_of_call_pc; normalize nodelta
1524#H @('bind_inversion H) -H ** #id #fn *
1525[ *[ #c | #c_id #c_arg #c_dest | #reg #lbl | #seq ] #prox | #fin | #H #r #l #l ]
1526#EQfetch normalize nodelta whd in ⊢ (??%% → ?); #EQ destruct(EQ)
1527%{id} %{fn} %{c_id} %{c_arg} %{c_dest} assumption
1528qed.
1529
1530lemma sigma_stored_pc_inj : ∀ prog : ertl_program.
1531∀f_lbls,pc,pc'. sigma_pc_opt prog f_lbls pc ≠ None ? →
1532sigma_pc_opt prog f_lbls pc = sigma_pc_opt prog f_lbls pc' →
1533pc = pc'.
1534#prog #f_lbls ** #id #EQblid #off ** #id' #EQblid' #off'
1535* inversion(sigma_pc_opt ???) [#_ #H @⊥ @H %]
1536#pc1 whd in match sigma_pc_opt; normalize nodelta @if_elim
1537[ @eqZb_elim [2: #_ *] #EQbl * whd in ⊢ (??%? → ?); #EQ destruct #_
1538#H lapply(sym_eq ??? H) -H @if_elim [#_ whd in ⊢ (??%? → ?); #EQ destruct %]
1539@eqZb_elim [ #_ *] * #EQbl' #_ #H @('bind_inversion H) -H #lb #EQlb
1540whd in ⊢ (??%? → ?); #EQ destruct @⊥ @EQbl' assumption] @eqZb_elim [#_ *] * #EQbl #_
1541#H @('bind_inversion H) -H * #lb #EQlb whd in ⊢ (??%? → ?); #EQ destruct #_
1542#H lapply(sym_eq ??? H) -H @if_elim
1543[ @eqZb_elim [2: #_ *] #EQbl' #_ whd in ⊢ (??%? → ?); #EQ destruct @⊥ @EQbl @EQbl']
1544#_ #H @('bind_inversion H) -H * #lb' #EQlb' whd in ⊢ (??%? → ?);
1545whd in match (pc_of_point ???); whd in match (offset_of_point ??);
1546whd in match (offset_of_point ??); #EQ destruct @eq_f
1547cut(an_identifier LabelTag off = an_identifier LabelTag off') [2: #EQ destruct %]
1548@(partial_inj_sigma prog f_lbls id) [>EQlb % #ABS destruct | >EQlb >EQlb' %]
1549qed.
1550
1551lemma bool_of_beval_ok : ∀prog : ertl_program.
1552∀f_lbls. preserving1 … res_preserve1 …
1553              (sigma_beval prog f_lbls)
1554              (λx.x)
1555              (bool_of_beval)
1556              (bool_of_beval).
1557#prog #f_lbls * [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1558whd in match bool_of_beval; normalize nodelta try @res_preserve_error1
1559try @mfr_return1 whd in match sigma_beval; normalize nodelta
1560cases (sigma_pc_opt ???) normalize nodelta [2: #pc] @res_preserve_error1
1561qed.
1562
1563
1564lemma block_of_call_ok : ∀prog: ertl_program.
1565 let trans_prog ≝ ertl_to_ertlptr prog in
1566 ∀ f_lbls,f_regs.
1567∀called,restr. preserving1 … res_preserve1 …
1568              (sigma_state prog f_lbls f_regs restr)
1569              (λx.x)
1570              (block_of_call ERTL_semantics (prog_var_names … prog)
1571                      (globalenv_noinit … prog) called)
1572              (block_of_call ERTLptr_semantics (prog_var_names … trans_prog)
1573                      (globalenv_noinit … trans_prog) called).
1574#prog #f_lbls #f_regs #called #restr #st whd in match block_of_call; normalize nodelta
1575@mfr_bind1
1576[ @(λx.x)
1577| cases(called) [#c_id | #c_ptr] normalize nodelta
1578  [ @opt_to_res_preserve1 #bl #EQbl %{bl} % [2: %]
1579    >(find_symbol_transf …
1580          (λvars.transf_fundef … (λfn.(b_graph_translate … fn))) prog c_id)
1581   assumption
1582  | @mfr_bind1
1583    [2: whd in match dpl_arg_retrieve; normalize nodelta @(ps_arg_retrieve_ok) |
1584    | #bv1 @mfr_bind1
1585      [2: whd in match dph_arg_retrieve; normalize nodelta @(ps_arg_retrieve_ok) |
1586      | #bv2 @mfr_bind1
1587        [ @(λx.x)
1588        | whd in match pointer_of_bevals; normalize nodelta
1589          cases bv1 normalize nodelta
1590          [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1591          try @res_preserve_error1
1592          [ cases bv2 [ | | #ptr1' #ptr2' #p' | #by' | #p' | #ptr' #p' | #pc1' #p1']
1593          normalize nodelta
1594          [1,2,3,4,5: @res_preserve_error1
1595          | @if_elim #_ [@mfr_return_eq1 % | @res_preserve_error1]
1596          ]
1597          ] whd in match sigma_beval; normalize nodelta cases(sigma_pc_opt ???)
1598            normalize nodelta [2,4: #pc ] @res_preserve_error1
1599        |
1600        #ptr @if_elim #_ [@mfr_return_eq1 % | @res_preserve_error1]
1601      ]
1602    ]
1603  ]
1604 ]
1605| #bl @opt_to_res_preserve1 whd in match code_block_of_block; normalize nodelta
1606  @match_reg_elim [ #_ @opt_preserve_none1 | #prf @mfr_return_eq1 %]
1607]
1608qed.
1609
1610lemma bvpc_sigma_pc_to_sigma_beval : ∀prog : ertl_program.
1611∀f_lbls,pc,p. sigma_pc_opt prog f_lbls pc ≠ None ? →
1612BVpc (sigma_stored_pc prog f_lbls pc) p =
1613sigma_beval prog f_lbls (BVpc pc p).
1614#prog #f_lbls #pc #p #prf whd in match sigma_stored_pc;
1615whd in match sigma_beval; normalize nodelta lapply prf
1616cases(sigma_pc_opt ???) [ * #H @⊥ @H % | #pc' #_ % ]
1617qed.
1618
1619lemma push_ra_ok : ∀prog : ertl_program.
1620∀f_lbls,f_regs,restr,pc. sigma_pc_opt prog f_lbls pc ≠ None ? →
1621    preserving1 ?? res_preserve1 …
1622          (sigma_state prog f_lbls f_regs restr)
1623          (sigma_state prog f_lbls f_regs restr)
1624          (λst.push_ra ERTL_semantics st (sigma_stored_pc prog f_lbls pc))
1625          (λst.push_ra ERTLptr_semantics st pc).
1626#prog #f_lbls #f_regs #restr #pc #prf #st whd in match push_ra; normalize nodelta
1627@mfr_bind1
1628[  @(sigma_state prog f_lbls f_regs restr)
1629|  >(bvpc_sigma_pc_to_sigma_beval … prf) @push_ok
1630|  #st' >(bvpc_sigma_pc_to_sigma_beval … prf) @push_ok
1631] qed.
1632
1633
1634lemma ertl_save_frame_ok : ∀prog : ertl_program.
1635∀f_lbls.∀f_regs : regs_funct.∀kind,restr.
1636preserving1 ?? res_preserve1 ????
1637      (λst : Σs: state_pc ERTLptr_semantics.
1638             sigma_pc_opt prog f_lbls (pc … s) ≠ None ?
1639      . match fetch_internal_function … (globalenv_noinit … prog)
1640                       (pc_block (pc … st)) with
1641                 [ OK y ⇒ let 〈f,fn〉 ≝ y in
1642                          let added ≝ added_registers … (prog_var_names … prog) fn
1643                                       (f_regs (pc_block (pc … st))) in
1644                          mk_state_pc ? (sigma_state prog f_lbls f_regs added st)
1645                                        (sigma_stored_pc prog f_lbls (pc … st))
1646                                        (sigma_stored_pc prog f_lbls (last_pop … st))
1647                 | Error e ⇒ dummy_state_pc
1648                 ])
1649           (sigma_state prog f_lbls f_regs restr)
1650           (ertl_save_frame kind it)
1651           (match kind with
1652            [ID ⇒ ertlptr_save_frame kind it
1653            |PTR ⇒ λst. !st' ← push_ra … st (pc … st);
1654                        ertlptr_save_frame kind it (set_no_pc … st' st)
1655            ]).
1656#prog #f_lbls #f_regs * #restr * #st #st_prf
1657inversion(fetch_internal_function ???) normalize nodelta
1658[1,3: * #f #fn #EQfn normalize nodelta whd in match ertl_save_frame; whd in match ertlptr_save_frame;
1659      normalize nodelta @mfr_bind1
1660      [2,5: @push_ra_ok [1,2: assumption] |1,4: skip
1661      |*: #st1 [ >m_return_bind] @mfr_bind_inversion1
1662          [1,4: @(λf.match sigma_frames_opt prog f_lbls f_regs f with [Some g ⇒  g | None ⇒ [ ]])
1663          |2,5: @opt_to_res_preserve1 whd in match sigma_state; whd in match set_no_pc;
1664                normalize nodelta cases(st_frms … st1) [1,3: @opt_preserve_none1]
1665                #frames #frames1 whd in match sigma_frames; normalize nodelta
1666                >m_return_bind #EQframes %{frames} % [%] >EQframes %
1667          |*: #frames #H lapply(opt_eq_from_res ???? H) -H whd in match sigma_state;
1668              normalize nodelta #EQt_frames #H lapply(opt_eq_from_res ???? H) -H
1669              whd in match set_no_pc; normalize nodelta #EQframes >EQframes in EQt_frames;
1670              whd in match sigma_frames; normalize nodelta >m_return_bind
1671              inversion(sigma_frames_opt ???) [1,3: #_ #ABS destruct(ABS)]
1672              #t_frames #EQt_frames #_ @mfr_return_eq1 normalize nodelta @eq_f
1673              whd in match set_frms; normalize nodelta >m_return_bind
1674              cut(∀ a1,a2,b1,b2,c1,c2,d1,d2,e1,e2.
1675                    a1=a2 → b1 = b2 → c1 = c2 → d1 = d2 → e1 = e2 →
1676                      mk_state ERTL_semantics a1 b1 c1 d1 e1 =
1677                      mk_state ERTL_semantics a2 b2 c2 d2 e2)
1678              [1,3: #H1 #H2 #H3 #H4 #H5 #H6 #H7 #H8 #H9 #H10 #H11 #H12 #H13 #H14
1679                    #H15 //] #APP @APP try %
1680              [1,3: whd in match sigma_frames_opt; whd in match m_list_map;
1681                    normalize nodelta  whd in match (foldr ?????); normalize nodelta
1682                    >EQfn >m_return_bind normalize nodelta
1683                    change with (sigma_frames_opt prog f_lbls f_regs frames)
1684                                                         in match (foldr ?????);
1685                    >EQt_frames >m_return_bind whd in match sigma_regs;
1686                    normalize nodelta cases(regs … st1) #ps_reg #hw_reg
1687                    >(pc_block_eq … st_prf) %
1688              |*: whd in match set_regs; whd in match sigma_regs; normalize nodelta
1689                  cases(regs … st1) #ps_r #hw_r normalize nodelta
1690                  whd in match sigma_register_env; normalize nodelta
1691                  @eq_f2 // change with (empty_map RegisterTag beval) in match (map RegisterTag ????);
1692                  <(empty_set_minus … restr) %
1693              ]
1694          ]
1695      ]   
1696|*: #e #_ #x whd in match ertl_save_frame; normalize nodelta normalize nodelta
1697    #H @('bind_inversion H) -H #y whd in match push_ra; normalize nodelta
1698    #H @('bind_inversion H) -H #z whd in match push; normalize nodelta
1699    whd in match (istack ??); whd in match is_push; normalize nodelta
1700    >m_return_bind whd in match set_istack; normalize nodelta whd in ⊢ (??%% →?);
1701    #EQ destruct(EQ) normalize nodelta >m_return_bind whd in ⊢ (??%% → ?);
1702    #EQ destruct(EQ) whd in match (st_frms ??); whd in ⊢ (??%% → ?);
1703    #EQ destruct(EQ)
1704]
1705qed.
1706
1707
Note: See TracBrowser for help on using the repository browser.