source: src/ERTLptr/ERTLtoERTLptrUtils.ma @ 3362

Last change on this file since 3362 was 3018, checked in by sacerdot, 7 years ago

1) some files repaired
2) all stuff related to the aborted pass ERTLptr (now merged with

ERTLToLTL) moved into the ERTLptr directory (no longer used/linked)

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