| 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 | { 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 *) |
|---|
| 27 | definition final_abstract_status ≝ abstract_status. |
|---|
| 28 | |
|---|
| 29 | definition as_costed : ∀a_s : abstract_status.a_s → Prop ≝ |
|---|
| 30 | λa_s,st.as_label ? st ≠ None ?. |
|---|
| 31 | |
|---|
| 32 | definition 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 | |
|---|
| 36 | inductive trace_ends_with_ret: Type[0] ≝ |
|---|
| 37 | | ends_with_ret: trace_ends_with_ret |
|---|
| 38 | | doesnt_end_with_ret: trace_ends_with_ret. |
|---|
| 39 | |
|---|
| 40 | inductive 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 |
|---|
| 53 | with 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 |
|---|
| 61 | with 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 | |
|---|
| 114 | let 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 | |
|---|
| 124 | let 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 | ] |
|---|
| 129 | and 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 | ] |
|---|
| 133 | and 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 | |
|---|
| 145 | definition 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 | |
|---|
| 150 | definition 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 | |
|---|
| 157 | let 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)) ≝ ?. |
|---|
| 159 | cases 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 |
|---|
| 163 | qed. |
|---|
| 164 | |
|---|
| 165 | inductive 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 | |
|---|
| 193 | inductive 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 | |
|---|
| 202 | definition 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 | |
|---|
| 208 | coinductive 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 | |
|---|
| 225 | definition 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. *) |
|---|
| 233 | coinductive 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 | |
|---|
| 250 | inductive 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. *) |
|---|
| 269 | inductive 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 | |
|---|
| 288 | let 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 ] ≝ |
|---|
| 290 | match 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 | |
|---|
| 298 | definition 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 | |
|---|
| 302 | lemma 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 |
|---|
| 305 | cases tr |
|---|
| 306 | #f #start #end #tr' #C @(trace_any_label_label … tr') |
|---|
| 307 | qed. |
|---|
| 308 | |
|---|
| 309 | definition 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 | |
|---|
| 313 | lemma 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 // |
|---|
| 316 | qed. |
|---|
| 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 *) |
|---|
| 321 | inductive 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 | |
|---|
| 335 | let 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 | |
|---|
| 341 | let 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 | |
|---|
| 352 | let 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 | |
|---|
| 365 | let 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 ≝ |
|---|
| 368 | match 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 | ] |
|---|
| 381 | and 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 | ] |
|---|
| 392 | and 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 | ]. |
|---|