1open HolKernel Parse boolLib bossLib; 2open optionTheory pairTheory pred_setTheory finite_mapTheory stringTheory; 3open integerTheory listTheory optionTheory rich_listTheory; 4open BasicProvers; 5open for_ndTheory for_nd_semTheory oracleSemTheory simple_traceTheory; 6open relationTheory; 7 8val _ = new_theory "for_osmall"; 9 10val ect = BasicProvers.EVERY_CASE_TAC; 11val fct = BasicProvers.FULL_CASE_TAC; 12 13val some_no_choice = Q.prove ( 14`!f. (some x. f x) = NONE ��� ��?x. f x`, 15 rw [some_def]); 16 17val some_SAT = Q.prove( 18`!P y. (some x. P x) = SOME y ��� P y`, 19rw[some_def,SELECT_THM]>> 20metis_tac[SELECT_AX]) 21 22(* A small step semantics for the non-deterministic FOR language with I/O *) 23 24(* Add AddL and AddR to model making the choice one which sub-expression to 25 * evaluate before starting the evaluation. Thus preventing switching in the 26 * middle of evaluating one of them. 27 *) 28val _ = Datatype ` 29small_e = 30 | Var string 31 | Num int 32 | Add small_e small_e 33 | AddL small_e small_e 34 | AddR small_e small_e 35 | Assign string small_e 36 | Getchar 37 | Putchar small_e`; 38 39(* Add a Handle statement that will stop breaks from propagating *) 40val _ = Datatype ` 41small_t = 42 | Dec string small_t 43 | Exp small_e 44 | Break 45 | Seq small_t small_t 46 | If small_e small_t small_t 47 | For small_e small_e small_t 48 | Handle small_t`; 49 50val _ = Datatype ` 51 lab = ND bool | W char | R char`; 52 53val e_to_small_e_def = Define ` 54(e_to_small_e ((Num i):e) = ((Num i) : small_e)) ��� 55(e_to_small_e (Var x) = Var x) ��� 56(e_to_small_e (Add e1 e2) = Add (e_to_small_e e1) (e_to_small_e e2)) ��� 57(e_to_small_e (Assign x e) = Assign x (e_to_small_e e)) ��� 58(e_to_small_e Getchar = Getchar) ��� 59(e_to_small_e (Putchar e) = Putchar (e_to_small_e e))`; 60 61val t_to_small_t_def = Define ` 62(t_to_small_t ((Dec string t):t) = ((Dec string (t_to_small_t t)) : small_t)) ��� 63(t_to_small_t (Exp e) = Exp (e_to_small_e e)) ��� 64(t_to_small_t Break = Break) ��� 65(t_to_small_t (Seq t1 t2) = Seq (t_to_small_t t1) (t_to_small_t t2)) ��� 66(t_to_small_t (If e t1 t2) = If (e_to_small_e e) (t_to_small_t t1) (t_to_small_t t2)) ��� 67(t_to_small_t (For e1 e2 t) = For (e_to_small_e e1) (e_to_small_e e2) (t_to_small_t t))`; 68 69val is_val_e_def = Define ` 70(is_val_e (Num n) = T) ��� 71(is_val_e _ = F)`; 72 73val (step_e_rules, step_e_ind, step_e_cases) = Hol_reln ` 74(!s x n. 75 FLOOKUP s.store x = SOME n 76 ��� 77 step_e (s, Var x) NONE (s, Num n)) ��� 78(!s e1 e2 o'. 79 oracle_get s.non_det_o = (F, o') 80 ��� 81 step_e (s, Add e1 e2) 82 (SOME (INR F)) 83 (s with <| non_det_o := o'; io_trace := s.io_trace ++ [INR F] |>, AddL e1 e2)) ��� 84(!s e1 e2 o'. 85 oracle_get s.non_det_o = (T, o') 86 ��� 87 step_e (s, Add e1 e2) (SOME (INR T)) (s with <| non_det_o := o'; io_trace := s.io_trace ++ [INR T] |>, AddR e1 e2)) ��� 88(!s n1 n2. 89 step_e (s, AddL (Num n1) (Num n2)) NONE (s, Num (n1 + n2))) ��� 90(!s n1 n2. 91 step_e (s, AddR (Num n1) (Num n2)) NONE (s, Num (n1 + n2))) ��� 92(!s s2 e1 e2 e3 l. 93 step_e (s, e1) l (s2, e3) 94 ��� 95 step_e (s, AddL e1 e2) l (s2, AddL e3 e2)) ��� 96(!s s2 i e1 e2 l. 97 step_e (s, e1) l (s2, e2) 98 ��� 99 step_e (s, AddL (Num i) e1) l (s2, AddL (Num i) e2)) ��� 100(!s s2 i e1 e2 l. 101 step_e (s, e1) l (s2, e2) 102 ��� 103 step_e (s, AddR e1 (Num i)) l (s2, AddR e2 (Num i))) ��� 104(!s s2 e1 e2 e3 l. 105 step_e (s, e2) l (s2, e3) 106 ��� 107 step_e (s, AddR e1 e2) l (s2, AddR e1 e3)) ��� 108(!s x n. 109 step_e (s, Assign x (Num n)) NONE (s with store := s.store |+ (x, n), Num n)) ��� 110(!s s2 x e1 e2 l. 111 step_e (s, e1) l (s2, e2) 112 ��� 113 step_e (s, Assign x e1) l (s2, Assign x e2)) ��� 114(!s i input'. 115 getchar s.input = (i,input') 116 ��� 117 step_e (s, Getchar) 118 (SOME (INL (Itag i))) 119 (s with <| input := input'; io_trace := s.io_trace ++ [INL (Itag i)] |>, Num i)) ��� 120(!s s2 e1 e2 l. 121 step_e (s, e1) l (s2, e2) 122 ��� 123 step_e (s, Putchar e1) l (s2, Putchar e2)) ��� 124(!s i. 125 step_e (s, Putchar (Num i)) 126 (SOME (INL (Otag i))) 127 (s with io_trace := s.io_trace ++ [INL (Otag i)], Num i))`; 128 129val is_val_t_def = Define ` 130(is_val_t (Exp (e : small_e)) = is_val_e e) ��� 131(is_val_t Break = T) ��� 132(is_val_t _ = F)`; 133 134val (step_t_rules, step_t_ind, step_t_cases) = Hol_reln ` 135(!s t x. 136 step_t (s, Dec x t) NONE (s with store := s.store |+ (x, 0), t)) ��� 137(!s s2 e e2 l. 138 step_e (s, e) l (s2, e2) 139 ��� 140 step_t (s, Exp e) l (s2, Exp e2)) ��� 141(!s s2 t1 t2 t1' l. 142 step_t (s, t1) l (s2, t1') 143 ��� 144 step_t (s, Seq t1 t2) l (s2, Seq t1' t2)) ��� 145(!s t. 146 step_t (s, Seq Break t) NONE (s, Break)) ��� 147(!s n t. 148 step_t (s, Seq (Exp (Num n)) t) NONE (s, t)) ��� 149(!s s2 e t1 t2 e2 l. 150 step_e (s, e) l (s2,e2) 151 ��� 152 step_t (s, If e t1 t2) l (s2, If e2 t1 t2)) ��� 153(!s t1 t2. 154 step_t (s, If (Num 0) t1 t2) NONE (s, t2)) ��� 155(!s n t1 t2. 156 n ��� 0 157 ��� 158 step_t (s, If (Num n) t1 t2) NONE (s, t1)) ��� 159(!s. 160 step_t (s, Handle Break) NONE (s, Exp (Num 0))) ��� 161(!s t. 162 is_val_t t ��� 163 t ��� Break 164 ��� 165 step_t (s, Handle t) NONE (s, t)) ��� 166(!s1 s2 t1 t2 l. 167 step_t (s1, t1) l (s2, t2) 168 ��� 169 step_t (s1, Handle t1) l (s2, Handle t2)) ��� 170(!s e1 e2 t. 171 step_t (s, For e1 e2 t) NONE (s, Handle (If e1 (Seq t (Seq (Exp e2) (For e1 e2 t))) (Exp (Num 0)))))`; 172 173val filter_map_def = Define ` 174(filter_map f [] = []) ��� 175(filter_map f (h::t) = 176 case f h of 177 | NONE => filter_map f t 178 | SOME x => x :: filter_map f t)`; 179 180val path_to_obs_def = Define ` 181 path_to_obs p = 182 if ��finite p then 183 Diverge (lfilter_map I (labels p)) 184 else if is_val_t (SND (last p)) then 185 Terminate (filter_map I (THE (toList (labels p)))) 186 else 187 Crash`; 188 189val semantics_small_def = Define ` 190 (semantics_small input prog = 191 { path_to_obs p | p,nd | 192 okpath step_t p ��� complete step_t p ��� first p = (init_st 0 nd input, t_to_small_t prog) })`; 193 194(* ----------- Connect to functional big step -------------- *) 195 196val for_small_sem_def = Define ` 197 for_small_sem input = 198 <| step := (\st. some st'. ?l. step_t st l st'); 199 is_result := (\st. is_val_t (SND st)); 200 load := (\nd t. (init_st 0 nd input , t_to_small_t t)); 201 unload := (\st. (FST st).io_trace) |>`; 202 203val for_eval_def = Define ` 204 for_eval st env t = 205 case sem_t st t of 206 (Rval v, s) => (s, Val (SOME v)) 207 | (Rbreak, s) => (s, Val NONE) 208 | (Rtimeout, s) => (s, Timeout) 209 | (Rfail, s) => (s, Error)`; 210 211val for_big_sem_def = Define ` 212 for_big_sem input = 213 <| eval := for_eval; 214 init_st := (\nd. init_st 0 nd input); 215 init_env := (); 216 get_clock := (\x. x.clock); 217 set_clock := (\c st. st with clock := c); 218 get_oracle_events := (\st. st.io_trace) |>`; 219 220val (res_rel_t_rules, res_rel_t_ind, res_rel_t_cases) = Hol_reln ` 221(!i s. 222 res_rel_t (Rval i, s) (s with clock := 0, Exp (Num i))) ��� 223(!s t. 224 (~?l s' t'. step_t (s with clock := 0, t) l (s', t')) ��� 225 ~is_val_t t 226 ��� 227 res_rel_t (Rfail, s) (s with clock := 0, t)) ��� 228(!s. 229 res_rel_t (Rbreak, s) (s with clock := 0, Break)) ��� 230(!s t. 231 (?l s' t'. step_t (s, t) l (s', t')) ��� 232 s.clock = 0 233 ��� 234 res_rel_t (Rtimeout, s) (s, t))`; 235 236val (res_rel_e_rules, res_rel_e_ind, res_rel_e_cases) = Hol_reln ` 237(!i s. 238 res_rel_e (Rval i, s) (s with clock:=0, Num i)) ��� 239(!s e. 240 (~?s' e' l. step_e (s, e) l (s', e')) ��� 241 ~is_val_e e 242 ��� 243 res_rel_e (Rfail, s) (s with clock:=0, e))` 244 245val _ = set_trace "Goalstack.print_goal_at_top" 0; 246 247val step_t_strongind = (fetch "-" "step_t_strongind") 248val step_e_strongind = (fetch "-" "step_e_strongind") 249 250val conjs_def = Define` conjs A B ��� A ��� B` 251 252val etac = (fs[Once step_t_cases]>>fs[Once step_t_cases,Once step_e_cases,conjs_def]) 253 254(* Determinism of small-step w.r.t. an oracle *) 255 256val step_e_determ = Q.prove( 257` ���se l1 se1. 258 step_e se l1 se1 ��� 259 (���l2 se2. 260 step_e se l2 se2 ��� conjs (se1 = se2) (l1 = l2))`, 261 ho_match_mp_tac step_e_strongind>>rw[]>>fs[FORALL_PROD] 262 >- (rw[conjs_def]>>fs[Once step_e_cases]>>rfs[]) 263 >- (rw[conjs_def]>>ntac 2(fs[Once step_e_cases]>>rfs[])) 264 >- (rw[conjs_def]>>ntac 2(fs[Once step_e_cases]>>rfs[])) 265 >- (rw[conjs_def]>>ntac 2(fs[Once step_e_cases]>>rfs[])) 266 >- (rw[conjs_def]>>ntac 2(fs[Once step_e_cases]>>rfs[])) 267 >> 268 TRY 269 (pop_assum mp_tac>>simp[Once step_e_cases]>>rw[]>> 270 fs[Once step_e_cases]) 271 >> 272 fs[conjs_def])|>REWRITE_RULE[conjs_def] 273 274val step_t_determ = Q.prove( 275` ���st l1 st1. 276 step_t st l1 st1 ��� 277 (���l2 st2. 278 step_t st l2 st2 ��� conjs (st1 = st2) (l1 = l2))`, 279 ho_match_mp_tac step_t_strongind >>rw[] 280 >- etac 281 >- 282 (fs[Once step_t_cases]>> 283 imp_res_tac step_e_determ>> 284 fs[conjs_def]) 285 >- 286 (pop_assum mp_tac>> 287 simp[Once step_t_cases]>>fs[FORALL_PROD]>>rw[]>> 288 fs[Once step_t_cases,Once step_e_cases]) 289 >- etac 290 >- etac 291 >- 292 (fs[Once step_t_cases] 293 >- 294 (imp_res_tac step_e_determ>>fs[conjs_def]) 295 >> etac) 296 >- etac 297 >- etac 298 >- etac 299 >- 300 (fs[Once step_t_cases]>>rfs[conjs_def]>> 301 Cases_on`t`>>fs[is_val_t_def]>> 302 Cases_on`s'`>>fs[is_val_e_def]>> 303 fs[Once step_t_cases]>> 304 fs[Once step_e_cases]) 305 >- 306 (pop_assum mp_tac>> 307 simp[Once step_t_cases]>>rw[] 308 >- 309 etac 310 >- 311 (Cases_on`t1`>>fs[is_val_t_def]>>Cases_on`s`>>fs[is_val_e_def]>> 312 fs[Once step_t_cases,Once step_e_cases]) 313 >> 314 fs[FORALL_PROD]>>metis_tac[]) 315 >> 316 fs[Once step_t_cases,conjs_def])|>REWRITE_RULE[conjs_def] 317 318val step_t_select_unique = Q.prove( 319`step_t (q,r) l st' ��� 320 (@st'. ���l. step_t (q,r) l st') = st'`, 321 rw[]>> 322 metis_tac[step_t_determ]) 323 324val some_to_SOME_step_e = Q.prove( 325`step_e A l B ��� 326 (some st'. ���l. step_e A l st') = SOME B`, 327 rw[]>>fs[some_def]>> 328 metis_tac[step_e_determ]) |> GEN_ALL 329 330val some_to_SOME_step_t = Q.prove( 331`step_t A l B ��� 332 (some st'. ���l. step_t A l st') = 333 SOME B`, 334 rw[]>>fs[some_def]>>metis_tac[step_t_determ]) |>GEN_ALL 335 336(* Contextual transitions of the small step semantics *) 337val check_trace_seq = Q.prove( 338`���tr. 339 check_trace (��st. some st'. ���l. step_t st l st') tr ��� 340 check_trace (��st. some st'. ���l. step_t st l st') (MAP (��st,t. (st,Seq t p)) tr)`, 341 Induct>>rw[]>> 342 Cases_on`tr`>>fs[check_trace_def]>> 343 Cases_on`h`>>Cases_on`h'`>> 344 match_mp_tac some_to_SOME_step_t>> 345 fs[some_def]>> 346 simp[Once step_t_cases]>> 347 metis_tac[step_t_select_unique]) 348 349val check_trace_assign = Q.prove( 350`���tr. 351 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 352 check_trace (��st. some st'. ?l. step_e st l st') (MAP (��st,e. (st,Assign s e)) tr)`, 353 Induct>>rw[]>>Cases_on`tr`>>fs[check_trace_def]>> 354 Cases_on`h`>>Cases_on`h'`>> 355 match_mp_tac some_to_SOME_step_e>> 356 fs[some_def]>> 357 simp[Once step_e_cases]>> 358 metis_tac[step_e_determ]) 359 360val check_trace_putchar = Q.prove( 361`���tr. 362 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 363 check_trace (��st. some st'. ?l. step_e st l st') (MAP (��st,e. (st,Putchar e)) tr)`, 364 Induct>>rw[]>>Cases_on`tr`>>fs[check_trace_def]>> 365 Cases_on`h`>>Cases_on`h'`>> 366 match_mp_tac some_to_SOME_step_e>> 367 fs[some_def]>> 368 simp[Once step_e_cases]>> 369 metis_tac[step_e_determ]) 370 371val check_trace_addl1 = Q.prove( 372`���tr. 373 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 374 check_trace (��st. some st'. ?l. step_e st l st') (MAP (��st,e. (st,AddL e e')) tr)`, 375 Induct>>rw[]>>Cases_on`tr`>>fs[check_trace_def]>> 376 Cases_on`h`>>Cases_on`h'`>> 377 match_mp_tac some_to_SOME_step_e>> 378 fs[some_def]>> 379 simp[Once step_e_cases]>> 380 metis_tac[step_e_determ]) 381 382val check_trace_addl2 = Q.prove( 383`���tr. 384 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 385 check_trace (��st. some st'. ?l. step_e st l st') (MAP (��st,e'. (st,AddL (Num i) e')) tr)`, 386 Induct>>rw[]>>Cases_on`tr`>>fs[check_trace_def]>> 387 Cases_on`h`>>Cases_on`h'`>> 388 match_mp_tac some_to_SOME_step_e>> 389 fs[some_def]>> 390 simp[Once step_e_cases]>> 391 metis_tac[step_e_determ]) 392 393val check_trace_addr1 = Q.prove( 394`���tr. 395 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 396 check_trace (��st. some st'. ?l. step_e st l st') (MAP (��st,e'. (st,AddR e e')) tr)`, 397 Induct>>rw[]>>Cases_on`tr`>>fs[check_trace_def]>> 398 Cases_on`h`>>Cases_on`h'`>> 399 match_mp_tac some_to_SOME_step_e>> 400 fs[some_def]>> 401 simp[Once step_e_cases]>> 402 metis_tac[step_e_determ,is_val_e_def]) 403 404val check_trace_addr2 = Q.prove( 405`���tr. 406 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 407 check_trace (��st. some st'. ?l. step_e st l st') (MAP (��st,e'. (st,AddR e' (Num i))) tr)`, 408 Induct>>rw[]>>Cases_on`tr`>>fs[check_trace_def]>> 409 Cases_on`h`>>Cases_on`h'`>> 410 match_mp_tac some_to_SOME_step_e>> 411 fs[some_def]>> 412 simp[Once step_e_cases]>> 413 metis_tac[step_e_determ,is_val_e_def]) 414 415val check_trace_exp = Q.prove( 416`���tr. 417 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 418 check_trace (��st. some st'. ?l. step_t st l st') (MAP (��st,e'. (st,Exp e')) tr)`, 419 Induct>>rw[check_trace_def]>>Cases_on`tr`>>fs[check_trace_def]>> 420 Cases_on`h`>>Cases_on`h'`>> 421 match_mp_tac some_to_SOME_step_t>> 422 fs[some_def]>> 423 simp[Once step_t_cases]>> 424 metis_tac[step_e_determ]) 425 426val check_trace_if1 = Q.prove( 427`���tr. 428 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 429 check_trace (��st. some st'. ?l. step_t st l st') (MAP (��st,e'. (st,If e' a b)) tr)`, 430 Induct>>rw[check_trace_def]>>Cases_on`tr`>>fs[check_trace_def]>> 431 Cases_on`h`>>Cases_on`h'`>> 432 match_mp_tac some_to_SOME_step_t>> 433 fs[some_def]>> 434 simp[Once step_t_cases]>> 435 metis_tac[step_e_determ]) 436 437val check_trace_for1 = Q.prove( 438`���tr. 439 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 440 check_trace (��st. some st'. ?l. step_t st l st') 441 (MAP (��st,e'. (st, 442 Handle (If e' a b))) tr)`, 443 Induct>>rw[check_trace_def]>>Cases_on`tr`>>fs[check_trace_def]>> 444 Cases_on`h`>>Cases_on`h'`>> 445 match_mp_tac some_to_SOME_step_t>> 446 fs[some_def]>> 447 simp[Once step_t_cases]>> 448 simp[Once step_t_cases]>> 449 metis_tac[step_e_determ]) 450 451val check_trace_for2 = Q.prove( 452`���tr. 453 check_trace (��st. some st'. ?l. step_t st l st') tr ��� 454 check_trace (��st. some st'. ?l. step_t st l st') 455 (MAP (��st,t'. (st, 456 Handle (Seq t' a))) tr)`, 457 Induct>>rw[check_trace_def]>>Cases_on`tr`>>fs[check_trace_def]>> 458 Cases_on`h`>>Cases_on`h'`>> 459 match_mp_tac some_to_SOME_step_t>> 460 fs[some_def]>> 461 simp[Once step_t_cases]>> 462 simp[Once step_t_cases]>> 463 metis_tac[step_e_determ]) 464 465val check_trace_for3 = Q.prove( 466`���tr. 467 check_trace (��st. some st'. ?l. step_e st l st') tr ��� 468 check_trace (��st. some st'. ?l. step_t st l st') 469 (MAP (��st,e'. (st, 470 Handle (Seq (Exp e') a))) tr)`, 471 Induct>>rw[check_trace_def]>>Cases_on`tr`>>fs[check_trace_def]>> 472 Cases_on`h`>>Cases_on`h'`>> 473 match_mp_tac some_to_SOME_step_t>> 474 fs[some_def]>> 475 ntac 3 (simp[Once step_t_cases])>> 476 metis_tac[step_e_determ]) 477 478val check_trace_handle = Q.prove( 479`���tr. 480 check_trace (��st. some st'. ?l. step_t st l st') tr ��� 481 check_trace (��st. some st'. ?l. step_t st l st') 482 (MAP (��st,t'. (st, 483 Handle t')) tr)`, 484 Induct>>rw[check_trace_def]>>Cases_on`tr`>>fs[check_trace_def]>> 485 Cases_on`h`>>Cases_on`h'`>> 486 match_mp_tac some_to_SOME_step_t>> 487 fs[some_def]>> 488 simp[Once step_t_cases]>> 489 Cases_on`st'`>>metis_tac[step_t_determ]) 490 491(* Non-existence of contextual transitions in small-step *) 492val no_step_e_assign = Q.prove( 493`���e. 494 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 495 ��is_val_e e 496 ��� 497 ���s' e' l. ��step_e (s,Assign v e) l (s',e')`, 498 Induct>>rw[is_val_e_def]>> 499 simp[Once step_e_cases]) 500 501val no_step_e_putchar = Q.prove( 502`���e. 503 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 504 ��is_val_e e 505 ��� 506 ���s' e' l. ��step_e (s,Putchar e) l (s',e')`, 507 Induct>>rw[is_val_e_def]>> 508 simp[Once step_e_cases]) 509 510val no_step_e_addl1 = Q.prove( 511`���e. 512 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 513 ��is_val_e e 514 ��� 515 ���s' e' l. ��step_e (s,AddL e e'') l (s',e')`, 516 Induct>>rw[is_val_e_def]>>simp[Once step_e_cases,is_val_e_def]) 517 518val no_step_e_addl2 = Q.prove( 519`���e. 520 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 521 ��is_val_e e 522 ��� 523 ���s' e' l. ��step_e (s,AddL (Num i) e) l (s',e')`, 524 Induct>>rw[is_val_e_def]>>rpt (simp[Once step_e_cases,is_val_e_def])) 525 526val no_step_e_addr1 = Q.prove( 527`���e. 528 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 529 ��is_val_e e 530 ��� 531 ���s' e' l. ��step_e (s,AddR e'' e) l (s',e')`, 532 Induct>>rw[is_val_e_def]>> 533 rpt (simp[Once step_e_cases])) 534 535val no_step_e_addr2 = Q.prove( 536`���e. 537 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 538 ��is_val_e e 539 ��� 540 ���s' e' l. ��step_e (s,AddR e (Num i)) l (s',e')`, 541 Induct>>rw[is_val_e_def]>> 542 rpt (simp[Once step_e_cases])) 543 544val no_step_t_exp = Q.prove( 545`���e. 546 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 547 ��is_val_e e 548 ��� 549 ���s' t' l. ��step_t (s,Exp e) l (s',t')`, 550 Induct>>rw[is_val_e_def]>> 551 simp[Once step_t_cases]) 552 553val no_step_t_seq = Q.prove( 554`���t. 555 (���s' t' l. ��step_t (s,t) l (s',t')) ��� 556 ��is_val_t t 557 ��� 558 ���s' t' l. ��step_t (s,Seq t p) l (s',t')`, 559 Induct>>rw[is_val_t_def]>> 560 simp[Once step_t_cases]>> 561 Cases_on`s'`>>fs[is_val_e_def]) 562 563val no_step_t_if1 = Q.prove( 564`���e. 565 (���s' e' l. ��step_e (s,e) l (s',e')) ��� 566 ��is_val_e e 567 ��� 568 ���s' t' l. ��step_t (s,If e a b) l (s',t')`, 569 Induct>>rw[is_val_e_def]>> 570 simp[Once step_t_cases]) 571 572val no_step_t_handle = Q.prove( 573`���t. 574 (���s' t' l. ��step_t (s,t) l (s',t')) ��� 575 ��is_val_t t 576 ��� 577 ���s' t' l. ��step_t (s,Handle t) l (s',t')`, 578 Induct>>rw[is_val_t_def]>> 579 simp[Once step_t_cases,is_val_t_def]) 580 581val LAST_MAP = Q.prove( 582`���ls. ls ��� [] ��� LAST (MAP f ls) = f (LAST ls)`, 583 Induct>>fs[LAST_DEF]>>rw[]) 584 585val HD_MAP = Q.prove( 586`���ls. ls ��� [] ��� HD(MAP f ls) = f (HD ls)`, 587 Induct>>rw[]) 588 589val HD_APPEND = Q.prove( 590`ls ��� [] ��� HD (ls ++ ls') = HD ls`, 591Cases_on`ls`>>fs[]) 592 593val LAST_APPEND = Q.prove( 594`ls' ��� [] ��� LAST (ls ++ ls') = LAST ls'`, 595Cases_on`ls'`>>fs[]) 596 597val sem_e_not_timeout = Q.prove ( 598`!st e r. sem_e st e ��� (Rtimeout, r)`, 599 Induct_on `e` >> 600 rw [sem_e_def, LET_THM, permute_pair_def, oracle_get_def, unpermute_pair_def, getchar_def] >> 601 ect >> 602 fs [] >> 603 metis_tac []); 604 605val sem_e_not_break = Q.prove( 606`!st e r. sem_e st e ��� (Rbreak,r)`, 607 Induct_on`e`>>srw_tac[][sem_e_def]>> 608 ect>> 609 fs[LET_THM,unpermute_pair_def,permute_pair_def,oracle_get_def] >> 610 qpat_x_assum `_ = (fst_e,snd_e)` mp_tac >> rw[] >> 611 rename1 `sem_e st' _ = (Rbreak, new_r)` >> 612 first_x_assum (qspecl_then [`st'`,`new_r`] assume_tac) >> 613 first_x_assum (qspecl_then [`st'`,`new_r`] assume_tac) >> 614 fs[] 615 ); 616 617val LAST_HD_eq = Q.prove(` 618���ls ls'. 619 ls ��� [] ��� ls' ��� [] ��� 620 LAST ls = HD ls' ��� 621 BUTLASTN 1 ls ++ ls' = 622 ls ++ TL ls'`, 623 Induct>>fs[LAST_DEF,BUTLASTN_1]>>rw[]>> 624 Cases_on`ls'`>>fs[FRONT_DEF]) 625 626val check_trace_append3 = Q.prove(` 627 check_trace f ls ��� 628 f h = SOME (HD ls) ��� 629 check_trace f (h :: ls)`, 630 rw[]>>imp_res_tac check_trace_append2>> 631 pop_assum(qspec_then`[h]`assume_tac)>>fs[]>> 632 rfs[check_trace_def]) 633 634val check_trace_tl = Q.prove(` 635 check_trace f ls ��� ls ��� [] ��� 636 check_trace f (TL ls)`, 637 Cases_on`ls`>>fs[check_trace_def]>> 638 Cases_on`t`>>fs[check_trace_def]) 639 640(* Start connecting functional big step to small step traces *) 641local val rw = srw_tac[] val fs = fsrw_tac[] in 642val sem_e_big_small_lem = Q.prove( 643`!s e r. 644 sem_e s e = r 645 ��� 646 ?tr. 647 tr ��� [] ��� 648 check_trace (\st. some st'. ?l. step_e st l st') tr ��� 649 HD tr = (s with clock:=0, e_to_small_e e) ��� 650 res_rel_e r (LAST tr)`, 651 Induct_on`e`>>rw[]>>fs[sem_e_def,e_to_small_e_def] 652 >- ( 653 fct>>fs[res_rel_e_cases] 654 >- ( 655 qexists_tac`[(s' with clock:=0,Var s)]`>>fs[check_trace_def,is_val_e_def]>> 656 simp[Once step_e_cases] 657 ) 658 >- ( 659 qexists_tac`[(s' with clock:=0,Var s);(s' with clock:=0,Num x)]`>> 660 fs[check_trace_def,some_def]>> 661 ntac 2 (simp[Once step_e_cases]) 662 ) 663 ) 664 >- ( 665 fs[res_rel_e_cases]>> 666 qexists_tac`[s with clock:=0,Num i]`>>fs[check_trace_def] 667 ) 668 >- ( 669 fs[LET_THM,permute_pair_def,oracle_get_def]>>IF_CASES_TAC>>fs[] 670 >- ( 671 qpat_abbrev_tac`st = s with <|io_trace:=B;non_det_o:=C|>`>> 672 first_x_assum(qspec_then`st`assume_tac)>> 673 Cases_on`sem_e st e'`>>Cases_on`q`>> 674 fs[sem_e_not_break,sem_e_not_timeout,unpermute_pair_def] 675 >- ( 676 fct>>Cases_on`q`>> 677 fs[sem_e_not_break,sem_e_not_timeout]>> 678 last_x_assum(qspec_then`r` assume_tac)>>rfs[]>> 679 qpat_abbrev_tac`h =(A,B)`>> 680 qabbrev_tac`ls1 = (MAP (��st,e'. (st,AddR (e_to_small_e e) e')) tr)`>> 681 qabbrev_tac`ls2 = (MAP (��st,e'. (st,AddR e' (Num i))) tr')`>> 682 qabbrev_tac`ls = BUTLASTN 1 ls1 ++ ls2`>> 683 fs[res_rel_e_cases]>> 684 `LAST ls1 = HD ls2` by 685 (unabbrev_all_tac>>fs[LAST_MAP,HD_MAP])>> 686 `ls = ls1 ++ (TL ls2)` by 687 (unabbrev_all_tac>> 688 fs[LAST_HD_eq])>> 689 `check_trace (��st. some st'. ���l. step_e st l st') ls2` by 690 fs[Abbr`ls2`,check_trace_addr2]>> 691 `check_trace (��st. some st'. ���l. step_e st l st') ls` by ( 692 fs[Abbr`ls`]>>Cases_on`ls2`>>fs[]>>Cases_on`t`>>fs[] 693 >- fs[check_trace_addr1,Abbr`ls1`] >> 694 match_mp_tac check_trace_append2>>rw[] 695 >- fs[check_trace_addr1,Abbr`ls1`] 696 >- ( 697 fs[markerTheory.Abbrev_def]>> 698 `h''::t' = TL (LAST ls1::h''::t')` by fs[]>> 699 pop_assum SUBST_ALL_TAC>> 700 match_mp_tac check_trace_tl>>fs[check_trace_addr2] 701 ) >> 702 fs[check_trace_def] 703 ) 704 >- ( 705 qexists_tac`[h] ++ ls ++ [(r' with clock:=0,Num(i'+i))]`>> 706 rw[]>> 707 match_mp_tac check_trace_append3>>fs[check_trace_def]>>rw[] 708 >- ( 709 match_mp_tac check_trace_append2>> 710 fs[check_trace_def]>> 711 fs[markerTheory.Abbrev_def,LAST_APPEND,LAST_MAP]>> 712 match_mp_tac some_to_SOME_step_e>> 713 simp[Once step_e_cases] 714 ) >> 715 match_mp_tac some_to_SOME_step_e>> 716 fs[HD_APPEND,Abbr`ls1`,HD_MAP,Abbr`h`,Abbr`st`]>> 717 simp[Once step_e_cases,oracle_get_def] 718 ) >> 719 qexists_tac`[h]++ls` >>rw[] 720 >- ( 721 match_mp_tac check_trace_append3>> 722 fs[HD_APPEND,Abbr`ls1`,HD_MAP]>> 723 match_mp_tac some_to_SOME_step_e>> 724 fs[Abbr`h`,Abbr`st`]>> 725 simp[Once step_e_cases,oracle_get_def] 726 ) >> 727 fs[markerTheory.Abbrev_def,LAST_DEF,LAST_APPEND,LAST_MAP, 728 is_val_e_def,no_step_e_addr2] 729 ) 730 >- ( 731 qpat_abbrev_tac`h =(A,B)`>> 732 qexists_tac`[h]++(MAP (��st,e'. (st,AddR (e_to_small_e e) e')) tr)`>> 733 fs[HD_MAP,res_rel_e_cases,LAST_MAP,is_val_e_def, 734 LAST_APPEND,no_step_e_addr1]>> 735 match_mp_tac check_trace_append3>>fs[check_trace_addr1,HD_MAP]>> 736 match_mp_tac some_to_SOME_step_e>> 737 unabbrev_all_tac>> 738 simp[Once step_e_cases,oracle_get_def] 739 ) 740 ) 741 >- ( 742 (*symmetric*) 743 qpat_abbrev_tac`st = s with <|io_trace:=B;non_det_o:=C|>`>> 744 last_x_assum(qspec_then`st`assume_tac)>> 745 Cases_on`sem_e st e`>>Cases_on`q`>> 746 fs[sem_e_not_break,sem_e_not_timeout,unpermute_pair_def] 747 >- ( 748 fct>>Cases_on`q`>> 749 fs[sem_e_not_break,sem_e_not_timeout]>> 750 last_x_assum(qspec_then`r` assume_tac)>>rfs[]>> 751 qpat_abbrev_tac`h =(A,B)`>> 752 qabbrev_tac`ls1 = (MAP (��st,e. (st,AddL e (e_to_small_e e'))) tr)`>> 753 qabbrev_tac`ls2 = (MAP (��st,e'. (st,AddL (Num i) e')) tr')`>> 754 qabbrev_tac`ls = BUTLASTN 1 ls1 ++ ls2`>> 755 fs[res_rel_e_cases]>> 756 `LAST ls1 = HD ls2` by 757 (unabbrev_all_tac>>fs[LAST_MAP,HD_MAP])>> 758 `ls = ls1 ++ (TL ls2)` by 759 (unabbrev_all_tac>> 760 fs[LAST_HD_eq])>> 761 `check_trace (��st. some st'. ���l. step_e st l st') ls2` by 762 fs[Abbr`ls2`,check_trace_addl2]>> 763 `check_trace (��st. some st'. ���l. step_e st l st') ls` by ( 764 fs[Abbr`ls`]>>Cases_on`ls2`>>fs[]>>Cases_on`t`>>fs[] 765 >- fs[check_trace_addl1,Abbr`ls1`] >> 766 match_mp_tac check_trace_append2>>rw[] 767 >- fs[check_trace_addl1,Abbr`ls1`] 768 >- ( 769 fs[markerTheory.Abbrev_def]>> 770 `h''::t' = TL (LAST ls1::h''::t')` by fs[]>> 771 pop_assum SUBST_ALL_TAC>> 772 match_mp_tac check_trace_tl>>fs[check_trace_addr2] 773 ) >> 774 fs[check_trace_def] 775 ) 776 >- ( 777 qexists_tac`[h] ++ ls ++ [(r' with clock:=0,Num(i+i'))]`>> 778 rw[]>> 779 match_mp_tac check_trace_append3>>fs[check_trace_def]>>rw[] 780 >- ( 781 match_mp_tac check_trace_append2>> 782 fs[check_trace_def]>> 783 fs[markerTheory.Abbrev_def,LAST_APPEND,LAST_MAP]>> 784 match_mp_tac some_to_SOME_step_e>> 785 simp[Once step_e_cases] 786 ) >> 787 match_mp_tac some_to_SOME_step_e>> 788 fs[HD_APPEND,Abbr`ls1`,HD_MAP,Abbr`h`,Abbr`st`]>> 789 simp[Once step_e_cases,oracle_get_def] 790 ) 791 >- ( 792 qexists_tac`[h]++ls` >>rw[] 793 >- ( 794 match_mp_tac check_trace_append3>> 795 fs[HD_APPEND,Abbr`ls1`,HD_MAP]>> 796 match_mp_tac some_to_SOME_step_e>> 797 fs[Abbr`h`,Abbr`st`]>> 798 simp[Once step_e_cases,oracle_get_def] 799 ) >> 800 fs[markerTheory.Abbrev_def,LAST_DEF,LAST_APPEND,LAST_MAP, 801 is_val_e_def,no_step_e_addl2] 802 ) 803 ) 804 >- ( 805 qpat_abbrev_tac`h =(A,B)`>> 806 qexists_tac`[h]++(MAP (��st,e. (st,AddL e (e_to_small_e e'))) tr)`>> 807 fs[HD_MAP,res_rel_e_cases,LAST_MAP,is_val_e_def,LAST_APPEND, 808 no_step_e_addl1]>> 809 match_mp_tac check_trace_append3>>fs[check_trace_addl1,HD_MAP]>> 810 match_mp_tac some_to_SOME_step_e>> 811 unabbrev_all_tac>> 812 simp[Once step_e_cases,oracle_get_def] 813 ) 814 ) 815 ) 816 >- ( 817 EVERY_CASE_TAC>>fs[res_rel_e_cases,sem_e_not_break,sem_e_not_timeout]>> 818 first_x_assum(qspec_then`s'` assume_tac)>>rfs[] 819 >- ( 820 qexists_tac`(MAP (��st,e. (st,Assign s e)) tr)++ 821 [r with <|store :=r.store |+ (s,i); clock:=0|>,Num i]`>> 822 fs[HD_MAP,HD_APPEND]>> 823 ho_match_mp_tac check_trace_append2>> 824 fs[check_trace_def,LAST_MAP,check_trace_assign]>> 825 ntac 2 (simp[Once step_e_cases]) 826 ) >> 827 ( 828 qexists_tac`(MAP (��st,e. (st,Assign s e)) tr)`>> 829 fs[HD_MAP,LAST_MAP,is_val_e_def,no_step_e_assign,check_trace_assign] 830 ) 831 ) 832 >- ( 833 Cases_on`getchar s.input`>>fs[LET_THM,res_rel_e_cases]>> 834 qpat_abbrev_tac`t = (A,B)`>> 835 qpat_abbrev_tac`t' = (A,B)`>> 836 qexists_tac`[t;t']`>>unabbrev_all_tac>>fs[check_trace_def]>> 837 match_mp_tac some_to_SOME_step_e>> 838 simp[Once step_e_cases] 839 ) 840 >- ( 841 first_x_assum(qspec_then`s` assume_tac)>>fs[]>> 842 Cases_on`sem_e s e`>>Cases_on`q`>>fs[sem_e_not_break,sem_e_not_timeout]>> 843 qpat_abbrev_tac`t = (A,B)`>> 844 qpat_abbrev_tac`t' = (A,B)` 845 >- ( 846 qexists_tac`MAP (��st,e. (st,Putchar e)) tr ++ 847 [(r with <|io_trace := r.io_trace ++ [INL(Otag i)];clock:=0|>,Num i)]`>> 848 fs[HD_MAP,HD_APPEND,Abbr`t'`,res_rel_e_cases]>> 849 ho_match_mp_tac check_trace_append2>> 850 fs[check_trace_def,LAST_MAP,check_trace_putchar]>> 851 ntac 2 (simp[Once step_e_cases]) 852 ) >> 853 qexists_tac`MAP (��st,e. (st,Putchar e)) tr`>>unabbrev_all_tac>> 854 fs[HD_MAP,res_rel_e_cases,LAST_MAP,is_val_e_def,check_trace_putchar, 855 no_step_e_putchar] 856 ) 857) 858end 859 860val sem_t_for_no_break = Q.prove( 861 `���s s'. sem_t s (For e1 e2 t) ��� (Rbreak,s')`, 862 completeInduct_on`s.clock`>>fs[sem_t_def_with_stop]>> 863 rw[]>>fct>>Cases_on`q`>> 864 fs[sem_e_not_break,sem_e_not_timeout]>> 865 IF_CASES_TAC>>fs[]>> 866 fct>>Cases_on`q`>>fs[]>> 867 fct>>Cases_on`q`>>fs[sem_e_not_break,sem_e_not_timeout]>> 868 imp_res_tac sem_e_clock>>imp_res_tac sem_t_clock>>fs[]>> 869 IF_CASES_TAC>>fs[dec_clock_def]>> 870 simp[STOP_def]>> 871 simp[sem_t_def_with_stop]>> 872 fs[PULL_FORALL]>> 873 first_x_assum(qspec_then `r'' with clock := r''.clock-1` mp_tac)>> 874 fs[]>> 875 `r''.clock < 1 + r.clock ��� 0 < r.clock` by 876 DECIDE_TAC>> 877 fs[dec_clock_def]) 878 879val step_e_clock = Q.prove(` 880 ���se l1 se'. 881 step_e se l1 se' ��� 882 ���s e s' e'. 883 se = (s,e) ��� 884 se' = (s',e') ��� 885 (���c. 886 step_e (s with clock:=c,e) l1 (s' with clock:=c,e'))`, 887 ho_match_mp_tac step_e_strongind>>rw[]>> 888 simp[Once step_e_cases]) 889 890val step_e_zero_clock = Q.prove( 891 `(���s e l. ��step_e (r,e') l (s,e))��� 892 ���s e l. ��step_e (r with clock:=0,e') l (s,e)`, 893 rw[]>>CCONTR_TAC>>fs[]>>imp_res_tac step_e_clock>>fs[]>> 894 pop_assum(qspec_then`r.clock`assume_tac)>>fs[]>> 895 `r with clock:= r.clock = r` by fs[state_component_equality]>> 896 metis_tac[]) 897 898val big_small_lem = Q.prove ( 899`!s t r. 900 sem_t s t = r 901 ��� 902 ?tr. 903 tr ��� [] ��� 904 s.clock - (SND r).clock ��� LENGTH tr ��� 905 check_trace (\st. some st'. ?l. step_t st l st') tr ��� 906 HD tr = (s with clock := 0, (t_to_small_t t)) ��� 907 res_rel_t r (LAST tr)`, 908 ho_match_mp_tac sem_t_ind >> 909 rw [sem_t_def_with_stop, t_to_small_t_def] 910 >- 911 (qabbrev_tac`r = sem_e s e`>>fs[markerTheory.Abbrev_def]>> 912 pop_assum (assume_tac o SYM)>> 913 imp_res_tac sem_e_big_small_lem>> 914 Cases_on`r`>> 915 qexists_tac`MAP (��st,e. (st,Exp e)) tr`>> 916 imp_res_tac sem_e_clock>>fs[HD_MAP,LAST_MAP]>> 917 CONJ_TAC>- 918 fs[check_trace_exp] 919 >> 920 fs[res_rel_t_cases,res_rel_e_cases,is_val_t_def]>> 921 imp_res_tac step_e_zero_clock>> 922 fs[Once step_t_cases]) 923 >- 924 (qpat_abbrev_tac`A = (s with clock:=0,D)`>> 925 qexists_tac`A::tr`>>fs[Abbr`A`,check_trace_def]>> 926 CONJ_TAC >- 927 (Cases_on`tr`>> 928 simp[check_trace_def,optionTheory.some_def]>> 929 ntac 2 (simp[Once step_t_cases])>> 930 fs[])>> 931 fs[LAST_DEF]) 932 >- 933 (qexists_tac`[s with clock:=0,Break]`>> 934 fs[res_rel_t_cases,check_trace_def]) 935 >- 936 (EVERY_CASE_TAC>>fs[] 937 >- 938 (qpat_abbrev_tac`p = t_to_small_t t'`>> 939 qexists_tac`MAP (��st,t. (st,Seq t p)) tr ++ tr'`>> 940 fs[HD_MAP,HD_APPEND,LAST_APPEND]>>rw[] >> 941 match_mp_tac check_trace_append2>> 942 fs[check_trace_seq,LAST_MAP]>> 943 Cases_on`LAST tr`>>fs[]>> 944 match_mp_tac some_to_SOME_step_t>> 945 simp[Once step_t_cases]>>fs[Abbr`p`,res_rel_t_cases]>> 946 metis_tac[]) 947 >- 948 (qpat_abbrev_tac `p = t_to_small_t t'`>> 949 qexists_tac`(MAP (��st,t. (st,Seq t p)) tr)++[r with clock:=0,Break]`>> 950 fs[HD_APPEND,HD_MAP, res_rel_t_cases]>>rw[] >> 951 match_mp_tac check_trace_append2>> 952 fs[check_trace_seq,LAST_MAP,check_trace_def]>> 953 fs[res_rel_t_cases]>> 954 match_mp_tac some_to_SOME_step_t>> 955 simp[Once step_t_cases]>>fs[Abbr`p`,res_rel_t_cases]) 956 >- 957 (qpat_abbrev_tac `p = t_to_small_t t'`>> 958 qexists_tac`(MAP (��st,t. (st,Seq t p)) tr)`>> 959 fs[HD_APPEND,HD_MAP,check_trace_def,check_trace_seq]>>rw[]>> 960 fs[Once res_rel_t_cases,LAST_MAP]>> 961 rename1 `step_t _ _ (s',_)` >> 962 `step_t (r,Seq t'' p) l (s',Seq t''' p)` by 963 simp[Once step_t_cases]>> 964 metis_tac[]) 965 >- 966 (qpat_abbrev_tac `p = t_to_small_t t'`>> 967 qexists_tac`(MAP (��st,t. (st,Seq t p)) tr)`>> 968 fs[HD_APPEND,HD_MAP,check_trace_def,check_trace_seq]>>rw[]>> 969 fs[Once res_rel_t_cases,LAST_MAP,is_val_t_def]>> 970 metis_tac[no_step_t_seq])) 971 >- 972 (EVERY_CASE_TAC>>fs[sem_e_not_break,sem_e_not_timeout]>> 973 imp_res_tac sem_e_big_small_lem>> 974 imp_res_tac sem_e_clock>> 975 qpat_abbrev_tac`p1 = t_to_small_t t1`>> 976 qpat_abbrev_tac`p2 = t_to_small_t t2`>> 977 TRY 978 ( 979 qexists_tac`(MAP (��st,e. (st,(If e p1 p2))) tr') ++ tr`>> 980 fs[HD_MAP,HD_APPEND,LAST_MAP,LAST_APPEND]>>rw[] >> 981 match_mp_tac check_trace_append2>>fs[res_rel_e_cases]>>CONJ_TAC 982 >- metis_tac[check_trace_if1] 983 >> match_mp_tac some_to_SOME_step_t>>fs[LAST_MAP]>> 984 simp[Once step_t_cases]>> 985 metis_tac[] 986 ) 987 >> 988 qexists_tac`(MAP (��st,e. (st,(If e p1 p2))) tr)`>>rw[]>> 989 fs[HD_MAP,res_rel_t_cases,LAST_MAP,res_rel_e_cases,is_val_t_def,check_trace_if1,no_step_t_if1]>> 990 metis_tac[check_trace_if1,no_step_t_if1,step_e_zero_clock]) 991 >- ( (*For*) 992 reverse (Cases_on`sem_e s e1`>>Cases_on`q`)>> 993 fs[sem_e_not_break,sem_e_not_timeout]>> 994 qpat_abbrev_tac`e1s = e_to_small_e e1`>> 995 qpat_abbrev_tac`e2s = e_to_small_e e2`>> 996 (*trace for e1*) 997 imp_res_tac sem_e_big_small_lem>> 998 imp_res_tac sem_e_clock>> 999 qpat_abbrev_tac`p = t_to_small_t t`>> 1000 qabbrev_tac ` 1001 e1tr = (MAP (��st,e. (st,Handle 1002 (If e (Seq p (Seq (Exp e2s) (For e1s e2s p))) (Exp (Num 0))))) tr)`>> 1003 `check_trace (��st. some st'. ���l. step_t st l st') e1tr` by metis_tac[check_trace_for1]>> 1004 qabbrev_tac`ls = [s with clock:=0,For e1s e2s p]`>> 1005 `check_trace (��st. some st'. ���l. step_t st l st') (ls++e1tr)` by ( 1006 match_mp_tac check_trace_append2>>unabbrev_all_tac>> 1007 fs[check_trace_def,HD_MAP]>> 1008 match_mp_tac some_to_SOME_step_t>> 1009 simp[Once step_t_cases] 1010 ) 1011 >- ( 1012 qexists_tac` ls ++ e1tr`>> 1013 unabbrev_all_tac>>fs[res_rel_t_cases,LAST_DEF,LAST_MAP,HD_APPEND]>> 1014 fs[LAST_APPEND,LAST_MAP,res_rel_e_cases,is_val_t_def]>> 1015 match_mp_tac no_step_t_handle>>fs[is_val_t_def]>> 1016 imp_res_tac step_e_zero_clock>> 1017 metis_tac[no_step_t_if1] 1018 ) >> 1019 IF_CASES_TAC>>fs[] 1020 >- ( (*run out of time*) 1021 fs[res_rel_t_cases,res_rel_e_cases]>> 1022 qexists_tac` (ls ++ e1tr) ++ 1023 [(r with clock:=0,Handle(Exp (Num 0)));(r with clock:=0,Exp (Num 0))]`>> 1024 fs[LAST_APPEND,LAST_MAP]>>fs[]>>rw[] 1025 >- ( 1026 match_mp_tac check_trace_append2>>rw[] 1027 >- ( 1028 fs[check_trace_def]>> 1029 match_mp_tac some_to_SOME_step_t>> 1030 simp[Once step_t_cases,is_val_e_def,is_val_t_def] 1031 ) 1032 >- ( 1033 unabbrev_all_tac>>fs[LAST_APPEND,LAST_MAP]>> 1034 match_mp_tac some_to_SOME_step_t>> 1035 ntac 2 (simp[Once step_t_cases]) 1036 ) 1037 ) 1038 >- (unabbrev_all_tac>>fs[HD_APPEND]) 1039 ) >> 1040 reverse (Cases_on`sem_t r t`>>Cases_on`q`)>>fs[]>> 1041 qabbrev_tac`ttr = (MAP (��st,t. (st,Handle (Seq t (Seq (Exp e2s) (For e1s e2s p))) ))) tr'`>> 1042 `check_trace (��st. some st'. ���l. step_t st l st') ttr` by 1043 metis_tac[check_trace_for2]>> 1044 `check_trace (��st. some st'. ���l. step_t st l st') (ls++e1tr++ttr)` by ( 1045 match_mp_tac check_trace_append2>> 1046 fs[]>> unabbrev_all_tac>> 1047 fs[LAST_MAP,res_rel_e_cases,HD_MAP,LAST_DEF]>> 1048 match_mp_tac some_to_SOME_step_t>> 1049 ntac 2 (simp[Once step_t_cases]) 1050 ) 1051 >- ( 1052 qexists_tac`ls++e1tr++ttr`>>unabbrev_all_tac>> 1053 fs[LAST_APPEND,LAST_MAP,res_rel_t_cases]>>CONJ_TAC >> 1054 fs[is_val_t_def]>>match_mp_tac no_step_t_handle>> 1055 fs[is_val_t_def]>>match_mp_tac no_step_t_seq>> 1056 metis_tac[] 1057 ) 1058 >- ( 1059 qexists_tac`ls++e1tr++ttr`>>unabbrev_all_tac>> 1060 fs[LAST_APPEND,LAST_MAP,res_rel_t_cases] >> 1061 ntac 2 (simp[Once step_t_cases,is_val_t_def])>> 1062 metis_tac[] 1063 ) 1064 >- ( 1065 qexists_tac` 1066 ls++e1tr++ttr++ 1067 [(r' with clock:= 0,Handle Break);(r' with clock:=0,Exp (Num 0))]`>> 1068 fs[LAST_APPEND,LAST_MAP,res_rel_t_cases]>>rw[] 1069 >- (unabbrev_all_tac>>fs[]>>DECIDE_TAC) 1070 >- ( 1071 match_mp_tac check_trace_append2>>fs[check_trace_def]>>CONJ_TAC>> 1072 match_mp_tac some_to_SOME_step_t>> 1073 unabbrev_all_tac>>fs[LAST_APPEND,LAST_MAP,res_rel_t_cases]>> 1074 ntac 2 (simp[Once step_t_cases]) 1075 ) 1076 >- (unabbrev_all_tac>>fs[]>>DECIDE_TAC) 1077 ) >> 1078 (*continue executing*) 1079 reverse (Cases_on`sem_e r' e2`>>Cases_on`q`)>> 1080 fs[sem_e_not_break,sem_e_not_timeout]>> 1081 imp_res_tac sem_e_big_small_lem>> 1082 imp_res_tac sem_e_clock>> 1083 qabbrev_tac` 1084 e2tr = (MAP (��st,e. (st,Handle (Seq (Exp e) (For e1s e2s p)) ))) tr''`>> 1085 `check_trace (��st. some st'. ���l. step_t st l st') e2tr` by 1086 metis_tac[check_trace_for3]>> 1087 `check_trace (��st. some st'. ���l. step_t st l st')(ls++e1tr++ttr++e2tr)` by ( 1088 match_mp_tac check_trace_append2>>fs[]>> 1089 match_mp_tac some_to_SOME_step_t>> 1090 unabbrev_all_tac>>fs[LAST_APPEND,LAST_MAP,HD_MAP,res_rel_t_cases]>> 1091 ntac 2 (simp[Once step_t_cases,res_rel_e_cases]) 1092 ) 1093 >- ( (* e2 fails *) 1094 qexists_tac`ls++e1tr++ttr++e2tr`>>fs[res_rel_e_cases]>> 1095 unabbrev_all_tac>> 1096 fs[LAST_APPEND,LAST_MAP,res_rel_t_cases,is_val_t_def]>>rw[] >> 1097 imp_res_tac step_e_zero_clock>> 1098 metis_tac[no_step_t_exp,no_step_t_handle,no_step_t_seq,is_val_t_def] 1099 ) >> 1100 (* e2 ok *) 1101 reverse (IF_CASES_TAC) >>fs[] 1102 >- ( 1103 (*clock ended*) 1104 fs[res_rel_t_cases]>> 1105 qexists_tac`ls++e1tr++ttr++e2tr`>>fs[]>>reverse (rw[]) 1106 >- ( 1107 unabbrev_all_tac>>fs[LAST_APPEND,LAST_MAP,res_rel_e_cases]>> 1108 `r'' with clock:=0 = r''` by fs[state_component_equality]>> 1109 ntac 2 (simp[Once step_t_cases,is_val_t_def])>> 1110 metis_tac[] 1111 ) >> 1112 unabbrev_all_tac>>fs[]>>DECIDE_TAC 1113 ) >> 1114 (*clock ok*) 1115 simp[STOP_def]>> 1116 simp[Once sem_t_def_with_stop]>> 1117 fs[dec_clock_def]>> 1118 (*Need a handle wrapper around rest of trace*) 1119 qabbrev_tac`ftr = MAP (��st,t. (st, Handle t))tr''''` >> 1120 `check_trace (��st. some st'. ���l. step_t st l st') ftr` by 1121 metis_tac[check_trace_handle]>> 1122 `check_trace (��st. some st'. ���l. step_t st l st') 1123 (ls++e1tr++ttr++e2tr++ftr)` by ( 1124 match_mp_tac check_trace_append2>>fs[]>> 1125 match_mp_tac some_to_SOME_step_t>> 1126 unabbrev_all_tac>>fs[LAST_APPEND,LAST_MAP,HD_MAP]>> 1127 fs[res_rel_e_cases]>> 1128 ntac 2 (simp[Once step_t_cases]) 1129 ) >> 1130 fs[res_rel_t_cases] 1131 (*Case split on the rest of loop*) 1132 >- ( 1133 qexists_tac` 1134 ls ++ e1tr ++ ttr ++ e2tr ++ ftr ++[s' with clock:=0,Exp (Num i''')]`>> 1135 fs[]>>rw[] 1136 >- (unabbrev_all_tac>>fs[]>>DECIDE_TAC) 1137 >- ( 1138 match_mp_tac check_trace_append2>>fs[check_trace_def]>> 1139 match_mp_tac some_to_SOME_step_t>>unabbrev_all_tac>> 1140 fs[LAST_DEF,LAST_APPEND,LAST_MAP,res_rel_e_cases]>> 1141 simp[Once step_t_cases,is_val_t_def,is_val_e_def] 1142 ) 1143 >- (unabbrev_all_tac>>fs[]>>DECIDE_TAC) 1144 >- (simp[Once sem_t_def_with_stop,LAST_APPEND,dec_clock_def]) 1145 ) 1146 >- ( 1147 qexists_tac`ls ++ e1tr++ttr++e2tr++ftr`>>fs[]>> reverse (rw[]) 1148 >- ( 1149 ntac 4 (simp[Once sem_t_def_with_stop,LAST_APPEND,dec_clock_def])>> 1150 unabbrev_all_tac>>fs[LAST_APPEND,LAST_MAP,is_val_t_def]>> 1151 match_mp_tac no_step_t_handle>> 1152 metis_tac[] 1153 ) >> 1154 unabbrev_all_tac>>fs[]>>DECIDE_TAC 1155 ) 1156 >- ( (*break never occurs*) 1157 qpat_x_assum `A = (RBreak,s')` mp_tac>> 1158 fct>>Cases_on`q`>> 1159 fs[sem_e_not_timeout,sem_e_not_break]>> 1160 IF_CASES_TAC>>fs[]>> 1161 fct>>Cases_on`q`>> 1162 fs[]>> 1163 fct>>Cases_on`q`>> 1164 fs[sem_e_not_timeout,sem_e_not_break]>> 1165 IF_CASES_TAC>>fs[]>> 1166 simp[STOP_def]>> 1167 metis_tac[sem_t_for_no_break] 1168 ) 1169 >- ( 1170 qexists_tac`ls ++ e1tr ++ ttr ++ e2tr ++ ftr`>>fs[]>> reverse (rw[]) >> 1171 unabbrev_all_tac 1172 >- ( 1173 ntac 3 ( 1174 simp[Once sem_t_def_with_stop,LAST_APPEND,dec_clock_def,LAST_MAP])>> 1175 simp[Once step_t_cases]>>metis_tac[] 1176 ) >> 1177 fs[] >> DECIDE_TAC 1178 ) 1179 ) 1180 ) 1181 1182val big_timeout_0 = Q.prove ( 1183`!st p r. 1184 sem_t st p = (Rtimeout,r) 1185 ��� 1186 r.clock = 0`, 1187 ho_match_mp_tac sem_t_ind >> 1188 conj_tac >- ( 1189 rw [sem_t_def_with_stop, sem_e_not_timeout]) >> 1190 conj_tac >- ( 1191 rw [sem_t_def_with_stop, sem_e_not_timeout]) >> 1192 conj_tac >- ( 1193 rw [sem_t_def_with_stop, sem_e_not_timeout] >> 1194 ect >> fs []) >> 1195 conj_tac >- ( 1196 rw [sem_t_def_with_stop, sem_e_not_timeout] >> 1197 ect >> fs []) >> 1198 conj_tac >- ( 1199 rw [sem_t_def_with_stop, sem_e_not_timeout] >> 1200 ect >> fs [sem_e_not_timeout]) 1201 >- ( 1202 rw [] >> 1203 pop_assum mp_tac >> 1204 simp [sem_t_def_with_stop] >> 1205 ect >> 1206 fs [sem_e_not_timeout, STOP_def] >> 1207 rw [] >> 1208 fs [])); 1209 1210(* check traces are unique up to prefixing *) 1211val check_trace_determ = Q.prove( 1212`���tr h f. 1213 check_trace f (h::tr) ��� 1214 ���tr'. 1215 LENGTH tr' ��� LENGTH tr ��� 1216 check_trace f (h::tr') ��� 1217 isPREFIX tr' tr`, 1218 Induct>>rw[]>>fs[check_clock_def,isPREFIX,LENGTH_NIL]>> 1219 Cases_on`tr'`>>fs[check_trace_def]>> 1220 metis_tac[]) 1221 1222val check_trace_prefixes = Q.prove( 1223`���tr f. 1224 tr ��� [] ��� 1225 check_trace f tr ��� 1226 ���tr'. 1227 tr' ��� [] ��� HD tr' = HD tr ��� 1228 check_trace f tr' ��� 1229 isPREFIX tr tr' ��� isPREFIX tr' tr`, 1230 rw[]>> 1231 Cases_on`tr`>>Cases_on`tr'`>>fs[]>> 1232 Cases_on`LENGTH t' ��� LENGTH t`>> 1233 TRY(`LENGTH t ��� LENGTH t'` by DECIDE_TAC)>> 1234 metis_tac[check_trace_determ]) 1235 1236val check_trace_TL = Q.prove( 1237`���tr tr'. 1238 (tr ��� [] ��� 1239 check_trace (��st. some st'. ?l. step_t st l st') tr ��� 1240 (���l t'. ��step_t (LAST tr) l t') ��� 1241 check_trace (��st. some st'. ?l. step_t st l st') tr' ��� 1242 isPREFIX tr tr') ��� 1243 tr = tr'`, 1244 Induct>>fs[check_trace_def,LAST_DEF]>>rw[]>>Cases_on`tr'`>>fs[] 1245 >- 1246 (Cases_on`t`>>fs[check_trace_def,some_def]>> 1247 metis_tac[]) 1248 >> 1249 Cases_on`tr`>>Cases_on`t`>>fs[check_trace_def]>> 1250 res_tac>>fs[]) 1251 1252val prefix_append = Q.prove( 1253`���ls ls'. 1254 ls ��� ls' ��� 1255 ���ls''. ls++ls'' = ls'`, 1256 metis_tac[rich_listTheory.IS_PREFIX_APPEND]) 1257 1258val res_rel_t_io_trace = Q.prove( 1259 `res_rel_t (q,r) s ��� 1260 r.io_trace = (FST s).io_trace`, 1261 simp[res_rel_t_cases]>>rw[]>>fs[]) 1262 1263(*slow*) 1264val res_rel_t_clock = Q.prove( 1265 `res_rel_t (q,r) s ��� 1266 step_t s l t ��� 1267 q = Rtimeout ��� (FST s).clock = 0`, 1268 simp[res_rel_t_cases]>>rw[] 1269 >> 1270 fs[Once step_t_cases,Once step_e_cases] 1271 >> 1272 metis_tac[PAIR,FST]) 1273 1274val step_e_io_mono = Q.prove( 1275`���s l s'. 1276 step_e s l s' ��� 1277 (FST s).io_trace ��� (FST s').io_trace`, 1278 ho_match_mp_tac step_e_strongind>>fs[]) 1279 1280val step_t_io_mono = Q.prove( 1281`���s l s'. 1282 step_t s l s' ��� 1283 (FST s).io_trace ��� (FST s').io_trace`, 1284 ho_match_mp_tac step_t_strongind>> 1285 fs[]>>metis_tac[step_e_io_mono,FORALL_PROD,FST]) 1286 1287val RTC_step_t_io_mono = Q.prove( 1288 `���x y. (��s1 s2. (some st'. ���l. step_t s1 l st') = SOME s2)^* x y ��� 1289 (FST x).io_trace ��� (FST y).io_trace`, 1290 ho_match_mp_tac RTC_INDUCT >> rw[] >> 1291 last_x_assum mp_tac >> 1292 DEEP_INTRO_TAC some_intro >> rw[] >> 1293 metis_tac[step_t_io_mono,IS_PREFIX_TRANS]) 1294 1295val check_trace_io_trace = Q.prove( 1296 `���tr ls. 1297 tr ��� [] ��� check_trace (��st. some st'. ���l. step_t st l st') (tr ++ ls) ��� 1298 (FST(LAST tr)).io_trace ��� 1299 (FST(LAST (tr++ls))).io_trace`, 1300 rw[] >> 1301 match_mp_tac RTC_step_t_io_mono >> 1302 simp[check_trace_thm] >> 1303 qexists_tac`LAST tr::ls` >> 1304 simp[] >> 1305 conj_tac >- ( Cases_on`ls`>>simp[] ) >> 1306 `LAST tr::ls = DROP (LENGTH tr - 1) (tr++ls)` suffices_by ( 1307 disch_then SUBST1_TAC >> 1308 match_mp_tac check_trace_drop >> simp[] ) >> 1309 simp[DROP_APPEND1] >> 1310 Q.ISPECL_THEN[`1n`,`tr`]mp_tac (GSYM LASTN_DROP) >> 1311 `1 ��� LENGTH tr` by ( 1312 Cases_on`tr`>>fs[] >> simp[] ) >> 1313 simp[] >> 1314 Q.ISPEC_THEN`tr`FULL_STRUCT_CASES_TAC SNOC_CASES >- fs[] >> 1315 REWRITE_TAC[arithmeticTheory.ONE,LASTN,LAST,SNOC]) 1316 1317val sem_e_ignores_clock = Q.prove( 1318 `���s e c r s'. 1319 sem_e s e = (r,s') ��� 1320 sem_e (s with clock:=c) e = (r,s' with clock:=c)`, 1321 ho_match_mp_tac sem_e_ind>>srw_tac[][sem_e_def]>>fs[LET_THM] 1322 >- 1323 (ect>>fs[]) 1324 >- ( 1325 fs[permute_pair_def,LET_THM,oracle_get_def,unpermute_pair_def]>> 1326 Cases_on`switch`>>fs[]>> 1327 qpat_x_assum`A=(r,s')` mp_tac>> 1328 fct>>Cases_on`q`>>res_tac>> 1329 fs[sem_e_not_break,sem_e_not_timeout]>> 1330 fct>>Cases_on`q`>>res_tac>> 1331 rw[]>> 1332 fs[sem_e_not_break,sem_e_not_timeout]) 1333 >> 1334 Cases_on`sem_e s e`>>res_tac>>fs[]>> 1335 Cases_on`q`>>fs[state_component_equality]) 1336 1337val sem_e_io_mono = Q.prove( 1338 `���s e c. 1339 (SND (sem_e s e)).io_trace ��� 1340 (SND (sem_e (s with clock:= c) e)).io_trace`, 1341 rw[]>>Cases_on`sem_e s e`>>imp_res_tac sem_e_ignores_clock>> 1342 fs[]) 1343 1344val sem_e_clock_inc = Q.prove( 1345 `���s e r. 1346 sem_e s e = r ��� 1347 ���k. sem_e (s with clock:= s.clock+k) e =(FST r,(SND r)with clock:= (SND r).clock+k)`, 1348 metis_tac[sem_e_ignores_clock,sem_e_clock,FST,SND,PAIR]) 1349 1350val sem_t_clock_inc = Q.prove( 1351 `���s t r. 1352 sem_t s t = r ��� FST r ��� Rtimeout ��� 1353 ���k. sem_t (s with clock:= s.clock+k) t =(FST r,(SND r)with clock:= (SND r).clock+k)`, 1354 ho_match_mp_tac sem_t_ind>>rw[]>>fs[sem_e_clock]>> 1355 TRY(fs[sem_t_def_with_stop]>>NO_TAC) 1356 >- 1357 (fs[sem_t_def_with_stop]>> 1358 Cases_on`sem_e s e`>> 1359 imp_res_tac sem_e_ignores_clock>> 1360 fs[]>>metis_tac[sem_e_clock]) 1361 >- 1362 (fs[sem_t_def_with_stop]>>Cases_on`sem_t s t`>>Cases_on`q`>>fs[]) 1363 >- 1364 (fs[sem_t_def_with_stop]>>Cases_on`sem_e s e`>>Cases_on`q`>>fs[sem_e_res]>> 1365 imp_res_tac sem_e_clock_inc>> 1366 pop_assum(qspec_then`k` assume_tac)>>fs[]>> 1367 IF_CASES_TAC>>fs[]) 1368 >> 1369 pop_assum mp_tac>> 1370 simp[sem_t_def_with_stop]>> 1371 Cases_on`sem_e s e1`>>Cases_on`q`>>fs[]>> 1372 imp_res_tac sem_e_clock_inc>>fs[]>> 1373 TRY(pop_assum(qspec_then`k` assume_tac))>> 1374 fs[DECIDE ``(A:num)+B = B+A``]>> 1375 IF_CASES_TAC>>fs[]>> 1376 Cases_on`sem_t r t`>>Cases_on`q`>>fs[]>> 1377 Cases_on`sem_e r' e2`>>Cases_on`q`>>fs[]>> 1378 TRY(metis_tac[sem_e_res])>> 1379 imp_res_tac sem_e_clock_inc>>fs[]>> 1380 TRY(pop_assum(qspec_then`k` assume_tac))>> 1381 fs[DECIDE ``(A:num)+B = B+A``]>> 1382 IF_CASES_TAC>>fs[]>>rw[]>> 1383 fs[dec_clock_def,STOP_def]>> 1384 `1 ��� r''.clock` by DECIDE_TAC>> 1385 metis_tac[arithmeticTheory.LESS_EQ_ADD_SUB]) 1386 1387val check_trace_io_trace_simp = Q.prove( 1388 `tr ��� [] ��� 1389 check_trace (��st.some st'. ���l. step_t st l st') tr ��� 1390 (FST(HD tr)).io_trace ��� (FST (LAST tr)).io_trace`, 1391 Cases_on`tr`>>rw[]>> 1392 `FST h = FST(LAST [h])` by fs[]>> 1393 pop_assum SUBST1_TAC>> 1394 `h::t = [h]++t` by fs[]>> 1395 pop_assum SUBST1_TAC>> 1396 ho_match_mp_tac check_trace_io_trace>> 1397 rw[]) 1398 1399val sem_t_sing_io_mono = Q.prove( 1400 `���s t res s'. 1401 sem_t s t = (res,s') ��� 1402 s.io_trace ��� s'.io_trace`, 1403 rw[]>>imp_res_tac big_small_lem>> 1404 imp_res_tac check_trace_io_trace_simp>> 1405 fs[res_rel_t_cases]>> 1406 rfs[]) 1407 1408val sem_e_sing_io_mono = Q.prove( 1409`���s e res s'. 1410 sem_e s e = (res,s') ��� 1411 s.io_trace ��� s'.io_trace`, 1412 CCONTR_TAC>>fs[]>> 1413 `sem_t s (Exp e) = (res,s')` by 1414 fs[sem_t_def_with_stop]>> 1415 metis_tac[sem_t_sing_io_mono]) 1416 1417(* Monotonicity of io_trace w.r.t. to clock *) 1418val sem_t_io_mono_lem = Q.prove( 1419 `���s t k. 1420 (SND (sem_t s t)).io_trace ��� 1421 (SND (sem_t (s with clock:=s.clock+k) t)).io_trace`, 1422 ho_match_mp_tac sem_t_ind>>rw[]>> 1423 TRY(fs[sem_t_def_with_stop,sem_e_io_mono]>>NO_TAC) 1424 >- 1425 (fs[sem_t_def_with_stop]>> 1426 fct>>Cases_on`q`>>fs[]>> 1427 imp_res_tac sem_t_clock_inc>>fs[]>> 1428 fct>>Cases_on`q`>>fs[]>> 1429 first_x_assum(qspec_then`k` assume_tac)>>rfs[]>> 1430 Cases_on`sem_t r' t'`>> 1431 imp_res_tac sem_t_sing_io_mono>> 1432 fs[]>> 1433 metis_tac[IS_PREFIX_TRANS]) 1434 >- 1435 (fs[sem_t_def_with_stop]>> 1436 fct>>Cases_on`q`>>fs[]>>TRY(metis_tac[sem_e_res])>> 1437 imp_res_tac sem_e_clock_inc>>fs[]>> 1438 IF_CASES_TAC>>fs[]) 1439 >> 1440 simp[Once sem_t_def_with_stop]>> 1441 simp[Once sem_t_def_with_stop]>> 1442 fct>>Cases_on`q`>>fs[]>>TRY(metis_tac[sem_e_res])>> 1443 imp_res_tac sem_e_clock_inc>> 1444 pop_assum(qspec_then`k` assume_tac)>> 1445 fs[DECIDE ``(A:num)+B = B+A``]>> 1446 IF_CASES_TAC>>fs[]>> 1447 fct>>Cases_on`q`>>fs[]>> 1448 TRY(imp_res_tac sem_t_clock_inc>>fs[]>> 1449 pop_assum(qspec_then`k` assume_tac))>>rfs[]>> 1450 fs[DECIDE ``(A:num)+B = B+A``] 1451 >- 1452 (fct>>Cases_on`q`>>fs[]>>TRY(metis_tac[sem_e_res])>> 1453 imp_res_tac sem_e_clock_inc>> 1454 pop_assum(qspec_then`k` assume_tac)>> 1455 fs[DECIDE ``(A:num)+B = B+A``]>> 1456 IF_CASES_TAC>>fs[] 1457 >- 1458 (fs[dec_clock_def,STOP_def]>> 1459 `1 ��� r''.clock` by DECIDE_TAC>> 1460 metis_tac[arithmeticTheory.LESS_EQ_ADD_SUB]) 1461 >> 1462 IF_CASES_TAC>>fs[]>> 1463 qpat_abbrev_tac`A = sem_t B C`>> 1464 Cases_on`A`>>fs[markerTheory.Abbrev_def]>> 1465 pop_assum (assume_tac o SYM)>>imp_res_tac sem_t_sing_io_mono>> 1466 fs[dec_clock_def]) 1467 >> 1468 first_x_assum(qspec_then`k` assume_tac)>> 1469 fct>>Cases_on`q`>>fs[]>> 1470 fct>>Cases_on`q`>>fs[]>>TRY(metis_tac[sem_e_res])>> 1471 imp_res_tac sem_e_sing_io_mono 1472 >- 1473 (IF_CASES_TAC>>fs[dec_clock_def]>> 1474 TRY(qpat_abbrev_tac`A = sem_t B C`>> 1475 Cases_on`A`>>fs[markerTheory.Abbrev_def]>> 1476 pop_assum (assume_tac o SYM)>>imp_res_tac sem_t_sing_io_mono)>> 1477 fs[]>>metis_tac[IS_PREFIX_TRANS]) 1478 >> 1479 metis_tac[IS_PREFIX_TRANS]) 1480 1481val sem_t_io_mono = Q.prove ( 1482`k1 ��� k2 ��� 1483 (SND (sem_t (init_st 0 nd input with clock := k1) p)).io_trace ��� 1484 (SND (sem_t (init_st 0 nd input with clock := k2) p)).io_trace`, 1485 qpat_abbrev_tac `st = init_st A B C`>> 1486 rw[]>>imp_res_tac arithmeticTheory.LESS_EQUAL_ADD >> 1487 Q.ISPECL_THEN [`st with clock:=k1`,`p`,`p'`] assume_tac sem_t_io_mono_lem>> 1488 fs[]) 1489 1490val sem_equiv_lem = Q.store_thm ("sem_equiv_lem", 1491`���input prog r. ofbs_sem (for_big_sem input) prog r ��� osmall_sem (for_small_sem input) prog r`, 1492 gen_tac >> 1493 match_mp_tac osmall_fbs_equiv2 >> 1494 conj_tac >- ( 1495 rw [for_small_sem_def] >> 1496 match_mp_tac step_t_io_mono>> 1497 Q.ISPEC_THEN `��st. ���l. step_t s1 l st` assume_tac some_SAT>> 1498 fs[ETA_AX])>> 1499 conj_tac >- ( 1500 rw [for_big_sem_def] >> 1501 rw [eval_with_clock_def, for_eval_def] >> 1502 every_case_tac >> 1503 fs [] >> 1504 metis_tac [sem_t_io_mono, SND]) >> 1505 conj_tac >- ( 1506 rw [for_big_sem_def, eval_with_clock_def, for_eval_def] >> 1507 ect >> 1508 fs [] >> 1509 metis_tac [big_timeout_0]) >> 1510 qexists_tac `I` >> 1511 conj_tac 1512 >- ( 1513 rw [unbounded_def] >> 1514 qexists_tac `SUC x` >> 1515 simp []) >> 1516 rpt gen_tac >> 1517 simp [for_big_sem_def, for_eval_def, eval_with_clock_def] >> 1518 DISCH_TAC >> 1519 ect >> 1520 imp_res_tac big_small_lem >> 1521 fs [] >> 1522 qexists_tac `tr` >> 1523 fs [for_small_sem_def] >> 1524 rw [same_result_def] >> 1525 fs [res_rel_t_cases, is_val_t_def, is_val_e_def, some_no_choice, init_st_def] >> 1526 simp [] >> 1527 rw [] 1528 >- (rw [Once step_t_cases] >> 1529 rw [Once step_e_cases]) 1530 >- rw [Once step_t_cases] 1531 >- (rw [some_def] >> 1532 metis_tac []) 1533 >- metis_tac [PAIR]); 1534 1535val FST_SPLIT = Q.prove( 1536`FST x = y ��� ���z. x = (y,z)`, 1537Cases_on`x`>>fs[]) 1538 1539val big_val_no_errors = Q.prove( 1540`!st p v s. 1541 sem_t st p = (Rval v,s) 1542 ��� 1543 (���c. 1544 (FST (sem_t (st with clock:= c) p) ��� Rbreak) 1545 ��� (FST (sem_t (st with clock:=c) p) ��� Rfail))`, 1546 rw[]>>CCONTR_TAC>>fs[]>>imp_res_tac FST_SPLIT>> 1547 imp_res_tac big_small_lem>> 1548 `HD tr = HD tr'` by fs[]>> 1549 fs[res_rel_t_cases]>> 1550 `���l t'. ��step_t (LAST tr) l t'` by 1551 fs[Once step_t_cases,FORALL_PROD]>> 1552 `���l t'. ��step_t (LAST tr') l t'` by 1553 fs[Once step_t_cases,FORALL_PROD,Once step_e_cases]>> 1554 `isPREFIX tr tr' ��� isPREFIX tr' tr` by 1555 metis_tac[check_trace_prefixes]>> 1556 `tr = tr'` by metis_tac[check_trace_TL]>> 1557 fs[]>> 1558 qpat_assum`A=t` (SUBST_ALL_TAC o SYM)>>fs[is_val_t_def,is_val_e_def]) 1559 1560(* we can prove an alternative characterisation of the semantics, now that we 1561 know sem_t's io_trace is a chain *) 1562 1563val over_all_def = Define`over_all f = GSPEC (��c. f c,T)`; 1564 1565val init_st_with_clock = Q.prove( 1566 `init_st a b c with clock := d = init_st d b c`, 1567 EVAL_TAC) 1568 1569val lprefix_chain_sem_t_io_trace_over_all_c = Q.store_thm("lprefix_chain_sem_t_io_trace_over_all_c", 1570 `prefix_chain (over_all (��c. (SND (sem_t (init_st c nd input) t)).io_trace))`, 1571 rw[lprefix_lubTheory.prefix_chain_def,over_all_def] >> 1572 qspecl_then[`c`,`c'`]strip_assume_tac arithmeticTheory.LESS_EQ_CASES >|[disj1_tac,disj2_tac] >> 1573 imp_res_tac sem_t_io_mono >> fs[init_st_with_clock]) 1574 1575val image_intro = Q.prove( 1576 `{fromList (FILTER P (Q c)) | c | T} = IMAGE fromList (IMAGE (FILTER P) (over_all Q))`, 1577 rw[EXTENSION,over_all_def,PULL_EXISTS]) 1578 1579val IMAGE_over_all = Q.store_thm("IMAGE_over_all", 1580 `IMAGE P (over_all f) = over_all (P o f)`, 1581 rw[EXTENSION,over_all_def,PULL_EXISTS]) 1582 1583(* Pretty Printing *) 1584val BIGSUP_def = Define`BIGSUP f = build_lprefix_lub (over_all f)` 1585 1586val _ = Parse.add_rule{term_name="BIGSUP",fixity=Parse.Binder,pp_elements=[TOK"BIGSUP"], 1587 block_style=(NoPhrasing,(PP.CONSISTENT,0)),paren_style=OnlyIfNecessary} 1588 1589val semantics_alt = save_thm("semantics_alt", 1590 semantics_def 1591 |> SIMP_RULE bool_ss [image_intro] 1592 |> SIMP_RULE bool_ss [lprefix_chain_sem_t_io_trace_over_all_c,lprefix_lubTheory.prefix_chain_FILTER,lprefix_lubTheory.prefix_chain_lprefix_chain,lprefix_lubTheory.build_prefix_lub_intro] 1593 |> SIMP_RULE bool_ss [IMAGE_over_all] 1594 |> SIMP_RULE bool_ss [prove(``f o g = ��c. f (g c)``,rw[FUN_EQ_THM])] 1595 |> SIMP_RULE bool_ss [GSYM BIGSUP_def]) 1596 1597val oracle_upd_def = Define` 1598 oracle_upd s (b,a) = 1599 s with <|non_det_o := a; io_trace:=s.io_trace ++[INR b]|>` 1600 1601val _ = save_thm ("step_e_rules_oracle_upd",step_e_rules|>REWRITE_RULE[GSYM oracle_upd_def]) 1602 1603val _ = export_theory (); 1604