1 | include "basics/bool.ma". |
---|
2 | include "basics/jmeq.ma". |
---|
3 | include "common/CostLabel.ma". |
---|
4 | include "utilities/option.ma". |
---|
5 | include "basics/lists/listb.ma". |
---|
6 | include "common/IO.ma". |
---|
7 | include "utilities/hide.ma". |
---|
8 | include "ASM/Util.ma". |
---|
9 | |
---|
10 | inductive status_class: Type[0] ≝ |
---|
11 | | cl_return: status_class |
---|
12 | | cl_jump: status_class |
---|
13 | | cl_call: status_class |
---|
14 | | cl_tailcall: status_class |
---|
15 | | cl_other: status_class. |
---|
16 | |
---|
17 | record abstract_status : Type[1] ≝ |
---|
18 | { as_status :> Type[0] |
---|
19 | ; as_execute : relation as_status |
---|
20 | ; as_pc : DeqSet |
---|
21 | ; as_pc_of : as_status → as_pc |
---|
22 | ; as_classify : as_status → status_class |
---|
23 | ; as_label_of_pc : as_pc → option costlabel |
---|
24 | ; as_after_return : (Σs:as_status. as_classify s = cl_call) → as_status → Prop |
---|
25 | ; as_result: as_status → option int |
---|
26 | ; as_call_ident : (Σs:as_status.as_classify s = cl_call) → ident |
---|
27 | ; as_tailcall_ident : (Σs:as_status.as_classify s = cl_tailcall) → ident |
---|
28 | }. |
---|
29 | |
---|
30 | definition as_classifier ≝ λS,s,cl.as_classify S s = cl. |
---|
31 | definition as_call ≝ λS,s,f.as_call_ident S s = f. |
---|
32 | definition as_final ≝ λS,s.as_result S s ≠ None ?. |
---|
33 | |
---|
34 | definition as_label ≝ λS : abstract_status. λs : S. as_label_of_pc ? (as_pc_of ? s). |
---|
35 | |
---|
36 | (* temporary alias for backward compatibility *) |
---|
37 | (* definition final_abstract_status ≝ abstract_status. *) |
---|
38 | |
---|
39 | definition as_costed : ∀a_s : abstract_status.a_s → Prop ≝ |
---|
40 | λa_s,st.as_label ? st ≠ None ?. |
---|
41 | |
---|
42 | lemma as_costed_exc : ∀S:abstract_status. ∀s:S. (as_costed S s) + (¬as_costed S s). |
---|
43 | #S #s whd in match (as_costed S s); |
---|
44 | cases (as_label S s) [ %2 % * /2/ | #c %1 % #E destruct ] |
---|
45 | qed. |
---|
46 | |
---|
47 | lemma not_costed_no_label : ∀S,st. |
---|
48 | ¬as_costed S st → |
---|
49 | as_label S st = None ?. |
---|
50 | #S #st * normalize cases (as_label_of_pc S ?) |
---|
51 | [ // | #l #H cases (H ?) % #E destruct ] |
---|
52 | qed. |
---|
53 | |
---|
54 | (* cost map generalities *) |
---|
55 | |
---|
56 | definition as_cost_labelled_at ≝ |
---|
57 | λS : abstract_status. λl.λpc.as_label_of_pc S pc = Some ? l. |
---|
58 | |
---|
59 | definition as_cost_labelled ≝ |
---|
60 | λS : abstract_status. λl.∃pc.as_cost_labelled_at S l pc. |
---|
61 | |
---|
62 | definition as_cost_label ≝ |
---|
63 | λS : abstract_status. Σl.as_cost_labelled S l. |
---|
64 | |
---|
65 | unification hint 0 ≔ S ⊢ as_cost_label S ≡ Sig costlabel (λl.as_cost_labelled S l). |
---|
66 | |
---|
67 | definition as_cost_labels ≝ |
---|
68 | λS : abstract_status. list (as_cost_label S). |
---|
69 | |
---|
70 | (* |
---|
71 | definition as_cost_get_label ≝ |
---|
72 | λS : abstract_status. λl_sig: as_cost_label S. pi1 … l_sig. |
---|
73 | |
---|
74 | (* JHM: this no longer is a complete definition! but not used; so commented out for now *) |
---|
75 | definition as_cost_get_labels ≝ |
---|
76 | λS : abstract_status. map … (as_cost_get_label S). |
---|
77 | *) |
---|
78 | |
---|
79 | definition as_cost_map ≝ |
---|
80 | λS : abstract_status. (as_cost_label S) → ℕ. |
---|
81 | |
---|
82 | definition as_label_safe : ∀a_s : abstract_status. |
---|
83 | (Σs : a_s.as_costed ? s) → as_cost_label a_s ≝ |
---|
84 | λa_s,st_sig.«opt_safe ?? (pi2 … st_sig), ?». |
---|
85 | @hide_prf |
---|
86 | @opt_safe_elim #c #EQ %{EQ} qed. |
---|
87 | |
---|
88 | definition lift_sigma_map_id : |
---|
89 | ∀A,B : Type[0].∀P_in,P_out : A → Prop.B → |
---|
90 | (∀a.P_out a + ¬ P_out a) → |
---|
91 | ((Σa.P_out a) → B) → (Σa.P_in a) → B ≝ λA,B,P_in,P_out,dflt,dec,m,a_sig. |
---|
92 | match dec a_sig with |
---|
93 | [ inl prf ⇒ m «a_sig, prf» |
---|
94 | | inr _ ⇒ dflt (* labels not present in out code get 0 *) |
---|
95 | ]. |
---|
96 | |
---|
97 | lemma lift_sigma_map_id_eq : |
---|
98 | ∀A,B,P_in,P_out,dflt,dec,m,a_in,a_out. |
---|
99 | pi1 ?? a_in = pi1 ?? a_out → |
---|
100 | lift_sigma_map_id A B P_in P_out dflt dec m a_in = m a_out. |
---|
101 | #A#B#P_in#P_out#dflt#dec#m#a_in#a_out#EQ |
---|
102 | whd in match lift_sigma_map_id; normalize nodelta |
---|
103 | cases (dec a_in) normalize nodelta >EQ cases a_out |
---|
104 | #a #H #G [ % | @⊥ /2 by absurd/ ] |
---|
105 | qed. |
---|
106 | |
---|
107 | notation > "Σ_{ ident i ∈ l } f" |
---|
108 | with precedence 20 |
---|
109 | for @{'fold plus 0 (λ${ident i}.true) (λ${ident i}. $f) $l}. |
---|
110 | notation < "Σ_{ ident i ∈ l } f" |
---|
111 | with precedence 20 |
---|
112 | for @{'fold plus 0 (λ${ident i}:$X.true) (λ${ident i}:$Y. $f) $l}. |
---|
113 | |
---|
114 | definition lift_cost_map_id : |
---|
115 | ∀S_in,S_out : abstract_status.? → |
---|
116 | as_cost_map S_out → as_cost_map S_in |
---|
117 | ≝ |
---|
118 | λS_in,S_out : abstract_status. |
---|
119 | lift_sigma_map_id costlabel ℕ |
---|
120 | (*λl.∃pc.as_label_of_pc S_in pc = Some ? l*) (as_cost_labelled S_in) |
---|
121 | (*λl.∃pc.as_label_of_pc S_out pc = Some ? l*) (as_cost_labelled S_out) |
---|
122 | 0. |
---|
123 | |
---|
124 | lemma lift_cost_map_same_cost : |
---|
125 | ∀S_in, S_out, dec, m_out, trace_in, trace_out. |
---|
126 | map … (pi1 ??) trace_in = map … (pi1 ??) trace_out → |
---|
127 | (Σ_{ l_sig ∈ trace_in } (lift_cost_map_id S_in S_out dec m_out l_sig)) = |
---|
128 | (Σ_{ l_sig ∈ trace_out } (m_out l_sig)). |
---|
129 | #S_in #S_out #dec #m_out #trace_in elim trace_in |
---|
130 | [2: #hd_in #tl_in #IH] * [2,4: #hd_out #tl_out] |
---|
131 | normalize in ⊢ (%→?); |
---|
132 | [2,3: #ABS destruct(ABS) |
---|
133 | |4: #_ % |
---|
134 | |1: |
---|
135 | #EQ destruct |
---|
136 | whd in ⊢(??%%); |
---|
137 | whd in match lift_cost_map_id; normalize nodelta |
---|
138 | >(lift_sigma_map_id_eq ????????? e0) |
---|
139 | >e0 in e1; normalize in ⊢(%→?); #EQ |
---|
140 | >(IH … EQ) % |
---|
141 | ] |
---|
142 | qed. |
---|
143 | |
---|
144 | |
---|
145 | (* structured traces: down to business *) |
---|
146 | |
---|
147 | inductive trace_ends_with_ret: Type[0] ≝ |
---|
148 | | ends_with_ret: trace_ends_with_ret |
---|
149 | | doesnt_end_with_ret: trace_ends_with_ret. |
---|
150 | |
---|
151 | inductive trace_label_return (S:abstract_status) : S → S → Type[0] ≝ |
---|
152 | | tlr_base: |
---|
153 | ∀status_before: S. |
---|
154 | ∀status_after: S. |
---|
155 | trace_label_label S ends_with_ret status_before status_after → |
---|
156 | trace_label_return S status_before status_after |
---|
157 | | tlr_step: |
---|
158 | ∀status_initial: S. |
---|
159 | ∀status_labelled: S. |
---|
160 | ∀status_final: S. |
---|
161 | trace_label_label S doesnt_end_with_ret status_initial status_labelled → |
---|
162 | trace_label_return S status_labelled status_final → |
---|
163 | trace_label_return S status_initial status_final |
---|
164 | with trace_label_label: trace_ends_with_ret → S → S → Type[0] ≝ |
---|
165 | | tll_base: |
---|
166 | ∀ends_flag: trace_ends_with_ret. |
---|
167 | ∀start_status: S. |
---|
168 | ∀end_status: S. |
---|
169 | trace_any_label S ends_flag start_status end_status → |
---|
170 | as_costed S start_status → |
---|
171 | trace_label_label S ends_flag start_status end_status |
---|
172 | with trace_any_label: trace_ends_with_ret → S → S → Type[0] ≝ |
---|
173 | (* Single steps within a function which reach a label. |
---|
174 | Note that this is the only case applicable for a jump. *) |
---|
175 | | tal_base_not_return: |
---|
176 | ∀start_status: S. |
---|
177 | ∀final_status: S. |
---|
178 | as_execute S start_status final_status → |
---|
179 | (as_classifier S start_status cl_jump ∨ |
---|
180 | as_classifier S start_status cl_other) → |
---|
181 | as_costed S final_status → |
---|
182 | trace_any_label S doesnt_end_with_ret start_status final_status |
---|
183 | | tal_base_return: |
---|
184 | ∀start_status: S. |
---|
185 | ∀final_status: S. |
---|
186 | as_execute S start_status final_status → |
---|
187 | as_classifier S start_status cl_return → |
---|
188 | trace_any_label S ends_with_ret start_status final_status |
---|
189 | (* A call followed by a label on return. *) |
---|
190 | | tal_base_call: |
---|
191 | ∀status_pre_fun_call: S. |
---|
192 | ∀status_start_fun_call: S. |
---|
193 | ∀status_final: S. |
---|
194 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
195 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
196 | as_after_return S «status_pre_fun_call, H» status_final → |
---|
197 | trace_label_return S status_start_fun_call status_final → |
---|
198 | as_costed S status_final → |
---|
199 | trace_any_label S doesnt_end_with_ret status_pre_fun_call status_final |
---|
200 | (* A tailcall, which ends the trace like a return. *) |
---|
201 | | tal_base_tailcall: |
---|
202 | ∀status_pre_fun_call: S. |
---|
203 | ∀status_start_fun_call: S. |
---|
204 | ∀status_final: S. |
---|
205 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
206 | as_classifier S status_pre_fun_call cl_tailcall → |
---|
207 | trace_label_return S status_start_fun_call status_final → |
---|
208 | trace_any_label S ends_with_ret status_pre_fun_call status_final |
---|
209 | (* A call followed by a non-empty trace. *) |
---|
210 | | tal_step_call: |
---|
211 | ∀end_flag: trace_ends_with_ret. |
---|
212 | ∀status_pre_fun_call: S. |
---|
213 | ∀status_start_fun_call: S. |
---|
214 | ∀status_after_fun_call: S. |
---|
215 | ∀status_final: S. |
---|
216 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
217 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
218 | as_after_return S «status_pre_fun_call, H» status_after_fun_call → |
---|
219 | trace_label_return S status_start_fun_call status_after_fun_call → |
---|
220 | ¬ as_costed S status_after_fun_call → |
---|
221 | trace_any_label S end_flag status_after_fun_call status_final → |
---|
222 | trace_any_label S end_flag status_pre_fun_call status_final |
---|
223 | | tal_step_default: |
---|
224 | ∀end_flag: trace_ends_with_ret. |
---|
225 | ∀status_pre: S. |
---|
226 | ∀status_init: S. |
---|
227 | ∀status_end: S. |
---|
228 | as_execute S status_pre status_init → |
---|
229 | trace_any_label S end_flag status_init status_end → |
---|
230 | as_classifier S status_pre cl_other → |
---|
231 | ¬ (as_costed S status_init) → |
---|
232 | trace_any_label S end_flag status_pre status_end. |
---|
233 | |
---|
234 | let rec tal_pc_list (S : abstract_status) fl st1 st2 (tal : trace_any_label S fl st1 st2) |
---|
235 | on tal : list (as_pc S) ≝ |
---|
236 | match tal with |
---|
237 | [ tal_step_call fl' pre _ st1' st2' _ _ _ _ _ tl ⇒ as_pc_of … pre :: tal_pc_list … tl |
---|
238 | | tal_step_default fl' pre st1' st2' _ tl _ _ ⇒ as_pc_of … pre :: tal_pc_list … tl |
---|
239 | | tal_base_not_return pre _ _ _ _ ⇒ [as_pc_of … pre] |
---|
240 | | tal_base_return pre _ _ _ ⇒ [as_pc_of … pre] |
---|
241 | | tal_base_call pre _ _ _ _ _ _ _ ⇒ [as_pc_of … pre] |
---|
242 | | tal_base_tailcall pre _ _ _ _ _ ⇒ [as_pc_of … pre] |
---|
243 | ]. |
---|
244 | |
---|
245 | definition as_trace_any_label_length': |
---|
246 | ∀S: abstract_status. |
---|
247 | ∀trace_ends_flag: trace_ends_with_ret. |
---|
248 | ∀start_status: S. |
---|
249 | ∀final_status: S. |
---|
250 | ∀the_trace: trace_any_label S trace_ends_flag start_status final_status. |
---|
251 | nat ≝ |
---|
252 | λS: abstract_status. |
---|
253 | λtrace_ends_flag: trace_ends_with_ret. |
---|
254 | λstart_status: S. |
---|
255 | λfinal_status: S. |
---|
256 | λthe_trace: trace_any_label S trace_ends_flag start_status final_status. |
---|
257 | |tal_pc_list … the_trace|. |
---|
258 | |
---|
259 | let rec tlr_unrepeating S st1 st2 (tlr : trace_label_return S st1 st2) on tlr : Prop ≝ |
---|
260 | match tlr with |
---|
261 | [ tlr_base st1 st2 tll ⇒ tll_unrepeating … tll |
---|
262 | | tlr_step st1 st2 st3 tll tl ⇒ tll_unrepeating … tll ∧ tlr_unrepeating … tl |
---|
263 | ] |
---|
264 | and tll_unrepeating S fl st1 st2 (tll : trace_label_label S fl st1 st2) on tll : Prop ≝ |
---|
265 | match tll with |
---|
266 | [ tll_base fl st1 st2 tal _ ⇒ tal_unrepeating … tal |
---|
267 | ] |
---|
268 | and tal_unrepeating S fl st1 st2 (tal : trace_any_label S fl st1 st2) on tal : Prop ≝ |
---|
269 | match tal with |
---|
270 | [ tal_step_call fl st1 st2 st3 st4 _ _ _ tlr _ tl ⇒ |
---|
271 | bool_to_Prop (notb (memb ? (as_pc_of … st1) (tal_pc_list … tl))) ∧ |
---|
272 | tal_unrepeating … tl ∧ |
---|
273 | tlr_unrepeating … tlr |
---|
274 | | tal_step_default fl st1 st2 st3 _ tl _ _ ⇒ |
---|
275 | bool_to_Prop (notb (memb ? (as_pc_of … st1) (tal_pc_list … tl))) ∧ |
---|
276 | tal_unrepeating … tl |
---|
277 | | tal_base_call pre _ _ _ _ _ trace _ ⇒ tlr_unrepeating … trace |
---|
278 | | tal_base_tailcall pre _ _ _ _ trace ⇒ tlr_unrepeating … trace |
---|
279 | | _ ⇒ True |
---|
280 | ]. |
---|
281 | |
---|
282 | definition tll_hd_label : ∀S : abstract_status.∀fl,st1,st2. |
---|
283 | trace_label_label S fl st1 st2 → costlabel ≝ |
---|
284 | λS,fl,st1,st2,tr.match tr with |
---|
285 | [ tll_base _ st1' _ _ prf ⇒ as_label_safe … «st1', prf» ]. |
---|
286 | |
---|
287 | definition tlr_hd_label : ∀S : abstract_status.∀st1,st2. |
---|
288 | trace_label_return S st1 st2 → costlabel ≝ |
---|
289 | λS,st1,st2,tr.match tr with |
---|
290 | [ tlr_base st1' st2' tll ⇒ tll_hd_label … tll |
---|
291 | | tlr_step st1' st2' _ tll _ ⇒ tll_hd_label … tll |
---|
292 | ]. |
---|
293 | |
---|
294 | let rec tal_unrepeating_uniqueb S fl st1 st2 tal on tal : |
---|
295 | tal_unrepeating S fl st1 st2 tal → bool_to_Prop (uniqueb … (tal_pc_list … tal)) ≝ ?. |
---|
296 | cases tal // |
---|
297 | #fl' #st1' [#st_fun] #st2' #st3' #H |
---|
298 | [ #H0 #H1 #tlr #G #tal | #tal #H0 #G ] whd in ⊢ (% → ?%); [*]* |
---|
299 | #A #B [#_] >A normalize nodelta @tal_unrepeating_uniqueb assumption |
---|
300 | qed. |
---|
301 | |
---|
302 | lemma tal_pc_list_start : ∀S,fl,s1,s2. ∀tal: trace_any_label S fl s1 s2. |
---|
303 | ∃tl. tal_pc_list … tal = (as_pc_of S s1)::tl. |
---|
304 | #S #fl0 #s10 #s20 * |
---|
305 | [ #s1 #s2 #EX #CL #CS |
---|
306 | | #s1 #s2 #EX #CL |
---|
307 | | #s1 #s2 #s3 #EX #CL #AF #tlr #CS |
---|
308 | | #s1 #s2 #s3 #EX #CL #tlr |
---|
309 | | #fl #s1 #s2 #s3 #s4 #EX #CL #AF #tlr #CS #tal |
---|
310 | | #fl #s1 #s2 #s3 #EX #tal #CL #CS |
---|
311 | ] whd in ⊢ (??(λ_.??%?)); % [2,4,6,8,10,12: % | *: skip ] |
---|
312 | qed. |
---|
313 | |
---|
314 | let rec tal_tail_not_costed S fl st1 st2 tal |
---|
315 | (H:Not (as_costed S st1)) on tal : |
---|
316 | All ? (λpc. as_label_of_pc S pc = None ?) (tal_pc_list S fl st1 st2 tal) ≝ ?. |
---|
317 | cases tal in H ⊢ %; |
---|
318 | [ #start #final #EX #CL #CS #CS' % // @(not_costed_no_label ?? CS') |
---|
319 | | #start #final #EX #CL #CS % // @(not_costed_no_label ?? CS) |
---|
320 | | #pre #start #final #EX #CL #AF #tlr #CS #CS' % // @(not_costed_no_label ?? CS') |
---|
321 | | #pre #start #final #EX #CL #tlr #CS' % // @(not_costed_no_label ?? CS') |
---|
322 | | #fl' #pre #start #after #final #EX #CL #AF #tlr #CS #tal' #CS' |
---|
323 | cases (tal_pc_list_start … tal') |
---|
324 | #hd #E >E |
---|
325 | % [ @(not_costed_no_label ?? CS') | @tal_tail_not_costed assumption ] |
---|
326 | | #fl' #pre #init #end #EX #tal' #CL #CS #CS' |
---|
327 | cases (tal_pc_list_start … tal') |
---|
328 | #hd #E >E |
---|
329 | % [ @(not_costed_no_label ?? CS') | @tal_tail_not_costed assumption ] |
---|
330 | ] qed. |
---|
331 | |
---|
332 | |
---|
333 | inductive trace_any_call (S:abstract_status) : S → S → Type[0] ≝ |
---|
334 | | tac_base: |
---|
335 | ∀status: S. |
---|
336 | as_classifier S status cl_call ∨ as_classifier S status cl_tailcall → |
---|
337 | trace_any_call S status status |
---|
338 | | tac_step_call: |
---|
339 | ∀status_pre_fun_call: S. |
---|
340 | ∀status_after_fun_call: S. |
---|
341 | ∀status_final: S. |
---|
342 | ∀status_start_fun_call: S. |
---|
343 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
344 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
345 | as_after_return S (mk_Sig ?? status_pre_fun_call H) status_after_fun_call → |
---|
346 | trace_label_return S status_start_fun_call status_after_fun_call → |
---|
347 | ¬ as_costed S status_after_fun_call → |
---|
348 | trace_any_call S status_after_fun_call status_final → |
---|
349 | trace_any_call S status_pre_fun_call status_final |
---|
350 | | tac_step_default: |
---|
351 | ∀status_pre: S. |
---|
352 | ∀status_end: S. |
---|
353 | ∀status_init: S. |
---|
354 | as_execute S status_pre status_init → |
---|
355 | trace_any_call S status_init status_end → |
---|
356 | as_classifier S status_pre cl_other → |
---|
357 | ¬ (as_costed S status_init) → |
---|
358 | trace_any_call S status_pre status_end. |
---|
359 | |
---|
360 | |
---|
361 | inductive trace_label_call (S:abstract_status) : S → S → Type[0] ≝ |
---|
362 | | tlc_base: |
---|
363 | ∀start_status: S. |
---|
364 | ∀end_status: S. |
---|
365 | trace_any_call S start_status end_status → |
---|
366 | as_costed S start_status → |
---|
367 | trace_label_call S start_status end_status |
---|
368 | . |
---|
369 | |
---|
370 | definition tlc_hd_label : ∀S : abstract_status.∀st1,st2. |
---|
371 | trace_label_call S st1 st2 → costlabel ≝ |
---|
372 | λS,st1,st2,tr.match tr with |
---|
373 | [ tlc_base st1' _ _ prf ⇒ as_label_safe … «st1', prf» |
---|
374 | ]. |
---|
375 | |
---|
376 | coinductive trace_label_diverges (S:abstract_status) : S → Type[0] ≝ |
---|
377 | | tld_step: |
---|
378 | ∀status_initial: S. |
---|
379 | ∀status_labelled: S. |
---|
380 | trace_label_label S doesnt_end_with_ret status_initial status_labelled → |
---|
381 | trace_label_diverges S status_labelled → |
---|
382 | trace_label_diverges S status_initial |
---|
383 | | tld_base: |
---|
384 | ∀status_initial: S. |
---|
385 | ∀status_pre_fun_call: S. |
---|
386 | ∀status_start_fun_call: S. |
---|
387 | trace_label_call S status_initial status_pre_fun_call → |
---|
388 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
389 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
390 | trace_label_diverges S status_start_fun_call → |
---|
391 | trace_label_diverges S status_initial. |
---|
392 | |
---|
393 | definition tld_hd_label : ∀S : abstract_status.∀st. |
---|
394 | trace_label_diverges S st → costlabel ≝ |
---|
395 | λS,st,tr.match tr with |
---|
396 | [ tld_step st' st'' tll _ ⇒ tll_hd_label … tll |
---|
397 | | tld_base st' st'' _ tlc _ _ _ ⇒ tlc_hd_label … tlc |
---|
398 | ]. |
---|
399 | |
---|
400 | (* Version in Prop for showing existence. *) |
---|
401 | coinductive trace_label_diverges_exists (S:abstract_status) : S → Prop ≝ |
---|
402 | | tld_step': |
---|
403 | ∀status_initial: S. |
---|
404 | ∀status_labelled: S. |
---|
405 | trace_label_label S doesnt_end_with_ret status_initial status_labelled → |
---|
406 | trace_label_diverges_exists S status_labelled → |
---|
407 | trace_label_diverges_exists S status_initial |
---|
408 | | tld_base': |
---|
409 | ∀status_initial: S. |
---|
410 | ∀status_pre_fun_call: S. |
---|
411 | ∀status_start_fun_call: S. |
---|
412 | trace_label_call S status_initial status_pre_fun_call → |
---|
413 | as_execute S status_pre_fun_call status_start_fun_call → |
---|
414 | ∀H:as_classifier S status_pre_fun_call cl_call. |
---|
415 | trace_label_diverges_exists S status_start_fun_call → |
---|
416 | trace_label_diverges_exists S status_initial. |
---|
417 | |
---|
418 | inductive trace_whole_program (S: abstract_status) : S → Type[0] ≝ |
---|
419 | | twp_terminating: |
---|
420 | ∀status_initial: S. |
---|
421 | ∀status_start_fun: S. |
---|
422 | ∀status_final: S. |
---|
423 | as_classifier S status_initial cl_call → |
---|
424 | as_execute S status_initial status_start_fun → |
---|
425 | trace_label_return S status_start_fun status_final → |
---|
426 | as_final S status_final → |
---|
427 | trace_whole_program S status_initial |
---|
428 | | twp_diverges: |
---|
429 | ∀status_initial: S. |
---|
430 | ∀status_start_fun: S. |
---|
431 | as_classifier S status_initial cl_call → |
---|
432 | as_execute S status_initial status_start_fun → |
---|
433 | trace_label_diverges S status_start_fun → |
---|
434 | trace_whole_program S status_initial. |
---|
435 | |
---|
436 | (* Again, an identical version in Prop for existence proofs. *) |
---|
437 | inductive trace_whole_program_exists (S: abstract_status) : S → Prop ≝ |
---|
438 | | twp_terminating: |
---|
439 | ∀status_initial: S. |
---|
440 | ∀status_start_fun: S. |
---|
441 | ∀status_final: S. |
---|
442 | as_classifier S status_initial cl_call → |
---|
443 | as_execute S status_initial status_start_fun → |
---|
444 | trace_label_return S status_start_fun status_final → |
---|
445 | as_final S status_final → |
---|
446 | trace_whole_program_exists S status_initial |
---|
447 | | twp_diverges: |
---|
448 | ∀status_initial: S. |
---|
449 | ∀status_start_fun: S. |
---|
450 | as_classifier S status_initial cl_call → |
---|
451 | as_execute S status_initial status_start_fun → |
---|
452 | trace_label_diverges_exists S status_start_fun → |
---|
453 | trace_whole_program_exists S status_initial. |
---|
454 | |
---|
455 | |
---|
456 | let rec trace_any_label_label S s s' f |
---|
457 | (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 ] ≝ |
---|
458 | match tr return λf,s,s',tr. match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ] with |
---|
459 | [ tal_base_not_return start final _ _ C ⇒ C |
---|
460 | | tal_base_return _ _ _ _ ⇒ I |
---|
461 | | tal_base_call _ _ _ _ _ _ _ C ⇒ C |
---|
462 | | tal_base_tailcall _ _ _ _ _ _ ⇒ I |
---|
463 | | tal_step_call f pre start after final X C RET LR C' tr' ⇒ trace_any_label_label … tr' |
---|
464 | | tal_step_default f pre init end X tr' C C' ⇒ trace_any_label_label … tr' |
---|
465 | ]. |
---|
466 | |
---|
467 | definition tal_tl_label : ∀S : abstract_status.∀st1,st2. |
---|
468 | trace_any_label S doesnt_end_with_ret st1 st2 → costlabel ≝ |
---|
469 | λS,st1,st2,tr.as_label_safe … «st2, trace_any_label_label … tr». |
---|
470 | |
---|
471 | lemma trace_label_label_label : ∀S,s,s',f. |
---|
472 | ∀tr:trace_label_label S f s s'. match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ]. |
---|
473 | #S #s #s' #f #tr |
---|
474 | cases tr |
---|
475 | #f #start #end #tr' #C @(trace_any_label_label … tr') |
---|
476 | qed. |
---|
477 | |
---|
478 | definition tll_tl_label : ∀S : abstract_status.∀st1,st2. |
---|
479 | trace_label_label S doesnt_end_with_ret st1 st2 → costlabel ≝ |
---|
480 | λS,st1,st2,tr.as_label_safe … «st2, trace_label_label_label … tr». |
---|
481 | |
---|
482 | lemma trace_any_call_call : ∀S,s,s'. |
---|
483 | trace_any_call S s s' → as_classifier S s' cl_call ∨ as_classifier S s' cl_tailcall. |
---|
484 | #S #s #s' #T elim T [1,3: //] |
---|
485 | #H73 #H74 #H75 #H76 #H77 #H78 #H79 #H80 #H81 #H82 #H83 // |
---|
486 | qed. |
---|
487 | |
---|
488 | (* |
---|
489 | (* an trace of unlabeled and cl_other states, possibly empty *) |
---|
490 | inductive trace_no_label_any (S:abstract_status) : S → S → Type[0] ≝ |
---|
491 | | tna_base : |
---|
492 | ∀start_status: S. |
---|
493 | ¬as_costed … start_status → |
---|
494 | trace_no_label_any S start_status start_status |
---|
495 | | tna_step : |
---|
496 | ∀status_pre: S. |
---|
497 | ∀status_init: S. |
---|
498 | ∀status_end: S. |
---|
499 | as_execute S status_pre status_init → |
---|
500 | as_classifier S status_pre cl_other → |
---|
501 | ¬as_costed … status_pre → |
---|
502 | trace_no_label_any S status_init status_end → |
---|
503 | trace_no_label_any S status_pre status_end. |
---|
504 | |
---|
505 | let rec tna_append_tna S st1 st2 st3 (taa1 : trace_no_label_any S st1 st2) |
---|
506 | on taa1 : |
---|
507 | trace_no_label_any S st2 st3 → |
---|
508 | trace_no_label_any S st1 st3 ≝ |
---|
509 | match taa1 with |
---|
510 | [ tna_base st1' H ⇒ λtaa2.taa2 |
---|
511 | | tna_step st1' st2' st3' H G K tl ⇒ |
---|
512 | λtaa2.tna_step ???? H G K (tna_append_tna … tl taa2) |
---|
513 | ]. |
---|
514 | |
---|
515 | definition tna_non_empty ≝ λS,st1,st2.λtna : trace_no_label_any S st1 st2. |
---|
516 | match tna with |
---|
517 | [ tna_base _ _ ⇒ false |
---|
518 | | tna_step _ _ _ _ _ _ _ ⇒ true |
---|
519 | ]. |
---|
520 | |
---|
521 | coercion tna_to_bool : ∀S,st1,st2.∀tna:trace_no_label_any S st1 st2.bool ≝ |
---|
522 | tna_non_empty on _tna : trace_no_label_any ??? to bool. |
---|
523 | |
---|
524 | lemma tna_unlabelled : ∀S,st1,st2.trace_no_label_any S st1 st2 → ¬as_costed … st1. |
---|
525 | #S #st1 #st2 * [#st #H @H | #st #st' #st'' #_ #_ #H #_ @H] qed. |
---|
526 | |
---|
527 | let rec tna_append_tal S st1 fl st2 st3 (tna : trace_no_label_any S st1 st2) |
---|
528 | on tna : |
---|
529 | trace_any_label S fl st2 st3 → |
---|
530 | if tna then Not (as_costed … st2) else True → |
---|
531 | trace_any_label S fl st1 st3 ≝ |
---|
532 | match tna return λst1,st2.λx : trace_no_label_any S st1 st2. |
---|
533 | ∀fl,st3. |
---|
534 | trace_any_label S fl st2 st3 → |
---|
535 | if x then Not (as_costed … st2) else True → |
---|
536 | trace_any_label S fl st1 st3 |
---|
537 | with |
---|
538 | [ tna_base st1' H ⇒ λfl,st3,taa2,prf.taa2 |
---|
539 | | tna_step st1' st2' st3' H G K tl ⇒ λfl,st3,taa2,prf. |
---|
540 | tal_step_default ????? H (tna_append_tal ????? tl taa2 ?) G (tna_unlabelled … tl) |
---|
541 | ] fl st3. |
---|
542 | cases (tna_non_empty … tl) [@prf|%] |
---|
543 | qed. |
---|
544 | *) |
---|
545 | |
---|
546 | inductive trace_any_any (S : abstract_status) : S → S → Type[0] ≝ |
---|
547 | | taa_base : ∀st.trace_any_any S st st |
---|
548 | | taa_step : ∀st1,st2,st3. |
---|
549 | as_execute S st1 st2 → |
---|
550 | as_classifier S st1 cl_other → |
---|
551 | ¬as_costed S st2 → |
---|
552 | trace_any_any S st2 st3 → |
---|
553 | trace_any_any S st1 st3. |
---|
554 | |
---|
555 | definition taa_non_empty ≝ λS,st1,st2.λtaa : trace_any_any S st1 st2. |
---|
556 | match taa with |
---|
557 | [ taa_base _ ⇒ false |
---|
558 | | taa_step _ _ _ _ _ _ _ ⇒ true |
---|
559 | ]. |
---|
560 | |
---|
561 | coercion taa_to_bool : ∀S,st1,st2.∀taa:trace_any_any S st1 st2.bool ≝ |
---|
562 | taa_non_empty on _taa : trace_any_any ??? to bool. |
---|
563 | |
---|
564 | let rec taa_append_tal S st1 fl st2 st3 |
---|
565 | (taa : trace_any_any S st1 st2) on taa : |
---|
566 | trace_any_label S fl st2 st3 → |
---|
567 | trace_any_label S fl st1 st3 ≝ |
---|
568 | match taa return λst1,st2.λx : trace_any_any S st1 st2. |
---|
569 | ∀fl,st3. |
---|
570 | trace_any_label S fl st2 st3 → |
---|
571 | trace_any_label S fl st1 st3 |
---|
572 | with |
---|
573 | [ taa_base st1' ⇒ λfl,st3,tal2.tal2 |
---|
574 | | taa_step st1' st2' st3' H G K tl ⇒ λfl,st3,tal2. |
---|
575 | tal_step_default ????? H (taa_append_tal ????? tl tal2) G K |
---|
576 | ] fl st3. |
---|
577 | |
---|
578 | interpretation "trace any any label append" 'append taa tal = (taa_append_tal ????? taa tal). |
---|
579 | |
---|
580 | let rec tal_collapsable S fl s1 s2 (tal : trace_any_label S fl s1 s2) on tal : Prop ≝ |
---|
581 | match tal with |
---|
582 | [ tal_base_not_return _ _ _ _ _ ⇒ True |
---|
583 | | tal_step_default fl1 _ st1' st1'' _ tl1 _ _ ⇒ tal_collapsable … tl1 |
---|
584 | | _ ⇒ False |
---|
585 | ]. |
---|
586 | |
---|
587 | let rec tlr_rel S1 st1 st1' S2 st2 st2' |
---|
588 | (tlr1 : trace_label_return S1 st1 st1') |
---|
589 | (tlr2 : trace_label_return S2 st2 st2') on tlr1 : Prop ≝ |
---|
590 | match tlr1 with |
---|
591 | [ tlr_base st1 st1' tll1 ⇒ |
---|
592 | match tlr2 with |
---|
593 | [ tlr_base st2 st2' tll2 ⇒ tll_rel … tll1 tll2 |
---|
594 | | _ ⇒ False |
---|
595 | ] |
---|
596 | | tlr_step st1 st1' st1'' tll1 tl1 ⇒ |
---|
597 | match tlr2 with |
---|
598 | [ tlr_step st2 st2' st2'' tll2 tl2 ⇒ |
---|
599 | tll_rel … tll1 tll2 ∧ tlr_rel … tl1 tl2 |
---|
600 | | _ ⇒ False |
---|
601 | ] |
---|
602 | ] |
---|
603 | and tll_rel S1 fl1 st1 st1' S2 fl2 st2 st2' |
---|
604 | (tll1 : trace_label_label S1 fl1 st1 st1') |
---|
605 | (tll2 : trace_label_label S2 fl2 st2 st2') on tll1 : Prop ≝ |
---|
606 | match tll1 with |
---|
607 | [ tll_base fl1 st1 st1' tal1 H ⇒ |
---|
608 | match tll2 with |
---|
609 | [ tll_base fl2 st2 st2 tal2 G ⇒ |
---|
610 | pi1 … (as_label_safe … («?, H»)) = pi1 … (as_label_safe … («?, G»)) ∧ |
---|
611 | tal_rel … tal1 tal2 |
---|
612 | ] |
---|
613 | ] |
---|
614 | and tal_rel S1 fl1 st1 st1' S2 fl2 st2 st2' |
---|
615 | (tal1 : trace_any_label S1 fl1 st1 st1') |
---|
616 | (tal2 : trace_any_label S2 fl2 st2 st2') |
---|
617 | on tal1 : Prop ≝ |
---|
618 | match tal1 with |
---|
619 | [ tal_base_not_return st1 st1' _ _ _ ⇒ |
---|
620 | fl2 = doesnt_end_with_ret ∧ |
---|
621 | ∃st2mid,taa,H,G,K. |
---|
622 | tal2 ≃ taa_append_tal ? st2 ??? taa |
---|
623 | (tal_base_not_return ? st2mid st2' H G K) |
---|
624 | | tal_base_return st1 st1' _ _ ⇒ |
---|
625 | fl2 = ends_with_ret ∧ |
---|
626 | ∃st2mid,taa,H,G. |
---|
627 | tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa |
---|
628 | (tal_base_return ? st2mid st2' H G) |
---|
629 | | tal_base_call st1 st1' st1'' _ prf _ tlr1 _ ⇒ |
---|
630 | fl2 = doesnt_end_with_ret ∧ |
---|
631 | ∃st2mid,G.as_call_ident S2 («st2mid, G») = as_call_ident ? «st1, prf» ∧ |
---|
632 | ∃taa : trace_any_any ? st2 st2mid.∃st2mid',H. |
---|
633 | (* we must allow a tal_base_call to be similar to a call followed |
---|
634 | by a collapsable trace (trace_any_any followed by a base_not_return; |
---|
635 | we cannot use trace_any_any as it disallows labels in the end as soon |
---|
636 | as it is non-empty) *) |
---|
637 | (∃K.∃tlr2 : trace_label_return ? st2mid' st2'.∃L. |
---|
638 | tal2 ≃ taa @ (tal_base_call … H G K tlr2 L) ∧ tlr_rel … tlr1 tlr2) ∨ |
---|
639 | ∃st2mid'',K.∃tlr2 : trace_label_return ? st2mid' st2mid''.∃L. |
---|
640 | ∃tl2 : trace_any_label … doesnt_end_with_ret st2mid'' st2'. |
---|
641 | tal2 ≃ taa @ (tal_step_call … H G K tlr2 L tl2) ∧ |
---|
642 | tlr_rel … tlr1 tlr2 ∧ tal_collapsable … tl2 |
---|
643 | | tal_base_tailcall st1 st1' st1'' _ prf tlr1 ⇒ |
---|
644 | fl2 = ends_with_ret ∧ |
---|
645 | ∃st2mid,G.as_tailcall_ident S2 («st2mid, G») = as_tailcall_ident ? «st1, prf» ∧ |
---|
646 | ∃taa : trace_any_any ? st2 st2mid.∃st2mid',H. |
---|
647 | ∃tlr2 : trace_label_return ? st2mid' st2'. |
---|
648 | tal2 ≃ taa @ (tal_base_tailcall … H G tlr2) ∧ tlr_rel … tlr1 tlr2 |
---|
649 | | tal_step_call fl1 st1 st1' st1'' st1''' _ prf _ tlr1 _ tl1 ⇒ |
---|
650 | ∃st2mid,G.as_call_ident S2 («st2mid, G») = as_call_ident ? «st1, prf» ∧ |
---|
651 | ∃taa : trace_any_any ? st2 st2mid.∃st2mid',H. |
---|
652 | (fl2 = doesnt_end_with_ret ∧ ∃K.∃tlr2 : trace_label_return ? st2mid' st2'.∃L. |
---|
653 | tal2 ≃ taa @ tal_base_call … H G K tlr2 L ∧ |
---|
654 | tal_collapsable … tl1 ∧ tlr_rel … tlr1 tlr2) ∨ |
---|
655 | ∃st2mid'',K.∃tlr2 : trace_label_return ? st2mid' st2mid''.∃L. |
---|
656 | ∃tl2 : trace_any_label ? fl2 st2mid'' st2'. |
---|
657 | tal2 ≃ taa @ (tal_step_call … H G K tlr2 L tl2) ∧ |
---|
658 | tal_rel … tl1 tl2 ∧ tlr_rel … tlr1 tlr2 |
---|
659 | | tal_step_default fl1 st1 st1' st1'' _ tl1 _ _ ⇒ |
---|
660 | tal_rel … tl1 tal2 (* <- this makes it many to many *) |
---|
661 | ]. |
---|
662 | |
---|
663 | interpretation "trace any label rel" 'napart t1 t2 = (tal_rel ???????? t1 t2). |
---|
664 | interpretation "trace label label rel" 'napart t1 t2 = (tll_rel ???????? t1 t2). |
---|
665 | interpretation "trace label return rel" 'napart t1 t2 = (tlr_rel ?????? t1 t2). |
---|
666 | |
---|
667 | let rec tal_collapsable_eq_fl S1 fl1 s1 s1' |
---|
668 | (tal1 : trace_any_label S1 fl1 s1 s1') on tal1 : |
---|
669 | tal_collapsable … tal1 → fl1 = doesnt_end_with_ret ≝ |
---|
670 | match tal1 return λfl1,s1,s1',tal1. |
---|
671 | tal_collapsable S1 fl1 s1 s1' tal1 → fl1 = doesnt_end_with_ret with |
---|
672 | [ tal_base_not_return _ _ _ _ _ ⇒ λ_.refl … |
---|
673 | | tal_step_default fl1 _ st1' st1'' _ tl1 _ _ ⇒ tal_collapsable_eq_fl … tl1 |
---|
674 | | _ ⇒ Ⓧ |
---|
675 | ]. |
---|
676 | |
---|
677 | let rec tal_rel_eq_fl S1 fl1 s1 s1' S2 fl2 s2 s2' |
---|
678 | (tal1 : trace_any_label S1 fl1 s1 s1') on tal1 : |
---|
679 | ∀tal2 : trace_any_label S2 fl2 s2 s2'.tal_rel … tal1 tal2 → fl1 = fl2 ≝ |
---|
680 | match tal1 return λfl1,s1,s1',tal1.? with |
---|
681 | [ tal_base_not_return st1 st1' _ _ _ ⇒ let BASE_NR ≝ 0 in ? |
---|
682 | | tal_base_return st1 st1' _ _ ⇒ let BASE_R ≝ 0 in ? |
---|
683 | | tal_base_call st1 st1' st1'' _ _ _ tlr1 _ ⇒ let BASE_C ≝ 0 in ? |
---|
684 | | tal_base_tailcall st1 st1' st1'' _ _ tlr1 ⇒ let BASE_TC ≝ 0 in ? |
---|
685 | | tal_step_call flg1 st1 st1' st1'' st1''' _ _ _ tlr1 _ tl1 ⇒ let STEP_C ≝ 0 in ? |
---|
686 | | tal_step_default flg1 st1 st1' st1'' _ tl1 _ _ ⇒ let STEP ≝ 0 in ? |
---|
687 | ]. |
---|
688 | -fl1 -s1 -s1' |
---|
689 | [1,2,3,4: -tal_rel_eq_fl #tal2 * // |
---|
690 | | #tal2 * #s2_mid * #G2 * #call * #taa2 * #s2' *#H2 * |
---|
691 | [ * #EQ1 *#K2 *#tlr2 *#L2 ** #_ #coll #_ >(tal_collapsable_eq_fl … coll) // |
---|
692 | | * #s2_mid' *#K2 *#tlr2 *#L2 *#tl2 ** #_ #step #_ |
---|
693 | @(tal_rel_eq_fl … step) |
---|
694 | ] |
---|
695 | | #tal2 whd in ⊢ (%→?); #step @(tal_rel_eq_fl … step) |
---|
696 | ] |
---|
697 | qed. |
---|
698 | |
---|
699 | let rec taa_rel_inv S1 fl1 st1 st1mid st1' S2 fl2 st2 st2' |
---|
700 | (taa1 : trace_any_any S1 st1 st1mid) on taa1 : |
---|
701 | ∀tal1 : trace_any_label S1 fl1 st1mid st1'. |
---|
702 | ∀tal2 : trace_any_label S2 fl2 st2 st2'. |
---|
703 | tal_rel … (taa1 @ tal1) tal2 → |
---|
704 | tal_rel … tal1 tal2 ≝ ?. |
---|
705 | cases taa1 -taa1 |
---|
706 | [ -taa_rel_inv // |
---|
707 | | #st #st' #st'' #H #G #K #tl #tal1 #tal2 whd in ⊢ (%→?); |
---|
708 | @(taa_rel_inv … tl) |
---|
709 | ] |
---|
710 | qed. |
---|
711 | |
---|
712 | lemma taa_append_collapsable : ∀S,s1,fl,s2,s3. |
---|
713 | ∀taa,tal.tal_collapsable S fl s2 s3 tal → tal_collapsable S fl s1 s3 (taa@tal). |
---|
714 | #S #s1 #fl #s2 #s3 #taa elim taa -s1 -s2 /2/ |
---|
715 | qed. |
---|
716 | |
---|
717 | let rec tal_rel_collapsable S1 fl1 s1 s1' S2 fl2 s2 s2' |
---|
718 | (tal1 : trace_any_label S1 fl1 s1 s1') on tal1 : |
---|
719 | ∀tal2 : trace_any_label S2 fl2 s2 s2'.tal_collapsable … tal1 → tal_rel … tal1 tal2 → |
---|
720 | tal_collapsable … tal2 ≝ |
---|
721 | match tal1 return λfl1,s1,s1',tal1.? with |
---|
722 | [ tal_base_not_return st1 st1' _ _ _ ⇒ let BASE_NR ≝ 0 in ? |
---|
723 | | tal_base_return st1 st1' _ _ ⇒ let BASE_R ≝ 0 in ? |
---|
724 | | tal_base_call st1 st1' st1'' _ _ _ tlr1 _ ⇒ let BASE_C ≝ 0 in ? |
---|
725 | | tal_base_tailcall st1 st1' st1'' _ _ tlr1 ⇒ let BASE_TC ≝ 0 in ? |
---|
726 | | tal_step_call flg1 st1 st1' st1'' st1''' _ _ _ tlr1 _ tl1 ⇒ let STEP_C ≝ 0 in ? |
---|
727 | | tal_step_default flg1 st1 st1' st1'' _ tl1 _ _ ⇒ let STEP ≝ 0 in ? |
---|
728 | ]. |
---|
729 | -fl1 -s1 -s1' |
---|
730 | [1,2,3,4: -tal_rel_collapsable #tal2 * * |
---|
731 | #EQ * #s2 * #taa2 *#H *#G *#K #EQ' destruct @taa_append_collapsable % |
---|
732 | | #tal2 * |
---|
733 | | #tal2 #tal2 whd in ⊢ (%→?); #step @(tal_rel_collapsable … step) assumption |
---|
734 | ] |
---|
735 | qed. |
---|
736 | |
---|
737 | inductive intensional_event : Type[0] ≝ |
---|
738 | | IEVcost : costlabel → intensional_event |
---|
739 | | IEVcall : ident → intensional_event |
---|
740 | | IEVtailcall : ident → ident → intensional_event |
---|
741 | | IEVret : ident → intensional_event. |
---|
742 | |
---|
743 | (* NB: we don't restrict call idents, because it would need some more tinkering |
---|
744 | with abstract_status *) |
---|
745 | definition as_emittable : abstract_status → intensional_event → Prop ≝ |
---|
746 | λS,ev. |
---|
747 | match ev with |
---|
748 | [ IEVcost c ⇒ as_cost_labelled S c |
---|
749 | | _ ⇒ True |
---|
750 | ]. |
---|
751 | |
---|
752 | definition as_trace ≝ |
---|
753 | λS : abstract_status. |
---|
754 | Σl : list intensional_event.All … (as_emittable S) l. |
---|
755 | |
---|
756 | unification hint 0 ≔ S ⊢ as_trace S ≡ Sig (list intensional_event) (λl.All … (as_emittable S) l). |
---|
757 | |
---|
758 | definition cons_safe : ∀A,P.(Σx.P x) → (Σl.All A P l) → Σl.All A P l ≝ |
---|
759 | λA,P,x,l.«x::l, conj … (pi2 … x) (pi2 … l)». |
---|
760 | |
---|
761 | definition append_safe : ∀A,P.(Σl.All A P l) → (Σl.All A P l) → Σl.All A P l ≝ |
---|
762 | λA,P,l1,l2.«l1@l2, |
---|
763 | cic:/matita/cerco/utilities/lists/All_append.def(2) … (pi2 … l1) (pi2 … l2)». |
---|
764 | |
---|
765 | definition nil_safe : ∀A,P.(Σl.All A P l) ≝ λA,P.«[ ], I». |
---|
766 | |
---|
767 | interpretation "safe consing" 'vcons hd tl = (cons_safe ?? hd tl). |
---|
768 | interpretation "safe appending" 'vappend l1 l2 = (append_safe ?? l1 l2). |
---|
769 | interpretation "safe nil" 'vnil = (nil_safe ??). |
---|
770 | |
---|
771 | definition emittable_cost : ∀S.as_cost_label S → Σev.as_emittable S ev ≝ |
---|
772 | λS,l.«IEVcost l, pi2 … l». |
---|
773 | |
---|
774 | let rec observables_trace_label_label |
---|
775 | (S: abstract_status) (trace_ends_flag: trace_ends_with_ret) |
---|
776 | (start_status: S) (final_status: S) |
---|
777 | (the_trace: trace_label_label S trace_ends_flag start_status final_status) |
---|
778 | (curr : ident) |
---|
779 | on the_trace: as_trace S ≝ |
---|
780 | match the_trace with |
---|
781 | [ tll_base ends_flag initial final given_trace labelled_proof ⇒ |
---|
782 | let label ≝ as_label_safe … «?, labelled_proof» in |
---|
783 | emittable_cost … label ::: observables_trace_any_label S ends_flag initial final given_trace curr |
---|
784 | ] |
---|
785 | and observables_trace_any_label |
---|
786 | (S: abstract_status) (trace_ends_flag: trace_ends_with_ret) |
---|
787 | (start_status: S) (final_status: S) |
---|
788 | (the_trace: trace_any_label S trace_ends_flag start_status final_status) |
---|
789 | (curr : ident) |
---|
790 | on the_trace: as_trace S ≝ |
---|
791 | match the_trace with |
---|
792 | [ tal_base_not_return the_status _ _ _ _ ⇒ [[ ]] |
---|
793 | | tal_base_call pre_fun_call start_fun_call final _ cl _ call_trace _ ⇒ |
---|
794 | let id ≝ as_call_ident ? «?, cl» in |
---|
795 | IEVcall id ::: observables_trace_label_return ??? call_trace id |
---|
796 | | tal_base_tailcall pre_fun_call start_fun_call final _ cl call_trace ⇒ |
---|
797 | let id ≝ as_tailcall_ident ? «?, cl» in |
---|
798 | IEVtailcall curr id ::: observables_trace_label_return … call_trace id |
---|
799 | | tal_base_return the_status _ _ _ ⇒ [[ IEVret curr]] |
---|
800 | | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final |
---|
801 | _ cl _ call_trace _ final_trace ⇒ |
---|
802 | let id ≝ as_call_ident ? «?, cl» in |
---|
803 | let call_cost_trace ≝ observables_trace_label_return … call_trace id in |
---|
804 | let final_cost_trace ≝ observables_trace_any_label … end_flag … final_trace curr in |
---|
805 | IEVcall id ::: call_cost_trace @@ final_cost_trace |
---|
806 | | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒ |
---|
807 | observables_trace_any_label … tail_trace curr |
---|
808 | ] |
---|
809 | and observables_trace_label_return |
---|
810 | (S: abstract_status) |
---|
811 | (start_status: S) (final_status: S) |
---|
812 | (the_trace: trace_label_return S start_status final_status) |
---|
813 | (curr : ident) |
---|
814 | on the_trace: as_trace S ≝ |
---|
815 | match the_trace with |
---|
816 | [ tlr_base before after trace_to_lift ⇒ |
---|
817 | observables_trace_label_label … trace_to_lift curr |
---|
818 | | tlr_step initial labelled final labelled_trace ret_trace ⇒ |
---|
819 | let labelled_cost ≝ observables_trace_label_label … doesnt_end_with_ret … labelled_trace curr in |
---|
820 | let return_cost ≝ observables_trace_label_return … ret_trace curr in |
---|
821 | labelled_cost @@ return_cost |
---|
822 | ]. % qed. |
---|
823 | |
---|
824 | let rec filter_map X Y (f : X → option Y) (l : list X) on l : list Y ≝ |
---|
825 | match l with |
---|
826 | [ nil ⇒ [ ] |
---|
827 | | cons hd tl ⇒ |
---|
828 | match f hd with |
---|
829 | [ Some y ⇒ [ y ] |
---|
830 | | None ⇒ [ ] |
---|
831 | ] @ filter_map … f tl |
---|
832 | ]. |
---|
833 | |
---|
834 | lemma filter_map_append: |
---|
835 | ∀X,Y,f,l1,l2. filter_map X Y f (l1@l2) = filter_map … f l1 @ filter_map … f l2. |
---|
836 | #X #Y #f #l1 elim l1 // #hd #tl #IH #l2 normalize >IH // |
---|
837 | qed. |
---|
838 | |
---|
839 | lemma map_to_filter_map : ∀X,Y,f,l.map X Y f l = filter_map X Y (λx.Some ? (f x)) l. |
---|
840 | #X #Y #f #l elim l normalize // qed. |
---|
841 | |
---|
842 | lemma filter_map_compose : ∀X,Y,Z,f,g,l. |
---|
843 | filter_map Y Z f (filter_map X Y g l) = |
---|
844 | filter_map X Z (λx.! y ← g x ; f y) l. |
---|
845 | #X #Y #Z #f #g #l elim l [%] |
---|
846 | #hd #tl #IH |
---|
847 | whd in ⊢ (??(????%)%); |
---|
848 | cases (g ?) normalize nodelta |
---|
849 | [2: #y >m_return_bind whd in ⊢ (??%?); @eq_f2 [ % ]] |
---|
850 | @IH |
---|
851 | qed. |
---|
852 | |
---|
853 | lemma filter_map_ext_eq : ∀X,Y,f,g,l. |
---|
854 | (∀x.f x = g x) → filter_map X Y f l = filter_map X Y g l. |
---|
855 | #X #Y #f #g #l #H elim l normalize [%] #hd #tl #IH >H @eq_f @IH qed. |
---|
856 | |
---|
857 | let rec list_distribute_sig_aux X P (l : list X) on l : All X P l → list (Σx.P x) ≝ |
---|
858 | match l return λl.All X P l → list (Σx.P x) with |
---|
859 | [ nil ⇒ λ_.[ ] |
---|
860 | | cons hd tl ⇒ λprf.«hd, proj1 … prf» :: list_distribute_sig_aux X P tl (proj2 … prf) |
---|
861 | ]. |
---|
862 | |
---|
863 | definition list_distribute_sig : ∀A,P.(Σl.All A P l) → list (Σx.P x) ≝ |
---|
864 | λA,P,l.list_distribute_sig_aux … l (pi2 … l). |
---|
865 | |
---|
866 | lemma list_distribute_sig_append: |
---|
867 | ∀A,P,l1,l2,prf1,prf2,prf3. |
---|
868 | list_distribute_sig A P «l1@l2,prf3» = |
---|
869 | list_distribute_sig … «l1,prf1» @ list_distribute_sig … «l2,prf2». |
---|
870 | #A #P #l1 whd in match list_distribute_sig; normalize nodelta elim l1 // |
---|
871 | #hd #tl #IH normalize #l2 #prf1 #prf2 #prf3 <IH // |
---|
872 | qed. |
---|
873 | |
---|
874 | let rec list_factor_sig X P (l : list (Σx.P x)) on l : Σl.All X P l ≝ |
---|
875 | match l with |
---|
876 | [ nil ⇒ [[ ]] |
---|
877 | | cons hd tl ⇒ hd ::: list_factor_sig … tl |
---|
878 | ]. |
---|
879 | |
---|
880 | definition costlabels_of_observables : ∀S.as_trace S → list (as_cost_label S) ≝ |
---|
881 | λS,l.filter_map (Σev.as_emittable S ev) ? |
---|
882 | (λev.match ev return λev.as_emittable S ev → option ? with |
---|
883 | [ IEVcost c ⇒ λprf.Some ? «c, prf» |
---|
884 | | _ ⇒ λ_.None ? |
---|
885 | ] (pi2 … ev)) (list_distribute_sig … l). |
---|
886 | |
---|
887 | axiom costlabels_of_observables_trace_label_return_id_irrelevant: |
---|
888 | ∀S,s1,s2,tr,id1,id2. |
---|
889 | costlabels_of_observables S (observables_trace_label_return S s1 s2 tr id1) = |
---|
890 | costlabels_of_observables S (observables_trace_label_return S s1 s2 tr id2). |
---|
891 | |
---|
892 | lemma costlabels_of_observables_append: |
---|
893 | ∀S:abstract_status. ∀tr1,tr2: as_trace S. |
---|
894 | costlabels_of_observables S (tr1 @ tr2) = |
---|
895 | costlabels_of_observables … tr1 @ costlabels_of_observables … tr2. |
---|
896 | [ #S #tr1 #tr2 whd in match costlabels_of_observables; normalize nodelta |
---|
897 | <filter_map_append <list_distribute_sig_append // |
---|
898 | | @All_append [ @(pi2 … tr1) | @(pi2 … tr2) ]] |
---|
899 | qed. |
---|
900 | |
---|
901 | (* JHM: base case now passes the termination checker *) |
---|
902 | let rec taa_append_tal_same_observables |
---|
903 | S st1 fl st2 st3 (taa : trace_any_any S st1 st2) on taa : |
---|
904 | ∀tal : trace_any_label S fl st2 st3.∀curr. |
---|
905 | observables_trace_any_label ???? (taa @ tal) curr = |
---|
906 | observables_trace_any_label ???? tal curr ≝ ?. |
---|
907 | cases taa -st1 -st2 |
---|
908 | [ #st #tal #curr normalize in ⊢ (??%?); // |
---|
909 | | #st_pre #st_init #st2 #H #G #K #taa' #tal #curr |
---|
910 | whd in match (? @ ?); |
---|
911 | whd in ⊢ (??%?); // |
---|
912 | ] |
---|
913 | qed. |
---|
914 | |
---|
915 | let rec tal_collapsable_observables S fl st1 st2 tal |
---|
916 | on tal : |
---|
917 | ∀curr. |
---|
918 | tal_collapsable S fl st1 st2 tal → observables_trace_any_label … tal curr = [ ] ≝ |
---|
919 | λcurr. |
---|
920 | match tal |
---|
921 | return λfl,st1,st2,tal.tal_collapsable S fl st1 st2 tal → observables_trace_any_label … tal curr = [ ] |
---|
922 | with |
---|
923 | [ tal_base_not_return the_status _ _ _ _ ⇒ λ_.refl ?? |
---|
924 | | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒ |
---|
925 | tal_collapsable_observables ???? tail_trace curr |
---|
926 | | _ ⇒ Ⓧ |
---|
927 | ]. |
---|
928 | |
---|
929 | let rec tll_rel_to_traces_same_observables |
---|
930 | (S: abstract_status) (S': abstract_status) |
---|
931 | (trace_ends_flag_l: trace_ends_with_ret) (trace_ends_flag_r: trace_ends_with_ret) |
---|
932 | (start_status_l: S) (final_status_l: S) (start_status_r: S') (final_status_r: S') |
---|
933 | (the_trace_l: trace_label_label S trace_ends_flag_l start_status_l final_status_l) |
---|
934 | (the_trace_r: trace_label_label S' trace_ends_flag_r start_status_r final_status_r) |
---|
935 | (curr : ident) |
---|
936 | on the_trace_l: |
---|
937 | tll_rel … the_trace_l the_trace_r → |
---|
938 | pi1 … (observables_trace_label_label … the_trace_l curr) = |
---|
939 | pi1 … (observables_trace_label_label … the_trace_r curr) ≝ |
---|
940 | match the_trace_l with |
---|
941 | [ tll_base fl1 st1 st1' tal1 H ⇒ |
---|
942 | match the_trace_r with |
---|
943 | [ tll_base fl2 st2 st2 tal2 G ⇒ ? |
---|
944 | ] |
---|
945 | ] |
---|
946 | and tal_rel_to_traces_same_observables |
---|
947 | (S: abstract_status) (S': abstract_status) (trace_ends_flag_l: trace_ends_with_ret) |
---|
948 | (trace_ends_flag_r: trace_ends_with_ret) |
---|
949 | (start_status_l: S) (final_status_l: S) (start_status_r: S') (final_status_r: S') |
---|
950 | (the_trace_l: trace_any_label S trace_ends_flag_l start_status_l final_status_l) |
---|
951 | (the_trace_r: trace_any_label S' trace_ends_flag_r start_status_r final_status_r) |
---|
952 | (curr : ident) |
---|
953 | on the_trace_l: |
---|
954 | tal_rel … the_trace_l the_trace_r → |
---|
955 | pi1 … (observables_trace_any_label … the_trace_l curr) = |
---|
956 | pi1 … (observables_trace_any_label … the_trace_r curr) ≝ |
---|
957 | match the_trace_l with |
---|
958 | [ tal_base_not_return st1 st1' H G K ⇒ ? |
---|
959 | | tal_base_return st1 st1' H G ⇒ ? |
---|
960 | | tal_base_call st1 st1' st1'' H G K tlr1 L ⇒ ? |
---|
961 | | tal_base_tailcall st1 st1' st1'' H G tlr1 ⇒ ? |
---|
962 | | tal_step_call fl1 st1 st1' st1'' st1''' H G K tlr1 L tl1 ⇒ ? |
---|
963 | | tal_step_default fl1 st1 st1' st1'' H tl1 G K ⇒ ? |
---|
964 | ] |
---|
965 | and tlr_rel_to_traces_same_observables |
---|
966 | (S: abstract_status) (S': abstract_status) (start_status_l: S) (final_status_l: S) |
---|
967 | (start_status_r: S') (final_status_r: S') |
---|
968 | (the_trace_l: trace_label_return S start_status_l final_status_l) |
---|
969 | (the_trace_r: trace_label_return S' start_status_r final_status_r) |
---|
970 | (curr : ident) |
---|
971 | on the_trace_l: |
---|
972 | tlr_rel … the_trace_l the_trace_r → |
---|
973 | pi1 … (observables_trace_label_return … the_trace_l curr) = |
---|
974 | pi1 … (observables_trace_label_return … the_trace_r curr) ≝ |
---|
975 | match the_trace_l with |
---|
976 | [ tlr_base before after tll_l ⇒ ? |
---|
977 | | tlr_step initial labelled final tll_l tlr_l ⇒ ? |
---|
978 | ]. |
---|
979 | [ * #EQ #H_tal |
---|
980 | whd in ⊢ (??%%); @eq_f2 [2: @(tal_rel_to_traces_same_observables … H_tal)] |
---|
981 | cases (as_label_safe ??) in EQ; #c1 #H1 |
---|
982 | cases (as_label_safe ??) #c2 #H2 #EQ destruct % |
---|
983 | |2,3,4,5,6,7: |
---|
984 | [1,2,3,4: * #EQ destruct(EQ)] |
---|
985 | [1,2,3,4,5: * #st_mid [1,2:|*: * #G' * #call ] * #taa |
---|
986 | [ *#H' *#G' *#K' #EQ |
---|
987 | | *#H' *#G' #EQ |
---|
988 | | *#st_mid' *#H' * [|*#st2_mid''] *#K' *#tlr2 *#L' |
---|
989 | [|*#tl2 *] * #EQ #H_tlr [| #H_tl] |
---|
990 | | *#st_mid' *#H' *#tlr2 * #EQ #H_tlr |
---|
991 | | *#st_fun *#H' * |
---|
992 | [*#fl_EQ destruct(fl_EQ) |* #st2_mid ] *#K' *#tlr2 *#L' |
---|
993 | [| *#tl2] ** #EQ #H_tl #H_tlr |
---|
994 | ] >EQ >taa_append_tal_same_observables |
---|
995 | | whd in ⊢ (%→??(???%)?); @tal_rel_to_traces_same_observables |
---|
996 | ] |
---|
997 | whd in ⊢ (??%%); |
---|
998 | [1,2: % |
---|
999 | |3,5: >call >(tlr_rel_to_traces_same_observables … H_tlr) % |
---|
1000 | |4,6: >call >(tal_collapsable_observables … H_tl) >append_nil |
---|
1001 | >(tlr_rel_to_traces_same_observables … H_tlr) % |
---|
1002 | |7: >call |
---|
1003 | >(tlr_rel_to_traces_same_observables … H_tlr) |
---|
1004 | >(tal_rel_to_traces_same_observables … H_tl) |
---|
1005 | % |
---|
1006 | ] |
---|
1007 | |*: cases the_trace_r |
---|
1008 | [1,3: #st_before_r #st_after_r #tll_r |
---|
1009 | [ @tll_rel_to_traces_same_observables | * ] |
---|
1010 | |*: #st_init_r #st_labld_r #st_fin_r #tll_r #tlr_r * |
---|
1011 | #H_tll #H_tlr |
---|
1012 | whd in ⊢ (??%%); |
---|
1013 | >(tll_rel_to_traces_same_observables … H_tll) |
---|
1014 | >(tlr_rel_to_traces_same_observables … H_tlr) |
---|
1015 | % |
---|
1016 | ] |
---|
1017 | ] |
---|
1018 | qed. |
---|
1019 | |
---|
1020 | (* cost maps specifics: summing over flattened traces *) |
---|
1021 | |
---|
1022 | (* lemma lift_cost_map_same_cost_tal : |
---|
1023 | ∀S_in, S_out, dec, m_out, f_in, f_out, start_in, start_out, end_in, end_out. |
---|
1024 | ∀the_trace_in : trace_any_label S_in f_in start_in end_in. |
---|
1025 | ∀the_trace_out : trace_any_label S_out f_out start_out end_out. |
---|
1026 | tal_rel … the_trace_in the_trace_out → |
---|
1027 | (Σ_{l ∈ flatten_trace_any_label … the_trace_in} |
---|
1028 | (lift_cost_map_id … dec m_out l)) = |
---|
1029 | (Σ_{l ∈ flatten_trace_any_label … the_trace_out} (m_out l)). |
---|
1030 | #S_in #S_out #dec #m_out #f_in #f_out #start_in #start_out #end_in #end_out |
---|
1031 | #tal_in #tal_out #H_tal |
---|
1032 | @(lift_cost_map_same_cost … (tal_rel_to_traces_same_flatten … H_tal)) |
---|
1033 | qed. |
---|
1034 | |
---|
1035 | lemma lift_cost_map_same_cost_tll : |
---|
1036 | ∀S_in, S_out, dec, m_out, f_in, f_out, start_in, start_out, end_in, end_out. |
---|
1037 | ∀the_trace_in : trace_label_label S_in f_in start_in end_in. |
---|
1038 | ∀the_trace_out : trace_label_label S_out f_out start_out end_out. |
---|
1039 | tll_rel … the_trace_in the_trace_out → |
---|
1040 | (Σ_{l ∈ flatten_trace_label_label … the_trace_in} |
---|
1041 | (lift_cost_map_id … dec m_out l)) = |
---|
1042 | (Σ_{l ∈ flatten_trace_label_label … the_trace_out} (m_out l)). |
---|
1043 | #S_in #S_out #dec #m_out #f_in #f_out #start_in #start_out #end_in #end_out |
---|
1044 | #tll_in #tll_out #H_tll |
---|
1045 | @(lift_cost_map_same_cost … (tll_rel_to_traces_same_flatten … H_tll)) |
---|
1046 | qed. |
---|
1047 | *) |
---|
1048 | |
---|
1049 | lemma map_pi1_distribute_sig : ∀A,P,l. |
---|
1050 | map ?? (pi1 ??) (list_distribute_sig A P l) = pi1 ?? l. |
---|
1051 | #A #P * #l elim l -l normalize // qed. |
---|
1052 | |
---|
1053 | definition flatten_trace_label_return ≝ |
---|
1054 | λS,st1,st2.λtlr : trace_label_return S st1 st2. |
---|
1055 | (* as cost events do not depend on current function identifier, we |
---|
1056 | can use a dummy one *) |
---|
1057 | let dummy ≝ an_identifier ? one in |
---|
1058 | costlabels_of_observables … (observables_trace_label_return … tlr dummy). |
---|
1059 | |
---|
1060 | definition flatten_trace_label_label ≝ |
---|
1061 | λS,flag,st1,st2.λtll : trace_label_label S flag st1 st2. |
---|
1062 | (* as cost events do not depend on current function identifier, we |
---|
1063 | can use a dummy one *) |
---|
1064 | let dummy ≝ an_identifier ? one in |
---|
1065 | costlabels_of_observables … (observables_trace_label_label … tll dummy). |
---|
1066 | |
---|
1067 | definition flatten_trace_any_label ≝ |
---|
1068 | λS,flag,st1,st2.λtll : trace_any_label S flag st1 st2. |
---|
1069 | (* as cost events do not depend on current function identifier, we |
---|
1070 | can use a dummy one *) |
---|
1071 | let dummy ≝ an_identifier ? one in |
---|
1072 | costlabels_of_observables … (observables_trace_any_label … tll dummy). |
---|
1073 | |
---|
1074 | lemma lift_cost_map_same_cost_tlr : |
---|
1075 | ∀S_in, S_out, dec, m_out, start_in, start_out, end_in, end_out. |
---|
1076 | ∀the_trace_in : trace_label_return S_in start_in end_in. |
---|
1077 | ∀the_trace_out : trace_label_return S_out start_out end_out. |
---|
1078 | tlr_rel … the_trace_in the_trace_out → |
---|
1079 | (Σ_{l ∈ flatten_trace_label_return … the_trace_in} |
---|
1080 | (lift_cost_map_id … dec m_out l)) = |
---|
1081 | (Σ_{l ∈ flatten_trace_label_return … the_trace_out} (m_out l)). |
---|
1082 | #S_in #S_out #dec #m_out #start_in #start_out #end_in #end_out |
---|
1083 | #tlr_in #tlr_out #H_tlr |
---|
1084 | @lift_cost_map_same_cost |
---|
1085 | whd in match flatten_trace_label_return; normalize nodelta |
---|
1086 | >map_to_filter_map >map_to_filter_map >filter_map_compose |
---|
1087 | >filter_map_compose |
---|
1088 | cut (∀S.∀x: (Σev.as_emittable S ev). |
---|
1089 | ! y ← |
---|
1090 | match pi1 ?? x return λx.as_emittable S x → option (Σc.as_cost_labelled S c) with |
---|
1091 | [ IEVcost c ⇒ λprf.Some ? «c, prf» | _ ⇒ λ_.None ? ] (pi2 ?? x) ; |
---|
1092 | Some ? (pi1 ?? y) = |
---|
1093 | ! ev ← Some ? (pi1 ?? x) ; |
---|
1094 | match ev with [ IEVcost c ⇒ Some ? c | _ ⇒ None ?]) |
---|
1095 | [ #S ** [ #c #em | #i * | #i #j * | #i * ] %] |
---|
1096 | #EQext >(filter_map_ext_eq … (EQext S_in)) >(filter_map_ext_eq … (EQext S_out)) |
---|
1097 | <filter_map_compose <filter_map_compose @eq_f |
---|
1098 | <map_to_filter_map <map_to_filter_map |
---|
1099 | >map_pi1_distribute_sig >map_pi1_distribute_sig |
---|
1100 | @(tlr_rel_to_traces_same_observables … H_tlr) % |
---|
1101 | qed. |
---|
1102 | |
---|
1103 | lemma lift_cost_map_same_cost_tll : |
---|
1104 | ∀S_in, S_out, dec, m_out, fl_in, fl_out, start_in, start_out, end_in, end_out. |
---|
1105 | ∀the_trace_in : trace_label_label S_in fl_in start_in end_in. |
---|
1106 | ∀the_trace_out : trace_label_label S_out fl_out start_out end_out. |
---|
1107 | tll_rel … the_trace_in the_trace_out → |
---|
1108 | (Σ_{l ∈ flatten_trace_label_label … the_trace_in} |
---|
1109 | (lift_cost_map_id … dec m_out l)) = |
---|
1110 | (Σ_{l ∈ flatten_trace_label_label … the_trace_out} (m_out l)). |
---|
1111 | #S_in #S_out #dec #m_out #fl_in #fl_out #start_in #start_out #end_in #end_out |
---|
1112 | #tlr_in #tlr_out #H_tlr |
---|
1113 | @lift_cost_map_same_cost |
---|
1114 | whd in match flatten_trace_label_label; normalize nodelta |
---|
1115 | >map_to_filter_map >map_to_filter_map >filter_map_compose |
---|
1116 | >filter_map_compose |
---|
1117 | cut (∀S.∀x: (Σev.as_emittable S ev). |
---|
1118 | ! y ← |
---|
1119 | match pi1 ?? x return λx.as_emittable S x → option (Σc.as_cost_labelled S c) with |
---|
1120 | [ IEVcost c ⇒ λprf.Some ? «c, prf» | _ ⇒ λ_.None ? ] (pi2 ?? x) ; |
---|
1121 | Some ? (pi1 ?? y) = |
---|
1122 | ! ev ← Some ? (pi1 ?? x) ; |
---|
1123 | match ev with [ IEVcost c ⇒ Some ? c | _ ⇒ None ?]) |
---|
1124 | [ #S ** [ #c #em | #i * | #i #j * | #i * ] %] |
---|
1125 | #EQext >(filter_map_ext_eq … (EQext S_in)) >(filter_map_ext_eq … (EQext S_out)) |
---|
1126 | <filter_map_compose <filter_map_compose @eq_f |
---|
1127 | <map_to_filter_map <map_to_filter_map |
---|
1128 | >map_pi1_distribute_sig >map_pi1_distribute_sig |
---|
1129 | @(tll_rel_to_traces_same_observables … H_tlr) % |
---|
1130 | qed. |
---|