root/src/common/StructuredTraces.ma @ 1926

Revision 1926, 16.4 KB (checked in by tranquil, 13 months ago)

* added as_label to abstract status, with as_costed defined with it. This temporarily breaks stuff around
* defined a relation on traces which tells that their shapes and labels are the same

Line 
1include "basics/types.ma".
2include "basics/bool.ma".
3include "basics/jmeq.ma".
4include "common/CostLabel.ma".
5include "utilities/option.ma".
6include "basics/lists/listb.ma".
7include "ASM/Util.ma".
8
9inductive 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
15record abstract_status : Type[1] ≝
16  { as_status :> Type[0]
17  ; as_execute : as_status → as_status → Prop
18  ; as_pc : DeqSet
19  ; as_pc_of : as_status → as_pc
20  ; as_classifier : as_status → status_class → Prop
21  ; as_label : as_status → option costlabel
22  ; as_after_return : (Σs:as_status. as_classifier s cl_call) → as_status → Prop
23  ; as_final: as_status → Prop
24}.
25
26(* temporary alias for backward compatibility *)
27definition final_abstract_status ≝ abstract_status.
28
29definition as_costed : ∀a_s : abstract_status.a_s → Prop ≝
30  λa_s,st.as_label ? st ≠ None ?.
31
32definition as_label_safe : ∀a_s : abstract_status.
33  (Σs : a_s.as_costed ? s) → costlabel ≝
34  λa_s,st_sig.opt_safe … (pi2 … st_sig).
35
36inductive trace_ends_with_ret: Type[0] ≝
37  | ends_with_ret: trace_ends_with_ret
38  | doesnt_end_with_ret: trace_ends_with_ret.
39
40inductive trace_label_return (S:abstract_status) : S → S → Type[0] ≝
41  | tlr_base:
42      ∀status_before: S.
43      ∀status_after: S.
44        trace_label_label S ends_with_ret status_before status_after →
45        trace_label_return S status_before status_after
46  | tlr_step:
47      ∀status_initial: S.
48      ∀status_labelled: S.
49      ∀status_final: S.
50        trace_label_label S doesnt_end_with_ret status_initial status_labelled →
51        trace_label_return S status_labelled status_final →
52          trace_label_return S status_initial status_final
53with trace_label_label: trace_ends_with_ret → S → S → Type[0] ≝
54  | tll_base:
55      ∀ends_flag: trace_ends_with_ret.
56      ∀start_status: S.
57      ∀end_status: S.
58        trace_any_label S ends_flag start_status end_status →
59        as_costed S start_status →
60          trace_label_label S ends_flag start_status end_status
61with trace_any_label: trace_ends_with_ret → S → S → Type[0] ≝
62  (* Single steps within a function which reach a label.
63     Note that this is the only case applicable for a jump. *)
64  | tal_base_not_return:
65      ∀start_status: S.
66      ∀final_status: S.
67        as_execute S start_status final_status →
68        (as_classifier S start_status cl_jump ∨
69         as_classifier S start_status cl_other) →
70        as_costed S final_status →
71          trace_any_label S doesnt_end_with_ret start_status final_status
72  | tal_base_return:
73      ∀start_status: S.
74      ∀final_status: S.
75        as_execute S start_status final_status →
76        as_classifier S start_status cl_return →
77          trace_any_label S ends_with_ret start_status final_status
78  (* A call followed by a label on return. *)
79  | tal_base_call:
80      ∀status_pre_fun_call: S.
81      ∀status_start_fun_call: S.
82      ∀status_final: S.
83        as_execute S status_pre_fun_call status_start_fun_call →
84        ∀H:as_classifier S status_pre_fun_call cl_call.
85          as_after_return S (mk_Sig ?? status_pre_fun_call H) status_final →
86          trace_label_return S status_start_fun_call status_final →
87          as_costed S status_final →
88            trace_any_label S doesnt_end_with_ret status_pre_fun_call status_final
89  (* A call followed by a non-empty trace. *)
90  | tal_step_call:
91      ∀end_flag: trace_ends_with_ret.
92      ∀status_pre_fun_call: S.
93      ∀status_start_fun_call: S.
94      ∀status_after_fun_call: S.
95      ∀status_final: S.
96        as_execute S status_pre_fun_call status_start_fun_call →
97        ∀H:as_classifier S status_pre_fun_call cl_call.
98          as_after_return S (mk_Sig ?? status_pre_fun_call H) status_after_fun_call →
99          trace_label_return S status_start_fun_call status_after_fun_call →
100          ¬ as_costed S status_after_fun_call →
101          trace_any_label S end_flag status_after_fun_call status_final →
102            trace_any_label S end_flag status_pre_fun_call status_final
103  | tal_step_default:
104      ∀end_flag: trace_ends_with_ret.
105      ∀status_pre: S.
106      ∀status_init: S.
107      ∀status_end: S.
108        as_execute S status_pre status_init →
109        trace_any_label S end_flag status_init status_end →
110        as_classifier S status_pre cl_other →
111        ¬ (as_costed S status_init) →
112          trace_any_label S end_flag status_pre status_end.
113
114let rec tal_pc_list (S : abstract_status) fl st1 st2 (tal : trace_any_label S fl st1 st2)
115  on tal : list (as_pc S) ≝
116 match tal with
117 [ tal_step_call fl' pre _ st1' st2' _ _ _ _ _ tl ⇒ as_pc_of … pre :: tal_pc_list … tl
118 | tal_step_default fl' pre st1' st2' _ tl _ _ ⇒  as_pc_of … pre :: tal_pc_list … tl
119 | tal_base_not_return pre _ _ _ _ ⇒ [as_pc_of … pre]
120 | tal_base_return pre _ _ _ ⇒ [as_pc_of … pre]
121 | tal_base_call pre _ _ _ _ _ _ _ ⇒ [as_pc_of … pre]
122 ].
123
124let rec tlr_unrepeating S st1 st2 (tlr : trace_label_return S st1 st2) on tlr : Prop ≝
125  match tlr with
126  [ tlr_base st1 st2 tll ⇒ tll_unrepeating … tll
127  | tlr_step st1 st2 st3 tll tl ⇒ tll_unrepeating … tll ∧ tlr_unrepeating … tl
128  ]
129and tll_unrepeating S fl st1 st2 (tll : trace_label_label S fl st1 st2) on tll : Prop ≝
130  match tll with
131  [ tll_base fl st1 st2 tal _ ⇒ tal_unrepeating … tal
132  ]
133and tal_unrepeating S fl st1 st2 (tal : trace_any_label S fl st1 st2) on tal : Prop ≝
134  match tal with
135  [ tal_step_call fl st1 st2 st3 st4 _ _ _ tlr _ tl ⇒
136    bool_to_Prop (notb (memb ? (as_pc_of … st1) (tal_pc_list … tl))) ∧
137    tal_unrepeating … tl ∧
138    tlr_unrepeating … tlr
139  | tal_step_default fl st1 st2 st3 _ tl _ _ ⇒
140    bool_to_Prop (notb (memb ? (as_pc_of … st1) (tal_pc_list … tl))) ∧
141    tal_unrepeating … tl
142  | _ ⇒ True
143  ].
144
145definition tll_hd_label : ∀S : abstract_status.∀fl,st1,st2.
146  trace_label_label S fl st1 st2 → costlabel ≝
147  λS,fl,st1,st2,tr.match tr with
148  [ tll_base _ st1' _ _ prf ⇒ as_label_safe … «st1', prf» ].
149
150definition tlr_hd_label : ∀S : abstract_status.∀st1,st2.
151  trace_label_return S st1 st2 → costlabel ≝
152  λS,st1,st2,tr.match tr with
153  [ tlr_base st1' st2' tll ⇒ tll_hd_label … tll
154  | tlr_step st1' st2' _ tll _ ⇒ tll_hd_label … tll
155  ].
156
157let rec tal_unrepeating_uniqueb S fl st1 st2 tal on tal :
158  tal_unrepeating S fl st1 st2 tal → bool_to_Prop (uniqueb … (tal_pc_list … tal)) ≝ ?.
159cases tal //
160#fl' #st1' [#st_fun] #st2' #st3' #H
161[ #H0 #H1 #tlr #G #tal | #tal #H0 #G ] whd in ⊢ (% → ?%); [*]*
162#A #B [#_] >A normalize nodelta @tal_unrepeating_uniqueb assumption
163qed.
164
165inductive trace_any_call (S:abstract_status) : S → S → Type[0] ≝
166  | tac_base:
167      ∀status: S.
168        as_classifier S status cl_call →
169          trace_any_call S status status
170  | tac_step_call:
171      ∀status_pre_fun_call: S.
172      ∀status_after_fun_call: S.
173      ∀status_final: S.
174      ∀status_start_fun_call: S.
175        as_execute S status_pre_fun_call status_start_fun_call →
176        ∀H:as_classifier S status_pre_fun_call cl_call.
177          as_after_return S (mk_Sig ?? status_pre_fun_call H) status_after_fun_call →
178          trace_label_return S status_start_fun_call status_after_fun_call →
179          ¬ as_costed S status_after_fun_call →
180          trace_any_call S status_after_fun_call status_final →
181            trace_any_call S status_pre_fun_call status_final
182  | tac_step_default:
183      ∀status_pre: S.
184      ∀status_end: S.
185      ∀status_init: S.
186        as_execute S status_pre status_init →
187        trace_any_call S status_init status_end →
188        as_classifier S status_pre cl_other →
189        ¬ (as_costed S status_init) →
190          trace_any_call S status_pre status_end.
191
192             
193inductive trace_label_call (S:abstract_status) : S → S → Type[0] ≝
194  | tlc_base:
195      ∀start_status: S.
196      ∀end_status: S.
197        trace_any_call S start_status end_status →
198        as_costed S start_status →
199        trace_label_call S start_status end_status
200.
201
202definition tlc_hd_label : ∀S : abstract_status.∀st1,st2.
203  trace_label_call S st1 st2 → costlabel ≝
204  λS,st1,st2,tr.match tr with
205  [ tlc_base st1' _ _ prf ⇒ as_label_safe … «st1', prf»
206  ].       
207
208coinductive trace_label_diverges (S:abstract_status) : S → Type[0] ≝
209  | tld_step:
210      ∀status_initial: S.
211      ∀status_labelled: S.
212          trace_label_label S doesnt_end_with_ret status_initial status_labelled →
213          trace_label_diverges S status_labelled →
214            trace_label_diverges S status_initial
215  | tld_base:
216      ∀status_initial: S.
217      ∀status_pre_fun_call: S.
218      ∀status_start_fun_call: S.
219        trace_label_call S status_initial status_pre_fun_call →
220        as_execute S status_pre_fun_call status_start_fun_call →
221        ∀H:as_classifier S status_pre_fun_call cl_call.
222          trace_label_diverges S status_start_fun_call →
223            trace_label_diverges S status_initial.
224
225definition tld_hd_label : ∀S : abstract_status.∀st.
226  trace_label_diverges S st → costlabel ≝
227  λS,st,tr.match tr with
228  [ tld_step st' st'' tll _ ⇒ tll_hd_label … tll
229  | tld_base st' st'' _ tlc _ _ _ ⇒ tlc_hd_label … tlc
230  ].       
231
232(* Version in Prop for showing existence. *)
233coinductive trace_label_diverges_exists (S:abstract_status) : S → Prop ≝
234  | tld_step:
235      ∀status_initial: S.
236      ∀status_labelled: S.
237          trace_label_label S doesnt_end_with_ret status_initial status_labelled →
238          trace_label_diverges_exists S status_labelled →
239            trace_label_diverges_exists S status_initial
240  | tld_base:
241      ∀status_initial: S.
242      ∀status_pre_fun_call: S.
243      ∀status_start_fun_call: S.
244        trace_label_call S status_initial status_pre_fun_call →
245        as_execute S status_pre_fun_call status_start_fun_call →
246        ∀H:as_classifier S status_pre_fun_call cl_call.
247          trace_label_diverges_exists S status_start_fun_call →
248            trace_label_diverges_exists S status_initial.
249
250inductive trace_whole_program (S: abstract_status) : S → Type[0] ≝
251  | twp_terminating:
252      ∀status_initial: S.
253      ∀status_start_fun: S.
254      ∀status_final: S.
255        as_classifier S status_initial cl_call →
256        as_execute S status_initial status_start_fun →
257        trace_label_return S status_start_fun status_final →
258        as_final S status_final →
259        trace_whole_program S status_initial
260  | twp_diverges:
261      ∀status_initial: S.
262      ∀status_start_fun: S.
263        as_classifier S status_initial cl_call →
264        as_execute S status_initial status_start_fun →
265        trace_label_diverges S status_start_fun →
266        trace_whole_program S status_initial.
267
268(* Again, an identical version in Prop for existence proofs. *)
269inductive trace_whole_program_exists (S: abstract_status) : S → Prop ≝
270  | twp_terminating:
271      ∀status_initial: S.
272      ∀status_start_fun: S.
273      ∀status_final: S.
274        as_classifier S status_initial cl_call →
275        as_execute S status_initial status_start_fun →
276        trace_label_return S status_start_fun status_final →
277        as_final S status_final →
278        trace_whole_program_exists S status_initial
279  | twp_diverges:
280      ∀status_initial: S.
281      ∀status_start_fun: S.
282        as_classifier S status_initial cl_call →
283        as_execute S status_initial status_start_fun →
284        trace_label_diverges_exists S status_start_fun →
285        trace_whole_program_exists S status_initial.
286
287
288let rec trace_any_label_label S s s' f
289  (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 ] ≝
290match tr return λf,s,s',tr. match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ] with
291[ tal_base_not_return start final _ _ C ⇒ C
292| tal_base_return _ _  _ _ ⇒ I
293| tal_base_call _ _ _ _ _ _ _ C ⇒ C
294| tal_step_call f pre start after final X C RET LR C' tr' ⇒ trace_any_label_label … tr'
295| tal_step_default f pre init end X tr' C C' ⇒ trace_any_label_label … tr'
296].
297
298definition tal_tl_label : ∀S : abstract_status.∀st1,st2.
299  trace_any_label S doesnt_end_with_ret st1 st2 → costlabel ≝
300  λS,st1,st2,tr.as_label_safe … «st2, trace_any_label_label … tr».
301
302lemma trace_label_label_label : ∀S,s,s',f.
303  ∀tr:trace_label_label S f s s'. match f with [ doesnt_end_with_ret ⇒ as_costed S s' | ends_with_ret ⇒ True ].
304#S #s #s' #f #tr
305cases tr
306#f #start #end #tr' #C @(trace_any_label_label … tr')
307qed.
308
309definition tll_tl_label : ∀S : abstract_status.∀st1,st2.
310  trace_label_label S doesnt_end_with_ret st1 st2 → costlabel ≝
311  λS,st1,st2,tr.as_label_safe … «st2, trace_label_label_label … tr».
312
313lemma trace_any_call_call : ∀S,s,s'.
314  trace_any_call S s s' → as_classifier S s' cl_call.
315#S #s #s' #T elim T //
316qed.
317
318(* an uncalling, unreturning and *unjumping*,
319  as well as unlabelled (but possibly for the first and last statuses)
320  possibly empty trace segment *)
321inductive trace_any_any (S:abstract_status) : S → S → Type[0] ≝
322  | taa_base :
323      ∀start_status: S.
324        trace_any_any S start_status start_status
325  | taa_step :
326      ∀status_pre: S.
327      ∀status_init: S.
328      ∀status_end: S.
329        as_execute S status_pre status_init →
330        trace_any_any S status_init status_end →
331        as_classifier S status_pre cl_other →
332        ¬as_costed … status_init →
333          trace_any_any S status_pre status_end.
334
335let rec taa_status_list S st1 st2 (taa : trace_any_any S st1 st2) on taa : list S ≝
336  match taa with
337  [ taa_base st1' ⇒ [st1']
338  | taa_step st1' st2' st3' _ tl _ _ ⇒ st1' :: taa_status_list … tl
339  ].
340
341let rec taa_append_taa S st1 st2 st3 (taa1 : trace_any_any S st1 st2)
342  on taa1 : trace_any_any S st2 st3 → trace_any_any S st1 st3 ≝
343  match taa1
344  return λst1,st2.λx : trace_any_any S st1 st2.
345    trace_any_any S st2 st3 → trace_any_any S st1 st3
346  with
347  [ taa_base _ ⇒ λtaa2.taa2
348  | taa_step st1' st2' st3' H tl G K ⇒ λtaa2.
349      taa_step … H (taa_append_taa … tl taa2) G K
350  ].
351
352let rec taa_append_tal S st1 fl st2 st3 (taa : trace_any_any S st1 st2)
353  on taa :
354  trace_any_label S fl st2 st3 →
355  trace_any_label S fl st1 st3 ≝
356  match taa
357  return λst1,st2.λx : trace_any_any S st1 st2.
358    trace_any_label S fl st2 st3 → trace_any_label S fl st1 st3
359  with
360  [ taa_base _ ⇒ λtaa2.taa2
361  | taa_step st1' st2' st3' H tl G K ⇒ λtaa2.
362      tal_step_default … H (taa_append_tal … tl taa2) G K
363  ].
364
365let rec tlr_rel S1 st1 st1' S2 st2 st2'
366  (tlr1 : trace_label_return S1 st1 st1')
367  (tlr2 : trace_label_return S2 st2 st2') on tlr1 : Prop ≝
368match tlr1 with
369  [ tlr_base st1 st1' tll1 ⇒
370    match tlr2 with
371    [ tlr_base st2 st2' tll2 ⇒ tll_rel … tll1 tll2
372    | _ ⇒ False
373    ]
374  | tlr_step st1 st1' st1'' tll1 tl1 ⇒
375    match tlr2 with
376    [ tlr_step st2 st2' st2'' tll2 tl2 ⇒
377      tll_rel … tll1 tll2 ∧ tlr_rel … tl1 tl2
378    | _ ⇒ False
379    ]
380  ]
381and tll_rel S1 fl1 st1 st1' S2 fl2 st2 st2'
382 (tll1 : trace_label_label S1 fl1 st1 st1')
383 (tll2 : trace_label_label S2 fl2 st2 st2') on tll1 : Prop ≝
384  match tll1 with
385  [ tll_base fl1 st1 st1' tal1 H ⇒
386    match tll2 with
387    [ tll_base fl2 st2 st2 tal2 G ⇒
388      as_label_safe … («?, H») = as_label_safe … («?, G») ∧
389      tal_rel … tal1 tal2
390    ]
391  ]
392and tal_rel S1 fl1 st1 st1' S2 fl2 st2 st2'
393 (tal1 : trace_any_label S1 fl1 st1 st1')
394 (tal2 : trace_any_label S2 fl2 st2 st2')
395   on tal1 : Prop ≝
396  match tal1 with
397  [ tal_base_not_return st1 st1' _ _ _ ⇒
398    ∃st2mid,taa,H,G,K.
399    tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa
400      (tal_base_not_return ? st2mid st2' H G K)
401  | tal_base_return st1 st1' _ _ ⇒
402    ∃st2mid,taa,H,G.
403    tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa
404      (tal_base_return ? st2mid st2' H G)
405  | tal_base_call st1 st1' st1'' _ _ _ tlr1 _ ⇒
406    ∃st2mid,taa,st2mid',H,G,K,tlr2,L.
407    tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa
408      (tal_base_call ? st2mid st2mid' st2' H G K tlr2 L) ∧
409      tlr_rel … tlr1 tlr2
410  | tal_step_call fl1 st1 st1' st1'' st1''' _ _ _ tlr1 _ tl1 ⇒
411    ∃st2mid,taa,st2_fun,st2_after_fun,H,G,K,tlr2,L,tl2.
412    tal2 ≃ taa_append_tal ? st2 ? st2mid st2' taa
413      (tal_step_call ?? st2mid st2_fun st2_after_fun st2' H G K tlr2 L tl2) ∧
414      tlr_rel … tlr1 tlr2 ∧ tal_rel … tl1 tl2
415  | tal_step_default fl1 st1 st1' st1'' _ tl1 _ _ ⇒
416    tal_rel … tl1 tal2 (* <- this makes it many to many *)
417  ].
Note: See TracBrowser for help on using the browser.