source: src/ERTLptr/ERTLtoERTLptrOK.ma @ 2662

Last change on this file since 2662 was 2662, checked in by piccolo, 8 years ago

Towards a very generalized lemma that summarizes all of Paolo's results.

File size: 122.6 KB
Line 
1
2(**************************************************************************)
3(*       ___                                                              *)
4(*      ||M||                                                             *)
5(*      ||A||       A project by Andrea Asperti                           *)
6(*      ||T||                                                             *)
7(*      ||I||       Developers:                                           *)
8(*      ||T||         The HELM team.                                      *)
9(*      ||A||         http://helm.cs.unibo.it                             *)
10(*      \   /                                                             *)
11(*       \ /        This file is distributed under the terms of the       *)
12(*        v         GNU General Public License Version 2                  *)
13(*                                                                        *)
14(**************************************************************************)
15
16include "ERTLptr/ERTLtoERTLptr.ma".
17include "common/StatusSimulation.ma".   
18include "joint/Traces.ma".
19include "ERTLptr/ERTLptr_semantics.ma".
20include "common/ExtraMonads.ma".
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 ≝ λ prog : ertl_program.
31joint_closed_internal_function ERTL (prog_var_names … prog) → label → option label.
32
33
34definition sigma_pc_opt :
35∀ prog : ertl_program.
36sigma_map prog → program_counter → option program_counter ≝
37λprog,sigma,pc.
38  let ge ≝ globalenv_noinit … prog in
39  if eqZb       (block_id (pc_block pc)) (-1) then (* check for dummy exit pc *)
40    return pc
41  else
42    ! 〈i, fd〉 ← res_to_opt … (fetch_internal_function … ge (pc_block pc)) ;
43    ! ertl_ptr_point ← sigma fd (point_of_pc ERTL_semantics pc) ;
44    return pc_of_point
45    ERTLptr_semantics (pc_block pc) ertl_ptr_point.
46
47definition sigma_stored_pc ≝
48λprog,sigma,pc. match sigma_pc_opt prog sigma pc with
49      [None ⇒ null_pc (pc_offset … pc) | Some x ⇒ x].
50     
51     
52definition sigma_beval :
53 ∀prog : ertl_program.
54  sigma_map prog →
55  beval → beval ≝
56λprog,sigma,bv.
57match bv with
58[ BVpc pc prt ⇒ match sigma_pc_opt prog sigma pc with
59                 [None ⇒ BVundef | Some x ⇒ BVpc x prt]
60| _ ⇒ bv
61].
62
63(*
64definition sigma_beval :
65 ∀prog,sigma,bv.
66 sigma_beval_opt prog sigma bv ≠ None ? → beval ≝
67 λprog,sigma,bv.opt_safe ….
68*)
69definition sigma_is :
70 ∀prog : ertl_program.
71  sigma_map prog →
72  internal_stack → internal_stack ≝
73λprog,sigma,is.
74match is with
75[ empty_is ⇒ empty_is
76| one_is bv ⇒ one_is (sigma_beval prog sigma bv)
77| both_is bv1 bv2 ⇒
78  both_is (sigma_beval prog sigma bv1) (sigma_beval prog sigma bv2)
79].
80
81lemma sigma_is_empty : ∀prog,sigma.
82  sigma_is prog sigma empty_is = empty_is.
83#prog #sigma %
84qed.
85
86definition sigma_mem :
87 ∀prog : ertl_program . sigma_map prog → bemem → bemem ≝
88 λprog,sigma,m.
89 mk_mem
90  (λb.
91    If Zltb (block_id b) (nextblock m) then with prf' do   
92      let l ≝ low_bound m b in
93      let h ≝ high_bound m b in
94      mk_block_contents l h
95      (λz.If Zleb l z ∧ Zltb z h then with prf'' do
96        sigma_beval prog sigma (contents (blocks m b) z)
97      else BVundef)
98    else empty_block OZ OZ)
99  (nextblock m)
100  (nextblock_pos m).
101
102(*DOPPIONE ASSIOMA IN LINEARISE_PROOF.MA *)
103axiom mem_ext_eq :
104  ∀m1,m2 : mem.
105  (∀b.let bc1 ≝ blocks m1 b in
106      let bc2 ≝ blocks m2 b in
107      low bc1 = low bc2 ∧ high bc1 = high bc2 ∧
108      ∀z.contents bc1 z = contents bc2 z) →
109  nextblock m1 = nextblock m2 → m1 = m2.
110
111
112
113inductive id_is_in (A : Type[0]) : Pos →  positive_map A → Prop ≝
114| is_in_root : ∀l,r,opt_a. id_is_in A (one) (pm_node … opt_a l r)
115| is_in_left : ∀l,r,opt_a,x. id_is_in A x l →
116                                    id_is_in A (p0 x) (pm_node … opt_a l r)
117| is_in_right : ∀l,r,opt_a,x. id_is_in A x r →
118                                    id_is_in A (p1 x) (pm_node … opt_a l r).
119
120definition id_is_in : ∀A : Type[0]. ∀tag : identifierTag.
121identifier_map tag A → identifier tag → Prop ≝
122λA,tag,m,id.match id with
123     [an_identifier x ⇒ match m with
124                              [an_id_map p ⇒ id_is_in A x p]
125     ].
126     
127lemma lookup_eq : ∀ A : Type[0].
128∀m,m' : positive_map A.
129(∀id. lookup_opt A id m = lookup_opt A id m'
130      ∧ (id_is_in A id m ↔ id_is_in A id m')) → m=m'.
131#A #m elim m
132[ * [#_ %] #opt_a #l #r #H lapply(H one) normalize * #EQ >EQ * #_ #H1 lapply(H1 ?) [%]
133  -H1 -H <EQ -EQ #H inversion H #l1 #r1 #opt_a1
134  [ #_ #EQ  lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct(EQ)
135  |*: #pos #H1 #_ #_ #EQ  lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct(EQ)
136  ]
137| #opt_a #l #r #Hl #Hr *
138  [ #H lapply(H one) normalize * #EQ >EQ * #H1 #_ lapply(H1 ?) [%]
139  -H1 -H -EQ #H inversion H #l1 #r1 #opt_a1
140    [ #_ #EQ  lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct(EQ)
141    |*: #pos #H1 #_ #_ #EQ  lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct(EQ)
142    ]
143  | #opt_a1 #l1 #r1 #H lapply(H one) normalize * #EQ >EQ -EQ #_ @eq_f2 [@Hl|@Hr]
144    #id [ lapply(H (p0 id)) | lapply(H (p1 id))] normalize * #H1 * #H2 #H3 %
145    [1,3: assumption] % #H4 [1,3: lapply(H2 ?) |*: lapply(H3 ?)]
146    try %2 try %3 try assumption #H5 inversion H5 #l2 #r2 #opt_a2
147    [1,4,7,10: #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ @⊥
148               [1,3: cut(p0 id ≠ one) [1,3: @(pos_elim … id) /3/]
149               |*:   cut(p1 id ≠ one) [1,3: @(pos_elim … id) /3/]
150               ] * #H @H assumption
151    |*: #pos #H6 #_ #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct(EQ)
152        #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct(EQ) #_ assumption
153    ]
154  ]
155]
156qed.
157
158include alias "common/Identifiers.ma".
159include alias "common/PositiveMap.ma".
160
161
162lemma p0_neq_one : ∀x: Pos. p0 x ≠ one.
163#x /3/
164qed.
165
166lemma p1_neq_one : ∀x: Pos. p1 x ≠ one.
167#x /3/
168qed.
169
170lemma lookup_ok_to_update : ∀ A : Type[0].
171∀ tag : identifierTag.
172∀m,m' : identifier_map tag A. ∀id,a.
173(lookup tag A m' id = Some ? a)  → lookup tag A m id ≠ None ? →
174(∀ id'. id ≠ id' → (lookup tag A m id' = lookup tag A m' id') ∧
175     (id_is_in A tag m id' ↔ id_is_in A tag m' id')) →
176update tag A m id a = return m'.
177#A #tag * #m * #m' * #id #a
178normalize in ⊢ (%→%→?); lapply id -id lapply m' -m' elim m
179    [ #m' #id #m_spec' normalize in ⊢ (% → ?); * #EQ @⊥ @EQ %] #opt_a #l #r #Hl #Hr
180    #m' * [|*: #x] normalize in ⊢ (%→%→?); #m_spec'
181    [ cases opt_a -opt_a [* #H @⊥ @H %] #a1 #_ #H normalize @eq_f @eq_f
182      lapply H -H lapply m_spec'; -m_spec' lapply a -a cases m'
183      [#a normalize #EQ destruct] #opt_a1 #l1 #r1 #a
184      normalize in ⊢ (%→?); #EQ >EQ #H @eq_f2 @lookup_eq #id'
185      [ lapply (H (an_identifier tag (p0 id')) ?)
186      | lapply (H (an_identifier tag (p1 id')) ?)
187      ]
188      [1,3:% @(pos_elim … id') [1,3:#H destruct|*: #n #IP #H destruct]]
189      * normalize #H1 * #H2 #H3 % [1,3: >H1 %] % #H4
190      [1,3: lapply(H2 ?) |*: lapply(H3 ?)] try %2 try %3 try assumption
191      #H5 inversion H5 #l2 #r2 #opt_a2
192        [1,4,7,10: #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ @⊥
193                   [1,3: cut(p0 id' ≠ one) [1,3: /3/]
194                   |*: cut(p1 id' ≠ one) [1,3: /3/]
195                   ] >EQ * #H @H %
196        |*: #pos #H6 #_ #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1 destruct(EQ1)
197            #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1 destruct(EQ1) #_ assumption
198        ]
199    |*: #H lapply m_spec' -m_spec' cases m' -m' [1,3: normalize #EQ destruct]
200        #opt_a1 #l1 #r1 normalize in ⊢ (% → ?); #H1 #H2
201        [ lapply(Hr ?? H1 H ?) | lapply(Hl ?? H1 H ?)]
202          [1,3: * #y * #y_spec
203            [lapply(H2 (an_identifier tag (p1 y)) ?) | lapply(H2 (an_identifier tag (p0 y)) ?)]
204            [1,3: % #EQ destruct @y_spec %] * normalize #H3 * #H4 #H5 % // % #H6
205            [1,3: lapply(H4 ?) |*: lapply (H5 ?)] try %2 try %3 try assumption
206            #H7 inversion H7 #l2 #r2 #opt_a2
207              [1,4,7,10: #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ @⊥
208                   [1,3: cut(p1 y ≠ one) [1,3: /3/]
209                   |*: cut(p0 y ≠ one) [1,3: /3/]
210                   ] >EQ * #H @H %
211              |*: #pos #H6 #_ #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1
212                 destruct(EQ1) #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1
213                 destruct(EQ1) #_ assumption
214              ]
215          |2,4: normalize cases(update A x a ?) normalize [2,4: #pos_map]
216               #EQ destruct @eq_f @eq_f lapply(H2 (an_identifier tag one) ?)
217               [1,3: % #EQ destruct] * normalize #EQ >EQ #_ @eq_f2 [2,3: %]
218               @lookup_eq #id'
219               [lapply (H2 (an_identifier tag (p0 id')) ?) |
220                                   lapply (H2 (an_identifier tag (p1 id')) ?) ]
221               [1,3: % #EQ1 destruct] * normalize #H3 * #H4 #H5 % // % #H6
222               [1,3: lapply(H4 ?) |*: lapply(H5 ?)] try %2 try %3 try assumption
223               #H7 inversion H7 #l2 #r2 #opt_a2
224                  [1,4,7,10: #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ @⊥
225                    [1,3: cut(p0 id' ≠ one) [1,3: /3/]
226                    |*: cut(p1 id' ≠ one) [1,3: /3/]
227                   ] >EQ * #H @H %
228                  |*: #pos #H6 #_ #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1
229                      destruct(EQ1) #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1
230                      destruct(EQ1) #_ assumption
231                  ]
232            ]
233      ]
234qed.
235
236lemma update_ok_to_lookup : ∀ A : Type[0].
237∀ tag : identifierTag.
238∀m,m' : identifier_map tag A. ∀id,a.
239update tag A m id a = return m' →
240(lookup tag A m' id = Some ? a) ∧ lookup tag A m id ≠ None ? ∧
241(∀ id'. id ≠ id' → (lookup tag A m id' = lookup tag A m' id') ∧
242     (id_is_in A tag m id' ↔ id_is_in A tag m' id')).
243#A #tag * #m * #m' * #id #a
244whd in ⊢ (??%% →  ?); inversion(update A ???) normalize nodelta [#_ #ABS destruct]
245    #m1 #m1_spec #EQ destruct % [%]
246    [  normalize @(update_lookup_opt_same … m1_spec)
247    |3: * #id' * #id_spec' normalize %
248        [@(update_lookup_opt_other … m1_spec ??) % #EQ @id_spec' >EQ %]
249        lapply id_spec' lapply m1_spec -id_spec' -m1_spec
250        (*cases id [|*:#x] -id normalize*) lapply m' -m' lapply id lapply id' -id -id'
251        elim m [#id' #id #m' cases id [|*: #x] normalize #EQ destruct]
252        #opt_a #l #r #Hl #Hr #id' #id #m' cases id [|*:#x] -id normalize
253        [ cases opt_a [2:#a] normalize #EQ destruct cases id' [#H @⊥ @H %]
254          #x #_ normalize % #H [1,2: %3 |*: %2]
255          inversion H #l1 #r1 #opt_a1
256          [1,4,7,10: #EQ lapply(jmeq_to_eq ??? EQ) #EQ1 @⊥
257                     [1,2: cut(p1 x ≠ one) [1,3: @(pos_elim … x) /3/]
258                     |*:   cut(p0 x ≠ one) [1,3: @(pos_elim … x) /3/]
259                     ]
260                     * #H @H >EQ1 //   
261          |*:        #pos #H1 #_ #EQ lapply(jmeq_to_eq ??? EQ) #EQ1 destruct(EQ1)
262                     #EQ lapply(jmeq_to_eq ??? EQ) #EQ1 destruct(EQ1) #_ assumption
263          ]
264        |*: inversion(update A x a ?) normalize [1,3: #_ #EQ destruct] #pos_map
265            #pos_map_spec #EQ destruct #id_spec' % #H
266            inversion H #l1 #l2 #opt_a1
267            [1,4,7,10: #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ
268                       #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1 destruct(EQ1)
269                       #H1 %
270            |*: #pos #H1 #_ #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ
271                #EQ1 lapply(jmeq_to_eq ??? EQ1) -EQ1 #EQ1 destruct(EQ1)
272                #H2 try %2 try %3 try assumption
273                [ @(proj1 … (Hr ? ? pos_map pos_map_spec ?)) [#EQ1 destruct @id_spec' %]
274                | @(proj2 … (Hr ? ? l2 pos_map_spec ?)) [#EQ1 destruct @id_spec' %]
275                | @(proj1 … (Hl ? ? pos_map pos_map_spec ?)) [#EQ1 destruct @id_spec' %]
276                | @(proj2 … (Hl ? ? l1 pos_map_spec ?)) [#EQ1 destruct @id_spec' %]
277                ]
278                assumption
279            ]
280         ]     
281    | % normalize lapply m1_spec lapply id lapply m' -id -m' elim m
282      [#m' * [|*: #x] normalize #EQ destruct] #opt_a #l #r #Hl #Hr #m' * [|*: #x]
283      normalize [ cases opt_a [2:#a] normalize #EQ1 #EQ2 destruct]
284      inversion (update A x a ?) [1,3: #_ normalize #EQ destruct]
285      #pos_map #EQpos_map normalize #EQ destruct [@Hr|@Hl] assumption
286    ]
287qed.
288
289
290(*
291               
292lemma update_lookup_after : ∀ A : Type[0].
293∀ tag : identifierTag.
294∀m,m' : identifier_map tag A. ∀id,a.
295update tag A m id a = return m' →
296lookup tag A m' id = Some ? a.
297#A #B #tag * #m1 * #id #a whd in ⊢ (??%% → ?); inversion(update A ???)
298normalize nodelta [#_ #EQ destruct] #pos_map #pos_map_spec #EQ destruct
299@(update_lookup_opt_same … pos_map_spec)
300qed.
301
302lemma p0_neq_one : ∀x: Pos. p0 x ≠ one.
303#x /3/
304qed.
305
306lemma p1_neq_one : ∀x: Pos. p1 x ≠ one.
307#x /3/
308qed.
309
310lemma id_is_in_map : ∀ A,B : Type[0]. ∀tag : identifierTag.
311∀m : identifier_map tag A.
312∀ F : (∀a:A.(Σid. lookup tag A m id = Some A a) → B).
313∀id. id_is_in A tag m id ↔ id_is_in B tag (map_inf1 A B tag m F) id.
314#A #B #tag * #m elim m
315[ #F * #id % normalize #H inversion H #l #r #opt_a
316  [1,4: #_ #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct
317  |*: #pos #H1 #_ #_ #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct
318  ]
319| * [2:#a] #l #r #Hl #Hr #F ** [1,4: |*:#x] normalize % #H try % try %2 try %3
320  [1,2,5,6: cases(Hr ? (an_identifier tag x)) |*: cases (Hl ? (an_identifier tag x))]
321  [2,4,6,8,10,12,14,16: #a1 ** #id1 #prf1 @F try(@a1)
322                        try(%{(an_identifier tag (p1 id1))} assumption)
323                        try(%{(an_identifier tag (p0 id1))} assumption) ]
324  try(#H1 #_ @H1) try(#_ #H1 @H1) -H1 -Hl -Hr inversion H #l1 #r1 #opt_a1
325  [1,4,7,10,13,16,19,22: #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ @⊥
326             [1,2,3,4: lapply(p1_neq_one x)
327             |*:       lapply(p0_neq_one x)
328             ] * #H @H >EQ %
329  |*: #pos #H1 #_ #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct
330      #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQ destruct #_ assumption
331  ]
332]
333qed.
334
335lemma map_update_commute : ∀ A, B : Type[0].
336∀tag : identifierTag.
337∀m1,m2 : identifier_map tag A.
338∀id,a.
339update tag A m1 id a = return m2 →
340∀ F : (∀a:A.(Σid. lookup tag A m1 id = Some A a) → B).
341∀ F': (∀a:A.(Σid. lookup tag A m2 id = Some A a) → B). 
342(∀a',id',prf,prf'. F a' «id',prf» = F' a' «id',prf'») → ∃prf.
343update tag B (map_inf1 A B tag m1 F) id (F' a «id,prf») =
344return map_inf1 A B tag m2 F'.
345#A #B #tag #m1 #m2 #id #a #m2_spec #F #F' #eqFF' %
346[ @hide_prf cases(update_lookup_previous A tag m1 m2 id a) #H1 #_ cases (H1 m2_spec)
347  * #H1 #H2 #H3 assumption
348| cases(update_lookup_previous B tag (map_inf1 A B tag m1 F)
349                             (map_inf1 A B tag m2 F') id (F' a «id,?»))
350  [ #_ #H @H |] cases(update_lookup_previous A tag m1 m2 id a) #H2 #INUTILE
351cases(H2 m2_spec) * #H3 #H4 #H5 % [%]
352[ >(lookup_map … H3) %
353| elim H4 -H4 #H4 % #H5 @H4 lapply H5 cases m1 in F; -m1 #m1 cases id -id
354  elim m1 [ #id #F normalize * %] #a1 #l #r #Hl #Hr * [|*:#x] #F normalize
355  [ cases a1 in F; [2: #a2] #F normalize [2: * %] #EQ destruct
356  |*: #H
357    [@(Hr x ??) | @(Hl x ??)]
358    [1,3:#a ** #id1 #prf1 @F [1,3: @a]
359         [%{(an_identifier tag (p1 id1))}|%{(an_identifier tag (p0 id1))}]
360         normalize assumption
361    |*: normalize @H
362    ]
363  ]
364| #id' #id_spec' lapply(H5 id' id_spec') * #H6 * #H7 #H8 %
365  [ lapply H6 inversion (lookup tag A m2 id')
366    [2: #w] #w_spec #EQ >(lookup_map … EQ) normalize nodelta
367    >(lookup_map … w_spec) normalize nodelta [2: %] @eq_f @eqFF'
368  | cases(id_is_in_map A B tag m1 F id') cases(id_is_in_map A B tag m2 F' id')
369   #H9 #H10 #H11 #H12 % #H13 [ @H9 @H7 @H12 assumption | @H11 @H8 @H10 assumption]
370  ]
371]
372qed.
373
374(*
375definition well_formed_register_env :
376∀prog : ertl_program .∀sigma : (sigma_map prog).
377register_env beval → Prop ≝
378λprog,sigma,psd_reg.∀id,bv. lookup ?? psd_reg id = Some ? bv →
379sigma_beval_opt prog sigma bv ≠ None ?.
380*)
381*)
382
383definition map : ∀tag,A,B. identifier_map tag A → (A → B) → identifier_map tag B ≝
384λtag,A,B,m,f.match m with
385[an_id_map p ⇒ an_id_map … (map ?? f p)].
386
387lemma lookup_map : ∀A,B : Type[0].
388  ∀tag : identifierTag.
389  ∀m : identifier_map tag A.
390  ∀ f:A → B.
391  ∀ id.
392lookup tag B (map tag A B m f) id =
393! a ← lookup tag A m id; return f a.
394#A #B #tag * #m #f * #id normalize >lookup_opt_map %
395qed.
396
397lemma update_leaf_fail: ∀tag,A,i,v.
398 update tag A (empty_map ??) i v = Error ? [MSG MissingId; CTX … i].
399#ta #A ** [|*: #x] #v normalize %
400qed.
401
402lemma update_def : ∀tag,A,m,i,v.
403  update tag A m i v =
404  match lookup tag A m i with
405  [ Some _ ⇒ OK ? (add tag A m i v)
406  | None ⇒ Error ? [MSG MissingId; CTX … i]
407  ].
408#tag #A #m #i #v inversion(update tag A m i v)
409[ #m' #EQm' cases(update_ok_to_lookup ?????? EQm') * #_
410 #H #_ elim H cases(lookup tag A m i) [#H @⊥ @H %]
411 #x #_ normalize <EQm' lapply EQm' cases i cases m cases m' -m -m' -i
412 normalize #m' #m #i inversion(update A i v m) normalize [#_ #ABS destruct]
413 #m'' #EQm'' #EQ destruct(EQ) @eq_f @eq_f lapply EQm'' -EQm'' lapply i -i
414 lapply m' -m' elim m [#m' * [2,3: #z] normalize #EQ destruct]
415 #opt_a #l #r #Hl #Hr #m' * [2,3: #z] normalize
416 [3: cases opt_a normalize [2: #y] #EQ destruct %
417 |*: inversion(update A z v ?) [2,4: #m'']  #EQm'' normalize #EQ destruct
418     [<(Hr … EQm'') | <(Hl … EQm'')] %
419 ]
420| #err cases m -m cases i -i #i #m normalize inversion(update A i v m) [2:#m']
421  #EQerr normalize #EQ destruct lapply EQerr lapply i elim m
422  [ normalize #x #_ %] #opt_a #l #r #Hl #Hr * [2,3:#z] normalize
423 [3: cases opt_a [2:#w] normalize #EQ destruct %
424 |*: inversion(update A z v ?) [2,4: #m'] #EQm' normalize #EQ destruct
425     [lapply(Hr … EQm') | lapply(Hl … EQm')] cases(lookup_opt A z ?) [2,4: #a]
426     normalize #EQ destruct %
427 ]
428]
429qed.
430
431lemma map_add : ∀tag : identifierTag.∀A,B : Type[0].∀ f: A → B.∀m,id,v.
432map tag A B (add tag A m id v) f = add tag B (map tag A B m f) id (f v).
433#tag #A #B #f * #m * #id #v normalize @eq_f lapply v -v lapply id -id elim m
434[ #id elim id [#v %] #x #IH #id normalize >IH normalize inversion(pm_set ? ? ? ?)
435  normalize // cases x normalize [2,3,5,6: #y] #EQ destruct
436| #opt_a #l #r #Hl #Hr * [2,3: #x| #v normalize cases opt_a normalize [2: #a %]
437  cases (map_opt ? ? ? l) normalize [2: //] cases (map_opt ? ? ? r) normalize
438  //] #v normalize cases opt_a [2,4: #a] normalize //
439  [ cases(map_opt ? ? ? l) normalize // >Hr cases(map_opt ? ? ? r) normalize
440    [2: #opt_b #lb #rb] inversion(pm_set B x ? ?) normalize // cases x [2,3,5,6: #y]
441    normalize #EQ destruct
442  | >Hl cases(map_opt ? ? ? l) normalize [2: #opt_b #lb #rb]
443    inversion (pm_set B x ? ?) normalize //
444    [1,2: cases x [2,3,5,6: #y] normalize #EQ destruct]
445    #opt_b' #lb' #rb' #_ normalize #_ #EQ cases(map_opt ? ? ? r)
446    normalize nodelta [%] #opt_b'' #lb'' #rb'' >EQ %
447]
448qed.
449
450
451definition restrict : ∀tag.∀A,B.
452identifier_map tag A → identifier_map tag B → identifier_map tag A ≝
453λtag,A,B,m1,m2.an_id_map …
454           (merge A B A (λo,o'.match o' with [None ⇒ None ? | Some _ ⇒ o])
455                  (match m1 with [an_id_map p1 ⇒ p1])
456                  (match m2 with [an_id_map p2 ⇒ p2])).
457
458interpretation "identifier map restriction" 'intersects a b = (restrict ??? a b).
459
460unification hint 0 ≔ tag ; R ≟ identifier tag ⊢ list R ≡ list (identifier tag).
461 
462lemma map_update_commute : ∀tag : identifierTag.∀A,B : Type[0].∀f : A → B. ∀m,id,v.
463update tag B (map tag A B m f) id (f v) =
464!m' ← update tag A m id v; return map tag A B m' f.
465#tag #A #B #f #m #id #v >update_def >update_def >lookup_map
466cases (lookup tag A m id) [%] #a >m_return_bind >m_return_bind normalize nodelta
467whd in ⊢ (???%); @eq_f @sym_eq @map_add
468qed.
469
470definition is_leaf ≝ λA.λpm : positive_map A.
471match pm with [ pm_leaf ⇒ true | _ ⇒ false ].
472(*
473let rec pm_clean A (pm : positive_map A) on pm : positive_map A ≝
474match pm with
475[ pm_leaf ⇒ pm_leaf ?
476| pm_node o l r ⇒
477  let l' ≝ pm_clean … l in
478  let r' ≝ pm_clean … r in
479  match o with
480  [ Some _ ⇒ pm_node … o l' r'
481  | None ⇒
482    if is_leaf … l' ∧ is_leaf … r' then pm_leaf ? else
483    pm_node … o l' r'
484  ]
485].
486 
487definition clean ≝ λtag,A.λm : identifier_map tag A.
488  match m with [ an_id_map pm ⇒ an_id_map tag A (pm_clean … pm) ].
489*)
490
491definition sigma_register_env :
492∀prog : ertl_program.∀sigma : (sigma_map prog).
493register_env beval → list register →  register_env beval ≝
494λprog,sigma,psd_env,ids.
495let m' ≝  map ??? psd_env (λbv.sigma_beval prog sigma bv) in
496m' ∖ ids.
497
498(*
499definition well_formed_ertl_psd_env :
500∀prog : ertl_program. ∀sigma : (sigma_map prog).
501ertl_psd_env → Prop≝
502λprog,sigma,psd_env.well_formed_register_env prog sigma (psd_regs psd_env).
503*)
504(*
505let rec well_formed_frames
506(prog : ertl_program) (sigma : (sigma_map prog))
507(l : list ertl_psd_env) on l : Prop ≝
508match l with
509  [nil ⇒ True
510  | cons a tl ⇒ well_formed_ertl_psd_env prog sigma a ∧
511               well_formed_frames prog sigma tl
512  ].                           
513*)
514
515
516lemma lookup_restrict : ∀tag,A,B.∀a : identifier_map tag A.∀b : identifier_map tag B.
517∀i.lookup ?? (a ∩ b) i = if i ∈ b then lookup … a i else None ?.
518#tag #A #B * #a * #b * #i normalize >lookup_opt_merge [2: %] cases (lookup_opt B i b)
519[2: #b] normalize % qed.
520
521
522lemma lookup_set_minus : ∀tag,A,B. ∀a : identifier_map tag A. ∀b : identifier_map tag B.
523∀i. lookup ?? (a ∖ b) i = if i ∈ b then None ? else lookup … a i.
524#tag #A #B * #a * #b * #i normalize >lookup_opt_merge [2: %] cases(lookup_opt B i b)
525[2: #b] % qed.
526
527(*
528lemma clean_add : ∀tag,A,m,i,v.clean … (add tag A m i v) = add tag A (clean … m) i v.
529#tag #A * #m * #i #v normalize @eq_f
530lapply m -m
531elim i -i
532[ * [%]
533  * [2: #x] #l #r [%] normalize
534  cases (pm_clean A l) normalize // cases (pm_clean A r) //
535|*: #i #IH * normalize
536  [1,3: >IH cases i // ]
537  * [2,4: #x] #l #r normalize
538  [1,2: >IH % ]
539  >IH cases i cases (pm_clean A l) cases (pm_clean A r) normalize //
540]
541qed.
542
543lemma clean_lookup : ∀tag,A,m,i.lookup … (clean tag A m) i = lookup … m i.
544#tag #A * #m * #i normalize lapply i -i elim m
545[#i %] * [2: #a] #l #r #Hl #Hr * [2,3,5,6: #x] normalize in ⊢ (???%);
546[1,3:<Hr|2,4:<Hl] normalize try % [3: @if_elim #_ %]
547cases(pm_clean A l) in Hl; normalize
548[2: #opt_a1 #l1 #r1 #_ %
549|3: #H cases(pm_clean A r) normalize //
550| #H cases(pm_clean A r) in Hr; normalize //
551| #opt_a1 #l1 #r1 #H cases x normalize //
552]
553qed.   
554
555 
556lemma clean_update : ∀tag,A,m,i,v.
557! m' ← update tag A m i v; return clean … m' =
558update tag A (clean … m) i v.
559#tag #A #m #i #v
560>update_def >update_def >clean_lookup cases (lookup tag A m i)
561[ % ]
562#m' >m_return_bind normalize nodelta >clean_add %
563qed.
564*)
565lemma lookup_eq_id_map : ∀tag : identifierTag. ∀ A : Type[0].
566∀m,m' : identifier_map tag A.
567(∀id. lookup … m id = lookup … m' id
568      ∧ (id_is_in A tag m id ↔ id_is_in A tag m' id)) → m=m'.
569#tag #A * #m * #m' #H @eq_f @lookup_eq #id lapply(H (an_identifier tag id))
570* #H1 #H2 % // assumption
571qed.
572
573(*
574lemma clean_leaf : ∀tag : identifierTag . ∀ A : Type[0].
575∀m : identifier_map tag A. (∀ id. lookup … m id = None ?) →
576clean ?? m = empty_map ??.
577#tag #A * #m elim m [#_ %] #opt_a #l #r #Hl #Hr #H normalize @eq_f
578lapply(H (an_identifier tag one)) normalize #EQ >EQ -EQ normalize
579lapply(Hl ?) [2: lapply(Hr ?)]
580  [1,3: * #id [lapply(H (an_identifier tag (p1 id))) | lapply(H (an_identifier tag (p0 id)))]
581       #H assumption
582  | normalize #EQ #EQ1 destruct >e0 >e1 normalize %
583  ]
584qed.
585*)
586lemma id_is_in_lookup : ∀tag,A,m,id,v.
587 lookup tag A m id = Some ? v → id_is_in A tag m id.
588#tag #A * #m * #id #a normalize lapply m -m elim id
589[|*: #x #IH] * normalize [1,3,5: #EQ destruct] #opt_a #l #r [ #_ %] #H [%3 |%2]
590@IH assumption
591qed.
592(*
593lemma pm_clean_leaf : ∀ A : Type[0].
594∀m : positive_map A. (∀ id. lookup_opt … id m = None ?) →
595pm_clean ? m = pm_leaf ….
596#A #m elim m [ #id %] #opt_a #l #r #Hl #Hr #H normalize lapply(H one) normalize
597#EQ >EQ normalize >Hl [normalize >Hr [ %]] #id [@(H (p1 id))|@(H (p0 id))]
598qed.
599
600
601lemma pm_clean_canonic : ∀A,m,n.(∀i.lookup_opt A i m = lookup_opt A i n) →
602  pm_clean ? m = pm_clean ? n.
603#A #m #n lapply m -m elim n
604[ @pm_clean_leaf ]
605* [2: #x] #l #r #IHl #IHr *
606  [1,3: #H @sym_eq @pm_clean_leaf #id @sym_eq @H ] #opt #l' #r' #H
607 lapply (H one) normalize in ⊢ (%→?); #EQ destruct
608 whd in ⊢ (??%%);
609 >(IHl l') [1,3: >(IHr r') [1,3 : % ]] #i
610 [1,2: @(H (p1 i)) |*: @(H (p0 i)) ] qed.
611
612
613lemma clean_canonic : ∀tag,A,m,n.(∀i.lookup tag A m i = lookup tag A n i) →
614  clean ?? m = clean ?? n.
615#tag #A * #m * #n #H normalize @eq_f @pm_clean_canonic #i
616lapply(H (an_identifier tag i))
617normalize //
618qed.
619*)
620lemma update_fail_lookup : ∀tag,A,m,i,v,e.update tag A m i v = Error … e → 
621  e = [MSG MissingId; CTX … i] ∧ lookup … m i = None ?.
622#tag #A #m #i #v #errmsg >update_def cases(lookup tag A m i) [2: #a] normalize
623#EQ destruct % //
624qed.
625
626lemma lookup_hit_update : ∀tag,A,m,i,v.i ∈ m → 
627  ∃m'.update tag A m i v = OK ? m'.
628#tag #A #m #i #v #H % [2: >update_def lapply(in_map_domain … m i) >H * #v #EQ >EQ
629normalize %|]
630qed.
631
632lemma lookup_miss_update : ∀tag,A,m,i,v.lookup tag A m i = None ? → 
633  update … m i v = Error … [MSG MissingId; CTX … i].
634#tag #A #m #i #v #EQ >update_def >EQ normalize %
635qed.
636
637lemma update_ok_old_lookup : ∀tag,A,m,i,v,m'.update tag A m i v = OK ? m' →
638  i ∈ m.
639#tag #A #m #i #v #m' >update_def inversion(lookup tag A m i) [2: #a] #EQ normalize
640#EQ destruct >EQ normalize @I
641qed.
642
643lemma lookup_update_ok : ∀tag,A,m,i,v,m',i'.update tag A m i v = OK ? m' →
644  lookup … m' i' = if eq_identifier ? i' i then Some ? v else lookup … m i'.
645#tag #A #m #i #v #m' #i' >update_def inversion(lookup tag A m i) [2: #a] #EQ
646normalize nodelta #EQ1 destruct @eq_identifier_elim
647[ #H normalize nodelta >H @lookup_add_hit
648| #H normalize nodelta @lookup_add_miss assumption
649]
650qed.
651
652lemma mem_set_restrict : ∀tag,A,B.∀a : identifier_map tag A.∀b : identifier_map tag B.
653∀i.i ∈ a ∩ b = (i ∈ a ∧ i ∈ b).
654#tag #A #B * #a * #b  * #i normalize >lookup_opt_merge [2: %] cases(lookup_opt B i b)
655[2: #a1] normalize [2: @if_elim #_ %] cases(lookup_opt A i a) [2: #a2] normalize %
656qed.
657(*
658lemma merge_eq : ∀A.∀p : positive_map A.∀choice. merge
659*)
660(*
661lemma add_restrict : ∀tag,A,B.∀a : identifier_map tag A. ∀b : identifier_map tag B.
662∀i,v.i∈b → add tag A (a ∩ b) i v = (add tag A a i v) ∩ b.
663#tag #A #B * #a * #b * #i #v normalize inversion(lookup_opt B i b) normalize [#_ *]
664#v1 #EQv1 * @eq_f lapply EQv1 lapply v1 lapply a lapply b -a -b -v1 elim i normalize
665[ * normalize [#b #v #EQ destruct] #opt_a #l #r *
666  [#v #EQ destruct normalize %] #opt_b #l1 #r1 #v #EQ destruct normalize cases opt_b
667  normalize [2: #x %] cases(merge A B A ? l1 l) normalize [2: #opt_a2 #l2 #r2 %]
668  cases(merge A B A ? r1 r) //
669|*: #x #IH * [2,4: #opt_b #l1 #r1] #p1 normalize [3,4: #i #EQ destruct] cases p1 -p1
670    [2,4: #opt_a #l2 #r2] normalize #v #H cases opt_b [2,4,6,8: #b] normalize
671    [1,2,5,6: <IH try assumption [1,2: cases opt_a [2,4: #a] normalize try %]
672     cases(merge A B A ? l2 l1) normalize // lapply H [1,4: cases r1 |*: cases l1]
673     normalize [1,3,5,7,9,11: #EQ destruct] #opt_b4 #l4 #r4 cases x normalize
674     [1,4,7,10,13,16: #EQ destruct normalize // cases(merge A B A ? ? ?) normalize //]
675     #x #H normalize cases(merge A B A ? ? ?) normalize //
676    |*: <IH try assumption
677       [1,3: cases(map_opt ? ? ? l1) normalize // lapply H cases r1 normalize
678            [1,3: #EQ destruct] #opt_b2 #l2 #r2 cases x [1,4: //] #x normalize //
679       |*: lapply H cases x normalize [2,3,5,6: #y] cases l1 normalize
680          [1,3,5,7,9,11: #EQ destruct] #opt_b2 #l2 #r2 #H //
681       ]
682   ]
683]
684qed.
685
686lemma update_restrict : ∀tag,A,B.∀a : identifier_map tag A.∀b : identifier_map tag B.
687∀i,v.i ∈ b → update ?? (a ∩ b) i v =
688  ! a' ← update ?? a i v ; return a' ∩ b.
689#tag #A #B #a #b #id #v #H
690lapply (in_map_domain … b id) >H * #ignore #EQ_lookup_b
691(*<clean_update*)
692inversion (update tag A a id v)
693[2: #e #EQ cases (update_fail_lookup ?????? EQ) #EQ1 #EQ2 destruct
694  >lookup_miss_update [%]
695  >lookup_restrict >H assumption ]
696#m' #EQ >m_return_bind
697cases (lookup_hit_update ?? (a∩b) id v ?)
698[2: >mem_set_restrict >H >(update_ok_old_lookup ?????? EQ) % ]
699#m'' >update_def >update_def in EQ; >lookup_restrict >H normalize nodelta
700cases(lookup tag A a id) normalize nodelta [#ABS destruct] #v1 #EQ #EQ'' destruct
701whd in ⊢ (??%%); @eq_f @add_restrict assumption
702qed.
703*)
704lemma add_set_minus  : ∀tag,A,B.∀a : identifier_map tag A.∀b : identifier_map tag B.
705∀i,v.¬(i ∈ b) → add tag A (a ∖ b) i v = (add tag A a i v) ∖ b.
706#tag #A #B * #a * #b * #i #v @notb_elim @if_elim normalize [#_ *]
707@if_elim [2: #_ *] @if_elim [#_ *] inversion(lookup_opt B i b) normalize [2: #x #_ *]
708#H * * * * @eq_f lapply H -H lapply v -v lapply b -b lapply a -a elim i
709[  *
710  [ * [2: #opt_b #l #r] #v normalize in ⊢ (% → ?); #EQ destruct [2: %]
711  normalize in ⊢ (??%%); cases (map_opt ??? l) // normalize cases(map_opt ??? r)
712  normalize //
713  | * [2: #a] #l #r * [2,4: #opt_b #l1 #r1] #v normalize in ⊢ (% → ?); #EQ destruct
714    normalize [3: % |1,2: cases(merge ???? l l1) // cases(merge ???? r r1) //]
715    cases(map_opt ??? l) normalize // cases(map_opt ??? r) //
716  ]
717|2,3: #x #IH * [2,4: #opt_a #l #r] * [2,4,6,8: #opt_b #l1 #r1] #v
718      normalize in ⊢ (% → ?); #H whd in match (pm_set ????) in ⊢ (???%);
719      whd in match (merge ??????) in ⊢ (???%);
720      [1,2,3,4: <IH try assumption whd in match (pm_set ????) in ⊢ (??%?);
721                whd in match (merge ??????) in ⊢ (??%?); cases opt_b normalize
722                [2,4,6,8: #b] [5,6: cases opt_a normalize //]
723                [1,2,3,4: cases (merge ???? l l1) normalize [2,4,6,8: #opt_a2 #l2 #r2]
724                          // cases (merge ???? r r1) normalize
725                          [2,4,6,8,10,12: #opt_a3 #l3 #r3] inversion(pm_set ????)
726                          normalize // cases x
727                          [2,3,5,6,8,9,11,12,14,15,17,18,20,21,23,24 : #y]
728                          normalize #EQ destruct
729                |*: cases(map_opt ??? l1) normalize [2,4,6,8: #opt_a2 #l2 #r2] //
730                    cases(map_opt ??? r1) normalize [2,4,6,8,10,12: #opt_a3 #l3 #r3]
731                    inversion(pm_set ????) normalize // cases x
732                    [2,3,5,6,8,9,11,12,14,15,17,18,20,21,23,24 : #y]
733                    normalize #EQ destruct
734                ]
735     |*: whd in match (pm_set ????) in ⊢ (??%?);
736         whd in match (merge ??????) in ⊢ (??%?); [1,2: cases opt_a [2,4: #a]]
737         normalize
738         [1,2: @eq_f2 [1,4:%] | cases(map_opt ??? l) [2: #opt_a1 #l1 #r1] normalize
739         | cases(map_opt ??? r) [2: #opt_a1 #l1 #r1] normalize]       
740         [1,3,4: lapply(map_add tag A A (λx.x) (an_id_map … r) (an_identifier ? x) v)
741         |2,5,6: lapply(map_add tag A A (λx.x) (an_id_map … l) (an_identifier ? x) v)
742         |*: lapply(map_add tag A A (λx.x) (an_id_map … (pm_leaf ?)) (an_identifier ? x) v)
743         ] normalize #EQ destruct >e0 try % [4,5: cases x [2,3,5,6: #y] normalize %]
744           cases(map_opt ????) [2,4,6: #opt_a1 #l1 #r1] normalize
745           inversion(pm_set ????) normalize // cases x [2,3,5,6,8,9,11,12: #y]
746           normalize #EQ1 destruct
747     ]
748]
749qed.     
750
751lemma update_set_minus : ∀tag,A,B.∀a : identifier_map tag A.∀b : identifier_map tag B.
752∀i,v.¬(i ∈ b) → update ?? (a ∖ b) i v =
753  ! a' ← update ?? a i v ; return a' ∖ b.
754#tag #A #B #a #b #id #v #H >update_def >lookup_set_minus @if_elim
755[ #H1 @⊥ lapply H1 lapply H @notb_elim >H1 normalize *] #_ >update_def
756cases (lookup tag A a id) normalize [ %] #a @eq_f @add_set_minus assumption
757qed.
758
759
760record good_state_transformation
761(prog : ertl_program)
762(def_in : joint_closed_internal_function ERTL (prog_var_names ?? prog)) :
763Type[0] ≝
764{ f_lbls : label → option (list label)
765; f_regs : label → option (list register)
766; part_partition_f_lbls : partial_partition … f_lbls
767; part_partion_f_regs : partial_partition … f_regs
768; freshness_lab : let def_out ≝ translate_internal … def_in in
769     (∀l.opt_All … (All …
770    (λlbl.¬fresh_for_univ … lbl (joint_if_luniverse … def_in) ∧
771           fresh_for_univ … lbl (joint_if_luniverse … def_out))) (f_lbls l))
772; freshness_regs : let def_out ≝ translate_internal … def_in in
773  (∀l.opt_All … (All …
774    (λreg.¬fresh_for_univ … reg (joint_if_runiverse … def_in) ∧
775           fresh_for_univ … reg (joint_if_runiverse … def_out))) (f_regs l))
776; multi_fetch_ok : let def_out ≝ translate_internal … def_in in
777  let f_step ≝ translate_step ? in
778  let f_fin ≝  translate_fin_step ? in
779  ∀l,s.stmt_at … (joint_if_code … def_in) l = Some ? s →
780  ∃lbls,regs.f_lbls l = Some ? lbls ∧ f_regs l = Some ? regs ∧
781  match s with
782  [ sequential s' nxt ⇒
783    l ~❨f_step l s', lbls, regs❩~> nxt in joint_if_code … def_out
784  | final s' ⇒
785    l ~❨f_fin l s', lbls, regs❩~> it in joint_if_code … def_out
786  | FCOND abs _ _ _ ⇒ Ⓧabs
787  ]
788}.
789
790definition get_internal_function_from_ident :
791∀ p: sem_params. ∀ globals : list ident . ∀ge : genv_t (joint_function p globals).
792ident → option (joint_closed_internal_function p globals) ≝
793λp,globals,ge,id.
794! bl  ← (find_symbol (joint_function p globals) ge id);
795! bl' ← (code_block_of_block bl);
796! 〈f,fn〉 ← res_to_opt … (fetch_internal_function ? ge bl');
797return fn.
798
799definition get_sigma_from_good_state :
800∀prog : ertl_program.
801(∀ fn : joint_closed_internal_function ERTL (prog_var_names ?? prog).
802good_state_transformation prog fn) → sigma_map prog ≝
803λprog,good,fn,searched.
804!〈res,s〉 ← find ?? (joint_if_code … fn)
805                (λlbl.λ_. match (f_lbls … (good fn)) lbl with
806                          [None ⇒ false
807                          |Some lbls ⇒
808                             match lbls with
809                                [nil ⇒ eq_identifier … searched lbl
810                                |cons hd tl ⇒ let last ≝ last_ne … «hd::tl,I» in
811                                          eq_identifier … searched last
812                                ]
813                          ]);
814return res.
815
816
817definition sigma_frames : ∀prog : ertl_program.
818(∀fn.good_state_transformation prog fn) →
819list (register_env beval × ident) → (list (register_env beval × ident)) ≝
820λprog,good,frms.
821let sigma ≝ get_sigma_from_good_state … good in
822foldr ??
823(λx,tl.let 〈reg_env,id〉 ≝ x in
824       match get_internal_function_from_ident
825                  ERTL_semantics (prog_var_names … prog)
826                  (globalenv_noinit … prog) id with
827       [Some fn ⇒
828  〈(sigma_register_env prog sigma reg_env
829       (added_registers … fn (f_regs … (good fn)))),id〉 :: tl
830       |None ⇒ [ ]
831       ]) ([ ]) frms.
832
833
834(*
835lemma sigma_empty_frames_commute :
836∀prog : ertl_program. ∀ sigma : (sigma_map prog).
837∃prf.
838sigma_frames prog sigma [] prf = [].
839#p #s % normalize %
840qed.
841
842
843let rec sigma_bit_vector_trie_opt (prog : ertl_program)
844(sigma : (sigma_map prog)) (n : nat) (t : BitVectorTrie beval n)
845on t : option … (BitVectorTrie beval n) ≝
846match t with
847  [Leaf bv ⇒ ! bv' ← (sigma_beval_opt prog sigma bv);
848                   return Leaf … bv'
849  |Node n1 b1 b2 ⇒ ! b1' ← (sigma_bit_vector_trie_opt prog sigma n1 b1);
850                   ! b2' ← (sigma_bit_vector_trie_opt prog sigma n1 b2);
851                   return Node … n1 b1' b2'
852  |Stub n1 ⇒  return Stub … n1
853  ].
854
855
856definition well_formed_hw_register_env :
857∀ prog : ertl_program. ∀ sigma : (sigma_map prog).
858hw_register_env → Prop ≝
859λprog,sigma,regs.sigma_bit_vector_trie_opt prog sigma 6 (reg_env … regs) ≠ None ?.
860*)
861
862
863include "common/BitVectorTrieMap.ma".
864
865definition sigma_hw_register_env :
866∀prog: ertl_program. ∀sigma : (sigma_map prog).
867hw_register_env → hw_register_env ≝
868λprog,sigma,h_reg.mk_hw_register_env
869(map ? ? (sigma_beval prog sigma) 6 (reg_env … h_reg)) (other_bit … h_reg).
870
871
872definition sigma_regs :
873∀prog : ertl_program. ∀sigma : (sigma_map prog).
874(register_env beval)×hw_register_env→ list register →
875(register_env beval)×hw_register_env ≝
876λprog,sigma,regs,ids.let 〈x,y〉≝ regs in
877      〈sigma_register_env prog sigma x ids,
878       sigma_hw_register_env prog sigma y〉.
879(*
880lemma sigma_empty_regsT_commute :
881∀prog : ertl_program. ∀sigma : (sigma_map prog).
882∀ptr.∃ prf.
883  empty_regsT ERTLptr_semantics ptr =
884  sigma_regs prog sigma (empty_regsT ERTL_semantics ptr) prf.
885#prog #sigma #ptr %
886[ @hide_prf whd in match well_formed_regs; normalize nodelta %
887 [whd in match well_formed_ertl_psd_env; normalize nodelta #id #bv
888  normalize in ⊢ (%→?); #EQ destruct
889 | normalize % #EQ destruct
890 ]
891| % ]
892qed.
893
894axiom sigma_load_sp_commute :
895∀prog : ertl_program.∀sigma : (sigma_map prog).
896∀regs,ptr.
897load_sp ERTL_semantics regs = return ptr
898→ ∃prf.
899load_sp ERTLptr_semantics (sigma_regs prog sigma regs prf) = return ptr.
900
901axiom sigma_save_sp_commute :
902∀prog : ertl_program. ∀sigma : (sigma_map prog).
903∀reg,ptr,prf1. ∃prf2.
904save_sp ERTLptr_semantics (sigma_regs prog sigma reg prf1) ptr =
905sigma_regs prog sigma (save_sp ERTL_semantics reg ptr) prf2.
906
907definition well_formed_state :
908∀prog : ertl_program. ∀sigma : sigma_map prog.
909state ERTL_semantics → Prop ≝
910λprog,sigma,st.
911well_formed_frames prog sigma (st_frms … st) ∧
912sigma_is_opt prog sigma (istack … st) ≠ None ? ∧
913well_formed_regs prog sigma (regs … st) ∧
914well_formed_mem prog sigma (m … st).
915*)
916
917definition sigma_state : ∀prog : ertl_program.
918(∀fn.good_state_transformation prog fn) →
919 state ERTLptr_semantics → list register →
920 state ERTL_semantics ≝
921λprog,good,st,ids.
922let sigma ≝ get_sigma_from_good_state … good in
923mk_state ?
924  (sigma_frames prog good (st_frms ERTLptr_semantics st))
925  (sigma_is ? sigma (istack … st))
926  (carry … st)
927  (sigma_regs ? sigma (regs … st) ids)
928  (sigma_mem ? sigma (m … st)).
929
930
931definition dummy_state : state ERTL_semantics ≝
932mk_state ERTL_semantics
933   [ ] empty_is BBundef 〈empty_map ? ?,mk_hw_register_env … (Stub …) BBundef〉 empty.
934   
935definition dummy_state_pc : state_pc ERTL_semantics ≝
936mk_state_pc ? dummy_state (null_pc one) (null_pc one).
937
938definition sigma_state_pc :
939∀prog : ertl_program.
940(∀fn.good_state_transformation prog fn) →
941state_pc ERTLptr_semantics →
942 state_pc ERTL_semantics ≝
943λprog,good,st.
944  let sigma ≝ get_sigma_from_good_state … good in
945  let ge ≝ globalenv_noinit … prog in
946  if eqZb       (block_id (pc_block (pc … st))) (-1) then (* check for dummy pc *)
947    dummy_state_pc
948  else
949  match (fetch_internal_function (joint_closed_internal_function ERTL
950         (prog_var_names (joint_function ERTL) ℕ prog)) ge (pc_block (pc … st))) with
951   [OK x ⇒ let 〈i,fd〉 ≝ x in
952      mk_state_pc ?
953       (sigma_state prog good st (added_registers … fd (f_regs … (good fd))))
954       (pc … st) (sigma_stored_pc prog sigma (last_pop … st))
955   |Error msg ⇒ dummy_state_pc].
956
957
958definition ERTLptrStatusSimulation :
959∀ prog : ertl_program.
960let trans_prog ≝ ertl_to_ertlptr prog in
961∀stack_sizes.(∀fn.good_state_transformation prog fn) →
962status_rel (ERTL_status prog stack_sizes) (ERTLptr_status trans_prog stack_sizes) ≝
963λprog,stack_sizes,good.
964  let trans_prog ≝ ertl_to_ertlptr prog in
965    mk_status_rel ??
966    (* sem_rel ≝ *) (λs1:ERTL_status prog stack_sizes
967       .λs2:ERTLptr_status trans_prog stack_sizes
968        .s1=sigma_state_pc prog good s2)
969    (* call_rel ≝ *) 
970          (λs1:Σs:ERTL_status prog stack_sizes
971               .as_classifier (ERTL_status prog stack_sizes) s cl_call
972       .λs2:Σs:ERTLptr_status trans_prog stack_sizes
973                .as_classifier (ERTLptr_status trans_prog stack_sizes) s cl_call
974        .let sigma ≝ get_sigma_from_good_state … good in
975        pc (mk_prog_params ERTL_semantics prog stack_sizes) s1
976         =sigma_stored_pc prog sigma
977          (pc
978           (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_sizes)
979           s2))
980    (* sim_final ≝ *) ?.
981cases daemon
982qed.
983
984lemma fetch_function_no_minus_one :
985  ∀F,V,i,p,bl.
986  block_id (pi1 … bl) = -1 →
987  fetch_function … (globalenv (λvars.fundef (F vars)) V i p)
988    bl = Error … [MSG BadFunction].
989 #F#V#i#p ** #r #id #EQ1 destruct
990  whd in match fetch_function; normalize nodelta
991  >globalenv_no_minus_one
992  cases (symbol_for_block ???) normalize //
993qed.
994 
995lemma fetch_function_no_zero :
996 ∀F,V,i,p,bl.
997  block_id (pi1 … bl) = 0 →
998  fetch_function … (globalenv (λvars.fundef (F vars)) V i p)
999    bl = Error … [MSG BadFunction].
1000 #F#V#i#p ** #r #id #EQ1 destruct
1001  whd in match fetch_function; normalize nodelta
1002  >globalenv_no_zero
1003  cases (symbol_for_block ???) normalize //
1004qed.
1005
1006(*DOPPIONI dei LEMMI in LINEARISE_PROOF*)
1007lemma symbol_for_block_match:
1008    ∀M:matching.∀initV,initW.
1009     (∀v,w. match_var_entry M v w →
1010      size_init_data_list (initV (\snd v)) = size_init_data_list (initW (\snd w))) →
1011    ∀p: program (m_A M) (m_V M). ∀p': program (m_B M) (m_W M).
1012    ∀MATCH:match_program … M p p'.
1013    ∀b: block.
1014    symbol_for_block … (globalenv … initW p') b =
1015    symbol_for_block … (globalenv … initV p) b.
1016* #A #B #V #W #match_fn #match_var #initV #initW #H
1017#p #p' * #Mvars #Mfn #Mmain
1018#b
1019whd in match symbol_for_block; normalize nodelta
1020whd in match globalenv in ⊢ (???%); normalize nodelta
1021whd in match (globalenv_allocmem ????);
1022change with (add_globals ?????) in match (foldl ?????);
1023>(proj1 … (add_globals_match … initW … Mvars))
1024[ % |*:]
1025[ * #idr #v * #idr' #w #MVE %
1026  [ inversion MVE
1027    #H1 #H2 #H3 #H4 #H5 #H6 #H7 #H8 destruct %
1028  | @(H … MVE)
1029  ]
1030| @(matching_fns_get_same_blocks … Mfn)
1031  #f #g @match_funct_entry_id
1032]
1033qed.
1034
1035lemma symbol_for_block_transf :
1036 ∀A,B,V,init.∀prog_in : program A V.
1037 ∀trans : ∀vars.A vars → B vars.
1038 let prog_out ≝ transform_program … prog_in trans in
1039 ∀bl.
1040 symbol_for_block … (globalenv … init prog_out) bl =
1041 symbol_for_block … (globalenv … init prog_in) bl.
1042#A #B #V #iV #p #tf @(symbol_for_block_match … (transform_program_match … tf ?))
1043#v0 #w0 * //
1044qed.
1045
1046lemma fetch_function_transf :
1047 ∀A,B,V,init.∀prog_in : program A V.
1048 ∀trans : ∀vars.A vars → B vars.
1049 let prog_out ≝ transform_program … prog_in trans in
1050 ∀bl,i,f.
1051 fetch_function … (globalenv … init prog_in) bl =
1052  return 〈i, f〉
1053→ fetch_function … (globalenv … init prog_out) bl =
1054  return 〈i, trans … f〉.
1055#A #B #V #init #prog_in #trans #bl #i #f
1056 whd in match fetch_function; normalize nodelta
1057 #H lapply (opt_eq_from_res ???? H) -H
1058 #H @('bind_inversion H) -H #id #eq_symbol_for_block
1059 #H @('bind_inversion H) -H #fd #eq_find_funct
1060 whd in ⊢ (??%?→?); #EQ destruct(EQ)
1061 >(symbol_for_block_transf … trans) >eq_symbol_for_block >m_return_bind
1062 >(find_funct_ptr_transf A B …  eq_find_funct) %
1063qed.
1064
1065
1066lemma fetch_internal_function_transf :
1067 ∀A,B.∀prog_in : program (λvars.fundef (A vars)) ℕ.
1068 ∀trans : ∀vars.A vars → B vars.
1069 let prog_out ≝ transform_program … prog_in (λvars.transf_fundef … (trans vars)) in
1070 ∀bl,i,f.
1071 fetch_internal_function … (globalenv_noinit … prog_in) bl =
1072  return 〈i, f〉
1073→ fetch_internal_function … (globalenv_noinit … prog_out) bl =
1074  return 〈i, trans … f〉.
1075#A #B #prog #trans #bl #i #f
1076 whd in match fetch_internal_function; normalize nodelta
1077 #H @('bind_inversion H) * #id * #fd normalize nodelta #EQfetch
1078 whd in ⊢ (??%%→?); #EQ destruct(EQ)
1079 >(fetch_function_transf … EQfetch) %
1080qed.
1081
1082(*
1083definition good_local_sigma :
1084  ∀globals.
1085  ∀g:codeT ERTLptr globals.
1086  (Σl.bool_to_Prop (code_has_label … g l)) →
1087  codeT ERTL globals →
1088  (label → option label) → Prop ≝
1089  λglobals,g,c,sigma.
1090    ∀l,l'.sigma l = Some ? l' →
1091      ∃s. stmt_at … g l = Some ? s ∧
1092          All ? (λl.sigma l ≠ None ?) (stmt_labels … s) ∧
1093          (match s with
1094           [ sequential s' nxt ⇒
1095             match s' with
1096             [ step_seq _ ⇒
1097               (stmt_at … c n = Some ? (sequential … s' it)) ∧
1098                  ((sigma nxt = Some ? (S n)) ∨
1099                   (stmt_at … c (S n) = Some ? (GOTO … nxt)))
1100             | COND a ltrue ⇒
1101               (stmt_at … c n = Some ? (sequential … s' it) ∧ sigma nxt = Some ? (S n)) ∨
1102               (stmt_at … c n = Some ? (FCOND … I a ltrue nxt))
1103             ]
1104           | final s' ⇒
1105             stmt_at … c n = Some ? (final … s')
1106           | FCOND abs _ _ _ ⇒ Ⓧabs
1107           ]).
1108 
1109*)
1110
1111lemma ps_reg_retrieve_ok :  ∀prog : ertl_program.
1112∀sigma : sigma_map prog. ∀r,restr.
1113preserving1 ?? res_preserve1 …
1114     (λregs.sigma_regs prog sigma regs restr)
1115     (sigma_beval prog sigma)
1116     (λregs.ps_reg_retrieve regs r)
1117     (λregs.ps_reg_retrieve regs r).
1118#prog #sigma #r #restr * #psd_r #hw_r whd in match ps_reg_retrieve;
1119whd in match reg_retrieve; normalize nodelta @opt_to_res_preserve1
1120whd in match sigma_regs; whd in match sigma_register_env; normalize nodelta
1121>lookup_set_minus @if_elim [ #_ @opt_preserve_none1] #id_r_not_in
1122>(lookup_map ?? RegisterTag ???) #bv #H @('bind_inversion H) -H #bv1
1123#bv1_spec whd in ⊢ (??%? → ?); #EQ destruct %{bv1} % // >bv1_spec %
1124qed.
1125
1126lemma hw_reg_retrieve_ok : ∀prog : ertl_program.
1127∀sigma : sigma_map prog. ∀r,restr.
1128preserving1 ?? res_preserve1 …
1129    (λregs.sigma_regs prog sigma regs restr)
1130    (sigma_beval prog sigma)
1131    (λregs.hw_reg_retrieve regs r)
1132    (λregs.hw_reg_retrieve regs r).
1133#prog #sigma #r #restr * #psd_r * #hw_r #b whd in match hw_reg_retrieve;
1134whd in match hwreg_retrieve; normalize nodelta whd in match sigma_regs;
1135whd in match sigma_hw_register_env; normalize nodelta
1136change with (sigma_beval prog sigma BVundef) in ⊢ (???????(??(?????%))?);
1137#bv >lookup_map whd in ⊢ (???% → ?); #EQ destruct
1138%{(lookup beval 6 (bitvector_of_register r) hw_r BVundef)}
1139% //
1140qed.
1141
1142
1143lemma ps_reg_store_ok : ∀prog : ertl_program.
1144∀sigma : sigma_map prog. ∀r,restr.
1145preserving21 ?? res_preserve1 …
1146   (sigma_beval prog sigma)
1147   (λregs.sigma_regs prog sigma regs restr)
1148   (λregs.sigma_regs prog sigma regs restr)
1149   (ps_reg_store r)
1150   (ps_reg_store r).
1151#prog #sigma #r #restr whd in match ps_reg_store; normalize nodelta
1152#bv * #psd_r #hw_r @mfr_bind1
1153[ @(λr.sigma_register_env prog sigma r restr)
1154| whd in match reg_store; whd in match sigma_regs; normalize nodelta
1155  #x #x_spec lapply(update_ok_to_lookup ?????? x_spec) * * #_ #EQpsd #_
1156  lapply x_spec -x_spec lapply EQpsd -EQpsd whd in match sigma_register_env;
1157  normalize nodelta >lookup_set_minus @if_elim [ #_ * #H @⊥ @H %]
1158  #id_not_in #_ >update_set_minus [2: assumption] #H @('bind_inversion H) -H
1159  #x0 >map_update_commute #H @('bind_inversion H) -H #x1 #x1_spec
1160  whd in ⊢ (??%% → ??%% → ?); #EQ1 #EQ2 destruct %{x1} % //
1161| #x * #psd_r' #hw_r' whd in match sigma_regs; normalize nodelta
1162  whd in ⊢ (???% → ?); #EQ destruct %{〈x,hw_r〉} % //
1163]
1164qed.
1165
1166
1167lemma hw_reg_store_ok : ∀prog : ertl_program.
1168∀sigma : sigma_map prog. ∀r,restr.
1169preserving21 ?? res_preserve1 …
1170   (sigma_beval prog sigma)
1171   (λregs.sigma_regs prog sigma regs restr)
1172   (λregs.sigma_regs prog sigma regs restr)
1173   (hw_reg_store r)
1174   (hw_reg_store r).
1175#prog #sigma #r #restr whd in match hw_reg_store; normalize nodelta
1176#bv * #psd_r * #hw_r #b whd in match hwreg_store; whd in match sigma_regs; normalize nodelta
1177whd in match sigma_hw_register_env; normalize nodelta <insert_map * #psd_r'
1178* #hw_r' #b' whd in ⊢ (???% → ?); #EQ destruct % [2: % [%] % |]
1179qed.
1180
1181
1182lemma ertl_eval_move_ok : ∀prog : ertl_program.
1183∀sigma : sigma_map prog. ∀ restr,pm.
1184preserving1 ?? res_preserve1 …
1185     (λregs.sigma_regs prog sigma regs restr)
1186     (λregs.sigma_regs prog sigma regs restr)
1187     (λregs.ertl_eval_move regs pm)
1188     (λregs.ertl_eval_move regs pm).
1189#prog #sigma #restr * #mv_dst #arg_dst #pm whd in match ertl_eval_move;
1190normalize nodelta @mfr_bind1 [@(sigma_beval prog sigma)
1191| cases arg_dst normalize nodelta
1192  [2: #b change with (return sigma_beval prog sigma (BVByte b)) in ⊢ (???????%?);
1193      @mfr_return1]
1194  * #r normalize nodelta [@ps_reg_retrieve_ok| @hw_reg_retrieve_ok]
1195| #bv cases mv_dst #r normalize nodelta [@ps_reg_store_ok | @hw_reg_store_ok]
1196]
1197qed.
1198
1199lemma ps_arg_retrieve_ok : ∀prog : ertl_program.
1200∀sigma : sigma_map prog. ∀a,restr.
1201preserving1 ?? res_preserve1 …
1202    (λregs.sigma_regs prog sigma regs restr)
1203    (sigma_beval prog sigma)
1204    (λregs.ps_arg_retrieve regs a)
1205    (λregs.ps_arg_retrieve regs a).
1206#prog #sigma #a #restr whd in match ps_arg_retrieve; normalize nodelta cases a -a
1207normalize nodelta [#r | #b ] #regs
1208[ @ps_reg_retrieve_ok
1209| change with (return sigma_beval prog sigma (BVByte b)) in ⊢ (???????%?);
1210  @mfr_return1
1211]
1212qed.
1213
1214lemma pop_ok :
1215∀prog : ertl_program.
1216∀good : (∀fn.good_state_transformation prog fn).
1217∀restr.
1218preserving1 ?? res_preserve1 ????
1219   (λst.sigma_state prog good st restr)
1220   (λx.let 〈bv,st〉 ≝ x in
1221      〈let sigma ≝ get_sigma_from_good_state … good in
1222       sigma_beval prog sigma bv,
1223       sigma_state prog good st restr〉)
1224   (pop ERTL_semantics)
1225   (pop ERTLptr_semantics).
1226#prog #good #restr whd in match pop; normalize nodelta #st @mfr_bind1
1227[@(λx.let 〈bv,is〉 ≝ x in
1228      let sigma ≝ get_sigma_from_good_state … good in
1229     〈sigma_beval prog sigma bv,
1230      sigma_is prog sigma is 〉)
1231| whd in match is_pop; normalize nodelta whd in match sigma_state; normalize nodelta
1232  cases(istack ? st) normalize nodelta
1233  [@res_preserve_error1
1234  |2,3: #bv1 [2: #bv2] * #bv3 #is1 whd in ⊢ (??%% → ?); #EQ destruct
1235        % [2,4: % [1,3: %|*: %] |*:]
1236  ]
1237| * #bv #is * #bv1 #st whd in ⊢ (??%% → ?); #EQ destruct % [2: % [%] %|]
1238]
1239qed.
1240
1241lemma push_ok :
1242∀prog : ertl_program.
1243∀good : (∀fn.good_state_transformation prog fn).
1244∀restr.
1245preserving21 ?? res_preserve1 …
1246     (λst.sigma_state prog good st restr)
1247     (let sigma ≝ get_sigma_from_good_state … good in sigma_beval prog sigma)
1248     (λst.sigma_state prog good st restr)
1249     (push ERTL_semantics)
1250     (push ERTLptr_semantics).
1251#prog #good #restr whd in match push; normalize nodelta #st #bv @mfr_bind1
1252[ @(let sigma ≝ get_sigma_from_good_state … good in sigma_is ? sigma)
1253| whd in match is_push; normalize nodelta whd in match sigma_state; normalize nodelta
1254 cases (istack ? st) [2,3: #bv [2: #bv']]  whd in match sigma_is in ⊢ (???????%?);
1255 normalize nodelta [@res_preserve_error1] @mfr_return_eq1 %
1256| #is @mfr_return_eq1 %
1257]
1258qed.
1259
1260lemma be_opaccs_ok :
1261∀prog : ertl_program. ∀sigma : sigma_map prog.
1262∀ op.
1263preserving21 ?? res_preserve1 ??????
1264    (sigma_beval prog sigma)
1265    (sigma_beval prog sigma)
1266    (λx.let 〈bv1,bv2〉 ≝ x in
1267           〈sigma_beval prog sigma bv1,
1268            sigma_beval prog sigma bv2〉)
1269    (be_opaccs op)
1270    (be_opaccs op).
1271#prog #sigma #op #bv #bv1
1272whd in match be_opaccs; normalize nodelta @mfr_bind1
1273[ @(λx.x)
1274| cases bv
1275  [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1276  whd in match Byte_of_val; normalize nodelta
1277  try @res_preserve_error1 [ #x whd in ⊢ (???% → ?); #EQ destruct %{x} % //]
1278  whd in match sigma_beval; normalize nodelta cases (sigma_pc_opt ? ? ?)
1279  normalize nodelta [2: #pc] @res_preserve_error1
1280| #by @mfr_bind1
1281  [ @(λx.x)
1282  | cases bv1
1283    [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1284    whd in match Byte_of_val; normalize nodelta
1285    try @res_preserve_error1 [ #x whd in ⊢ (???% → ?); #EQ destruct %{x} % //]
1286    whd in match sigma_beval; normalize nodelta cases (sigma_pc_opt ? ? ?)
1287    normalize nodelta [2: #pc] @res_preserve_error1
1288 | #by1 * #bv2 #bv3 cases(opaccs eval op by by1) #by' #by1' normalize nodelta
1289   whd in ⊢ (??%% → ?); #EQ destruct % [2: % [%] % |]
1290qed.
1291
1292lemma be_op1_ok : ∀prog : ertl_program. ∀sigma : sigma_map prog.
1293∀ op.
1294preserving1 ?? res_preserve1 …
1295     (sigma_beval prog sigma)
1296     (sigma_beval prog sigma)
1297     (be_op1 op)
1298     (be_op1 op).
1299#prog #sigma #o #bv whd in match be_op1; normalize nodelta @mfr_bind1
1300[ @(λx.x)
1301| cases bv
1302  [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1303  whd in match Byte_of_val; whd in match sigma_beval; normalize nodelta
1304  try @res_preserve_error1 [ @mfr_return_eq1 %]
1305  cases(sigma_pc_opt prog sigma pc1) [2: #pc2] normalize nodelta
1306  @res_preserve_error1
1307| #by @mfr_return_eq1 %
1308]
1309qed.
1310
1311lemma res_preserve_error11 : ∀X,Y,F,e,n. (∃e'.n = Error … e') →
1312res_preserve1 X Y F n (Error … e).
1313#X #Y #F #e #n * #e' #n_spec >n_spec @res_preserve_error1
1314qed.
1315
1316
1317lemma be_op2_ok : ∀prog : ertl_program. ∀sigma : sigma_map prog.
1318∀ b,op.
1319preserving21 ?? res_preserve1 …
1320     (sigma_beval prog sigma)
1321     (sigma_beval prog sigma)
1322     (λx.let 〈bv,b〉≝ x in 〈sigma_beval prog sigma bv,b〉)
1323     (be_op2 b op)
1324     (be_op2 b op).
1325#prog #sigma #b #op #bv #bv1 whd in match be_op2; normalize nodelta
1326cases bv
1327[ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1328normalize nodelta [@res_preserve_error1] whd in match sigma_beval;
1329normalize nodelta
1330cases bv1
1331[1,2,8,9,15,16,22,23,29,30,36,37:
1332|3,10,17,24,31,38: #ptr1' #ptr2' #p'
1333|4,11,18,25,32,39: #by'
1334|5,12,19,26,33,40: #p'
1335|6,13,20,27,34,41: #ptr' #p'
1336|7,14,21,28,35,42: #pc1' #p1'
1337]
1338normalize nodelta try @res_preserve_error1
1339[4,5,8,13,16,20,21,22,23,24,25,26 : @res_preserve_error11 %
1340   [2,4,6,8,10,12,14,16,18,20,22,24: cases(sigma_pc_opt ???) try % #pc2 %
1341   |*:]
1342|*: cases op normalize nodelta
1343    try @res_preserve_error1 try( @mfr_return_eq1 %)
1344    [1,2,12,13,16,17,18: @if_elim #_ try @res_preserve_error1
1345                         try( @mfr_return_eq1 %)
1346                         [ @if_elim #_ @mfr_return_eq1 %
1347                         | cases(ptype ptr) normalize nodelta
1348                           [2: @res_preserve_error1] @mfr_bind1
1349                           [ @(λx.x)
1350                           | whd in match Bit_of_val; normalize nodelta
1351                             cases b [#bo|| #bo #ptr'' #p'' #bit_v]
1352                             normalize nodelta [2,3: @res_preserve_error1]
1353                             @mfr_return_eq1 %
1354                           | #bi cases(op2 ?????) #by #bi1 normalize nodelta
1355                             @mfr_return_eq1 %
1356                           ]
1357                         | cases(ptype ptr) normalize nodelta @res_preserve_error1
1358                         ]
1359    |3,4,5,6,7,8: @mfr_bind1
1360        [1,4,7,10,13,16: @(λx.x)
1361        |2,5,8,11,14,17: whd in match Bit_of_val; normalize nodelta
1362                         cases b [1,4,7,10,13,16: #bo|
1363                                 |2,5,8,11,14,17:
1364                                 |3,6,9,12,15,18: #bo #ptr'' #p'' #bit_v
1365                                 ] normalize nodelta try @res_preserve_error1
1366                                 @mfr_return_eq1 %
1367       |3,6,9,12,15,18: #bi cases(op2 ?????) #by #bi1 normalize nodelta
1368                        @mfr_return_eq1 %
1369       ]
1370    |*: whd in match be_add_sub_byte; normalize nodelta
1371        [1,2,3: cases(ptype ptr) normalize nodelta [2,4,6: @res_preserve_error1]
1372                cases p * [2,4,6: #p_no] #prf normalize nodelta
1373                [@res_preserve_error1
1374                |2,3: cases b [1,4: #bo|2,5: |3,6:  #bo #ptr'' #p'' #bit_v]
1375                      normalize nodelta [1,2,3,4: @res_preserve_error1]
1376                      @if_elim #_ [2,4: @res_preserve_error1]
1377                      @If_elim #INUTILE [2,4: @res_preserve_error1]
1378                      @pair_elim #a1 #a2 #_ normalize nodelta
1379                      @mfr_return_eq1 %
1380                |*: @mfr_bind1
1381                  [1,4,7: @(λx.x)
1382                  |2,5,8: whd in match Bit_of_val; normalize nodelta
1383                          [@mfr_return_eq1 %] cases b
1384                          [1,4: #bo|2,5: |3,6:  #bo #ptr'' #p'' #bit_v]
1385                          normalize nodelta [3,4,5,6: @res_preserve_error1]
1386                          @mfr_return_eq1 %
1387                  |3,6,9: * normalize nodelta [1,3,5: @res_preserve_error1]
1388                          cases(op2 ?????) #a1 #a2 normalize nodelta
1389                          @mfr_return_eq1 %
1390                  ]
1391               ]
1392         |*: cases(ptype ptr') normalize nodelta [2,4: @res_preserve_error1]
1393             cases p' * [2,4: #part_no] #prf normalize nodelta
1394             [ @res_preserve_error1
1395             | cases b [#bo|| #bo #ptr'' #p'' #bit_v]
1396               normalize nodelta [1,2: @res_preserve_error1] @if_elim #_
1397               [2: @res_preserve_error1] @If_elim #INUTILE [2: @res_preserve_error1]
1398               @pair_elim #a1 #a2 #_ normalize nodelta @mfr_return_eq1 %
1399             |*: @mfr_bind1
1400                [1,4: @(λx.x)
1401                |2,5: whd in match Bit_of_val; normalize nodelta [ @mfr_return_eq1 %]
1402                      cases b [#bo|| #bo #ptr'' #p'' #bit_v] normalize nodelta
1403                      [2,3: @res_preserve_error1] @mfr_return_eq1 %
1404                |3,6: * normalize nodelta [1,3: @res_preserve_error1]   
1405                      cases(op2 ?????) #a1 #a2 normalize nodelta
1406                      @mfr_return_eq1 %
1407                ]
1408              ]
1409          ]
1410      ]
1411]
1412qed.
1413
1414lemma pointer_of_address_ok : ∀prog : ertl_program. ∀sigma : sigma_map prog.
1415preserving1 … res_preserve1 …
1416     (λx.let 〈bv1,bv2〉 ≝ x in〈sigma_beval prog sigma bv1,
1417           sigma_beval prog sigma bv2〉)
1418     (λx.x)
1419     pointer_of_address pointer_of_address.
1420#prog #sigma * #bv1 #bv2 whd in match pointer_of_address;
1421whd in match pointer_of_bevals; normalize nodelta
1422cases bv1 normalize nodelta
1423[ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1424try @res_preserve_error1
1425[ cases bv2 [ | | #ptr1' #ptr2' #p' | #by' | #p' | #ptr' #p' | #pc1' #p1']
1426  normalize nodelta
1427  [1,2,3,4,5: @res_preserve_error1
1428  | @if_elim #_ [ @mfr_return_eq1 % | @res_preserve_error1]
1429  ]
1430] whd in match sigma_beval; normalize nodelta cases(sigma_pc_opt ???)
1431  [2,4: #pc4] normalize nodelta @res_preserve_error1
1432qed.
1433
1434lemma beloadv_ok : ∀prog : ertl_program. ∀sigma : sigma_map prog.
1435∀ptr.
1436preserving1 … opt_preserve1 …
1437     (sigma_mem prog sigma)
1438     (sigma_beval prog sigma)
1439     (λm.beloadv m ptr)
1440     (λm.beloadv m ptr).
1441#prog #sigma #ptr #mem whd in match beloadv; whd in match do_if_in_bounds;
1442normalize nodelta @if_elim [2: #_ @opt_preserve_none1]
1443whd in match sigma_mem in ⊢ (% → ?); normalize nodelta #Hzlb
1444@if_elim [2: #_ @opt_preserve_none1] whd in match sigma_mem in ⊢ (% → ?);
1445normalize nodelta @If_elim [2: >Hzlb * #H @⊥ @H %] #_ @andb_elim @if_elim
1446[2: #_ *] #Hzleb #Hzlb' >Hzlb normalize nodelta >Hzlb' normalize nodelta
1447@mfr_return_eq1 whd in match sigma_mem; normalize nodelta >Hzlb
1448@If_elim [2: * #H @⊥ @H %] * >Hzleb >Hzlb' @If_elim [2: * #H @⊥ @H %]
1449* %
1450qed.
1451
1452lemma bestorev_ok : ∀prog : ertl_program.∀sigma : sigma_map prog.
1453∀ptr.
1454preserving21 … opt_preserve1 …
1455    (sigma_mem prog sigma)
1456    (sigma_beval prog sigma)
1457    (sigma_mem prog sigma)
1458    (λm.bestorev m ptr)
1459    (λm.bestorev m ptr).
1460#prog #sigma #ptr #mem #bv whd in match bestorev; whd in match do_if_in_bounds;
1461normalize nodelta @if_elim [2: #_ @opt_preserve_none1]
1462whd in match sigma_mem in ⊢ (% → ?); normalize nodelta #Hzlb
1463@if_elim [2: #_ @opt_preserve_none1] @andb_elim @if_elim [2: #_ *]
1464whd in match sigma_mem in ⊢ (% → % → ?); normalize nodelta >Hzlb
1465@If_elim [2: * #H @⊥ @H %] * #Hzleb #Hzlb' normalize nodelta >Hzleb
1466>Hzlb' normalize nodelta @mfr_return_eq1 whd in ⊢ (???%); @eq_f @mem_ext_eq
1467[ #bl normalize nodelta % [%]
1468  [ whd in match sigma_mem; normalize nodelta >Hzlb @If_elim [2: * #H @⊥ @H %] *
1469    whd in match update_block; normalize nodelta @if_elim
1470    [ @eq_block_elim [2: #_ *] #EQbl * >EQbl >Hzlb @If_elim [2: * #H @⊥ @H %]
1471      * whd in match low_bound; normalize nodelta @if_elim [ #_ %]
1472      @eq_block_elim #_ * %
1473    | @eq_block_elim [#_ *] * #Hbl * @If_elim
1474      [ #Hzlb'' >Hzlb'' @If_elim [2: * #H @⊥ @H %] * whd in match low_bound;
1475        normalize nodelta @if_elim [2: #_ %] @eq_block_elim [2: #_ *] #H @⊥ @Hbl
1476        assumption
1477      | #Hzlb'' >Hzlb'' @If_elim [*] #_ %
1478      ]
1479   ]
1480 | whd in match update_block; whd in match sigma_mem; normalize nodelta
1481   @if_elim @eq_block_elim [2,3: #_ * |4: *] #Hbl #_ @If_elim
1482   [3,4: >Hbl >Hzlb * [2: #H @⊥ @H %] @If_elim [2: * #H @⊥ @H %] *
1483        whd in match high_bound; normalize nodelta @if_elim [#_ %]
1484        @eq_block_elim [ #_ *] * #H @⊥ @H %
1485   | #Hzlb'' >Hzlb'' @If_elim [2: * #H @⊥ @H %] * whd in match high_bound;
1486     normalize nodelta @if_elim [2: #_ %] @eq_block_elim [2: #_ *]
1487     #H @⊥ @Hbl assumption
1488  | #Hzlb'' >Hzlb'' @If_elim [*] #_ %
1489  ]
1490 | #z whd in match update_block; whd in match sigma_mem; normalize nodelta
1491   @if_elim @eq_block_elim [2,3: #_ * |4: *] #Hbl #_
1492   [ @If_elim #Hzlb'' >Hzlb'' [2: @If_elim * #_ %] @If_elim @andb_elim
1493     @if_elim [2: #_ *] #Hzleb' #Hzlb'''
1494     [ @If_elim [2: * #H @⊥ @H %] * whd in match low_bound; normalize nodelta
1495       @If_elim @andb_elim @if_elim [2: #_ *] @if_elim
1496       [1,3,5: @eq_block_elim [2,4,6: #_ *] #H @⊥ @Hbl assumption] #_ >Hzleb' *
1497       whd in match high_bound; normalize nodelta @if_elim
1498       [1,3: @eq_block_elim [2,4: #_ *] #H @⊥ @Hbl assumption] #_ >Hzlb'''
1499       [ * %] * #H @⊥ @H %
1500     | @If_elim * [2: #H @⊥ @H %] whd in match low_bound; normalize nodelta
1501       @if_elim [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_
1502       >Hzleb' whd in match high_bound; normalize nodelta @if_elim
1503       [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_ >Hzlb'''
1504       @If_elim [2: #_ %] *
1505     | @If_elim [2: * #H @⊥ @H %] whd in match low_bound; normalize nodelta @if_elim
1506       [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_ #_
1507       whd in match low_bound in Hzleb'; normalize nodelta in Hzleb';
1508       whd in match high_bound; normalize nodelta @if_elim
1509       [@eq_block_elim [2: #_ *] #H @⊥ @Hbl assumption] #_ @If_elim [2: #_ %]
1510       @andb_elim @if_elim [2: #_ *] #H >H in Hzleb'; *
1511     ]
1512   | whd in ⊢ (??%?); @if_elim @eqZb_elim [2,3: #_ * |4: *] #Hz *
1513       [ >Hzlb @If_elim [2: * #H @⊥ @H %] * @If_elim @andb_elim @if_elim
1514          [2: #_ *] #Hzleb' #Hzlb'' >Hbl >Hzlb @If_elim [2,4,6: * #H @⊥ @H %] #_
1515          whd in match low_bound; normalize nodelta @eq_block_elim
1516          [2,4,6: * #H @⊥ @H %] #_ normalize nodelta whd in match high_bound;
1517          normalize nodelta @eq_block_elim [2,4,6: * #H @⊥ @H %]
1518          #_ normalize nodelta
1519          [1,2: >Hzleb' >Hzlb'' @If_elim [2,3: * #H @⊥ @H %]
1520                #_ [2: %] whd in ⊢ (???(???%)); @if_elim [2: #_ %]
1521                @eqZb_elim [2: #_ *] #H @⊥ @Hz assumption
1522          | @If_elim [2: #_ %] @andb_elim @if_elim [2: #_ *] #H >H in Hzleb'; *
1523          ]
1524       | >Hbl >Hzlb @If_elim [2: * #H @⊥ @H %] * whd in match low_bound;
1525         normalize nodelta @eq_block_elim [2: * #H @⊥ @H %] #_ normalize nodelta
1526         whd in match high_bound; normalize nodelta @eq_block_elim [2: * #H @⊥ @H %]
1527         normalize nodelta >Hz >Hzleb >Hzlb' @If_elim [2: * #H @⊥ @H %] #_ #_
1528         whd in ⊢ (???(???%)); @eqZb_elim [2: * #H @⊥ @H %] #_ %
1529       ]
1530    ]
1531 ]
1532| %
1533]
1534qed.
1535
1536lemma match_reg_elim : ∀ A : Type[0]. ∀ P : A → Prop. ∀ r : region.
1537∀f : (r = XData) → A. ∀g : (r = Code) → A. (∀ prf : r = XData.P (f prf)) →
1538(∀ prf : r = Code.P (g prf)) →
1539P ((match r return λx.(r = x → ?) with
1540    [XData ⇒ f | Code ⇒ g])(refl ? r)).
1541#A #P * #f #g #H1 #H2 normalize nodelta [ @H1 | @H2]
1542qed.
1543
1544
1545lemma sp_ok : ∀prog : ertl_program.
1546∀good : (∀fn.good_state_transformation prog fn).
1547∀restr.
1548   preserving1 … res_preserve1 …
1549      (λst.sigma_state prog good st restr)
1550      (λx.x)
1551      (sp ERTL_semantics)
1552      (sp ERTLptr_semantics).
1553#prog #good #restr #st whd in match sp; normalize nodelta
1554whd in match (load_sp ??); whd in match (load_sp ??); whd in match sigma_state;
1555normalize nodelta whd in match sigma_regs; normalize nodelta
1556cases(regs ? st) #psd_r #hw_r normalize nodelta
1557inversion(pointer_of_address ?) normalize nodelta [2: #e #_ @res_preserve_error1]
1558#pt #EQ lapply(jmeq_to_eq ??? EQ) -EQ whd in match hwreg_retrieve; normalize nodelta
1559whd in match sigma_hw_register_env; normalize nodelta
1560change with (sigma_beval ? (get_sigma_from_good_state … good) BVundef) in ⊢ (??(?(???(?????%)(?????%)))? → ?);
1561>lookup_map >lookup_map
1562cases(lookup beval 6 (bitvector_of_register RegisterSPL) (reg_env hw_r) BVundef)
1563[ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1564whd in match pointer_of_address; whd in match pointer_of_bevals; normalize nodelta
1565[1,2,3,4,5: #ABS destruct
1566| cases(lookup beval 6 (bitvector_of_register RegisterSPH) (reg_env hw_r) BVundef)
1567  [ | | #ptr1' #ptr2' #p' | #by' | #p' | #ptr' #p' | #pc1' #p1']
1568  whd in match sigma_beval; normalize nodelta
1569  [1,2,3,4,5: #ABS destruct
1570  | @if_elim [2: #_ #ABS destruct] #H whd in ⊢ (??%? → ?); #EQ destruct
1571    normalize nodelta @match_reg_elim #INUTILE
1572    [ @mfr_return_eq1 % | @res_preserve_error1 ]
1573  | cases (sigma_pc_opt ? ? ?) normalize nodelta [2: #x] #EQ destruct
1574  ]
1575| whd in match sigma_beval; normalize nodelta cases(sigma_pc_opt ? ? ?)
1576 normalize nodelta [2: #x] #EQ destruct
1577]
1578qed.
1579
1580lemma set_sp_ok :  ∀prog : ertl_program.
1581∀good : (∀fn.good_state_transformation prog fn).
1582∀restr.∀ptr,st.
1583set_sp ? ptr (sigma_state prog good st restr) =
1584sigma_state prog good (set_sp ? ptr st) restr.
1585#prog #good #restr #ptr #st whd in match set_sp; whd in match sigma_state;
1586normalize nodelta @eq_f2 [2: %] whd in match (save_sp ???);
1587whd in match (save_sp ???); whd in match sigma_regs; normalize nodelta
1588cases(regs ? st) #psd_env #hw_regs normalize nodelta @eq_f
1589whd in match hwreg_store_sp; normalize nodelta whd in match sigma_hw_register_env;
1590normalize nodelta whd in match hwreg_store; normalize nodelta @eq_f2 [2: %]
1591>insert_map @eq_f >insert_map %
1592qed.
1593
1594lemma eval_seq_no_pc_no_call_ok :
1595∀prog : ertl_program.
1596let trans_prog ≝ (ertl_to_ertlptr prog) in
1597∀good : (∀fn.good_state_transformation prog fn).
1598∀stack_size. ∀id. ∀fn : (joint_closed_internal_function ??) .∀seq.
1599   preserving1 ?? res_preserve1 ????
1600      (λst.sigma_state prog good st (added_registers … fn (f_regs … (good fn))))
1601      (λst.sigma_state prog good st (added_registers … fn (f_regs … (good fn))))
1602      (eval_seq_no_pc ERTL_semantics
1603             (globals (mk_prog_params ERTL_semantics prog stack_size))
1604             (ev_genv (mk_prog_params ERTL_semantics prog stack_size)) id fn seq)
1605      (eval_seq_no_pc ERTLptr_semantics
1606  (globals (mk_prog_params ERTLptr_semantics trans_prog stack_size))
1607  (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_size)) id (translate_internal … fn) (seq_embed … seq)).
1608#prog #good #stack_size #f #fn *
1609whd in match eval_seq_no_pc; normalize nodelta
1610[ #c #st @mfr_return1
1611| #c #st @mfr_return1
1612| #pm #st whd in match pair_reg_move; normalize nodelta
1613  @mfr_bind1
1614  [ 2: change with (ertl_eval_move ??) in ⊢ (???????%%); @ertl_eval_move_ok
1615  | | #regs  @mfr_return_eq1 %
1616  ]
1617| #r #st @mfr_bind1
1618  [2:  @pop_ok |
1619  | * #bv #st whd in match acca_store; normalize nodelta @mfr_bind1
1620    [2: @ps_reg_store_ok |
1621    | #regs  @mfr_return_eq1 %
1622    ]
1623  ]
1624| #r #st @mfr_bind1
1625  [2: whd in match acca_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1626  | #bv @push_ok
1627  ]
1628| #i
1629  #i_spec
1630  change with ((dpl_reg ERTL) → ?)
1631  #dpl
1632  change with ((dph_reg ERTL) → ?)
1633  #dph #st @mfr_bind1
1634  [ @(λst.sigma_state prog good st (added_registers … fn (f_regs … (good fn))))
1635  | whd in match dpl_store; normalize nodelta @mfr_bind1
1636    [2: @opt_safe_elim #bl #EQbl
1637       @opt_safe_elim #bl'
1638       >(find_symbol_transf …
1639          (λvars.transf_fundef … (λfn.(translate_internal … fn))) prog i) in ⊢ (%→?);
1640       >EQbl #EQ destruct whd in match sigma_state; normalize nodelta       
1641       change with (sigma_beval prog (get_sigma_from_good_state … good) (BVptr …))
1642                                               in ⊢ (???????(?????%?)?);
1643       @ps_reg_store_ok |
1644    | #regs  @mfr_return_eq1 %
1645    ]
1646  | #st1 @opt_safe_elim #bl #EQbl @opt_safe_elim #bl'   
1647    >(find_symbol_transf …
1648          (λvars.transf_fundef … (λfn.(translate_internal … fn))) prog i) in ⊢ (%→?);
1649    >EQbl #EQ destruct whd in match dph_store; normalize nodelta @mfr_bind1
1650    [2: whd in match sigma_state; normalize nodelta       
1651       change with (sigma_beval prog (get_sigma_from_good_state … good) (BVptr …))
1652                                               in ⊢ (???????(?????%?)?);
1653      @ps_reg_store_ok |
1654    | #regs  @mfr_return_eq1 %
1655    ]
1656  ]
1657| #op #a #b #arg1 #arg2 #st @mfr_bind1
1658  [2: whd in match acca_arg_retrieve; whd in match sigma_state; normalize nodelta
1659     @ps_arg_retrieve_ok |
1660  | #bv1 @mfr_bind1
1661   [2: whd in match accb_arg_retrieve; whd in match sigma_state; normalize nodelta
1662      @ps_arg_retrieve_ok |
1663   | #bv2 @mfr_bind1
1664     [2: @be_opaccs_ok |
1665     | * #bv3 #bv4 normalize nodelta @mfr_bind1
1666       [ @(λst.sigma_state prog good st (added_registers … fn (f_regs … (good fn))))
1667       | whd in match acca_store; normalize nodelta @mfr_bind1
1668         [2: @ps_reg_store_ok |
1669         | #regs  @mfr_return_eq1 %
1670         ]
1671       | #st1 whd in match accb_store; normalize nodelta @mfr_bind1
1672         [2: whd in match sigma_state; normalize nodelta
1673            @ps_reg_store_ok |
1674         | #regs  @mfr_return_eq1 %
1675         ]         
1676       ]
1677     ]
1678   ]
1679  ] 
1680| #op #r1 #r2 #st @mfr_bind1
1681  [ @(sigma_beval prog (get_sigma_from_good_state … good))
1682  | whd in match acca_retrieve; normalize nodelta @ps_reg_retrieve_ok
1683  | #bv1 @mfr_bind1
1684    [ @(sigma_beval prog (get_sigma_from_good_state … good))
1685    | @be_op1_ok
1686    | #bv2 whd in match acca_store; normalize nodelta @mfr_bind1
1687      [2: whd in match sigma_state; normalize nodelta @ps_reg_store_ok |
1688      | #regs  @mfr_return_eq1 %
1689      ]
1690    ]
1691  ]
1692| #op2 #r1 #r2 #arg #st @mfr_bind1
1693  [2: whd in match acca_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1694  | #bv @mfr_bind1
1695    [2: whd in match snd_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1696    | #bv1 @mfr_bind1
1697      [2: @be_op2_ok |
1698      | * #bv2 #b @mfr_bind1
1699        [ @(λst.sigma_state prog good st (added_registers … fn (f_regs … (good fn))))
1700        | whd in match acca_store; normalize nodelta @mfr_bind1
1701          [2: whd in match sigma_state; normalize nodelta @ps_reg_store_ok |
1702          | #regs  @mfr_return_eq1 %
1703          ]
1704        | #st1 @mfr_return_eq1 %
1705        ]
1706      ]
1707    ]
1708  ]
1709| #st  @mfr_return_eq1 %
1710| #st  @mfr_return_eq1 %
1711| #r1 #dpl #dph #st @mfr_bind1
1712  [2: whd in match dph_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1713  | #bv @mfr_bind1
1714    [2: whd in match dpl_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1715    | #bv1 @mfr_bind1
1716      [ @(λx.x)
1717      | @(pointer_of_address_ok ? ? 〈bv1,bv〉)
1718      | #ptr @mfr_bind1
1719        [2: @opt_to_res_preserve1 @beloadv_ok |
1720        | #bv2 whd in match acca_store; normalize nodelta @mfr_bind1
1721          [2: whd in match sigma_state; normalize nodelta @ps_reg_store_ok |
1722          | #regs  @mfr_return_eq1 %
1723          ]
1724        ] 
1725      ]
1726    ]
1727  ] 
1728| #dpl #dph #r #st @mfr_bind1
1729  [2: whd in match dph_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1730  | #bv @mfr_bind1
1731    [2: whd in match dpl_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1732    | #bv1 @mfr_bind1
1733      [ @(λx.x)
1734      |  @(pointer_of_address_ok ? ? 〈bv1,bv〉)
1735      | #ptr @mfr_bind1
1736        [2: whd in match acca_arg_retrieve; normalize nodelta @ps_arg_retrieve_ok |
1737        | #bv2 @mfr_bind1
1738          [2: @opt_to_res_preserve1 @bestorev_ok |
1739          | #m @mfr_return_eq1 %
1740          ]
1741        ]
1742      ]
1743    ]
1744  ]
1745| #ext #st whd in ⊢ (???????%%); whd in match (stack_sizes ????); cases (stack_size f)
1746  normalize nodelta
1747  [ @res_preserve_error1
1748  | #n cases ext normalize nodelta
1749    [1,2: @mfr_bind1
1750      [1,4: @(λx.x)
1751      |2,5: @sp_ok
1752      |3,6: #ptr @mfr_return_eq1 >set_sp_ok %
1753      ]
1754    | #r whd in match ps_reg_store_status; normalize nodelta @mfr_bind1
1755      [2: whd in match sigma_state; normalize nodelta
1756          change with (sigma_beval ? (get_sigma_from_good_state … good) (BVByte ?))
1757               in ⊢ (???????(??%?)?);
1758          @ps_reg_store_ok
1759      |
1760      | #regs @mfr_return_eq1 %
1761      ]
1762    ]
1763  ]     
1764]
1765qed.
1766
1767lemma partial_inj_sigma : ∀ prog : ertl_program.
1768∀good : (∀fn.good_state_transformation prog fn).
1769let sigma ≝ (get_sigma_from_good_state … good) in
1770∀fn,lbl1,lbl2. sigma fn lbl1 ≠ None ? → sigma fn lbl1 = sigma fn lbl2 → lbl1 = lbl2.
1771#prog #good #fn #lbl1 #lbl2 inversion(get_sigma_from_good_state … lbl1)
1772[#_ * #H @⊥ @H %] #lbl1' whd in match get_sigma_from_good_state; normalize nodelta
1773#H @('bind_inversion H) -H * #lbl1'' #stmt1 #H1 whd in ⊢ (??%? → ?); #EQ destruct
1774#_ #H lapply(sym_eq ??? H) -H #H @('bind_inversion H) -H * #lbl2' #stmt2 #H2
1775whd in ⊢ (??%? → ?); #EQ destruct lapply(find_predicate ?????? H1)
1776lapply(find_predicate ?????? H2) cases(f_lbls ????) normalize nodelta [*]
1777* normalize nodelta
1778[@eq_identifier_elim #EQ1 * @eq_identifier_elim #EQ2 * >EQ1 >EQ2 % ]
1779#lb #tl @eq_identifier_elim #EQ1 * @eq_identifier_elim #EQ2 * >EQ1 >EQ2 %
1780qed.
1781
1782lemma pc_of_label_eq :
1783  ∀p,p'.let pars ≝ make_sem_graph_params p p' in
1784  ∀globals,ge,bl,i_fn,lbl.
1785  fetch_internal_function ? ge bl = return i_fn →
1786  pc_of_label pars globals ge bl lbl =
1787    OK ? (pc_of_point ERTL_semantics bl lbl).
1788#p #p' #globals #ge #bl #i_fn #lbl #EQf
1789whd in match pc_of_label;
1790normalize nodelta >EQf >m_return_bind %
1791qed.
1792
1793lemma pop_ra_ok :
1794∀prog : ertl_program.
1795∀good : (∀fn.good_state_transformation prog fn).
1796∀restr.
1797preserving1 … res_preserve1 …
1798     (λst.sigma_state prog good st restr)
1799     (λx.let 〈st,pc〉 ≝ x in
1800         let sigma ≝ (get_sigma_from_good_state … good) in
1801       〈sigma_state prog good st restr,
1802        sigma_stored_pc ? sigma pc〉)
1803     (pop_ra ERTL_semantics)
1804     (pop_ra ERTLptr_semantics).
1805#prog #good #restr #st whd in match pop_ra; normalize nodelta @mfr_bind1
1806[ | @pop_ok ] * #bv #st1 @mfr_bind1 [ | @pop_ok] * #bv1 #st2 @mfr_bind1
1807[ @(sigma_stored_pc ? (get_sigma_from_good_state … good))
1808| whd in match pc_of_bevals; normalize nodelta
1809  cases bv [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc #p]
1810  whd in match sigma_beval; normalize nodelta try @res_preserve_error1
1811  inversion(sigma_pc_opt ? ? ?) normalize nodelta [ #_ @res_preserve_error1]
1812  #sigma_pc #sigma_pc_spec normalize nodelta cases bv1
1813  [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc1 #p1]
1814  normalize nodelta try @res_preserve_error1
1815  inversion(sigma_pc_opt ? ? ?) normalize nodelta [#_ @res_preserve_error1]
1816  #sigma_pc1 #sigma_pc1_spec @if_elim [2: #_ @res_preserve_error1]
1817  @andb_elim @if_elim [2: #_ *] @andb_elim @if_elim [2: #_ *]
1818  #_ #H >H @eq_program_counter_elim [2: #_ *]
1819  #EQspc * @eq_program_counter_elim
1820  [#_ normalize nodelta @mfr_return_eq1 whd in match sigma_stored_pc; normalize nodelta
1821   >sigma_pc1_spec %] * #H1 @⊥ @H1 >EQspc in sigma_pc_spec; <sigma_pc1_spec
1822   whd in match sigma_pc_opt; normalize nodelta @if_elim
1823  [ #H2 #EQ lapply(sym_eq ??? EQ) -EQ @if_elim [#_  whd in ⊢ (??%% → ?); #EQ destruct %]
1824    #H3 #H @('bind_inversion H) -H #x #_ #H @('bind_inversion H) -H #y #_
1825    cases sigma_pc1 in H2; #bl_pc1 #z #H2 whd in ⊢ (??%? → ?); #EQ destruct >H2 in H3; *
1826  | #H2 @if_elim
1827    [ #H3 #H @('bind_inversion H) -H #x1 #_ #H @('bind_inversion H) -H #lbl1 #_
1828      cases pc in H2; #bl #z #H2 whd in match pc_of_point; normalize nodelta whd in ⊢ (??%? → ?);
1829      #EQ destruct >H3 in H2; *
1830    | #H3 lapply sigma_pc1_spec; whd in match sigma_pc_opt; normalize nodelta @if_elim
1831     [#H >H in H3; *] #_ #EQ >EQ @('bind_inversion EQ) -EQ #x #x_spec
1832     lapply(res_eq_from_opt ??? x_spec) -x_spec #x_spec #H @('bind_inversion H) * #lbl
1833     #lbl_spec whd in match pc_of_point; normalize nodelta cases sigma_pc1 #bl1 #lbl1
1834     whd in match (offset_of_point ??); whd in ⊢ (??%? → ?); #EQ destruct cases pc #bl2 #p2
1835     #H @('bind_inversion H) -H #x1 #x1_spec lapply(res_eq_from_opt ??? x1_spec) -x1_spec #x1_spec
1836     #H @('bind_inversion H) -H * #lbl2 #lbl2_spec
1837     whd in match (offset_of_point ??); whd in ⊢ (??%? → ?); #EQ destruct
1838     <lbl_spec in lbl2_spec; #EQsig >x_spec in x1_spec; whd in ⊢ (??%% → ?); #EQ destruct
1839     lapply(partial_inj_sigma … EQsig)
1840     [>EQsig >lbl_spec % #ABS destruct] whd in match point_of_pc; normalize nodelta
1841     whd in match (point_of_offset ??); whd in match (point_of_offset ??);
1842     #EQ destruct cases pc1 #bl #p %
1843    ]
1844  ]
1845| #pc @mfr_return_eq1 %
1846]
1847qed.
1848
1849lemma pc_block_eq : ∀prog : ertl_program.
1850∀sigma : sigma_map prog.
1851∀pc,id,fn.
1852fetch_internal_function (joint_closed_internal_function ERTL
1853  (prog_var_names (joint_function ERTL) ℕ prog))
1854  (globalenv_noinit (joint_function ERTL) prog) (pc_block … pc)
1855  = return 〈id,fn〉→
1856sigma fn (point_of_pc ERTL_semantics pc) ≠ None ? →
1857 pc_block … pc = pc_block … (sigma_stored_pc prog sigma pc).
1858#prog #sigma * #bl #pos #id #fn #EQfn #EQlbl whd in match sigma_stored_pc;
1859normalize nodelta whd in match sigma_pc_opt; normalize nodelta @if_elim [ #_ %]
1860#_ >EQfn >m_return_bind >(opt_to_opt_safe … EQlbl) >m_return_bind %
1861qed.
1862
1863inductive ex_Type1 (A:Type[1]) (P:A → Prop) : Prop ≝
1864    ex1_intro: ∀ x:A. P x →  ex_Type1 A P.
1865(*interpretation "exists in Type[1]" 'exists x = (ex_Type1 ? x).*)
1866
1867include "joint/semantics_blocks.ma".
1868
1869lemma fetch_internal_function_no_zero :
1870∀F,V,i,p,bl.
1871  block_id (pi1 … bl) = 0 →
1872  fetch_internal_function ?
1873 
1874  (globalenv (λvars.fundef (F vars)) V i p) bl =
1875  Error ? [MSG BadFunction].
1876#F #V #i #p #bl #EQbl whd in match fetch_internal_function;
1877normalize nodelta >fetch_function_no_zero [2: assumption] %
1878qed.
1879
1880lemma fetch_statement_no_zero :
1881∀pars,prog,stack_size,pc.
1882block_id(pi1 … (pc_block pc)) = 0 →
1883fetch_statement pars (prog_var_names … prog)
1884(ev_genv (mk_prog_params pars prog stack_size)) pc =
1885Error ? [MSG BadFunction].
1886#pars #vars #ge #pc #EQpc whd in match fetch_statement; normalize nodelta
1887>fetch_internal_function_no_zero [2: assumption] %
1888qed.
1889
1890lemma foo :
1891 ∀P1_unser,P2_unser: unserialized_params.
1892 ∀P1_sem_unser,P2_sem_unser.
1893 let P1_sem ≝ make_sem_graph_params P1_unser P1_sem_unser in
1894 let P2_sem ≝ make_sem_graph_params P2_unser P2_sem_unser in
1895 ∀init,translate_step.
1896 ∀translate_fin_step.
1897 ∀closed_graph_translate.
1898 let translate_internal :
1899  ∀globals.
1900   joint_closed_internal_function P1_sem globals →
1901   joint_closed_internal_function P2_sem globals
1902  ≝
1903  λglobals,fun.
1904   «b_graph_translate (mk_graph_params P1_sem) (mk_graph_params P2_sem) globals
1905    (init globals)
1906    (translate_step globals)
1907    (translate_fin_step globals)
1908    (pi1 … fun), closed_graph_translate globals fun» in
1909 ∀prog.
1910 let trans_prog ≝ transform_program ??? prog (λvarnames. transf_fundef ?? (translate_internal varnames)) in
1911 ∀stack_size.
1912 ∀sigma_state_pc.
1913 (∀s. pc_block (pc … (sigma_state_pc s)) = pc_block … (pc … s)) →
1914 ∀st : state_pc P2_sem.
1915 ∀st' : state_pc P1_sem.
1916 ∀f.
1917 ∀fn: joint_closed_internal_function P1_sem (globals (mk_prog_params P1_sem prog stack_size)).
1918 luniverse_ok … fn →
1919 ∀stmt,nxt.
1920 (∀pre_Instrs',last_Instrs',dst.
1921   ∃st''.∃st'''.∃st''''.
1922    repeat_eval_seq_no_pc (mk_prog_params P2_sem trans_prog stack_size)
1923     f (translate_internal ? fn) (map_eval ?? pre_Instrs' dst) st = return st''' ∧
1924    eval_seq_no_pc ? (prog_var_names … trans_prog) (ev_genv … (mk_prog_params P2_sem trans_prog stack_size))
1925                      f (translate_internal … fn) (last_Instrs' dst) st''' = return st'''' ∧
1926    st'' = (mk_state_pc (mk_prog_params P2_sem trans_prog stack_size)
1927     st'''' (pc_of_point P2_sem (pc_block (pc … (sigma_state_pc st))) dst) (last_pop … st)) ∧
1928    st' = sigma_state_pc st'' ∧
1929    let P2_prog_params ≝ mk_prog_params P2_sem trans_prog stack_size in
1930    let P2_globals ≝ globals P2_prog_params in
1931     All
1932      (joint_seq … P2_globals)
1933      (no_cost_label … P2_globals)
1934      (map_eval (code_point P2_sem) (joint_seq … P2_globals) pre_Instrs' dst)) →
1935 fetch_statement …
1936  (prog_var_names (joint_function P1_sem) ℕ prog)
1937  (ev_genv (mk_prog_params P1_sem prog stack_size))
1938  (pc … (sigma_state_pc st)) =
1939    return 〈f, fn,  sequential … (step_seq P1_sem … stmt) nxt〉 →
1940 eval_state …
1941 (prog_var_names (joint_function P1_sem) ℕ prog)
1942 (ev_genv … (mk_prog_params P1_sem prog stack_size))
1943 (sigma_state_pc st) = return st' →
1944 ∃st''. (*CSC: this needs to be linked back again st' = sigma_state_pc ? good st'' ∧*)
1945 ∃taf : trace_any_any_free (joint_abstract_status (mk_prog_params P2_sem trans_prog stack_size)) st st''.
1946 True (* the length of taf is the same of the length of ??? *).
1947#P1_unser #P2_unser #P1_sem_unser #P2_sem_unser
1948letin P1_sem ≝ (make_sem_graph_params P1_unser P1_sem_unser)
1949letin P2_sem ≝ (make_sem_graph_params P2_unser P2_sem_unser)
1950#init #translate_step #translate_fin_step #closed_graph_translate.
1951letin translate_internal ≝
1952 (λglobals,fun.
1953   «b_graph_translate (mk_graph_params P1_sem) (mk_graph_params P2_sem) globals
1954    (init globals)
1955    (translate_step globals)
1956    (translate_fin_step globals)
1957    (pi1 … fun), closed_graph_translate globals fun»)
1958#prog
1959letin trans_prog ≝ (transform_program ??? prog (λvarnames. transf_fundef ?? (translate_internal varnames)))
1960#stack_size #sigma_state_pc #sigma_state_pc_ok #st #st' #f #fn #fn_universe_ok #stmt #nxt #Hpass
1961#EQfetch lapply(fetch_statement_inv … EQfetch) * #EQfn #EQstmt
1962cases
1963 (b_graph_translate_ok … (init …) (translate_step …) (translate_fin_step …) … fn_universe_ok)
1964#_ * #MK_fresh_labels * #MK_fresh_registers **** #_ #_ #_ #_ (*CSC: useful things thrown out here *)
1965#MULTI_FETCH_OK cases (MULTI_FETCH_OK … EQstmt)
1966#list_b_last * #fresh_registers ** #EQlist_b_last #EQfresh_registers
1967normalize nodelta * #Instrs * #fresh_registers_spec whd in ⊢ (% → ?);
1968@pair_elim #pre_Instrs #last_Instrs #EQInstrs * #dst * #Multi_fetch #STEP_in_code
1969#EQeval
1970cut((list
1971   (code_point P2_sem
1972    →joint_seq P2_sem (prog_var_names (joint_function P1_sem) ℕ prog)))) [ cases daemon (*Paolo should fix the lemma*)]
1973#pre_Instrs'
1974cut((code_point P2_sem
1975   →joint_seq P2_sem (prog_var_names (joint_function P1_sem) ℕ prog))) [ cases daemon (*Paolo should fix the lemma*)]
1976#last_Instrs'
1977cases (Hpass pre_Instrs' last_Instrs' dst (* MANY MORE HERE *))
1978#st'' * #st''' * #st'''' **** #REPEAT #EVAL_NO_PC_Last #EQst'' #EQst' #NO_COSTED
1979lapply(produce_trace_any_any_free … NO_COSTED … REPEAT)
1980[ cases daemon (* should be @Multi_fetch *)
1981| <sigma_state_pc_ok @(fetch_internal_function_transf … (λvars.translate_internal vars))
1982  assumption
1983| @dst
1984| @list_b_last (*wrong, should dst be destination or the last of list_b_last *)
1985] #TAAF
1986lapply
1987  (produce_step_trace (mk_prog_params P2_sem trans_prog stack_size)
1988    (mk_state_pc (mk_prog_params P2_sem trans_prog stack_size)
1989       st''' (pc_of_point P2_sem (pc_block (pc … st)) dst) (last_pop … st))
1990    f (translate_internal ? fn) (last_Instrs' dst) nxt st'''' … EVAL_NO_PC_Last)
1991[ cases daemon (* should be @STEP_In_code *)
1992| <sigma_state_pc_ok
1993  @(fetch_internal_function_transf … (λvars. translate_internal vars) … EQfn) ]
1994#LAST_STEP
1995
1996
1997lemma eval_seq_no_call_ok :
1998 ∀prog.
1999 let trans_prog ≝ ertl_to_ertlptr prog in
2000 ∀good : (∀fn.good_state_transformation prog fn).     
2001 ∀stack_sizes.
2002 (*? →*)
2003 ∀st : state_pc ERTLptr_semantics.
2004 ∀st' : state_pc ERTL_semantics.
2005 ∀f,fn,stmt,nxt.
2006   fetch_statement ERTL_semantics
2007     (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2008    (ev_genv (mk_prog_params ERTL_semantics prog stack_sizes))
2009    (pc … (sigma_state_pc ? good st)) =
2010      return 〈f, fn,  sequential … (step_seq ERTL … stmt) nxt〉 →
2011   eval_state ERTL_semantics
2012   (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2013   (ev_genv … (mk_prog_params ERTL_semantics prog stack_sizes))
2014   (sigma_state_pc ? good st) =
2015    return st' →
2016 ∃st''. st' = sigma_state_pc ? good st'' ∧
2017 ∃taf : trace_any_any_free (ERTLptr_status trans_prog stack_sizes)
2018  st
2019  st''.
2020 bool_to_Prop (taaf_non_empty … taf).
2021#prog #good #stack_size #st #st' #f #fn #stmt #nxt
2022whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta @if_elim
2023[ #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2024#EQbl inversion(fetch_internal_function ?? (pc_block (pc ? st))) normalize nodelta
2025[2: #err #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2026* #id1 #fn1 #EQfn normalize nodelta #EQfetch lapply(fetch_statement_inv … EQfetch)
2027* >EQfn #EQ destruct normalize nodelta #EQstmt
2028cases(multi_fetch_ok … (good fn) ?? EQstmt)
2029#list_b_last * #fresh_registers ** #EQlist_b_last #EQfresh_registers
2030normalize nodelta * #Instrs * #fresh_registers_spec whd in ⊢ (% → ?);
2031@pair_elim #pre_Instrs #last_Instrs #EQInstrs * #dst * #Multi_fetch #STEP_in_code
2032#EQeval
2033cut((list
2034   (code_point ERTLptr
2035    →joint_seq ERTLptr (prog_var_names (joint_function ERTL) ℕ prog)))) [ cases daemon (*Paolo should fix the lemma*)]
2036#pre_Instrs'
2037cut((code_point ERTLptr
2038   →joint_seq ERTLptr (prog_var_names (joint_function ERTL) ℕ prog))) [ cases daemon (*Paolo should fix the lemma*)]
2039#last_Instrs'
2040letin list_map ≝ cic:/matita/basics/lists/list/map.fix(0,3,1)
2041cut(∃st''.∃st'''.∃st''''.
2042    repeat_eval_seq_no_pc (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2043     f (translate_internal ? fn) (map_eval ?? pre_Instrs' dst) st = return st''' ∧
2044    eval_seq_no_pc ? (prog_var_names … (ertl_to_ertlptr prog)) (ev_genv … (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size))
2045                      f (translate_internal … fn) (last_Instrs' dst) st''' = return st'''' ∧
2046    st'' = (mk_state_pc (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2047     st'''' (pc_of_point ERTLptr_semantics (pc_block (pc … st)) dst)
2048                                 (last_pop … st)) ∧
2049    st' = sigma_state_pc ? good st'')
2050     [ cases daemon (*to be generalized and TO be moved into an other lemma *)]
2051* #st'' * #st''' * #st'''' *** #REPEAT #EVAL_NO_PC_Last #EQst'' #EQst' %{st''} % [assumption]
2052lapply(produce_trace_any_any_free … REPEAT)
2053[ cases daemon (* Pass dependent *)
2054| cases daemon (* should be @Multi_fetch *)
2055| @(fetch_internal_function_transf … (λvars. translate_internal …) … EQfn)
2056| @dst
2057| @list_b_last (*wrong, should dst be destination or the last of list_b_last *)
2058] #TAAF
2059lapply(produce_step_trace (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2060       (mk_state_pc (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2061     st''' (pc_of_point ERTLptr_semantics (pc_block (pc … st)) dst)
2062                                 (last_pop … st)) f (translate_internal ? fn) (last_Instrs' dst) nxt st'''' (fetch_internal_function_transf … (λvars. translate_internal …) … EQfn)
2063       ? EVAL_NO_PC_Last) [cases daemon (* should be @STEP_in_code *)]
2064#LAST_STEP
2065letin taaf_last ≝ (taaf_step ???? TAAF LAST_STEP)
2066
2067        cut(dst = (point_of_pc
2068                           (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2069                           (pc … st))) [cases daemon (*TODO it is true since pre_Instr is empty *)]
2070                #EQ <EQ whd in match step_in_code; normalize nodelta
2071                cases STEP_in_code #x * #x_spec #x_spec' %{x} %
2072                [ >x_spec in ⊢ (??%?); @eq_f @eq_f2 [2: %] cases daemon (*should be % *) |
2073                 [<EVAL_NO_PC_Last in ⊢ (???%); @eq_f %
2074
2075
2076
2077whd in match eval_state; normalize nodelta >EQfetch >m_return_bind
2078lapply EQfetch -EQfetch whd in match sigma_state_pc in ⊢ (% → ?);
2079normalize nodelta @if_elim
2080[ #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2081#EQbl inversion(fetch_internal_function ?? (pc_block (pc ? st))) normalize nodelta
2082[2: #err #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2083* #id1 #fn1 #EQfn normalize nodelta #EQfetch lapply(fetch_statement_inv … EQfetch)
2084* >EQfn #EQ destruct normalize nodelta #EQstmt
2085whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta @if_elim
2086[#H >H in EQbl; *] #_ >EQfn normalize nodelta whd in match eval_statement_no_pc;
2087normalize nodelta #H @('bind_inversion H) -H #ex_st_nopc
2088#H lapply (err_eq_from_io ????? H) -H #EQnopc whd in match eval_statement_advance;
2089normalize nodelta whd in match set_no_pc; normalize nodelta
2090whd in ⊢ (??%% → ?); #EQ destruct cases(eval_seq_no_pc_no_call_ok … EQnopc)
2091#sigma_st_nopc * #EQsigma_st_nopc #sem_rel %
2092[ % [@sigma_st_nopc
2093    | @(succ_pc ERTL_semantics (pc ERTLptr_semantics st) nxt)
2094    | @(last_pop … st)
2095    ]
2096] % whd in match sigma_state_pc;
2097
2098
2099
2100qed.
2101
2102lemma ertl_to_ertlptr_ok:
2103∀prog.
2104let trans_prog ≝ ertl_to_ertlptr prog in
2105∀good : (∀fn.good_state_transformation prog fn).     
2106∀stack_sizes.
2107   ex_Type1 … (λR.
2108   status_simulation
2109    (ERTL_status prog stack_sizes) (ERTLptr_status trans_prog stack_sizes) R).
2110#prog #good #stack_size % [@ERTLptrStatusSimulation assumption]
2111whd in match status_simulation; normalize nodelta
2112whd in match ERTL_status; whd in match ERTLptr_status; normalize nodelta
2113whd in ⊢ (% → % → % → % → ?); #st1 #st1' #st2
2114change with
2115  (eval_state ERTL_semantics (prog_var_names ???) ?? = ? → ?) 
2116#EQeval @('bind_inversion EQeval)
2117** #id #fn #stmt #H lapply (err_eq_from_io ????? H) -H #EQfetch
2118#_  whd in match ERTLptrStatusSimulation; normalize nodelta #EQst2 destruct
2119cases stmt in EQfetch; -stmt
2120[ * [ #called_id #args #dest| #reg #lbl | #seq] #nxt | #fin_step | *] #EQfetch
2121change with (joint_classify ??) in ⊢ (match % with [ _ ⇒ ? | _ ⇒ ? ]);
2122[ (*CALL*) cases daemon
2123| (*COND*) cases daemon
2124| (*seq*) whd in match joint_classify; normalize nodelta >EQfetch >m_return_bind
2125          normalize nodelta cases (eval_seq_no_call_ok ?????????  EQfetch EQeval)
2126  #st3 * #EQ destruct *  #taf #tafne %{st3} %{taf} >tafne normalize nodelta
2127  % [% //] whd >as_label_ok [2:assumption] %
2128
2129
2130lapply(produce_trace_any_any_free
2131      (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2132      st2 id (translate_internal ? fn)) #PRODUCE_TAAF
2133cases stmt in EQfetch; -stmt
2134[ * [ #called_id #args #dest| #reg #lbl | #seq] #nxt | #fin_step | *] #EQfetch
2135normalize nodelta
2136
2137     
2138lapply EQfetch -EQfetch whd in match sigma_state_pc in ⊢ (% → ?);
2139normalize nodelta @if_elim
2140[ #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2141#EQbl inversion(fetch_internal_function ?? (pc_block (pc ? st2))) normalize nodelta
2142[2: #err #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2143* #id1 #fn1 #EQfn normalize nodelta #EQfetch lapply(fetch_statement_inv … EQfetch)
2144* >EQfn #EQ destruct normalize nodelta #EQstmt     
2145     
2146      ? ? ?? ? ???)
2147
2148
2149
2150cases stmt in EQfetch; -stmt
2151[ * [ #called_id #args #dest| #reg #lbl | #seq] #nxt | #fin_step | *] #EQstmt
2152change with (joint_classify ??) in ⊢ (match % with [ _ ⇒ ? | _ ⇒ ? ]);
2153whd in match joint_classify; normalize nodelta >EQstmt >m_return_bind
2154normalize nodelta lapply(fetch_statement_inv … EQstmt) * #fn_spec
2155#stmt_spec
2156cases(multi_fetch_ok … (good fn) ?? stmt_spec) #f_labs * #f_regs ** #f_labs_spec
2157#f_regs_spec normalize nodelta * #list_instr * #b_new_f_regs
2158whd in ⊢ (% → ?); normalize nodelta
2159[1,2,3: @pair_elim #list_instr1 #rgt #last_ne_spec * #last_lab *
2160       #list_instr1_spec #last_step
2161       lapply(fetch_internal_function_transf …
2162                                       (λvars. translate_internal …) … fn_spec)
2163       change with ((fetch_internal_function
2164                    (joint_closed_internal_function ? (prog_var_names … (ertl_to_ertlptr prog)))
2165                    (globalenv_noinit … (ertl_to_ertlptr prog)) ?) = ?  → ?)
2166       #EQtrans_fn
2167       check prog_params
2168       lapply(produce_trace_any_any_free
2169       (mk_prog_params ERTLptr_semantics (ertl_to_ertlptr prog) stack_size)
2170        ? id (translate_internal ? fn) ? ? ?? EQtrans_fn ???) [2: @EQtrans_fn
2171
2172
2173
2174
2175
2176lapply EQstmt whd in match sigma_state_pc in ⊢ (% → ?);
2177normalize nodelta @if_elim
2178[1,3: #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2179#EQbl inversion(fetch_internal_function ?? (pc_block (pc ? st2))) normalize nodelta
2180[2,4: #err #_ >fetch_statement_no_zero [2,4: %] whd in ⊢ (???% → ?); #ABS destruct]
2181* #id1 #fn1 #EQfn1 normalize nodelta #EQstmt1 lapply(fetch_statement_inv … EQstmt1)
2182* >EQfn1 #EQ destruct normalize nodelta #EQstmtat
2183
2184
2185
2186
2187[ (*CALL*)
2188  cases daemon (*TODO*)
2189| whd in match joint_classify; normalize nodelta
2190 >EQfetch in ⊢ (match % with [ _ ⇒ ? | _ ⇒ ? ]);
2191  normalize nodelta
2192 #n_cost
2193 cases (eval_cond_ok … EQfetch EQeval n_cost)
2194 #st3 * #EQ destruct * #taf #tafne %{st3} %{taf}
2195 % [ % [2: %] >tafne normalize nodelta @I] whd >as_label_ok %
2196| whd in match joint_classify; normalize nodelta
2197 >EQfetch in ⊢ (match % with [ _ ⇒ ? | _ ⇒ ? ]);
2198  normalize nodelta
2199  cases (eval_seq_no_call_ok ?????????  EQfetch EQeval)
2200  #st3 * #EQ destruct *  #taf #tafne %{st3} %{taf} >tafne normalize nodelta
2201  % [% //] whd >as_label_ok [2:assumption] %
2202| (*FIN*)
2203  cases fin_step in EQfetch;
2204  [ (*GOTO*) #lbl #EQfetch  whd in match joint_classify; normalize nodelta
2205  >EQfetch in ⊢ (match % with [ _ ⇒ ? | _ ⇒ ? ]); normalize nodelta
2206    cases (eval_goto_ok … EQfetch EQeval)
2207    #st3 * #EQ destruct * #taf #tarne %{st3} %{taf} >tarne normalize nodelta
2208    % [% //] whd >as_label_ok [2:assumption] %
2209  | (*RETURN*) #EQfetch
2210     whd in match joint_classify; normalize nodelta
2211    >EQfetch in ⊢ (match % with [ _ ⇒ ? | _ ⇒ ? ]); normalize nodelta
2212    cases (eval_return_ok … EQfetch EQeval) #is_ret
2213    * #st3 * #EQ destruct * #after_ret * #taf ** #taf_prf #EQeval' #ret_prf
2214    % [2: % [2: % [2: %{(taa_base …)} %{taf}] |*: ] |*:]
2215    % [2: whd >as_label_ok %] % [2: assumption] % [2: %] % [2: assumption]
2216    % assumption
2217  | (*TAILCALL*) #fl #called #args #EQfetch
2218    cases (eval_tailcall_ok … EQfetch EQeval) #st3 * #EQ destruct * #is_tailcall
2219    * #is_tailcall' *  #eq_call #EQeval' >is_tailcall normalize nodelta
2220    #prf  %{«?, is_tailcall'»} %{eq_call}
2221    % [2: % [2: %{(taa_base …)} %{(taa_base …)}  % [ %{EQeval'} % |] | ] | ]
2222    whd >as_label_ok %
2223  ]
2224]
2225qed.
2226
2227@('bind_inversion EQfetch) * #id1 #fn1 #EQfn #H @('bind_inversion H) -H
2228#stmt1 #H lapply(opt_eq_from_res ???? H) -H #EQstmt whd in ⊢ (??%% → ?);
2229#EQ destruct
2230
2231(*
2232lemma push_ra_ok : ∀prog : ertl_program.
2233∀good :  (∀fn.good_state_transformation prog fn).∀restr.
2234preserving21 … res_preserve1 …
2235     (sigma_state_pc prog good)
2236     (\l
2237     (λst.sigma_state prog good st restr)
2238     (push_ra ERTL_semantics)
2239     (push_ra ERTLptr_semantics).
2240#prog #good #restr #st #pc whd in match push_ra; normalize nodelta @mfr_bind1
2241[2: whd in match sigma_stored_pc; normalize nodelta
2242
2243[2: #x
2244
2245
2246lemma ertlptr_save_frame_ok : ∀prog : ertl_program.
2247∀good : (∀fn.good_state_transformation prog fn).
2248∀id.
2249    preserving1 … res_preserve1 …
2250        (sigma_state_pc prog good)
2251        (λst. match get_internal_function_from_ident
2252                  ERTL_semantics (prog_var_names … prog)
2253                  (globalenv_noinit … prog) id with
2254             [None ⇒ dummy_state
2255             |Some fd ⇒
2256                sigma_state prog good st (added_registers … fd (f_regs … (good fd)))
2257             ])
2258        (ertl_save_frame ID it id)
2259        (ertlptr_save_frame ID it id).
2260#prog #good #id #st whd in match ertl_save_frame; whd in match ertlptr_save_frame;
2261normalize nodelta @mfr_bind1
2262[2: whd in match push_ra; normalize nodelta @mfr_bind1
2263xxxxxxxxxxxx
2264
2265
2266
2267lemma fetch_statement_commute :
2268∀prog : ertl_program.
2269let trans_prog ≝ (ertl_to_ertlptr prog) in
2270∀sigma : sigma_map trans_prog.
2271∀stack_sizes,id,fn,stmt,pc.
2272fetch_statement ERTL_semantics
2273(globals (mk_prog_params ERTL_semantics prog stack_sizes))
2274(ev_genv (mk_prog_params ERTL_semantics prog stack_sizes))
2275pc = return 〈id,fn,stmt〉 →
2276match stmt with
2277[ sequential seq nxt ⇒
2278    match seq with
2279    [ CALL ids args dest ⇒
2280        match ids with
2281        [ inl i ⇒
2282          fetch_statement ERTLptr_semantics
2283          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2284          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2285          pc =
2286          return 〈id,
2287          translate_internal … fn,
2288          sequential ?? (CALL ERTLptr ? (inl ?? i) args dest) nxt〉
2289        | inr p ⇒ ?(*
2290          ∃reg,lbl.
2291          fetch_statement ERTLptr_semantics
2292          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2293          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2294           pc = return 〈id,translate_internal … fn,sequential ?? (extension_seq ERTLptr ? (LOW_ADDRESS reg lbl)) nxt〉
2295           ∧ ∃ nxt'.
2296           ! pc' ← get_pc_from_label ? ? (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2297                 id nxt;
2298           fetch_statement ERTLptr_semantics
2299          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2300          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2301           pc' = return 〈id,translate_internal … fn,sequential ?? (step_seq ERTLptr ? (PUSH … (Reg … reg))) nxt'〉
2302           ∧ ∃ nxt''.
2303           ! pc' ← get_pc_from_label ? ? (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2304                 id nxt';
2305           fetch_statement ERTLptr_semantics
2306          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2307          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2308           pc' = return 〈id,translate_internal … fn,sequential ?? (extension_seq ERTLptr ? (HIGH_ADDRESS reg lbl)) nxt''〉
2309           ∧ ∃ nxt'''.
2310           ! pc' ← get_pc_from_label ? ? (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2311                 id nxt'';
2312           fetch_statement ERTLptr_semantics
2313          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2314          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2315           pc' = return 〈id,translate_internal … fn,sequential ?? (step_seq ERTLptr ? (PUSH … (Reg … reg))) nxt'''〉
2316           ∧ ∃ nxt''''.
2317           ! pc' ← get_pc_from_label ? ? (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2318                 id nxt''';
2319           fetch_statement ERTLptr_semantics
2320          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2321          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2322           pc' = return 〈id,translate_internal … fn,sequential ?? (CALL ERTLptr ? (inr ?? p) args dest) nxt''''〉
2323           ∧ sigma (translate_internal … fn) nxt''' =  return point_of_pc ERTL_semantics pc *)
2324        ]
2325    | COND r lbl ⇒
2326          fetch_statement ERTLptr_semantics
2327          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2328          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2329          pc =
2330          return 〈id,
2331          translate_internal … fn,
2332          sequential ?? (COND ERTLptr ? r lbl) nxt〉
2333    | step_seq s ⇒
2334          fetch_statement ERTLptr_semantics
2335          (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2336          (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2337          pc =
2338          return 〈id,
2339          translate_internal … fn,
2340          sequential ?? (step_seq ERTLptr … (translate_step_seq ? s)) nxt〉
2341    ]                   
2342| final fin ⇒
2343     fetch_statement ERTLptr_semantics
2344     (globals (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2345     (ev_genv (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2346     pc = return 〈id,(translate_internal … fn),final … (joint_fin_step_id fin)〉
2347| FCOND abs _ _ _ ⇒ Ⓧabs
2348].
2349cases daemon
2350qed.
2351
2352lemma eval_seq_no_call_ok :
2353 ∀prog.
2354 let trans_prog ≝ ertl_to_ertlptr prog in
2355 ∀sigma : sigma_map trans_prog.∀stack_sizes.
2356 (*? →*)
2357 ∀st,st',f,fn,stmt,nxt.
2358   fetch_statement ERTL_semantics
2359     (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2360    (ev_genv (mk_prog_params ERTL_semantics prog stack_sizes))
2361    (pc … (sigma_state_pc ? sigma st)) =
2362      return 〈f, fn,  sequential … (step_seq ERTL … stmt) nxt〉 →
2363   eval_state ERTL_semantics
2364   (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2365   (ev_genv … (mk_prog_params ERTL_semantics prog stack_sizes))
2366   (sigma_state_pc ? sigma st) =
2367    return st' →
2368 ∃st''. st' = sigma_state_pc ? sigma st'' ∧
2369 ∃taf : trace_any_any_free (ERTLptr_status trans_prog stack_sizes)
2370  st
2371  st''.
2372 bool_to_Prop (taaf_non_empty … taf).
2373#prog #sigma #stack_size #st1 #st2 #f #fn #stmt #nxt #EQf whd in match eval_state;
2374normalize nodelta >EQf >m_return_bind whd in match eval_statement_advance;
2375whd in match eval_statement_no_pc; normalize nodelta
2376 #H @('bind_inversion H) -H #st_no_pc #EQ lapply(err_eq_from_io ????? EQ) -EQ
2377#EQeval whd in ⊢ (??%% → ?); #EQ destruct lapply EQf
2378whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta @if_elim
2379[ #EQbl
2380| #pc_st1_spec inversion(fetch_internal_function ???) [2: #e #_]
2381]
2382[1,2: whd in match dummy_state_pc; whd in match null_pc;
2383  whd in match fetch_statement; normalize nodelta whd in match fetch_internal_function;
2384  normalize nodelta lapply(fetch_function_no_zero ??????)
2385  [2,9: @( «mk_block Code OZ,refl region Code»)
2386    |1,8: % |3,10: @prog |7,14: #EQ >EQ |*:]  whd in ⊢ (??%% → ?); #EQ destruct]
2387* #f1 #fn1 #EQ lapply(jmeq_to_eq ??? EQ) -EQ #fn1_spec normalize nodelta
2388whd in match fetch_statement; normalize nodelta >fn1_spec
2389>m_return_bind #H @('bind_inversion H) -H #stmt1 #EQ
2390lapply(opt_eq_from_res ???? EQ) -EQ #stmt1_spec whd in ⊢ (??%% → ?); #EQ destruct
2391lapply EQeval -EQeval whd in match sigma_state_pc in ⊢ (% → ?);
2392normalize nodelta @if_elim [#H >H in pc_st1_spec; *] #_ >fn1_spec
2393normalize nodelta #EQeval cases(eval_seq_no_pc_no_call_ok ???????? EQeval)
2394#st_no_pc' * #EQeval' #EQst_no_pc'
2395whd in match set_no_pc; normalize nodelta
2396% [ % [@st_no_pc'|@(succ_pc ERTL_semantics (pc ERTL_semantics (sigma_state_pc prog sigma st1))
2397   nxt)| @(last_pop ? st1)]]
2398% [ whd in match sigma_state_pc; normalize nodelta
2399    @if_elim [#H >H in pc_st1_spec; *] #_ >fn1_spec normalize nodelta
2400    @if_elim [#H >H in pc_st1_spec; *] #_ >fn1_spec normalize nodelta
2401    >EQst_no_pc' %]
2402%{(taaf_step … (taa_base …) …)}
2403[3: //] lapply(fetch_statement_commute ? sigma ????? EQf) normalize nodelta
2404whd in match sigma_state_pc; normalize nodelta
2405@if_elim [1,3:#H >H in pc_st1_spec; *] #_ >fn1_spec normalize nodelta
2406#EQf1
2407[ whd in match as_classifier; normalize nodelta whd in match (as_classify ??);
2408  >EQf1 normalize nodelta %
2409| whd in match (as_execute ???); whd in match eval_state; normalize nodelta
2410  >EQf1 >m_return_bind whd in match eval_statement_no_pc; normalize nodelta
2411  >EQeval' >m_return_bind %
2412]
2413qed.
2414
2415
2416lemma eval_goto_ok :
2417 ∀prog : ertl_program.
2418 let trans_prog ≝ ertl_to_ertlptr prog in
2419 ∀stack_sizes.
2420 ∀sigma : sigma_map trans_prog.
2421 ∀st,st',f,fn,nxt.
2422   fetch_statement ERTL_semantics …
2423    (globalenv_noinit ? prog) (pc … (sigma_state_pc ? sigma st)) =
2424      return 〈f, fn,  final … (GOTO ERTL … nxt)〉 →
2425   eval_state ERTL_semantics
2426   (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2427   (ev_genv … (mk_prog_params ERTL_semantics prog stack_sizes))
2428   (sigma_state_pc ? sigma st) =
2429    return st' →
2430    ∃ st''. st' = sigma_state_pc ? sigma st'' ∧
2431 ∃taf : trace_any_any_free (ERTLptr_status trans_prog stack_sizes)
2432  st
2433  st''.
2434 bool_to_Prop (taaf_non_empty … taf).
2435#prog #stack_sizes #sigma #st #st' #f #fn #nxt
2436whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2437@if_elim
2438[ #EQbl whd in match dummy_state_pc; whd in match null_pc;
2439  whd in match fetch_statement; whd in match fetch_internal_function;
2440  normalize nodelta lapply(fetch_function_no_zero ??????)
2441  [2: @( «mk_block Code OZ,refl region Code»)
2442    | % | @prog |7: #EQ >EQ |*:]  whd in ⊢ (??%% → ?); #EQ destruct]
2443#Hbl inversion(fetch_internal_function ???)
2444[2: #e #_ normalize nodelta whd in match dummy_state_pc; whd in match null_pc;
2445   whd in match fetch_statement; whd in match fetch_internal_function;
2446  normalize nodelta lapply(fetch_function_no_zero ??????)
2447  [2: @( «mk_block Code OZ,refl region Code»)
2448    | % | @prog |7: #EQ >EQ |*:]  whd in ⊢ (??%% → ?); #EQ destruct]
2449* #f1 #fn1 #EQ lapply(jmeq_to_eq ??? EQ) -EQ #fn1_spec normalize nodelta
2450#EQf lapply EQf whd in match fetch_statement; normalize nodelta >fn1_spec
2451>m_return_bind #H @('bind_inversion H) -H #stmt' #_ whd in ⊢ (??%% → ?);
2452#EQ destruct whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2453@if_elim [#H >H in Hbl; *] #_ >fn1_spec normalize nodelta whd in match eval_state;
2454normalize nodelta >EQf >m_return_bind whd in match eval_statement_advance;
2455whd in match eval_statement_no_pc; normalize nodelta >m_return_bind
2456whd in match goto; normalize nodelta #H lapply (err_eq_from_io ????? H) -H
2457#H @('bind_inversion H) -H #pc' whd in match set_no_pc; normalize nodelta
2458>(pc_of_label_eq … fn1_spec) whd in ⊢ (???% → ?); #EQ whd in ⊢ (??%% → ?); #EQ1
2459destruct lapply (fetch_statement_commute … sigma … stack_sizes … EQf)
2460normalize nodelta #EQf' %
2461[ % [ @st
2462    | @(mk_program_counter
2463         (pc_block (pc ERTLptr_semantics st))
2464         (offset_of_point ERTL_semantics nxt))
2465    | @(last_pop … st)
2466    ]
2467] %
2468[ whd in match sigma_state_pc; normalize nodelta @if_elim [#H >H in Hbl; *]
2469  >fn1_spec normalize nodelta #_ % ]
2470%{(taaf_step … (taa_base …) …)}
2471[ whd in match as_classifier; normalize nodelta whd in match (as_classify ??);
2472  >EQf' normalize nodelta %
2473| whd in match (as_execute ???); whd in match eval_state; normalize nodelta
2474  >EQf' >m_return_bind whd in match eval_statement_no_pc;
2475  whd in match eval_statement_advance; normalize nodelta >m_return_bind
2476  whd in match goto; normalize nodelta whd in match pc_of_label; normalize nodelta
2477  lapply(fetch_internal_function_transf ??????? fn1_spec)
2478  [ #vars @translate_internal |] #EQ >EQ >m_return_bind %
2479| %
2480]
2481qed.
2482*)
2483
2484
2485                       
2486
2487 
2488lemma eval_return_ok :
2489∀prog : ertl_program.
2490let trans_prog ≝ ertl_to_ertlptr prog in
2491∀stack_sizes.
2492∀sigma : sigma_map trans_prog.
2493∀st,st',f,fn.
2494 fetch_statement ERTL_semantics …
2495  (globalenv_noinit ? prog) (pc … (sigma_state_pc ? sigma st)) =
2496    return 〈f, fn,  final … (RETURN ERTL … )〉 →
2497 eval_state ERTL_semantics
2498   (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2499   (ev_genv … (mk_prog_params ERTL_semantics prog stack_sizes))
2500   (sigma_state_pc ? sigma st) =
2501  return st' →
2502joint_classify (mk_prog_params ERTLptr_semantics trans_prog stack_sizes)
2503  st = Some ? cl_return ∧
2504∃ st''. st' = sigma_state_pc ? sigma st'' ∧
2505∃st2_after_ret.
2506∃taf : trace_any_any_free (ERTLptr_status trans_prog stack_sizes)
2507st2_after_ret
2508st''.
2509(if taaf_non_empty … taf then
2510  ¬as_costed (ERTLptr_status trans_prog stack_sizes)
2511    st2_after_ret
2512 else True) ∧
2513eval_state … (ev_genv …  (mk_prog_params ERTLptr_semantics trans_prog stack_sizes)) st =
2514return st2_after_ret ∧
2515ret_rel ?? (ERTLptrStatusSimulation prog stack_sizes sigma) st' st2_after_ret.
2516#prog #stack_size #sigma #st #st' #f #fn
2517whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2518@if_elim
2519[ #EQbl whd in match dummy_state_pc; whd in match null_pc;
2520  whd in match fetch_statement; whd in match fetch_internal_function;
2521  normalize nodelta >(fetch_function_no_zero ??????) [2: %]
2522  whd in ⊢ (??%% → ?); #EQ destruct ]
2523#Hbl inversion(fetch_internal_function ???)
2524[2: #e #_ normalize nodelta whd in match dummy_state_pc; whd in match null_pc;
2525   whd in match fetch_statement; whd in match fetch_internal_function;
2526  normalize nodelta lapply(fetch_function_no_zero ??????)
2527  [2: @( «mk_block Code OZ,refl region Code»)
2528    | % | @prog |7: #EQ >EQ |*:]  whd in ⊢ (??%% → ?); #EQ destruct]
2529* #f1 #fn1 #EQ lapply(jmeq_to_eq ??? EQ) -EQ #fn1_spec normalize nodelta
2530#EQf lapply EQf whd in match fetch_statement; normalize nodelta >fn1_spec
2531>m_return_bind #H @('bind_inversion H) -H #stmt' #_ whd in ⊢ (??%% → ?);
2532#EQ destruct whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2533@if_elim [#H >H in Hbl; *] #_ >fn1_spec normalize nodelta
2534whd in match eval_state; normalize nodelta >EQf >m_return_bind
2535whd in match eval_statement_no_pc; whd in match eval_statement_advance;
2536normalize nodelta >m_return_bind
2537#H lapply (err_eq_from_io ????? H) -H #H @('bind_inversion H) -H
2538* #st1 #pc1 #EQpop whd in match next_of_call_pc; normalize nodelta
2539>m_bind_bind #H @('bind_inversion H) -H ** #f1 #fn1 * normalize nodelta
2540[ * [ #c_id #args #dest | #r #lbl | #seq ] #nxt | #fin | * ]
2541#EQf1 normalize nodelta [2,3,4: whd in ⊢ (??%% → ?); #EQ destruct]
2542>m_return_bind whd in ⊢ (??%% → ?); #EQ destruct
2543lapply (fetch_statement_commute prog sigma stack_size … EQf)
2544normalize nodelta #EQf'
2545% [ whd in match joint_classify; normalize nodelta >EQf' >m_return_bind %]
2546change with (pop_ra ?? = ?) in EQpop; whd in match set_no_pc in EQpop;
2547normalize nodelta in EQpop;
2548cases(pop_ra_ok ? sigma  stack_size fn ?? EQpop) * #st3 #pc3 * #st3_spec
2549normalize nodelta #EQ destruct whd in match set_last_pop; whd in match succ_pc;
2550normalize nodelta whd in match (point_of_succ ???);
2551 % [ % [ @st3 | @(pc_of_point ERTL_semantics (pc_block … pc3) nxt) | @pc3] ]
2552 % [  @('bind_inversion EQf1) * #f3 #fn3 whd in match sigma_stored_pc;
2553      normalize nodelta inversion(sigma_pc_opt ???) normalize nodelta
2554      [ #_ #H @('bind_inversion H) -H #x whd in match null_pc; normalize nodelta
2555        >fetch_function_no_zero [2: %] whd in ⊢ (???% → ?); #EQ destruct
2556      | #pc4 whd in match sigma_pc_opt; normalize nodelta @if_elim
2557        [ #bl3_spec @('bind_inversion EQf1) #x #H @('bind_inversion H) -H
2558          #x1 >fetch_function_no_minus_one [ whd in ⊢ (???% → ?); #EQ destruct]
2559          lapply bl3_spec @eqZb_elim #EQ * whd in match sigma_stored_pc;
2560          normalize nodelta whd in match sigma_pc_opt; normalize nodelta
2561           >bl3_spec normalize nodelta assumption
2562        | #bl3_spec #H @('bind_inversion H) -H * #id4 #fn4
2563          #H lapply(res_eq_from_opt ??? H) -H #fn4_spec
2564          #H @('bind_inversion H) -H #lbl4 #lbl4_spec whd in ⊢ (??%? → ?); #EQ
2565          destruct #fn3_spec #H @('bind_inversion H) -H #stmt1 #_
2566          whd in ⊢ (??%% → ?); #EQ destruct
2567          >(fetch_internal_function_transf … fn3_spec) in fn4_spec;
2568          whd in ⊢ (??%% → ?); #EQ destruct
2569        ]
2570      ]
2571      whd in match sigma_state_pc; normalize nodelta @if_elim
2572      [ >(pc_block_eq prog sigma ????) in bl3_spec;
2573       [2: >lbl4_spec % #ABS destruct
2574       |3: >(fetch_internal_function_transf … fn3_spec) % |*:]
2575       #bl3_spec whd in match pc_of_point; normalize nodelta #EQ >EQ in bl3_spec; *
2576      | #_ cases daemon
2577      ]
2578  ] cases daemon
2579qed.
2580
2581(*
2582lemma ertl_allocate_local_ok : ∀ prog : ertl_program.
2583let trans_prog ≝ ertl_to_ertlptr prog in
2584∀sigma : sigma_map.
2585∀stack_size.
2586∀id,regs.
2587ertl_allocate_local id (sigma_regs ? sigma getLocalsFromId(
2588*)
2589
2590lemma eval_tailcall_ok :
2591∀prog.
2592let trans_prog ≝ ertl_to_ertlptr prog in
2593∀stack_sizes.
2594∀sigma : sigma_map trans_prog.
2595∀st,st',f,fn,fl,called,args.
2596 fetch_statement ERTL_semantics …
2597  (globalenv_noinit ? prog) (pc … (sigma_state_pc ? sigma st)) =
2598    return 〈f, fn,  final … (TAILCALL ERTL … fl called args)〉 →
2599 eval_state ERTL_semantics
2600   (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2601   (ev_genv … (mk_prog_params ERTL_semantics prog stack_sizes))
2602   (sigma_state_pc ? sigma st) =
2603  return st' →
2604  ∃ st''. st' = sigma_state_pc ? sigma st'' ∧
2605  ∃is_tailcall, is_tailcall'.
2606  joint_tailcall_ident (mk_prog_params ERTLptr_semantics trans_prog stack_sizes) «st, is_tailcall'» =
2607  joint_tailcall_ident (mk_prog_params ERTL_semantics prog stack_sizes) «(sigma_state_pc ? sigma st), is_tailcall» ∧
2608  eval_state … (ev_genv … (mk_prog_params ERTLptr_semantics trans_prog stack_sizes))
2609    st = return st''.
2610#prog #stack_size #sigma #st #st' #f #fn #fl #called #args
2611whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2612@if_elim
2613[ #EQbl whd in match dummy_state_pc; whd in match null_pc;
2614  whd in match fetch_statement; whd in match fetch_internal_function;
2615  normalize nodelta >(fetch_function_no_zero ??????) [2: %]
2616  whd in ⊢ (??%% → ?); #EQ destruct ]
2617#Hbl inversion(fetch_internal_function ???)
2618[2: #e #_ normalize nodelta whd in match dummy_state_pc; whd in match null_pc;
2619   whd in match fetch_statement; whd in match fetch_internal_function;
2620  normalize nodelta lapply(fetch_function_no_zero ??????)
2621  [2: @( «mk_block Code OZ,refl region Code»)
2622    | % | @prog |7: #EQ >EQ |*:]  whd in ⊢ (??%% → ?); #EQ destruct]
2623* #f1 #fn1 #EQ lapply(jmeq_to_eq ??? EQ) -EQ #fn1_spec normalize nodelta
2624#EQf lapply EQf whd in match fetch_statement; normalize nodelta >fn1_spec
2625>m_return_bind #H @('bind_inversion H) -H #stmt' #_ whd in ⊢ (??%% → ?);
2626#EQ destruct  whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2627@if_elim [#H >H in Hbl; *] #_ >fn1_spec normalize nodelta
2628whd in match eval_state; normalize nodelta >EQf >m_return_bind
2629whd in match eval_statement_no_pc; whd in match eval_statement_advance;
2630normalize nodelta >m_return_bind whd in match eval_tailcall;
2631normalize nodelta #H @('bind_inversion H) -H #bl whd in match set_no_pc;
2632normalize nodelta #bl_spec #H @('bind_inversion H) -H * #id1 * [#int_f | #ext_f] 
2633#H lapply(err_eq_from_io ????? H) -H #id1_spec normalize nodelta
2634[2: #H @('bind_inversion H) -H #st1 whd in match eval_external_call; normalize nodelta
2635    #H @('bind_inversion H) -H #l_val #_ #H @('bind_inversion H) -H #le #_
2636    #H @('bind_inversion H) -H #x whd in match do_io; normalize nodelta
2637    whd in ⊢ (???% → ?); #EQ destruct ]
2638#H lapply(err_eq_from_io ????? H) -H  #H @('bind_inversion H) -H #st1
2639whd in match eval_internal_call; normalize nodelta whd in match (stack_sizes ????);
2640#H @('bind_inversion H) -H #n #H lapply(opt_eq_from_res ???? H) -H #n_spec
2641whd in match(setup_call ???????); >m_return_bind
2642whd in ⊢ (??%% → ?); #EQ destruct whd in match sigma_state in ⊢ (% → ?);
2643normalize  nodelta whd in ⊢ (??%% → ?); #EQ destruct
2644% [ %
2645    [ %
2646      [ @(st_frms ERTLptr_semantics st)
2647      | @(istack ERTLptr_semantics st)
2648      | @(carry ERTLptr_semantics st)
2649      | cases daemon
2650      | @(m ERTLptr_semantics st)
2651      ]
2652    | @(mk_program_counter bl
2653            (offset_of_point ERTL_semantics
2654              (joint_if_entry ERTL_semantics
2655                  (prog_var_names (joint_function ERTL_semantics) ℕ prog) int_f)))
2656    | @(last_pop ERTLptr_semantics st)
2657    ]
2658  ]
2659% [ whd in match sigma_state_pc; normalize nodelta @if_elim whd in match pc_of_point;
2660    normalize nodelta
2661    [ #Hbl >fetch_function_no_minus_one in id1_spec;
2662       [2: lapply Hbl @eqZb_elim -Hbl #Hbl * @Hbl] whd in ⊢ (???% → ?);
2663       #EQ destruct(EQ)
2664    ] #_ whd in match fetch_internal_function; normalize nodelta >id1_spec
2665      >m_return_bind normalize nodelta cases daemon (*TO BE COmpleted *)
2666  ] cases daemon (*TO BE COMPLETED*)
2667qed.
2668   
2669   
2670   
2671   
2672lemma as_label_ok : ∀ prog : ertl_program.
2673let trans_prog ≝ ertl_to_ertlptr prog in
2674∀ sigma : sigma_map trans_prog.
2675∀stack_sizes.
2676∀ st.
2677as_label (ERTLptr_status trans_prog stack_sizes) st = as_label
2678(ERTL_status prog stack_sizes) (sigma_state_pc prog sigma st).
2679#prog #sigma #stack_size * #st #pc #lp
2680whd in match as_label; normalize nodelta whd in match (as_pc_of ??) in ⊢ (??%%);
2681whd in match (as_label_of_pc ??) in ⊢ (??%%);
2682
2683
2684(*
2685
2686whd in match fetch_statement; normalize nodelta
2687whd in match sigma_state_pc; normalize nodelta @if_elim
2688[ #EQbl whd in match fetch_internal_function; normalize nodelta >m_bind_bind
2689 lapply(fetch_function_no_minus_one ??????) [2: @(pc_block pc) | lapply EQbl
2690 @eqZb_elim #H * @H| @(ertl_to_ertlptr prog) |7: #EQ >EQ |*:] normalize nodelta
2691 whd in match dummy_state_pc; whd in match (as_label_of_pc ??); whd in match null_pc;
2692 whd in match fetch_statement; normalize nodelta whd in match fetch_internal_function;
2693 normalize nodelta >m_bind_bind
2694 lapply(fetch_function_no_zero ??????) [2: @( «mk_block Code OZ,refl region Code»)
2695 | % | @prog |7: #EQ >EQ |*:] %
2696| inversion ( fetch_internal_function
2697     (joint_closed_internal_function ERTL
2698      (prog_var_names (joint_function ERTL) ℕ prog))
2699     (globalenv_noinit (joint_function ERTL) prog) (pc_block pc))
2700 [ * #id #fn #fn_spec #_ lapply(fetch_internal_function_transf ??????? fn_spec)
2701   [ @(λvars,fn.translate_internal … fn) |] #EQ >EQ >m_return_bind normalize nodelta
2702     whd in match (as_label_of_pc ??);
2703     whd in match fetch_statement; normalize nodelta >fn_spec >m_return_bind
2704     cases daemon (*serve specifica su sigma TODO*)
2705   | #err #EQ lapply(jmeq_to_eq ??? EQ) -EQ #fetch_err #_ normalize nodelta
2706     whd in match dummy_state_pc;
2707     whd in match (as_label_of_pc ??); whd in match null_pc;
2708     whd in match fetch_statement; normalize nodelta
2709     whd in match fetch_internal_function in ⊢ (???%);
2710     normalize nodelta
2711     lapply(fetch_function_no_zero ??????) [2: @( «mk_block Code OZ,refl region Code»)
2712     | % | @prog |7: #EQ >EQ in ⊢ (???%); |*:] normalize nodelta -EQ
2713     lapply fetch_err -fetch_err whd in match fetch_internal_function; normalize nodelta
2714     inversion(fetch_function ???)
2715     [* #id * #fn #fn_spec >m_return_bind normalize nodelta [whd in ⊢ (??%? → ?); #EQ destruct]
2716     #EQ destruct  lapply(jmeq_to_eq ??? fn_spec) -fn_spec #fn_spec
2717     lapply(fetch_function_transf ????????? fn_spec) [ #v  @transf_fundef [2:@translate_internal |]|]
2718     #EQ >EQ >m_return_bind %
2719   | #err1 #EQ lapply(jmeq_to_eq ??? EQ) -EQ #EQfetch whd in ⊢ (??%? → ?); #EQ destruct
2720     normalize nodelta lapply EQfetch -EQfetch whd in match fetch_function;
2721     normalize nodelta check joint_function
2722      lapply(symbol_for_block_transf  ? ? ? ? prog (λvars.?)  (pc_block pc))
2723      [@transf_fundef [2: @translate_internal|] |4: #EQ >EQ in ⊢ (? → %); |*:] 
2724     cases(symbol_for_block ???) [ whd in ⊢ (??%% → ?); #EQ destruct %]
2725     #id >m_return_bind inversion(find_funct_ptr ???)
2726     [2: #fn1 #_ >m_return_bind whd in ⊢ (??%? → ?); #EQ destruct]
2727     #EQf whd in ⊢ (??%? → ?); #EQ destruct
2728     lapply(find_funct_ptr_none ??????? EQf) (*forse e' falso*)
2729     [#vars @transf_fundef [2: @translate_internal|]|]
2730     #EQ >EQ %
2731     ]
2732  ]
2733]*)
2734cases daemon
2735qed.
2736
2737lemma bool_of_beval_ok : ∀prog : ertlptr_program.
2738∀sigma : sigma_map prog.
2739preserving1 … res_preserve1 …
2740    (sigma_beval prog sigma)
2741    (λx.x)
2742    (bool_of_beval)
2743    (bool_of_beval).
2744#prog #sigma whd in match bool_of_beval; normalize nodelta
2745* normalize nodelta
2746 [ | | #ptr1 #ptr2 #p | #by | #p | #ptr #p | #pc #p]
2747try @res_preserve_error1 #x
2748[1,2,3,4: whd in ⊢ (???% → ?); #EQ destruct
2749          [1,4: %{true} % //
2750          |3: %{false} % //
2751          | %{(eq_bv 8 (zero 8) by)} % //
2752          ]
2753| whd in match sigma_beval; normalize nodelta cases(sigma_pc_opt ? ? ?)
2754  normalize nodelta [2: #pc1] whd in ⊢ (???% → ?); #EQ destruct
2755]
2756qed.
2757
2758lemma eval_cond_ok :
2759∀prog.
2760let trans_prog ≝ ertl_to_ertlptr prog in
2761∀stack_sizes.
2762∀sigma : sigma_map trans_prog.
2763∀st,st',f,fn,a,ltrue,lfalse.
2764 fetch_statement ERTL_semantics …
2765  (globalenv_noinit ? prog) (pc … (sigma_state_pc ? sigma st)) =
2766    return 〈f, fn,  sequential … (COND ERTL … a ltrue) lfalse〉 →
2767 eval_state ERTL_semantics
2768   (prog_var_names (joint_function ERTL_semantics) ℕ prog)
2769   (ev_genv … (mk_prog_params ERTL_semantics prog stack_sizes))
2770   (sigma_state_pc ? sigma st) =
2771  return st' →
2772as_costed (ERTL_status prog stack_sizes)
2773  st' →
2774∃ st''. st' = sigma_state_pc ? sigma st'' ∧
2775∃taf : trace_any_any_free (ERTLptr_status trans_prog stack_sizes)
2776st st''.
2777bool_to_Prop (taaf_non_empty … taf).
2778#prog #stack_size #sigma #st #st' #f #fn #a #lb_t #lb_f
2779whd in match sigma_state_pc in ⊢ (% → ?); normalize nodelta
2780@if_elim
2781[ #EQbl whd in match dummy_state_pc; whd in match null_pc;
2782  whd in match fetch_statement; whd in match fetch_internal_function;
2783  normalize nodelta >(fetch_function_no_zero ??????) [2: %]
2784  whd in ⊢ (??%% → ?); #EQ destruct ]
2785#Hbl inversion(fetch_internal_function ???)
2786[2: #e #_ normalize nodelta whd in match dummy_state_pc; whd in match null_pc;
2787   whd in match fetch_statement; whd in match fetch_internal_function;
2788  normalize nodelta >(fetch_function_no_zero ??????) [2: %]
2789 whd in ⊢ (??%% → ?); #EQ destruct]
2790* #f1 #fn1 #EQ lapply(jmeq_to_eq ??? EQ) -EQ #fn1_spec normalize nodelta
2791#EQf lapply EQf whd in match fetch_statement; normalize nodelta >fn1_spec
2792>m_return_bind #H @('bind_inversion H) -H #stmt' #_ whd in ⊢ (??%% → ?);
2793#EQ destruct whd in match eval_state; whd in match eval_statement_no_pc;
2794whd in match eval_statement_advance; whd in match sigma_state_pc in ⊢ (% → ?);
2795normalize nodelta @if_elim [#H >H in Hbl; *] #_ >fn1_spec normalize nodelta
2796>EQf >m_return_bind normalize nodelta >m_return_bind
2797#H lapply(err_eq_from_io ????? H) -H #H @('bind_inversion H) -H #bv
2798change with (ps_reg_retrieve ?? = ? → ?) whd in match set_no_pc;
2799whd in match sigma_state in ⊢ (??(?%?)? → ?); normalize nodelta #bv_spec
2800#H @('bind_inversion H) -H * #EQbv normalize nodelta
2801[ whd in match goto; normalize nodelta >pc_of_label_eq [2: assumption |3:]
2802  >m_return_bind whd in match pc_of_point; normalize nodelta whd in ⊢ (??%% → ?);
2803  whd in match set_pc; normalize nodelta #EQ destruct
2804| whd in match next; whd in match set_pc; normalize nodelta whd in match (succ_pc ???);
2805  whd in match (point_of_succ ???); whd in ⊢ (??%% → ?); #EQ destruct
2806]
2807whd in match as_costed; normalize nodelta * #n_cost %
2808[1,3: % [1,4: @st
2809        |2,5: @(mk_program_counter
2810                  (pc_block (pc ERTLptr_semantics st))
2811                  (offset_of_point ERTL_semantics ?)) [ @lb_t | @lb_f]
2812        |3,6: @(last_pop ? st)
2813        ]
2814]
2815% [1,3: whd in match sigma_state_pc; normalize nodelta @if_elim
2816       [1,3: #EQ >EQ in Hbl; *] #_ >fn1_spec %]
2817%{(taaf_step_jump … (taa_base …) …) I}
2818lapply (fetch_statement_commute prog sigma … stack_size … EQf)
2819normalize nodelta #EQf'
2820[1,4: whd in match as_costed; normalize nodelta >as_label_ok [2,4: @sigma]
2821      % #H @n_cost <H whd in match sigma_state_pc; normalize nodelta
2822      @if_elim [1,3: #EQ >EQ in Hbl; *] #_ >fn1_spec %
2823|2,5: whd in match as_classifier; normalize nodelta  whd in match (as_classify ??);
2824      normalize nodelta >EQf' %
2825|*:  whd in match (as_execute ???); whd in match eval_state; normalize nodelta
2826     >EQf' >m_return_bind whd in match eval_statement_no_pc; normalize nodelta
2827     >m_return_bind whd in match eval_statement_advance; normalize nodelta 
2828     change with (ps_reg_retrieve ??) in ⊢ (??(????(????%?))?);
2829     cases(ps_reg_retrieve_ok ????? ? bv_spec) #bv' * #bv_spec' #bv_bv'
2830     >bv_spec' >m_return_bind >bv_bv' in EQbv; #EQbv
2831     cases(bool_of_beval_ok ? sigma ? ? EQbv) #b1 * #b1_spec #EQ destruct
2832     >b1_spec >m_return_bind normalize nodelta [2: %] whd in match goto;
2833     normalize nodelta whd in match set_no_pc; normalize nodelta
2834     >pc_of_label_eq
2835     [ %
2836     | lapply(fetch_internal_function_transf ????????)
2837       [3: @f |2: @fn | whd in ⊢ (???%); <fn1_spec in ⊢ (???%); %
2838       | | #vars @translate_internal |9: #EQ >EQ in ⊢ (??%?); % |*:]
2839       |
2840     ]
2841]
2842qed.
2843       
2844
2845lemma
2846  find_funct_ptr_none:
2847    ∀A,B,V,iV. ∀p: program A V. ∀transf: (∀vs. A vs → B vs).
2848    ∀b: block.
2849    find_funct_ptr ? (globalenv … iV p) b = None ? →
2850    find_funct_ptr ? (globalenv … iV (transform_program … p transf)) b = None ?.
2851#A #B #V #i #p #transf #b
2852whd in match find_funct_ptr; normalize nodelta
2853cases b -b * normalize nodelta [#x #_ %] * normalize nodelta
2854[1,2: [2: #x] #_ %] #x whd in match globalenv; normalize nodelta
2855whd in match globalenv_allocmem; normalize nodelta
2856cases daemon (*forse e' falso *)
2857qed.
2858
2859
2860
2861
2862
2863
2864
Note: See TracBrowser for help on using the repository browser.