1 | include "basics/types.ma". |
---|
2 | include "basics/bool.ma". |
---|
3 | include "basics/jmeq.ma". |
---|
4 | include "common/CostLabel.ma". |
---|
5 | include "utilities/option.ma". |
---|
6 | include "basics/lists/listb.ma". |
---|
7 | include "ASM/Util.ma". |
---|
8 | |
---|
9 | inductive status_class: Type[0] ≝ |
---|
10 | | cl_return: status_class |
---|
11 | | cl_jump: status_class |
---|
12 | | cl_call: status_class |
---|
13 | | cl_other: status_class. |
---|
14 | |
---|
15 | record abstract_status : Type[1] ≝ |
---|
16 | { |
---|
17 | as_status :> Type[0] |
---|
18 | ; as_execute : as_status → as_status → Prop |
---|
19 | ; as_pc : DeqSet |
---|
20 | ; as_pc_of : as_status → as_pc |
---|
21 | ; as_classifier : as_status → status_class → Prop |
---|
22 | ; as_label_of_pc : as_pc → option costlabel |
---|
23 | ; as_after_return : (Σs:as_status. as_classifier s cl_call) → as_status → Prop |
---|
24 | ; as_final: as_status → Prop |
---|
25 | }. |
---|
26 | |
---|
27 | definition as_label ≝ λS : abstract_status. λs : S. as_label_of_pc ? (as_pc_of ? s). |
---|
28 | |
---|
29 | (* temporary alias for backward compatibility *) |
---|
30 | definition final_abstract_status ≝ abstract_status. |
---|
31 | |
---|
32 | definition as_costed : ∀a_s : abstract_status.a_s → Prop ≝ |
---|
33 | λa_s,st.as_label ? st ≠ None ?. |
---|
34 | |
---|
35 | definition as_label_safe : ∀a_s : abstract_status. |
---|
36 | (Σs : a_s.as_costed ? s) → costlabel ≝ |
---|
37 | λa_s,st_sig.opt_safe … (pi2 … st_sig). |
---|
38 | |
---|
39 | inductive trace_ends_with_ret: Type[0] ≝ |
---|
40 | | ends_with_ret: trace_ends_with_ret |
---|
41 | | doesnt_end_with_ret: trace_ends_with_ret. |
---|
42 | |
---|
43 | inductive trace_label_return (S:abstract_status) : S → S → Type[0] ≝ |
---|
44 | | tlr_base: |
---|
45 | ∀status_before: S. |
---|
46 | ∀status_after: S. |
---|
47 | trace_label_label S ends_with_ret status_before status_after → |
---|
48 | trace_label_return S status_before status_after |
---|
49 | | tlr_step: |
---|
50 | ∀status_initial: S. |
---|
51 | ∀status_labelled: S. |
---|
52 | ∀status_final: S. |
---|
53 | trace_label_label S doesnt_end_with_ret status_initial status_labelled → |
---|
54 | trace_label_return S status_labelled status_final → |
---|
55 | trace_label_return S status_initial status_final |
---|
56 | with trace_label_label: trace_ends_with_ret → S → S → Type[0] ≝ |
---|
57 | | tll_base: |
---|
58 | ∀ends_flag: trace_ends_with_ret. |
---|
59 | ∀start_status: S. |
---|
60 | ∀end_status: S. |
---|
61 | trace_any_label S ends_flag start_status end_status → |
---|
62 | as_costed S start_status → |
---|
63 | trace_label_label S ends_flag start_status end_status |
---|
64 | with trace_any_label: trace_ends_with_ret → S → S → Type[0] ≝ |
---|
65 | (* Single steps within a function which reach a label. |
---|
66 | Note that this is the only case applicable for a jump. *) |
---|
67 | | tal_base_not_return: |
---|
68 | ∀start_status: S. |
---|
69 | ∀final_status: S. |
---|
70 | as_execute S start_status final_status → |
---|
71 | (as_classifier S start_status cl_jump ∨ |
---|
72 | as_classifier S start_status cl_other) → |
---|
73 | as_costed S final_status → |
---|
74 | trace_any_label S doesnt_end_with_ret start_status final_status |
---|
75 | | tal_base_return: |
---|
76 | ∀start_status: S. |
---|
77 | ∀final_status: S. |
---|
78 | as_execute S start_status final_status → |
---|
79 | as_classifier S start_status cl_return → |
---|
80 | trace_any_label S ends_with_ret start_status final_status |
---|
81 | (* A call followed by a label on return. *) |
---|
82 | | tal_base_call: |
---|
83 | ∀status_pre_fun_call: S. |
---|
84 | ∀status_start_fun_call: S. |
---|
85 | ∀status_final: S. |
---|
86 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
87 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
88 | as_after_return S (mk_Sig ?? status_pre_fun_call H) status_final → |
---|
89 | trace_label_return S status_start_fun_call status_final → |
---|
90 | as_costed S status_final → |
---|
91 | trace_any_label S doesnt_end_with_ret status_pre_fun_call status_final |
---|
92 | (* A call followed by a non-empty trace. *) |
---|
93 | | tal_step_call: |
---|
94 | ∀end_flag: trace_ends_with_ret. |
---|
95 | ∀status_pre_fun_call: S. |
---|
96 | ∀status_start_fun_call: S. |
---|
97 | ∀status_after_fun_call: S. |
---|
98 | ∀status_final: S. |
---|
99 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
100 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
101 | as_after_return S (mk_Sig ?? status_pre_fun_call H) status_after_fun_call → |
---|
102 | trace_label_return S status_start_fun_call status_after_fun_call → |
---|
103 | ¬ as_costed S status_after_fun_call → |
---|
104 | trace_any_label S end_flag status_after_fun_call status_final → |
---|
105 | trace_any_label S end_flag status_pre_fun_call status_final |
---|
106 | | tal_step_default: |
---|
107 | ∀end_flag: trace_ends_with_ret. |
---|
108 | ∀status_pre: S. |
---|
109 | ∀status_init: S. |
---|
110 | ∀status_end: S. |
---|
111 | as_execute S status_pre status_init → |
---|
112 | trace_any_label S end_flag status_init status_end → |
---|
113 | as_classifier S status_pre cl_other → |
---|
114 | ¬ (as_costed S status_init) → |
---|
115 | trace_any_label S end_flag status_pre status_end. |
---|
116 | |
---|
117 | let rec tal_pc_list (S : abstract_status) fl st1 st2 (tal : trace_any_label S fl st1 st2) |
---|
118 | on tal : list (as_pc S) ≝ |
---|
119 | match tal with |
---|
120 | [ tal_step_call fl' pre _ st1' st2' _ _ _ _ _ tl ⇒ as_pc_of … pre :: tal_pc_list … tl |
---|
121 | | tal_step_default fl' pre st1' st2' _ tl _ _ ⇒ as_pc_of … pre :: tal_pc_list … tl |
---|
122 | | tal_base_not_return pre _ _ _ _ ⇒ [as_pc_of … pre] |
---|
123 | | tal_base_return pre _ _ _ ⇒ [as_pc_of … pre] |
---|
124 | | tal_base_call pre _ _ _ _ _ _ _ ⇒ [as_pc_of … pre] |
---|
125 | ]. |
---|
126 | |
---|
127 | definition as_trace_any_label_length': |
---|
128 | ∀S: abstract_status. |
---|
129 | ∀trace_ends_flag: trace_ends_with_ret. |
---|
130 | ∀start_status: S. |
---|
131 | ∀final_status: S. |
---|
132 | ∀the_trace: trace_any_label S trace_ends_flag start_status final_status. |
---|
133 | nat ≝ |
---|
134 | λS: abstract_status. |
---|
135 | λtrace_ends_flag: trace_ends_with_ret. |
---|
136 | λstart_status: S. |
---|
137 | λfinal_status: S. |
---|
138 | λthe_trace: trace_any_label S trace_ends_flag start_status final_status. |
---|
139 | |tal_pc_list … the_trace|. |
---|
140 | |
---|
141 | let rec tlr_unrepeating S st1 st2 (tlr : trace_label_return S st1 st2) on tlr : Prop ≝ |
---|
142 | match tlr with |
---|
143 | [ tlr_base st1 st2 tll ⇒ tll_unrepeating … tll |
---|
144 | | tlr_step st1 st2 st3 tll tl ⇒ tll_unrepeating … tll ∧ tlr_unrepeating … tl |
---|
145 | ] |
---|
146 | and tll_unrepeating S fl st1 st2 (tll : trace_label_label S fl st1 st2) on tll : Prop ≝ |
---|
147 | match tll with |
---|
148 | [ tll_base fl st1 st2 tal _ ⇒ tal_unrepeating … tal |
---|
149 | ] |
---|
150 | and tal_unrepeating S fl st1 st2 (tal : trace_any_label S fl st1 st2) on tal : Prop ≝ |
---|
151 | match tal with |
---|
152 | [ tal_step_call fl st1 st2 st3 st4 _ _ _ tlr _ tl ⇒ |
---|
153 | bool_to_Prop (notb (memb ? (as_pc_of … st1) (tal_pc_list … tl))) ∧ |
---|
154 | tal_unrepeating … tl ∧ |
---|
155 | tlr_unrepeating … tlr |
---|
156 | | tal_step_default fl st1 st2 st3 _ tl _ _ ⇒ |
---|
157 | bool_to_Prop (notb (memb ? (as_pc_of … st1) (tal_pc_list … tl))) ∧ |
---|
158 | tal_unrepeating … tl |
---|
159 | | tal_base_call pre _ _ _ _ _ trace _ ⇒ tlr_unrepeating … trace |
---|
160 | | _ ⇒ True |
---|
161 | ]. |
---|
162 | |
---|
163 | definition tll_hd_label : ∀S : abstract_status.∀fl,st1,st2. |
---|
164 | trace_label_label S fl st1 st2 → costlabel ≝ |
---|
165 | λS,fl,st1,st2,tr.match tr with |
---|
166 | [ tll_base _ st1' _ _ prf ⇒ as_label_safe … «st1', prf» ]. |
---|
167 | |
---|
168 | definition tlr_hd_label : ∀S : abstract_status.∀st1,st2. |
---|
169 | trace_label_return S st1 st2 → costlabel ≝ |
---|
170 | λS,st1,st2,tr.match tr with |
---|
171 | [ tlr_base st1' st2' tll ⇒ tll_hd_label … tll |
---|
172 | | tlr_step st1' st2' _ tll _ ⇒ tll_hd_label … tll |
---|
173 | ]. |
---|
174 | |
---|
175 | let rec tal_unrepeating_uniqueb S fl st1 st2 tal on tal : |
---|
176 | tal_unrepeating S fl st1 st2 tal → bool_to_Prop (uniqueb … (tal_pc_list … tal)) ≝ ?. |
---|
177 | cases tal // |
---|
178 | #fl' #st1' [#st_fun] #st2' #st3' #H |
---|
179 | [ #H0 #H1 #tlr #G #tal | #tal #H0 #G ] whd in ⊢ (% → ?%); [*]* |
---|
180 | #A #B [#_] >A normalize nodelta @tal_unrepeating_uniqueb assumption |
---|
181 | qed. |
---|
182 | |
---|
183 | inductive trace_any_call (S:abstract_status) : S → S → Type[0] ≝ |
---|
184 | | tac_base: |
---|
185 | ∀status: S. |
---|
186 | as_classifier S status cl_call → |
---|
187 | trace_any_call S status status |
---|
188 | | tac_step_call: |
---|
189 | ∀status_pre_fun_call: S. |
---|
190 | ∀status_after_fun_call: S. |
---|
191 | ∀status_final: S. |
---|
192 | ∀status_start_fun_call: S. |
---|
193 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
194 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
195 | as_after_return S (mk_Sig ?? status_pre_fun_call H) status_after_fun_call → |
---|
196 | trace_label_return S status_start_fun_call status_after_fun_call → |
---|
197 | ¬ as_costed S status_after_fun_call → |
---|
198 | trace_any_call S status_after_fun_call status_final → |
---|
199 | trace_any_call S status_pre_fun_call status_final |
---|
200 | | tac_step_default: |
---|
201 | ∀status_pre: S. |
---|
202 | ∀status_end: S. |
---|
203 | ∀status_init: S. |
---|
204 | as_execute S status_pre status_init → |
---|
205 | trace_any_call S status_init status_end → |
---|
206 | as_classifier S status_pre cl_other → |
---|
207 | ¬ (as_costed S status_init) → |
---|
208 | trace_any_call S status_pre status_end. |
---|
209 | |
---|
210 | |
---|
211 | inductive trace_label_call (S:abstract_status) : S → S → Type[0] ≝ |
---|
212 | | tlc_base: |
---|
213 | ∀start_status: S. |
---|
214 | ∀end_status: S. |
---|
215 | trace_any_call S start_status end_status → |
---|
216 | as_costed S start_status → |
---|
217 | trace_label_call S start_status end_status |
---|
218 | . |
---|
219 | |
---|
220 | definition tlc_hd_label : ∀S : abstract_status.∀st1,st2. |
---|
221 | trace_label_call S st1 st2 → costlabel ≝ |
---|
222 | λS,st1,st2,tr.match tr with |
---|
223 | [ tlc_base st1' _ _ prf ⇒ as_label_safe … «st1', prf» |
---|
224 | ]. |
---|
225 | |
---|
226 | coinductive trace_label_diverges (S:abstract_status) : S → Type[0] ≝ |
---|
227 | | tld_step: |
---|
228 | ∀status_initial: S. |
---|
229 | ∀status_labelled: S. |
---|
230 | trace_label_label S doesnt_end_with_ret status_initial status_labelled → |
---|
231 | trace_label_diverges S status_labelled → |
---|
232 | trace_label_diverges S status_initial |
---|
233 | | tld_base: |
---|
234 | ∀status_initial: S. |
---|
235 | ∀status_pre_fun_call: S. |
---|
236 | ∀status_start_fun_call: S. |
---|
237 | trace_label_call S status_initial status_pre_fun_call → |
---|
238 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
239 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
240 | trace_label_diverges S status_start_fun_call → |
---|
241 | trace_label_diverges S status_initial. |
---|
242 | |
---|
243 | definition tld_hd_label : ∀S : abstract_status.∀st. |
---|
244 | trace_label_diverges S st → costlabel ≝ |
---|
245 | λS,st,tr.match tr with |
---|
246 | [ tld_step st' st'' tll _ ⇒ tll_hd_label … tll |
---|
247 | | tld_base st' st'' _ tlc _ _ _ ⇒ tlc_hd_label … tlc |
---|
248 | ]. |
---|
249 | |
---|
250 | (* Version in Prop for showing existence. *) |
---|
251 | coinductive trace_label_diverges_exists (S:abstract_status) : S → Prop ≝ |
---|
252 | | tld_step': |
---|
253 | ∀status_initial: S. |
---|
254 | ∀status_labelled: S. |
---|
255 | trace_label_label S doesnt_end_with_ret status_initial status_labelled → |
---|
256 | trace_label_diverges_exists S status_labelled → |
---|
257 | trace_label_diverges_exists S status_initial |
---|
258 | | tld_base': |
---|
259 | ∀status_initial: S. |
---|
260 | ∀status_pre_fun_call: S. |
---|
261 | ∀status_start_fun_call: S. |
---|
262 | trace_label_call S status_initial status_pre_fun_call → |
---|
263 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
264 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
265 | trace_label_diverges_exists S status_start_fun_call → |
---|
266 | trace_label_diverges_exists S status_initial. |
---|
267 | |
---|
268 | inductive trace_whole_program (S: abstract_status) : S → Type[0] ≝ |
---|
269 | | twp_terminating: |
---|
270 | ∀status_initial: S. |
---|
271 | ∀status_start_fun: S. |
---|
272 | ∀status_final: S. |
---|
273 | as_classifier S status_initial cl_call → |
---|
274 | as_execute S status_initial status_start_fun → |
---|
275 | trace_label_return S status_start_fun status_final → |
---|
276 | as_final S status_final → |
---|
277 | trace_whole_program S status_initial |
---|
278 | | twp_diverges: |
---|
279 | ∀status_initial: S. |
---|
280 | ∀status_start_fun: S. |
---|
281 | as_classifier S status_initial cl_call → |
---|
282 | as_execute S status_initial status_start_fun → |
---|
283 | trace_label_diverges S status_start_fun → |
---|
284 | trace_whole_program S status_initial. |
---|
285 | |
---|
286 | (* Again, an identical version in Prop for existence proofs. *) |
---|
287 | inductive trace_whole_program_exists (S: abstract_status) : S → Prop ≝ |
---|
288 | | twp_terminating: |
---|
289 | ∀status_initial: S. |
---|
290 | ∀status_start_fun: S. |
---|
291 | ∀status_final: S. |
---|
292 | as_classifier S status_initial cl_call → |
---|
293 | as_execute S status_initial status_start_fun → |
---|
294 | trace_label_return S status_start_fun status_final → |
---|
295 | as_final S status_final → |
---|
296 | trace_whole_program_exists S status_initial |
---|
297 | | twp_diverges: |
---|
298 | ∀status_initial: S. |
---|
299 | ∀status_start_fun: S. |
---|
300 | as_classifier S status_initial cl_call → |
---|
301 | as_execute S status_initial status_start_fun → |
---|
302 | trace_label_diverges_exists S status_start_fun → |
---|
303 | trace_whole_program_exists S status_initial. |
---|
304 | |
---|
305 | |
---|
306 | let rec trace_any_label_label S s s' f |
---|
307 | (tr:trace_any_label S f s s') on tr : match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ] ≝ |
---|
308 | match tr return λf,s,s',tr. match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ] with |
---|
309 | [ tal_base_not_return start final _ _ C ⇒ C |
---|
310 | | tal_base_return _ _ _ _ ⇒ I |
---|
311 | | tal_base_call _ _ _ _ _ _ _ C ⇒ C |
---|
312 | | tal_step_call f pre start after final X C RET LR C' tr' ⇒ trace_any_label_label … tr' |
---|
313 | | tal_step_default f pre init end X tr' C C' ⇒ trace_any_label_label … tr' |
---|
314 | ]. |
---|
315 | |
---|
316 | definition tal_tl_label : ∀S : abstract_status.∀st1,st2. |
---|
317 | trace_any_label S doesnt_end_with_ret st1 st2 → costlabel ≝ |
---|
318 | λS,st1,st2,tr.as_label_safe … «st2, trace_any_label_label … tr». |
---|
319 | |
---|
320 | lemma trace_label_label_label : ∀S,s,s',f. |
---|
321 | ∀tr:trace_label_label S f s s'. match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ]. |
---|
322 | #S #s #s' #f #tr |
---|
323 | cases tr |
---|
324 | #f #start #end #tr' #C @(trace_any_label_label … tr') |
---|
325 | qed. |
---|
326 | |
---|
327 | definition tll_tl_label : ∀S : abstract_status.∀st1,st2. |
---|
328 | trace_label_label S doesnt_end_with_ret st1 st2 → costlabel ≝ |
---|
329 | λS,st1,st2,tr.as_label_safe … «st2, trace_label_label_label … tr». |
---|
330 | |
---|
331 | lemma trace_any_call_call : ∀S,s,s'. |
---|
332 | trace_any_call S s s' → as_classifier S s' cl_call. |
---|
333 | #S #s #s' #T elim T // |
---|
334 | qed. |
---|
335 | |
---|
336 | (* an uncalling, unreturning and *unjumping*, |
---|
337 | as well as unlabelled (but possibly for the first and last statuses) |
---|
338 | possibly empty trace segment *) |
---|
339 | inductive trace_any_any (S:abstract_status) : S → S → Type[0] ≝ |
---|
340 | | taa_base : |
---|
341 | ∀start_status: S. |
---|
342 | trace_any_any S start_status start_status |
---|
343 | | taa_step : |
---|
344 | ∀status_pre: S. |
---|
345 | ∀status_init: S. |
---|
346 | ∀status_end: S. |
---|
347 | as_execute S status_pre status_init → |
---|
348 | trace_any_any S status_init status_end → |
---|
349 | as_classifier S status_pre cl_other → |
---|
350 | ¬as_costed … status_init → |
---|
351 | trace_any_any S status_pre status_end. |
---|
352 | |
---|
353 | let rec taa_status_list S st1 st2 (taa : trace_any_any S st1 st2) on taa : list S ≝ |
---|
354 | match taa with |
---|
355 | [ taa_base st1' ⇒ [st1'] |
---|
356 | | taa_step st1' st2' st3' _ tl _ _ ⇒ st1' :: taa_status_list … tl |
---|
357 | ]. |
---|
358 | |
---|
359 | let rec taa_append_taa S st1 st2 st3 (taa1 : trace_any_any S st1 st2) |
---|
360 | on taa1 : trace_any_any S st2 st3 → trace_any_any S st1 st3 ≝ |
---|
361 | match taa1 |
---|
362 | return λst1,st2.λx : trace_any_any S st1 st2. |
---|
363 | trace_any_any S st2 st3 → trace_any_any S st1 st3 |
---|
364 | with |
---|
365 | [ taa_base _ ⇒ λtaa2.taa2 |
---|
366 | | taa_step st1' st2' st3' H tl G K ⇒ λtaa2. |
---|
367 | taa_step … H (taa_append_taa … tl taa2) G K |
---|
368 | ]. |
---|
369 | |
---|
370 | let rec taa_append_tal S st1 fl st2 st3 (taa : trace_any_any S st1 st2) |
---|
371 | on taa : |
---|
372 | trace_any_label S fl st2 st3 → |
---|
373 | trace_any_label S fl st1 st3 ≝ |
---|
374 | match taa |
---|
375 | return λst1,st2.λx : trace_any_any S st1 st2. |
---|
376 | trace_any_label S fl st2 st3 → trace_any_label S fl st1 st3 |
---|
377 | with |
---|
378 | [ taa_base _ ⇒ λtaa2.taa2 |
---|
379 | | taa_step st1' st2' st3' H tl G K ⇒ λtaa2. |
---|
380 | tal_step_default … H (taa_append_tal … tl taa2) G K |
---|
381 | ]. |
---|
382 | |
---|
383 | let rec tlr_rel S1 st1 st1' S2 st2 st2' |
---|
384 | (tlr1 : trace_label_return S1 st1 st1') |
---|
385 | (tlr2 : trace_label_return S2 st2 st2') on tlr1 : Prop ≝ |
---|
386 | match tlr1 with |
---|
387 | [ tlr_base st1 st1' tll1 ⇒ |
---|
388 | match tlr2 with |
---|
389 | [ tlr_base st2 st2' tll2 ⇒ tll_rel … tll1 tll2 |
---|
390 | | _ ⇒ False |
---|
391 | ] |
---|
392 | | tlr_step st1 st1' st1'' tll1 tl1 ⇒ |
---|
393 | match tlr2 with |
---|
394 | [ tlr_step st2 st2' st2'' tll2 tl2 ⇒ |
---|
395 | tll_rel … tll1 tll2 ∧ tlr_rel … tl1 tl2 |
---|
396 | | _ ⇒ False |
---|
397 | ] |
---|
398 | ] |
---|
399 | and tll_rel S1 fl1 st1 st1' S2 fl2 st2 st2' |
---|
400 | (tll1 : trace_label_label S1 fl1 st1 st1') |
---|
401 | (tll2 : trace_label_label S2 fl2 st2 st2') on tll1 : Prop ≝ |
---|
402 | match tll1 with |
---|
403 | [ tll_base fl1 st1 st1' tal1 H ⇒ |
---|
404 | match tll2 with |
---|
405 | [ tll_base fl2 st2 st2 tal2 G ⇒ |
---|
406 | as_label_safe … («?, H») = as_label_safe … («?, G») ∧ |
---|
407 | tal_rel … tal1 tal2 |
---|
408 | ] |
---|
409 | ] |
---|
410 | and tal_rel S1 fl1 st1 st1' S2 fl2 st2 st2' |
---|
411 | (tal1 : trace_any_label S1 fl1 st1 st1') |
---|
412 | (tal2 : trace_any_label S2 fl2 st2 st2') |
---|
413 | on tal1 : Prop ≝ |
---|
414 | match tal1 with |
---|
415 | [ tal_base_not_return st1 st1' _ _ _ ⇒ |
---|
416 | fl2 = doesnt_end_with_ret ∧ |
---|
417 | ∃st2mid,taa,H,G,K. |
---|
418 | tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa |
---|
419 | (tal_base_not_return ? st2mid st2' H G K) |
---|
420 | | tal_base_return st1 st1' _ _ ⇒ |
---|
421 | fl2 = ends_with_ret ∧ |
---|
422 | ∃st2mid,taa,H,G. |
---|
423 | tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa |
---|
424 | (tal_base_return ? st2mid st2' H G) |
---|
425 | | tal_base_call st1 st1' st1'' _ _ _ tlr1 _ ⇒ |
---|
426 | fl2 = doesnt_end_with_ret ∧ |
---|
427 | ∃st2mid,taa,st2mid',H,G,K,tlr2,L. |
---|
428 | tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa |
---|
429 | (tal_base_call ? st2mid st2mid' st2' H G K tlr2 L) ∧ |
---|
430 | tlr_rel … tlr1 tlr2 |
---|
431 | | tal_step_call fl1 st1 st1' st1'' st1''' _ _ _ tlr1 _ tl1 ⇒ |
---|
432 | ∃st2mid,taa,st2_fun,st2_after_fun,H,G,K,tlr2,L,tl2. |
---|
433 | tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa |
---|
434 | (tal_step_call ?? st2mid st2_fun st2_after_fun st2' H G K tlr2 L tl2) ∧ |
---|
435 | tlr_rel … tlr1 tlr2 ∧ tal_rel … tl1 tl2 |
---|
436 | | tal_step_default fl1 st1 st1' st1'' _ tl1 _ _ ⇒ |
---|
437 | tal_rel … tl1 tal2 (* <- this makes it many to many *) |
---|
438 | ]. |
---|
439 | |
---|
440 | interpretation "trace any label rel" 'napart t1 t2 = (tal_rel ???????? t1 t2). |
---|
441 | interpretation "trace label label rel" 'napart t1 t2 = (tll_rel ???????? t1 t2). |
---|
442 | interpretation "trace label return rel" 'napart t1 t2 = (tlr_rel ???????? t1 t2). |
---|
443 | |
---|
444 | |
---|
445 | let rec flatten_trace_label_label |
---|
446 | (S: abstract_status) (trace_ends_flag: trace_ends_with_ret) |
---|
447 | (start_status: S) (final_status: S) |
---|
448 | (the_trace: trace_label_label S trace_ends_flag start_status final_status) |
---|
449 | on the_trace: list (Σl: costlabel. ∃pc. as_label_of_pc S pc = Some … l) ≝ |
---|
450 | match the_trace with |
---|
451 | [ tll_base ends_flag initial final given_trace labelled_proof ⇒ |
---|
452 | let label ≝ |
---|
453 | match as_label … initial return λx: option costlabel. x ≠ None costlabel → ? with |
---|
454 | [ None ⇒ λabs. ⊥ |
---|
455 | | Some l ⇒ λ_. l |
---|
456 | ] labelled_proof |
---|
457 | in |
---|
458 | (mk_Sig … label ?)::flatten_trace_any_label S ends_flag initial final given_trace |
---|
459 | ] |
---|
460 | and flatten_trace_any_label |
---|
461 | (S: abstract_status) (trace_ends_flag: trace_ends_with_ret) |
---|
462 | (start_status: S) (final_status: S) |
---|
463 | (the_trace: trace_any_label S trace_ends_flag start_status final_status) |
---|
464 | on the_trace: list (Σl: costlabel. ∃pc. as_label_of_pc S pc = Some … l) ≝ |
---|
465 | match the_trace with |
---|
466 | [ tal_base_not_return the_status _ _ _ _ ⇒ [ ] |
---|
467 | | tal_base_call pre_fun_call start_fun_call final _ _ _ call_trace _ ⇒ |
---|
468 | flatten_trace_label_return … call_trace |
---|
469 | | tal_base_return the_status _ _ _ ⇒ [ ] |
---|
470 | | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final |
---|
471 | _ _ _ call_trace _ final_trace ⇒ |
---|
472 | let call_cost_trace ≝ flatten_trace_label_return … call_trace in |
---|
473 | let final_cost_trace ≝ flatten_trace_any_label … end_flag … final_trace in |
---|
474 | call_cost_trace @ final_cost_trace |
---|
475 | | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒ |
---|
476 | flatten_trace_any_label … tail_trace |
---|
477 | ] |
---|
478 | and flatten_trace_label_return |
---|
479 | (S: abstract_status) |
---|
480 | (start_status: S) (final_status: S) |
---|
481 | (the_trace: trace_label_return S start_status final_status) |
---|
482 | on the_trace: list (Σl: costlabel. ∃pc. as_label_of_pc S pc = Some … l) ≝ |
---|
483 | match the_trace with |
---|
484 | [ tlr_base before after trace_to_lift ⇒ |
---|
485 | flatten_trace_label_label … trace_to_lift |
---|
486 | | tlr_step initial labelled final labelled_trace ret_trace ⇒ |
---|
487 | let labelled_cost ≝ flatten_trace_label_label … doesnt_end_with_ret … labelled_trace in |
---|
488 | let return_cost ≝ flatten_trace_label_return … ret_trace in |
---|
489 | labelled_cost @ return_cost |
---|
490 | ]. |
---|
491 | [2: |
---|
492 | cases abs -abs #abs @abs % |
---|
493 | |1: |
---|
494 | %{(as_pc_of … initial)} whd in match label; |
---|
495 | change with (as_label ?? = ?) |
---|
496 | generalize in match labelled_proof; whd in ⊢ (% → ?); |
---|
497 | cases (as_label S initial) |
---|
498 | [1: |
---|
499 | #absurd @⊥ cases absurd -absurd #absurd @absurd % |
---|
500 | |2: |
---|
501 | #costlabel normalize nodelta #_ % |
---|
502 | ] |
---|
503 | ] |
---|
504 | qed. |
---|
505 | |
---|
506 | let rec taa_append_tal_same_flatten |
---|
507 | S st1 fl st2 st3 (taa : trace_any_any S st1 st2) on taa : |
---|
508 | ∀tal : trace_any_label S fl st2 st3. |
---|
509 | flatten_trace_any_label … (taa_append_tal … taa tal) = |
---|
510 | flatten_trace_any_label … tal ≝ ?. |
---|
511 | cases taa -st1 -st2 |
---|
512 | [ #st1 #tal % |
---|
513 | | #st_pre #st_init #st2 #H #taa #G #K #tal |
---|
514 | whd in match (taa_append_tal ???????); |
---|
515 | whd in ⊢ (??%?); // |
---|
516 | ] |
---|
517 | qed. |
---|
518 | |
---|
519 | |
---|
520 | let rec tll_rel_to_traces_same_flatten |
---|
521 | (S: abstract_status) (S': abstract_status) |
---|
522 | (trace_ends_flag_l: trace_ends_with_ret) (trace_ends_flag_r: trace_ends_with_ret) |
---|
523 | (start_status_l: S) (final_status_l: S) (start_status_r: S') (final_status_r: S') |
---|
524 | (the_trace_l: trace_label_label S trace_ends_flag_l start_status_l final_status_l) |
---|
525 | (the_trace_r: trace_label_label S' trace_ends_flag_r start_status_r final_status_r) |
---|
526 | on the_trace_l: |
---|
527 | tll_rel … the_trace_l the_trace_r → |
---|
528 | map … (pi1 …) (flatten_trace_label_label … the_trace_l) = |
---|
529 | map … (pi1 …) (flatten_trace_label_label … the_trace_r) ≝ |
---|
530 | match the_trace_l with |
---|
531 | [ tll_base fl1 st1 st1' tal1 H ⇒ |
---|
532 | match the_trace_r with |
---|
533 | [ tll_base fl2 st2 st2 tal2 G ⇒ ? |
---|
534 | ] |
---|
535 | ] |
---|
536 | and tal_rel_to_traces_same_flatten |
---|
537 | (S: abstract_status) (S': abstract_status) (trace_ends_flag_l: trace_ends_with_ret) |
---|
538 | (trace_ends_flag_r: trace_ends_with_ret) |
---|
539 | (start_status_l: S) (final_status_l: S) (start_status_r: S') (final_status_r: S') |
---|
540 | (the_trace_l: trace_any_label S trace_ends_flag_l start_status_l final_status_l) |
---|
541 | (the_trace_r: trace_any_label S' trace_ends_flag_r start_status_r final_status_r) |
---|
542 | on the_trace_l: |
---|
543 | tal_rel … the_trace_l the_trace_r → |
---|
544 | map … (pi1 …) (flatten_trace_any_label … the_trace_l) = |
---|
545 | map … (pi1 …) (flatten_trace_any_label … the_trace_r) ≝ |
---|
546 | match the_trace_l with |
---|
547 | [ tal_base_not_return st1 st1' H G K ⇒ ? |
---|
548 | | tal_base_return st1 st1' H G ⇒ ? |
---|
549 | | tal_base_call st1 st1' st1'' H G K tlr1 L ⇒ ? |
---|
550 | | tal_step_call fl1 st1 st1' st1'' st1''' H G K tlr1 L tl1 ⇒ ? |
---|
551 | | tal_step_default fl1 st1 st1' st1'' H tl1 G K ⇒ ? |
---|
552 | ] |
---|
553 | and tlr_rel_to_traces_same_flatten |
---|
554 | (S: abstract_status) (S': abstract_status) (start_status_l: S) (final_status_l: S) |
---|
555 | (start_status_r: S') (final_status_r: S') |
---|
556 | (the_trace_l: trace_label_return S start_status_l final_status_l) |
---|
557 | (the_trace_r: trace_label_return S' start_status_r final_status_r) |
---|
558 | on the_trace_l: |
---|
559 | tlr_rel … the_trace_l the_trace_r → |
---|
560 | map … (pi1 …) (flatten_trace_label_return … the_trace_l) = |
---|
561 | map … (pi1 …) (flatten_trace_label_return … the_trace_r) ≝ |
---|
562 | match the_trace_l with |
---|
563 | [ tlr_base before after tll_l ⇒ ? |
---|
564 | | tlr_step initial labelled final tll_l tlr_l ⇒ ? |
---|
565 | ]. |
---|
566 | [ * whd in match as_label_safe; normalize nodelta |
---|
567 | @opt_safe_elim #l1 #EQ1 |
---|
568 | @opt_safe_elim #l2 #EQ2 |
---|
569 | #EQ destruct(EQ) #H_tal |
---|
570 | change with (? :: ? = ? :: ?) lapply H -H lapply G -G |
---|
571 | whd in match as_costed; normalize nodelta |
---|
572 | >EQ1 >EQ2 normalize nodelta #_ #_ |
---|
573 | >(tal_rel_to_traces_same_flatten … H_tal) @refl |
---|
574 | |2,3,4,5,6: |
---|
575 | [1,2,3: * #EQ destruct(EQ)] |
---|
576 | [1,2,3,4: * #st_mid * #taa |
---|
577 | [ *#H' *#G' *#K' #EQ |
---|
578 | | *#H' *#G' #EQ |
---|
579 | | *#st_mid' *#H' *#G' *#K' *#tlr2 *#L' * #EQ #H_tlr |
---|
580 | | *#st_fun *#st_after *#H' *#G' *#K' *#tlr2 *#L' *#tl2 ** #EQ #H_tlr #H_tal |
---|
581 | ] >EQ >taa_append_tal_same_flatten |
---|
582 | | whd in ⊢ (%→??(????%)?); |
---|
583 | @tal_rel_to_traces_same_flatten |
---|
584 | ] |
---|
585 | [1,2: % |
---|
586 | | @(tlr_rel_to_traces_same_flatten … H_tlr) |
---|
587 | | <map_append |
---|
588 | >(tlr_rel_to_traces_same_flatten … H_tlr) |
---|
589 | >(tal_rel_to_traces_same_flatten … H_tal) |
---|
590 | @map_append |
---|
591 | ] |
---|
592 | |*: cases the_trace_r |
---|
593 | [1,3: #st_before_r #st_after_r #tll_r |
---|
594 | [ @tll_rel_to_traces_same_flatten | * ] |
---|
595 | |*: #st_init_r #st_labld_r #st_fin_r #tll_r #tlr_r * |
---|
596 | #H_tll #H_tlr |
---|
597 | <map_append |
---|
598 | >(tll_rel_to_traces_same_flatten … H_tll) |
---|
599 | >(tlr_rel_to_traces_same_flatten … H_tlr) |
---|
600 | @map_append |
---|
601 | ] |
---|
602 | ] |
---|
603 | qed. |
---|
604 | |
---|
605 | definition as_cost_map ≝ |
---|
606 | λS : abstract_status. (Σl.∃pc.as_label_of_pc S pc = Some ? l) → ℕ. |
---|
607 | |
---|
608 | definition lift_cost_map_id : |
---|
609 | ∀S_in, S_out: abstract_status. |
---|
610 | (∀l. (∃pc.as_label_of_pc S_out pc = Some … l) + |
---|
611 | ¬(∃pc.as_label_of_pc S_out pc = Some … l)) → |
---|
612 | (as_cost_map S_out) → as_cost_map S_in ≝ λS_in,S_out,dec,m,l_sig. |
---|
613 | match dec l_sig with |
---|
614 | [ inl prf ⇒ m «l_sig, prf» |
---|
615 | | inr _ ⇒ 0 (* labels not present in out code get 0 *) |
---|
616 | ]. |
---|
617 | |
---|
618 | lemma lift_cost_map_id_eq : |
---|
619 | ∀S_in, S_out, dec, m, l_in, l_out. |
---|
620 | pi1 ?? l_in = pi1 ?? l_out → lift_cost_map_id S_in S_out dec m l_in = m l_out. |
---|
621 | #S_in #S_out #dec #m #l_in * #l_out #prf #EQ |
---|
622 | whd in match lift_cost_map_id; normalize nodelta |
---|
623 | cases (dec l_in) normalize nodelta >EQ |
---|
624 | [2: #H @⊥] /2 by refl, absurd/ |
---|
625 | qed. |
---|
626 | |
---|
627 | notation > "Σ_{ ident i ∈ l } f" |
---|
628 | with precedence 20 |
---|
629 | for @{'fold plus 0 (λ${ident i}.true) (λ${ident i}. $f) $l}. |
---|
630 | notation < "Σ_{ ident i ∈ l } f" |
---|
631 | with precedence 20 |
---|
632 | for @{'fold plus 0 (λ${ident i}:$X.true) (λ${ident i}:$Y. $f) $l}. |
---|
633 | |
---|
634 | lemma lift_cost_map_same_cost : |
---|
635 | ∀S_in, S_out, dec, m_out, trace_in, trace_out. |
---|
636 | map … (pi1 ??) trace_in = map … (pi1 ??) trace_out → |
---|
637 | (Σ_{ l_sig ∈ trace_in } (lift_cost_map_id S_in S_out dec m_out l_sig)) = |
---|
638 | (Σ_{ l_sig ∈ trace_out } (m_out l_sig)). |
---|
639 | #S_in #S_out #dec #m_out #trace_in elim trace_in |
---|
640 | [2: #hd_in #tl_in #IH] * [2,4: #hd_out #tl_out] |
---|
641 | normalize in ⊢ (%→?); |
---|
642 | [2,3: #ABS destruct(ABS) |
---|
643 | |4: #_ % |
---|
644 | |1: |
---|
645 | #EQ destruct |
---|
646 | whd in ⊢(??%%); |
---|
647 | >(lift_cost_map_id_eq … e0) |
---|
648 | >e0 in e1; normalize in ⊢(%→?); #EQ |
---|
649 | >(IH … EQ) % |
---|
650 | ] |
---|
651 | qed. |
---|
652 | |
---|
653 | lemma lift_cost_map_same_cost_tal : |
---|
654 | ∀S_in, S_out, dec, m_out, f_in, f_out, start_in, start_out, end_in, end_out. |
---|
655 | ∀the_trace_in : trace_any_label S_in f_in start_in end_in. |
---|
656 | ∀the_trace_out : trace_any_label S_out f_out start_out end_out. |
---|
657 | tal_rel … the_trace_in the_trace_out → |
---|
658 | (Σ_{l ∈ flatten_trace_any_label … the_trace_in} |
---|
659 | (lift_cost_map_id … dec m_out l)) = |
---|
660 | (Σ_{l ∈ flatten_trace_any_label … the_trace_out} (m_out l)). |
---|
661 | #S_in #S_out #dec #m_out #f_in #f_out #start_in #start_out #end_in #end_out |
---|
662 | #tal_in #tal_out #H_tal |
---|
663 | @(lift_cost_map_same_cost … (tal_rel_to_traces_same_flatten … H_tal)) |
---|
664 | qed. |
---|
665 | |
---|
666 | lemma lift_cost_map_same_cost_tll : |
---|
667 | ∀S_in, S_out, dec, m_out, f_in, f_out, start_in, start_out, end_in, end_out. |
---|
668 | ∀the_trace_in : trace_label_label S_in f_in start_in end_in. |
---|
669 | ∀the_trace_out : trace_label_label S_out f_out start_out end_out. |
---|
670 | tll_rel … the_trace_in the_trace_out → |
---|
671 | (Σ_{l ∈ flatten_trace_label_label … the_trace_in} |
---|
672 | (lift_cost_map_id … dec m_out l)) = |
---|
673 | (Σ_{l ∈ flatten_trace_label_label … the_trace_out} (m_out l)). |
---|
674 | #S_in #S_out #dec #m_out #f_in #f_out #start_in #start_out #end_in #end_out |
---|
675 | #tll_in #tll_out #H_tll |
---|
676 | @(lift_cost_map_same_cost … (tll_rel_to_traces_same_flatten … H_tll)) |
---|
677 | qed. |
---|
678 | |
---|
679 | lemma lift_cost_map_same_cost_tlr : |
---|
680 | ∀S_in, S_out, dec, m_out, start_in, start_out, end_in, end_out. |
---|
681 | ∀the_trace_in : trace_label_return S_in start_in end_in. |
---|
682 | ∀the_trace_out : trace_label_return S_out start_out end_out. |
---|
683 | tlr_rel … the_trace_in the_trace_out → |
---|
684 | (Σ_{l ∈ flatten_trace_label_return … the_trace_in} |
---|
685 | (lift_cost_map_id … dec m_out l)) = |
---|
686 | (Σ_{l ∈ flatten_trace_label_return … the_trace_out} (m_out l)). |
---|
687 | #S_in #S_out #dec #m_out #start_in #start_out #end_in #end_out |
---|
688 | #tlr_in #tlr_out #H_tlr |
---|
689 | @(lift_cost_map_same_cost … (tlr_rel_to_traces_same_flatten … H_tlr)) |
---|
690 | qed. |
---|