190075Sobrien(*****************************************************************************) 2117395Skan(* Create "WeakPSLUnclockedSemanticsTheory" *) 3169689Skan(*****************************************************************************) 4132718Skan 590075Sobrien(****************************************************************************** 6132718Skan* Load theory of syntax, paths and models 790075Sobrien* (commented out for compilation) 8132718Skan******************************************************************************) 9132718Skan(* 10132718Skanquietdec := true; (* Switch off output *) 11132718SkanloadPath (* Add official-semantics to path *) 1290075Sobrien := 13132718Skan "../1.1/official-semantics" :: "../path" :: !loadPath; 14132718Skanmap load 15132718Skan ["intLib", "Cooper","rich_listTheory", (* Load useful theories *) 16132718Skan "FinitePathTheory", "PathTheory", 1790075Sobrien "res_quanLib", "res_quanTheory", 18132718Skan "SyntaxTheory","SyntacticSugarTheory", 19132718Skan "LemmasTheory","ProjectionTheory", 20169689Skan "UnclockedSemanticsTheory"]; 21169689Skanopen FinitePathTheory PathTheory (* Open theories *) 2290075Sobrien SyntaxTheory SyntacticSugarTheory 23132718Skan UnclockedSemanticsTheory 2490075Sobrien LemmasTheory ProjectionTheory 25132718Skan arithmeticTheory listTheory 26132718Skan rich_listTheory 2790075Sobrien res_quanLib res_quanTheory; 28132718SkanintLib.deprecate_int(); (* Set num as default numbers type *) 29132718Skanquietdec := false; (* Restore output *) 3090075Sobrien*) 31132718Skan 32132718Skan(****************************************************************************** 33132718Skan* Boilerplate needed for compilation 34132718Skan******************************************************************************) 35132718Skanopen HolKernel Parse boolLib bossLib; 36132718Skan 37132718Skan(****************************************************************************** 38132718Skan* Open theories 39132718Skan******************************************************************************) 40132718Skanopen FinitePathTheory PathTheory SyntaxTheory SyntacticSugarTheory 41132718Skan UnclockedSemanticsTheory LemmasTheory ProjectionTheory 42132718Skan arithmeticTheory listTheory rich_listTheory res_quanLib res_quanTheory; 43132718Skan 44132718Skan(****************************************************************************** 45132718Skan* Set default parsing to natural numbers rather than integers 46132718Skan******************************************************************************) 47132718Skanval _ = intLib.deprecate_int(); 48132718Skan 49132718Skan(*****************************************************************************) 50132718Skan(* END BOILERPLATE *) 51132718Skan(*****************************************************************************) 52132718Skan 53169689Skan(*****************************************************************************) 54169689Skan(* Start a new theory called WeakPSLUnclockedSemanticsTheory *) 55169689Skan(*****************************************************************************) 56169689Skan 57169689Skanval _ = new_theory "WeakPSLUnclockedSemantics"; 58169689Skan 5990075Sobrien(*****************************************************************************) 60169689Skan(* N^f = { w | w is a finite list of states/letters } (the set of neutral *) 61169689Skan(* finite words) *) 62169689Skan(* *) 63169689Skan(* we let \epsilon be the empty (neutral) word *) 64169689Skan(* *) 65146895Skan(* W = { W(w) | w \in N^f } (the set of weak finite words) *) 66146895Skan(* *) 67146895Skan(* Let A = N^f U W *) 68146895Skan(*****************************************************************************) 69146895Skan 7090075Sobrien(*****************************************************************************) 71132718Skan(* Definition of a datatypetype A. It creates a tagged disjoint union with *) 72169689Skan(* elements ``N l``, ``W l`` and ``S l``, where l is a HOL list. *) 73132718Skan(*****************************************************************************) 74132718Skanval A_def = 75132718Skan Hol_datatype 76132718Skan `A = N of 'a list 77132718Skan | W of 'a list 78132718Skan | S of 'a list`; 79132718Skan 80132718Skan(*****************************************************************************) 81169689Skan(* Retrieve from data-base (DB) automatically proved theorems about A *) 82132718Skan(*****************************************************************************) 83132718Skanval A_11 = assoc "A_11" (DB.theorems "-") 84132718Skanand A_distinct = assoc "A_distinct" (DB.theorems "-"); 85132718Skan 86132718Skanval A_ELEM_def = 87132718Skan Define 88132718Skan `(A_ELEM (N l) n = EL n l) 89132718Skan /\ 90169689Skan (A_ELEM (W l) n = EL n l) 91132718Skan /\ 92132718Skan (A_ELEM (S l) n = EL n l)`; 93132718Skan 94132718Skan(*****************************************************************************) 95132718Skan(* We define concatenation ( * ) on A: if v,w \in N then v*w is just the *) 96132718Skan(* list concatenation of v and w (remember v,w finite) v*W(w) = W(v*w) *) 97132718Skan(* and for v\in W and w\in A v*w = v *) 98132718Skan(*****************************************************************************) 99132718Skan 100132718Skan(*****************************************************************************) 101132718Skan(* For readability overload "++" onto HOL's list append constant APPEND, *) 102132718Skan(* and make it a left associative infix with precedence 500. *) 103132718Skan(*****************************************************************************) 104132718Skanval _ = set_fixity "++" (Infixl 500); 105132718Skanval _ = overload_on("++", ``APPEND``); 106169689Skan 107132718Skan(*****************************************************************************) 108132718Skan(* Define ``CONC`` for concatenation on values of type A. *) 109132718Skan(*****************************************************************************) 110132718Skanval _ = set_fixity "CONC" (Infixl 500); 111132718Skan 112132718Skanval CONC_def = 113132718Skan Define 114132718Skan `(N v CONC N w = N(v++w)) 115132718Skan /\ 116132718Skan (N v CONC W w = W(v++w)) 117132718Skan /\ 118132718Skan (N v CONC S w = S(v++w)) 119132718Skan /\ 120132718Skan (W v CONC a = W v) 121132718Skan /\ 122132718Skan (S v CONC a = S v)`; 123132718Skan 124132718Skan(*****************************************************************************) 125132718Skan(* Overload "*" on to "CONC" for readability. *) 126132718Skan(*****************************************************************************) 127132718Skanval _ = overload_on("*", ``$CONC``); 128132718Skan 129132718Skan(*****************************************************************************) 130132718Skan(* We want to show that A is closed under *, that * is associative on A and *) 131132718Skan(* that \epsilon is the identity for this operation. *) 132132718Skan(*****************************************************************************) 133132718Skanval CONC_IDENTITY = 134132718Skan prove 135103445Skan (``(N[] * a = a) /\ (a * N[] = a)``, 136132718Skan Cases_on `a` 137103445Skan THEN RW_TAC list_ss [CONC_def]); 138132718Skan 139132718Skanval CONC_ASSOC = 140169689Skan prove 141132718Skan (``a * (b * c) = (a * b) * c``, 142132718Skan Cases_on `a` THEN Cases_on `b` THEN Cases_on `c` 143132718Skan THEN RW_TAC list_ss [CONC_def]); 144132718Skan 145169689Skanval ASSOC_CONC = 146132718Skan prove 147132718Skan (``ASSOC $*``, 148132718Skan RW_TAC std_ss [operatorTheory.ASSOC_DEF,CONC_ASSOC]); 149169689Skan 150132718Skan(*****************************************************************************) 151132718Skan(* for w \in N |w| is the number of elements in w, and |W(w)| = |w| *) 152132718Skan(*****************************************************************************) 153132718Skan 154132718Skan(*****************************************************************************) 155132718Skan(* Represent |w| by LEN w. HOL's built-in length function on lists *) 156132718Skan(* is LENGTH. *) 157132718Skan(*****************************************************************************) 158132718Skanval LEN_def = 159132718Skan Define 160132718Skan `(LEN(N w) = LENGTH w) 161132718Skan /\ 162132718Skan (LEN(W w) = LENGTH w) 163132718Skan /\ 164132718Skan (LEN(S w) = LENGTH w)`; 165132718Skan 166132718Skan(*****************************************************************************) 167132718Skan(* we want to show that if w \in N then *) 168132718Skan(* |w*v| = |w|+|v|, |W(w)*v| = |w| and |S(w)*v| = |w| *) 169132718Skan(*****************************************************************************) 170132718Skanval LEN = 171132718Skan prove 172132718Skan (``(LEN(N w * a) = LEN(N w) + LEN a) 173132718Skan /\ 174132718Skan (LEN(W w * a) = LEN(W w)) 175132718Skan /\ 176132718Skan (LEN(S w * a) = LEN(S w))``, 177132718Skan Cases_on `a` 178132718Skan THEN RW_TAC list_ss [LEN_def,CONC_def]); 179132718Skan 180132718Skan(*****************************************************************************) 181132718Skan(* We define (on A) w<=v (prefix) if there is u \in A such that w*u=v *) 182132718Skan(*****************************************************************************) 183132718Skanval PREFIX_def = Define `PREFIX w v = ?u. w*u = v`; 184132718Skan 185132718Skanval STRICT_PREFIX_def = Define `STRICT_PREFIX w v = PREFIX w v /\ ~(w = v)`; 186132718Skan 187132718Skan(*****************************************************************************) 188132718Skan(* u<w is u is prefix of w and u/=w *) 189132718Skan(* One could try to prove that if u<w u is neutral *) 190132718Skan(*****************************************************************************) 191132718Skan 192132718Skanval STRICT_PREFIX_NEUTRAL = 19390075Sobrien prove 19490075Sobrien (``STRICT_PREFIX u w ==> ?l. u = N l``, 19590075Sobrien Cases_on `u` THEN Cases_on `w` 19690075Sobrien THEN RW_TAC list_ss [STRICT_PREFIX_def,PREFIX_def,CONC_def]); 197132718Skan 198132718Skanval IS_WEAK_def = 199132718Skan Define 200132718Skan `(IS_WEAK(W w) = T) /\ (IS_WEAK(N w) = F) /\ (IS_WEAK(S w) = F)` 201132718Skanand IS_NEUTRAL_def = 202132718Skan Define 203132718Skan `(IS_NEUTRAL(W w) = F) /\ (IS_NEUTRAL(N w) = T) /\ (IS_NEUTRAL(S w) = F)` 204146895Skanand IS_STRONG_def = 205146895Skan Define 20690075Sobrien `(IS_STRONG(W w) = F) /\ (IS_STRONG(N w) = F) /\ (IS_STRONG(S w) = T)`; 207132718Skan 208132718Skanval IS_LETTER_def = 209132718Skan Define 210169689Skan `(IS_LETTER(N w) = ?l. w = [l]) 211132718Skan /\ 212132718Skan (IS_LETTER(W w) = ?l. w = [l]) 213132718Skan /\ 214132718Skan (IS_LETTER(S w) = ?l. w = [l])`; 215103445Skan 21690075Sobrien(*****************************************************************************) 217132718Skan(* WeakPSL Semantics of SEREs *) 218132718Skan(*****************************************************************************) 219132718Skan 220132718Skan(*###################################################################### 221132718Skan# 222132718Skan# [Notation: w^- = W(w) and w^+ = S(w)] 223132718Skan# 224132718Skan# Weak/neutral word definition 225132718Skan# ---------------------------- 22690075Sobrien# for finite w \in W U N U S 227132718Skan# 228132718Skan# we define (let l be a letter or \epsilon^-) 229132718Skan# 230132718Skan# w|==wns b <=> either w=\epsilon^- or (w not \in S and |w|=1 and w^0||-b) 231169689Skan# w|==wns r1;r2 <=> there exist u,v s.t. uv=w and u|==wns r1 and v|==wns r2 232169689Skan# w|==wns r1:r2 <=> there exist u,v,l s.t. ulv=w and ul|==wns r1 and lv|==wns r2 233169689Skan# w|==wns r1&r2 <=> w|==wns r1 and w|==wns r2 234169689Skan# w|==wns r1|r2 <=> w|==wns r1 or w|==wns r2 235169689Skan# w|==wns r* <=> either w=\epsilon 236132718Skan# or there exist w_1,..w_j 23790075Sobrien# s.t. w=w_1w_2...w_j and for 1<=i<=j w_i|==wns r 23890075Sobrien######################################################################*) 239161651Skan 240161651Skanval WUS_SEM_def = 241161651Skan Define 242161651Skan `(WUS_SEM v (S_BOOL b) = 243161651Skan (v = W[]) \/ (~(IS_STRONG v) /\ (LEN v = 1) /\ B_SEM (A_ELEM v 0) b)) 244161651Skan /\ 24590075Sobrien (WUS_SEM v (S_CAT(r1,r2)) = 24690075Sobrien ?v1 v2. (v = v1 * v2) /\ WUS_SEM v1 r1 /\ WUS_SEM v2 r2) 247132718Skan /\ 24890075Sobrien (WUS_SEM v (S_FUSION(r1,r2)) = 249132718Skan ?v1 v2 l. (IS_LETTER l \/ (l = W[])) /\ (v = v1*l*v2) 250132718Skan /\ 251132718Skan WUS_SEM (v1*l) r1 /\ WUS_SEM (l*v2) r2) 252132718Skan /\ 253169689Skan (WUS_SEM v (S_AND(r1,r2)) = 254132718Skan WUS_SEM v r1 /\ WUS_SEM v r2) 255132718Skan /\ 256132718Skan (WUS_SEM v (S_OR(r1,r2)) = 257132718Skan WUS_SEM v r1 \/ WUS_SEM v r2) 258132718Skan /\ 259132718Skan (WUS_SEM v S_EMPTY = (v = N[]) \/ (v = W[])) 260132718Skan /\ 26190075Sobrien (WUS_SEM v (S_REPEAT r) = 262132718Skan ?vlist. (v = FOLDL $* (N[]) vlist) /\ EVERY (\v. WUS_SEM v r) vlist)`; 263132718Skan 264132718Skan(*****************************************************************************) 265132718Skan(* We can now prove with fusion in the language *) 266132718Skan(* for all unclocked r: W(\espilon) |==wns r *) 267132718Skan(*****************************************************************************) 26890075Sobrienlocal 26990075Sobrienval WUS_SEM_SIMP_TAC = 27090075Sobrien RW_TAC list_ss 27190075Sobrien [S_CLOCK_FREE_def,WUS_SEM_def,IS_WEAK_def,IS_NEUTRAL_def,LEN_def,A_ELEM_def] 27290075Sobrienin 273132718Skanval TightTrueEmpty = 274132718Skan prove 27590075Sobrien (``!r. S_CLOCK_FREE r ==> WUS_SEM (W[]) r``, 276117395Skan INDUCT_THEN sere_induct ASSUME_TAC 27790075Sobrien THENL 27890075Sobrien [(* S_BOOL b *) 27990075Sobrien WUS_SEM_SIMP_TAC, 280146895Skan (* S_CAT (r,r') *) 281146895Skan WUS_SEM_SIMP_TAC 282146895Skan THEN Q.EXISTS_TAC `W []` 283146895Skan THEN Q.EXISTS_TAC `W []` 284146895Skan THEN RW_TAC list_ss [CONC_def], 285146895Skan (* S_FUSION (r,r') *) 286169689Skan WUS_SEM_SIMP_TAC 287146895Skan THEN Q.EXISTS_TAC `W []` 288132718Skan THEN Q.EXISTS_TAC `W []` 289169689Skan THEN Q.EXISTS_TAC `W []` 290132718Skan THEN RW_TAC list_ss [CONC_def,IS_LETTER_def], 291132718Skan (* S_OR (r,r') *) 292132718Skan WUS_SEM_SIMP_TAC, 293132718Skan (* S_AND (r,r') *) 294132718Skan WUS_SEM_SIMP_TAC, 295132718Skan (* S_EMPTY *) 296132718Skan WUS_SEM_SIMP_TAC 297132718Skan THEN Q.EXISTS_TAC `[W []]` 298132718Skan THEN RW_TAC list_ss [CONC_def], 299132718Skan (* S_REPEAT (r,r') *) 300132718Skan WUS_SEM_SIMP_TAC 301132718Skan THEN Q.EXISTS_TAC `[W []]` 302132718Skan THEN RW_TAC list_ss [CONC_def], 303132718Skan (* S_REPEAT (r,r') *) 304132718Skan WUS_SEM_SIMP_TAC]) 305132718Skanend; 306132718Skan 307132718Skan(*****************************************************************************) 308132718Skan(* Weaken a word *) 309132718Skan(*****************************************************************************) 310117395Skanval WEAKEN_def = 31190075Sobrien Define `(WEAKEN(N l) = W l) /\ (WEAKEN(W l) = W l) /\ (WEAKEN(S l) = S l)`; 31290075Sobrien 31390075Sobrienval LEN_WEAKEN = 31490075Sobrien prove 31590075Sobrien (``LEN(WEAKEN w) = LEN w``, 31690075Sobrien Cases_on `w` 31790075Sobrien THEN RW_TAC list_ss [WEAKEN_def,LEN_def]); 31890075Sobrien 31990075Sobrien(*****************************************************************************) 32090075Sobrien(* Tight prefix theorem *) 32190075Sobrien(* w |==wns r and u <= w => W(u) |==wns r *) 32290075Sobrien(*****************************************************************************) 32390075Sobrienval APPEND_EQ_NIL = 32490075Sobrien prove 32590075Sobrien (``!l1 l2. (LENGTH(l1++l2) = 0) ==> (l1 = []) /\ (l2 = [])``, 32690075Sobrien Induct 32790075Sobrien THEN RW_TAC list_ss [] 32890075Sobrien THEN `LENGTH l2 = 0` by DECIDE_TAC 32990075Sobrien THEN PROVE_TAC[LENGTH_NIL]); 33090075Sobrien 33190075Sobrienval APPEND_EQ_SINGLETON = 33290075Sobrien prove 33390075Sobrien (``!l1 l2. (LENGTH(l1++l2) = 1) ==> (l1 = []) \/ (l2 = [])``, 33490075Sobrien Induct 33590075Sobrien THEN RW_TAC list_ss [] 33690075Sobrien THEN `LENGTH l2 = 0` by DECIDE_TAC 33790075Sobrien THEN PROVE_TAC[LENGTH_NIL]); 33890075Sobrien 339169689Skanval APPEND_NIL_CANCEL = 340169689Skan prove 341169689Skan (``!l1 l2. (l1++l2 = l1) ==> (l2 = [])``, 342169689Skan Induct 343169689Skan THEN RW_TAC list_ss []); 344169689Skan 345169689Skanval PREFIX_CONC = 346169689Skan prove 347169689Skan (``PREFIX u v1 ==> !v2. PREFIX u (v1 * v2)``, 348169689Skan Cases_on `u` THEN Cases_on `v1` 349169689Skan THEN RW_TAC list_ss [PREFIX_def,CONC_def] 350169689Skan THEN Cases_on `u` THEN Cases_on `v2` 351169689Skan THEN FULL_SIMP_TAC list_ss [CONC_def,A_11,A_distinct] 352169689Skan THENL 353169689Skan [Q.EXISTS_TAC `N(l''++l''')` THEN RW_TAC list_ss [CONC_def], 354132718Skan Q.EXISTS_TAC `W(l''++l''')` THEN RW_TAC list_ss [CONC_def], 35590075Sobrien Q.EXISTS_TAC `S(l''++l''')` THEN RW_TAC list_ss [CONC_def]]); 356169689Skan 357132718Skanval HD_APPEND = 358132718Skan prove 359132718Skan (``!v1 v2. ~(v1 = []) ==> (HD(APPEND v1 v2) = HD v1)``, 360169689Skan Induct 361117395Skan THEN RW_TAC list_ss []); 36290075Sobrien 363132718Skanval TL_APPEND = 364132718Skan prove 365132718Skan (``!v1 v2. ~(v1 = []) ==> (TL(APPEND v1 v2) = APPEND (TL v1) v2)``, 366132718Skan Induct 36790075Sobrien THEN RW_TAC list_ss []); 36890075Sobrien 369132718Skanval LIST_TRICHOTOMY_LEMMA1 = 370132718Skan prove 371132718Skan (``~(v = []) ==> (h::u ++ u' = v ++ v') ==> (h = HD v) /\ (u ++ u' = TL v ++ v')``, 372132718Skan RW_TAC list_ss [] 373132718Skan THEN PROVE_TAC[HD,HD_APPEND,TL,TL_APPEND]); 374132718Skan 37590075Sobrienval LIST_TRICHOTOMY_LEMMA2 = 37690075Sobrien prove 37790075Sobrien (``~(v = []) ==> (!w. ~(HD v::u ++ w = v)) ==> !w. ~(u ++ w = TL v)``, 37890075Sobrien RW_TAC list_ss [] 37990075Sobrien THEN POP_ASSUM(ASSUME_TAC o SPEC_ALL) 380132718Skan THEN Cases_on `~(u ++ w = TL v)` 381132718Skan THEN FULL_SIMP_TAC list_ss [] 38290075Sobrien THEN `HD v :: u ++ w = HD v :: TL v` by PROVE_TAC[] 383132718Skan THEN `~(NULL v)` by PROVE_TAC[NULL_EQ_NIL] 384132718Skan THEN FULL_SIMP_TAC std_ss [CONS] 38590075Sobrien THEN RES_TAC); 386132718Skan 387132718Skanval LIST_TRICHOTOMY_LEMMA3 = 38890075Sobrien prove 38990075Sobrien (``!u v. 39090075Sobrien (u ++ u' = v ++ v') /\ (!w. ~(u ++ w = v)) 39190075Sobrien ==> 39290075Sobrien ?w. v ++ w = u``, 39390075Sobrien Induct 39490075Sobrien THEN RW_TAC list_ss [] 39590075Sobrien THEN Cases_on `v=[]` 39690075Sobrien THEN RW_TAC list_ss [] 39790075Sobrien THEN IMP_RES_TAC LIST_TRICHOTOMY_LEMMA1 39890075Sobrien THEN RW_TAC list_ss [] 39990075Sobrien THEN `TL(HD v::u ++ u') = TL(v ++ v')` by PROVE_TAC[] 40090075Sobrien THEN FULL_SIMP_TAC list_ss [] 401132718Skan THEN IMP_RES_TAC LIST_TRICHOTOMY_LEMMA2 40290075Sobrien THEN RES_TAC 40390075Sobrien THEN `HD v :: TL v ++ w = HD v :: u` by PROVE_TAC[] 40490075Sobrien THEN PROVE_TAC[APPEND,CONS,NULL_EQ_NIL]); 40590075Sobrien 406117395Skanval LIST_TRICHOTOMY = 407117395Skan prove 408117395Skan (``!u v. 409117395Skan (?u' v'. u ++ u' = v ++ v') 410117395Skan ==> 411169689Skan (?w. u ++ w = v) \/ (?w. v ++ w = u)``, 412117395Skan RW_TAC list_ss [] 413117395Skan THEN Cases_on `(?w. u ++ w = v)` (* u<=v *) 414117395Skan THEN RW_TAC list_ss [] 415117395Skan THEN FULL_SIMP_TAC list_ss [] 416117395Skan THEN Induct_on `u` 417169689Skan THEN RW_TAC list_ss [] 418169689Skan THEN PROVE_TAC[LIST_TRICHOTOMY_LEMMA3,APPEND]); 419169689Skan 420169689Skanval PREFIX_TRICHOTOMY = 421169689Skan prove 422169689Skan (``!v1 v2 w. 423117395Skan PREFIX v1 w /\ PREFIX v2 w ==> STRICT_PREFIX v1 v2 \/ PREFIX v2 v1``, 424169689Skan REPEAT GEN_TAC 425117395Skan THEN Cases_on `v1` THEN Cases_on `v2` THEN Cases_on `w` 42690075Sobrien THEN RW_TAC list_ss [PREFIX_def,STRICT_PREFIX_def,CONC_def] 42790075Sobrien THEN Cases_on `u` THEN Cases_on `u'` 428132718Skan THEN FULL_SIMP_TAC list_ss [PREFIX_def,STRICT_PREFIX_def,CONC_def,A_11,A_distinct] 42990075Sobrien THEN Cases_on `?u. l' ++ u = l` 430132718Skan THEN FULL_SIMP_TAC list_ss [PREFIX_def,STRICT_PREFIX_def,CONC_def,A_11,A_distinct] 43190075Sobrien THEN ZAP_TAC list_ss [CONC_def,A_11] 432132718Skan THEN Cases_on `?u. l++u = l'` 43390075Sobrien THEN ZAP_TAC list_ss [CONC_def,A_11] 434132718Skan THEN FULL_SIMP_TAC list_ss [] 43590075Sobrien THEN IMP_RES_TAC LIST_TRICHOTOMY 43690075Sobrien THEN RES_TAC); 43790075Sobrien 43890075Sobrienval PREFIX_REFL = 43990075Sobrien prove 44096263Sobrien (``!v. PREFIX v v``, 44196263Sobrien Induct 44296263Sobrien THEN RW_TAC list_ss [PREFIX_def,CONC_def] 44396263Sobrien THEN Q.EXISTS_TAC `N[]` 44496263Sobrien THEN RW_TAC list_ss [CONC_def]); 44596263Sobrien 44696263Sobrienval APPEND_LEFT_CANCEL = 447132718Skan store_thm 448169689Skan ("APPEND_LEFT_CANCEL", 449132718Skan ``(APPEND l l1 = APPEND l l2) = (l1 = l2)``, 45096263Sobrien Induct_on `l` 451132718Skan THEN ZAP_TAC list_ss []); 452169689Skan 45396263Sobrienval PREFIX_CANCEL = 45496263Sobrien prove 45596263Sobrien (``(PREFIX (N(u ++ v1)) (N(u ++ v2)) ==> PREFIX (N v1) (N v2)) /\ 45696263Sobrien (PREFIX (W(u ++ v1)) (N(u ++ v2)) ==> PREFIX (W v1) (N v2)) /\ 45796263Sobrien (PREFIX (S(u ++ v1)) (N(u ++ v2)) ==> PREFIX (S v1) (N v2)) /\ 458117395Skan (PREFIX (N(u ++ v1)) (W(u ++ v2)) ==> PREFIX (N v1) (W v2)) /\ 45990075Sobrien (PREFIX (W(u ++ v1)) (W(u ++ v2)) ==> PREFIX (W v1) (W v2)) /\ 46090075Sobrien (PREFIX (S(u ++ v1)) (W(u ++ v2)) ==> PREFIX (S v1) (W v2)) /\ 46190075Sobrien (PREFIX (N(u ++ v1)) (S(u ++ v2)) ==> PREFIX (N v1) (S v2)) /\ 46290075Sobrien (PREFIX (W(u ++ v1)) (S(u ++ v2)) ==> PREFIX (W v1) (S v2)) /\ 46390075Sobrien (PREFIX (S(u ++ v1)) (S(u ++ v2)) ==> PREFIX (S v1) (S v2))``, 46490075Sobrien RW_TAC list_ss [PREFIX_def,CONC_def] 46590075Sobrien THEN Cases_on `u'` 46690075Sobrien THEN FULL_SIMP_TAC std_ss 46790075Sobrien [GSYM APPEND_ASSOC,CONC_def,A_11,A_distinct,APPEND_LEFT_CANCEL] 46890075Sobrien THEN PROVE_TAC[CONC_def]); 46990075Sobrien 47090075Sobrienval B_FALSE = 47190075Sobrien prove 47290075Sobrien (``B_SEM (STATE s) B_FALSE = F``, 47390075Sobrien RW_TAC list_ss [B_SEM_def]); 47490075Sobrien 47590075Sobrienval IS_WEAK_LEN_0 = 47690075Sobrien prove 47790075Sobrien (``!v. IS_WEAK v /\ (LEN v = 0) = (v = W[])``, 478132718Skan Induct 479132718Skan THEN RW_TAC list_ss [IS_WEAK_def,LEN_def,LENGTH_NIL]); 480132718Skan 481169689Skanval FOLDL_W_NIL = 482132718Skan prove 483132718Skan (``!l. ALL_EL (\v. v = W []) l ==> (FOLDL $* (W []) l = W[])``, 484132718Skan Induct 485132718Skan THEN RW_TAC list_ss [CONC_def]); 486169689Skan 487132718Skanval FOLDL_N_NIL = 48890075Sobrien prove 489103445Skan (``!l. ~(l = []) ==> ALL_EL (\v. v = W []) l ==> (FOLDL $* (N []) l = W[])``, 490103445Skan Induct 491103445Skan THEN RW_TAC list_ss [CONC_def,FOLDL_W_NIL]); 492103445Skan 493103445Skan(*****************************************************************************) 494132718Skan(* Not sure why I defined WS_CATN here and S_CATN in ProjectionTheory. *) 495132718Skan(* Probably could get away with just the latter, but I'm too lazy to redo *) 496132718Skan(* the proofs! *) 497132718Skan(*****************************************************************************) 498132718Skanval WS_CATN_def = 499132718Skan Define 500132718Skan `(WS_CATN 0 r = r) /\ (WS_CATN (SUC n) r = S_CAT(r, WS_CATN n r))`; 501132718Skan 502132718Skan(*****************************************************************************) 503132718Skan(* Theorem to connect WS_CATN and S_CATN in the LRM 1.1 semantics *) 504146895Skan(*****************************************************************************) 505132718Skanval US_SEM_WS_CATN = 506169689Skan store_thm 507132718Skan ("US_SEM_WS_CATN", 508132718Skan ``!n w r. US_SEM w (WS_CATN n r) = US_SEM w (S_CATN (SUC n) r)``, 509132718Skan Induct 510132718Skan THEN RW_TAC list_ss [US_SEM,WS_CATN_def,S_CATN_def]); 511169689Skan 512169689Skanval ASSOC_FOLDL = 513169689Skan prove 514132718Skan (``!l x y. ASSOC f ==> (FOLDL f (f x y) l = f x (FOLDL f y l))``, 515169689Skan Induct 516169689Skan THEN RW_TAC list_ss [operatorTheory.ASSOC_DEF]); 517169689Skan 518169689Skanval FOLDL_CONCAT_N = 519169689Skan prove 520169689Skan (``!vlist v. FOLDL $* v vlist = v * FOLDL $* (N []) vlist``, 521169689Skan PROVE_TAC[ASSOC_FOLDL,ASSOC_CONC,CONC_IDENTITY]); 522169689Skan 523169689Skanval WUS_SEM_CAT_REPEAT_CATN = 524169689Skan store_thm 525169689Skan ("WUS_SEM_CAT_REPEAT_CATN", 526169689Skan ``!v r. WUS_SEM v (S_CAT(S_REPEAT r, r)) = ?n. WUS_SEM v (WS_CATN n r)``, 527169689Skan RW_TAC list_ss [WUS_SEM_def] 528169689Skan THEN EQ_TAC 529169689Skan THEN RW_TAC list_ss [] 530 THENL 531 [Induct_on `vlist` 532 THEN RW_TAC list_ss [CONC_IDENTITY,WS_CATN_def,WUS_SEM_def] 533 THEN ZAP_TAC std_ss [WS_CATN_def] 534 THEN RW_TAC std_ss [] 535 THEN RES_TAC 536 THEN Q.EXISTS_TAC `SUC n` 537 THEN RW_TAC list_ss [WS_CATN_def,WUS_SEM_def] 538 THEN Q.EXISTS_TAC `h` THEN Q.EXISTS_TAC `FOLDL $* (N []) vlist * v2` 539 THEN RW_TAC std_ss [] 540 THEN PROVE_TAC[FOLDL_CONCAT_N,CONC_ASSOC], 541 Q.UNDISCH_TAC `WUS_SEM v (WS_CATN n r)` 542 THEN Q.SPEC_TAC(`v`,`v`) 543 THEN Q.SPEC_TAC(`r`,`r`) 544 THEN Q.SPEC_TAC(`n`,`n`) 545 THEN Induct 546 THEN RW_TAC list_ss [WS_CATN_def] 547 THENL 548 [Q.EXISTS_TAC `N[]` THEN Q.EXISTS_TAC `v` 549 THEN RW_TAC list_ss [CONC_IDENTITY] 550 THEN Q.EXISTS_TAC `[]` 551 THEN RW_TAC list_ss [], 552 FULL_SIMP_TAC list_ss [WUS_SEM_def] 553 THEN RES_TAC 554 THEN RW_TAC std_ss [] 555 THEN Q.EXISTS_TAC `v1 * FOLDL $* (N []) vlist` 556 THEN Q.EXISTS_TAC `v2'` 557 THEN RW_TAC std_ss [CONC_ASSOC] 558 THEN Q.EXISTS_TAC `v1::vlist` 559 THEN RW_TAC list_ss [CONC_IDENTITY] 560 THEN PROVE_TAC[FOLDL_CONCAT_N]]]); 561 562val FOLDLN_def = 563 Define 564 `(FOLDLN 0 f e l = e) /\ 565 (FOLDLN (SUC n) f e l = FOLDLN n f (f e (HD l)) (TL l))`; 566 567val FOLDLN_LENGTH = 568 prove 569 (``!l f e. FOLDLN (LENGTH l) f e l = FOLDL f e l``, 570 Induct 571 THEN RW_TAC list_ss [FOLDLN_def]); 572 573val FOLDLN_ASSOC = 574 prove 575 (``!n v1 v2 l. FOLDLN n $* (v1 * v2) l = v1 * FOLDLN n $* v2 l``, 576 Induct 577 THEN RW_TAC list_ss [FOLDLN_def,CONC_ASSOC]); 578 579val FOLDLN_CATN = 580 prove 581 (``!l v0 r. 582 ALL_EL (\v. WUS_SEM v r) l /\ WUS_SEM v0 r 583 ==> 584 !n. n <= LENGTH l ==> WUS_SEM (FOLDLN n $* v0 l) (WS_CATN n r)``, 585 Induct 586 THEN RW_TAC list_ss [FOLDLN_def,WS_CATN_def] 587 THEN Cases_on `n = 0` 588 THEN RW_TAC list_ss [FOLDLN_def,WS_CATN_def] 589 THEN `?m. n = SUC m` by Cooper.COOPER_TAC 590 THEN RW_TAC list_ss [FOLDLN_def,WS_CATN_def] 591 THEN FULL_SIMP_TAC arith_ss [WUS_SEM_def] 592 THEN RES_TAC 593 THEN Q.EXISTS_TAC `v0` 594 THEN Q.EXISTS_TAC `FOLDLN m $* h l` 595 THEN RW_TAC list_ss [FOLDLN_ASSOC]); 596 597val WUS_SEM_REPEAT_WS_CATN = 598 store_thm 599 ("WUS_SEM_REPEAT_WS_CATN", 600 ``!v r. WUS_SEM v (S_REPEAT r) = (v = N[]) 601 \/ 602 ?n. WUS_SEM v (WS_CATN n r)``, 603 RW_TAC list_ss [] 604 THEN EQ_TAC 605 THENL 606 [SIMP_TAC list_ss[WUS_SEM_def] 607 THEN REPEAT STRIP_TAC 608 THEN Cases_on `v = N[]` 609 THEN ASM_REWRITE_TAC[] 610 THEN Cases_on `vlist` 611 THEN FULL_SIMP_TAC list_ss [CONC_IDENTITY] 612 THEN RES_TAC 613 THEN `LENGTH t <= LENGTH t` by DECIDE_TAC 614 THEN IMP_RES_TAC FOLDLN_CATN 615 THEN Q.EXISTS_TAC `LENGTH t` 616 THEN FULL_SIMP_TAC list_ss [FOLDLN_LENGTH], 617 RW_TAC list_ss [WUS_SEM_def] 618 THENL 619 [Q.EXISTS_TAC `[]` 620 THEN RW_TAC list_ss [], 621 Q.UNDISCH_TAC `WUS_SEM v (WS_CATN n r)` 622 THEN Q.SPEC_TAC(`v`,`v`) 623 THEN Q.SPEC_TAC(`r`,`r`) 624 THEN Q.SPEC_TAC(`n`,`n`) 625 THEN Induct 626 THEN RW_TAC list_ss [WS_CATN_def] 627 THENL 628 [Q.EXISTS_TAC `[v]` 629 THEN RW_TAC list_ss [CONC_IDENTITY], 630 FULL_SIMP_TAC list_ss [WUS_SEM_def] 631 THEN RES_TAC 632 THEN Q.EXISTS_TAC `v1::vlist` 633 THEN RW_TAC list_ss [CONC_IDENTITY] 634 THEN PROVE_TAC[FOLDL_CONCAT_N]]]]); 635 636val NN_APPEND_PREFIX = 637 prove 638 (``!u v. PREFIX (N u) (N v) ==> PREFIX (N(w ++ u)) (N(w ++ v))``, 639 RW_TAC list_ss [PREFIX_def,CONC_def] 640 THEN Cases_on `u` THEN Cases_on `u'` THEN Cases_on `v` THEN Cases_on `w` 641 THEN FULL_SIMP_TAC list_ss 642 [CONC_def,CONC_IDENTITY,A_11,A_distinct] 643 THENL 644 [PROVE_TAC[CONC_IDENTITY], 645 Q.EXISTS_TAC `N(h::t)` 646 THEN RW_TAC list_ss [CONC_def], 647 Q.EXISTS_TAC `N l` 648 THEN RW_TAC std_ss [CONC_def,GSYM APPEND_ASSOC,APPEND], 649 Q.EXISTS_TAC `N l` 650 THEN RW_TAC std_ss [CONC_def,GSYM APPEND_ASSOC,APPEND]]); 651 652val WN_APPEND_PREFIX = 653 prove 654 (``!u v. PREFIX (W u) (N v) ==> PREFIX (W(w ++ u)) (N(w ++ v))``, 655 RW_TAC list_ss [PREFIX_def,CONC_def] 656 THEN Cases_on `u` THEN Cases_on `u'` THEN Cases_on `v` THEN Cases_on `w` 657 THEN FULL_SIMP_TAC list_ss 658 [CONC_def,CONC_IDENTITY,A_11,A_distinct]); 659 660val NW_APPEND_PREFIX = 661 prove 662 (``!u v. PREFIX (N u) (W v) ==> PREFIX (N(w ++ u)) (W(w ++ v))``, 663 RW_TAC list_ss [PREFIX_def,CONC_def] 664 THEN Cases_on `u` THEN Cases_on `u'` THEN Cases_on `v` THEN Cases_on `w` 665 THEN FULL_SIMP_TAC list_ss 666 [CONC_def,CONC_IDENTITY,A_11,A_distinct] 667 THENL 668 [Q.EXISTS_TAC `W[]` 669 THEN RW_TAC list_ss [CONC_def], 670 Q.EXISTS_TAC `W(h::t)` 671 THEN RW_TAC list_ss [CONC_def], 672 Q.EXISTS_TAC `W l` 673 THEN RW_TAC std_ss [CONC_def,GSYM APPEND_ASSOC,APPEND], 674 Q.EXISTS_TAC `W l` 675 THEN RW_TAC std_ss [CONC_def,GSYM APPEND_ASSOC,APPEND]]); 676 677val WW_APPEND_PREFIX = 678 prove 679 (``!u v. PREFIX (W u) (W v) ==> PREFIX (W(w ++ u)) (W(w ++ v))``, 680 RW_TAC list_ss [PREFIX_def,CONC_def] 681 THEN Cases_on `u` THEN Cases_on `u'` THEN Cases_on `v` THEN Cases_on `w` 682 THEN FULL_SIMP_TAC list_ss 683 [CONC_def,CONC_IDENTITY,A_11,A_distinct]); 684 685local 686val WUS_SEM_SIMPS = 687 [WUS_SEM_def,IS_WEAK_def,IS_NEUTRAL_def,LEN_def,A_ELEM_def, 688 WEAKEN_def,(*WEAKEN,*)LEN_WEAKEN,PREFIX_def,PREFIX_def,CONC_def] 689in 690val TightPrefix_S_BOOL = 691 prove 692 (``!b w. 693 WUS_SEM w (S_BOOL b) 694 ==> 695 !u. PREFIX u w ==> WUS_SEM (WEAKEN u) (S_BOOL b)``, 696 RW_TAC list_ss WUS_SEM_SIMPS 697 THEN Cases_on `u` THEN Cases_on `u'` 698 THEN FULL_SIMP_TAC list_ss 699 (WUS_SEM_SIMPS@[IS_STRONG_def,CONC_def,A_11,A_distinct]) 700 THEN `(LENGTH l = 0) \/ (LENGTH l' = 0)` by DECIDE_TAC 701 THEN (`l = []` by PROVE_TAC[LENGTH_NIL] ORELSE 702 `l' = []` by PROVE_TAC[LENGTH_NIL]) 703 THEN FULL_SIMP_TAC list_ss []) 704end; 705 706val TightPrefix_S_CAT = 707 prove 708 (``(!w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r) /\ 709 (!w. WUS_SEM w r' ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r') 710 ==> 711 !w. WUS_SEM w (S_CAT (r,r')) 712 ==> 713 !u. PREFIX u w ==> WUS_SEM (WEAKEN u) (S_CAT (r,r'))``, 714 RW_TAC list_ss [WUS_SEM_def] 715 THEN Cases_on `PREFIX u v1` 716 THENL 717 [RES_TAC 718 THEN Q.EXISTS_TAC `WEAKEN u` THEN Q.EXISTS_TAC `v2` 719 THEN RW_TAC list_ss [] 720 THEN Cases_on `u` THEN Cases_on `v2` 721 THEN RW_TAC list_ss [WEAKEN_def,CONC_def], 722 `STRICT_PREFIX v1 u` 723 by PROVE_TAC[PREFIX_TRICHOTOMY,PREFIX_def,PREFIX_CONC,PREFIX_REFL] 724 THEN FULL_SIMP_TAC list_ss [STRICT_PREFIX_def,PREFIX_def] 725 THEN Q.EXISTS_TAC `v1` THEN Q.EXISTS_TAC `WEAKEN u''` 726 THEN RW_TAC list_ss [CONC_def] 727 THENL 728 [Cases_on `v1` THEN Cases_on `v2` THEN Cases_on `u''` 729 THEN FULL_SIMP_TAC list_ss [WEAKEN_def,CONC_def,A_11,A_distinct], 730 FULL_SIMP_TAC list_ss [GSYM CONC_ASSOC] 731 THEN Cases_on `v1` THEN Cases_on `v2` THEN Cases_on `u'' * u'` 732 THEN FULL_SIMP_TAC list_ss [WEAKEN_def,CONC_def,A_11,A_distinct] 733 THEN RW_TAC std_ss [] 734 THEN RES_TAC]]); 735 736val CONC_WEAKEN = 737 store_thm 738 ("CONC_WEAKEN", 739 ``!u v. WEAKEN u * v = WEAKEN u``, 740 Cases_on `u` 741 THEN RW_TAC list_ss [CONC_def,WEAKEN_def]); 742 743val WEAKEN_CONC = 744 store_thm 745 ("WEAKEN_CONC", 746 ``!v1 v2. WEAKEN(v1 * v2) = v1 * WEAKEN v2``, 747 REPEAT GEN_TAC 748 THEN Cases_on `v1` THEN Cases_on `v2` 749 THEN RW_TAC list_ss [] 750 THEN FULL_SIMP_TAC list_ss [WEAKEN_def] 751 THEN RW_TAC list_ss [CONC_def,WEAKEN_def]); 752 753val APPEND_NIL_CANCEL = 754 store_thm 755 ("APPEND_NIL_CANCEL", 756 ``!l1 l2. (l1 = l1 ++ l2 ) = (l2 = [])``, 757 RW_TAC list_ss [] 758 THEN EQ_TAC 759 THEN RW_TAC list_ss [] 760 THEN `LENGTH l1 = LENGTH(l1 ++ l2)` by PROVE_TAC[] 761 THEN FULL_SIMP_TAC list_ss [] 762 THEN `LENGTH l2 = 0` by DECIDE_TAC 763 THEN PROVE_TAC[LENGTH_NIL]); 764 765(*********************************************************************** 766* if w\in N and w finite and for some u,u', w*u=w*u' then u=u' 767************************************************************************ 768** 769** Assume w \in N and w finite 770** if B is W, N or S then w*u \in B iff u \in B 771** Assume that w*u=w*u' 772** then u \in B iff u' \in B. 773** and also |u|=|u'| since |w|+|u|=|w*u|=|w*u|=|w|+|u'| 774** Now assume for contradiction that u/=u' 775** then there is k such that u^k/=u'^k. 776** but then (w*u)^(|w|+k)/=(w*u')^(|w|+k) contradicting the 777** assumption. 778** 779************************************************************************) 780val CONC_CANCEL = 781 store_thm 782 ("CONC_CANCEL", 783 ``!w u u'. IS_NEUTRAL w ==> ((w * u = w * u') = (u = u'))``, 784 Cases_on `w` THEN Cases_on `u` THEN Cases_on `u'` 785 THEN FULL_SIMP_TAC list_ss [CONC_def,A_11,A_distinct,IS_NEUTRAL_def]); 786 787(*********************************************************************** 788* For v,w in A if v<=w and w<=v then w=v (antisymmetry) 789************************************************************************ 790** 791** Assume that v,w in A and v<=w and w<=v th 792** then there is u1 and u2 such that 793** v*u1=w and w*u2=v 794** if v \in N then w also \in N (because w*u2=w) 795** and v=w (antisymmetry of <= on neutral words) 796** if v \in W (\in S) 797** then v*u1=v so v=w. 798***********************************************************************) 799val PREFIX_ANTISYM = 800 store_thm 801 ("PREFIX_ANTISYM", 802 ``!v w. PREFIX v w /\ PREFIX w v ==> (w = v)``, 803 RW_TAC list_ss [PREFIX_def] 804 THEN Cases_on `w` THEN Cases_on `u` THEN Cases_on `u'` 805 THEN FULL_SIMP_TAC list_ss [CONC_def,A_distinct,A_11] 806 THEN `l'' ++ l' = []` by PROVE_TAC[APPEND_NIL_CANCEL,APPEND_ASSOC] 807 THEN FULL_SIMP_TAC list_ss [APPEND_eq_NIL]); 808 809(*********************************************************************** 810* if l is a letter or \epsilon^- and v1*l*v2 \in A then 811* 812* if v1*l<=u<=v1*l*v2 then there is v2' s.t. v1*l*v2'=u and l*v2'<=l*v2 813************************************************************************ 814** 815** Assume that l is a letter or \epsilon^- [MJCG: this is not needed] 816** and v1*l*v2 \in A 817** and that u is such that v1*l<=u<=v1*l*v2 818** 819** Either v1 \in N or not 820** Assume v1 \in N. 821** let v2' be such that v1*l*v2'=u, so v1*l*v2'<=v1*l*v2 822** let x be such that (v1*l*v2')*x=v1*l*v2. 823** By associativity v1*((l*v2')*x)=v1*(l*v2). 824** so by the previous lemma (l*v2')*x=l*v2 so l*v2'<=l*v2 825** Assume v1 \in W U S. 826** If v1 \in S U W. then v1*l=v1*l*v2=v1, by antisymmetry also u=v1 827** let v2'=\epsilon then v1*l*v2'=u and l*v2'=l<=l*v2. 828***********************************************************************) 829val PREFIX_FUSION_LEMMA = 830 store_thm 831 ("PREFIX_FUSION_LEMMA", 832 ``!v1 v2 l. 833 PREFIX (v1 * l) u /\ PREFIX u (v1 * l * v2) 834 ==> 835 ?v2'. (v1 * l * v2' = u) /\ PREFIX (l * v2') (l * v2)``, 836 RW_TAC list_ss [] 837 THEN Cases_on `IS_NEUTRAL v1` 838 THEN FULL_SIMP_TAC list_ss [GSYM CONC_ASSOC,CONC_def] 839 THENL 840 [PROVE_TAC[CONC_CANCEL,CONC_ASSOC,PREFIX_def], 841 Cases_on `v1` 842 THEN FULL_SIMP_TAC list_ss [CONC_def,IS_NEUTRAL_def] 843 THEN IMP_RES_TAC PREFIX_ANTISYM 844 THEN RW_TAC list_ss [] 845 THEN Q.EXISTS_TAC `v2` 846 THEN RW_TAC list_ss [PREFIX_def] 847 THEN Cases_on `l` 848 THEN RW_TAC list_ss 849 [CONC_def,GSYM CONC_ASSOC,CONC_CANCEL,IS_NEUTRAL_def] 850 THEN Cases_on `v2` 851 THEN RW_TAC list_ss [CONC_def,CONC_CANCEL,IS_NEUTRAL_def] 852 THEN Q.EXISTS_TAC `N[]` 853 THEN RW_TAC list_ss [CONC_def,CONC_CANCEL,IS_NEUTRAL_def]]); 854 855val TightPrefix_S_FUSION = 856 prove 857 (``(!w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r) /\ 858 (!w. WUS_SEM w r' ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r') 859 ==> 860 !w. WUS_SEM w (S_FUSION (r,r')) 861 ==> 862 !u. PREFIX u w ==> WUS_SEM (WEAKEN u) (S_FUSION (r,r'))``, 863 RW_TAC list_ss [WUS_SEM_def] 864 THEN Cases_on `STRICT_PREFIX u (v1 * l)` 865 THEN FULL_SIMP_TAC list_ss [CONC_def,GSYM CONC_ASSOC] 866 THENL 867 [FULL_SIMP_TAC list_ss [STRICT_PREFIX_def] 868 THEN RES_TAC 869 THEN Q.EXISTS_TAC `WEAKEN u` 870 THEN Q.EXISTS_TAC `v2` 871 THEN Q.EXISTS_TAC `l` 872 THEN RW_TAC list_ss [WEAKEN_def,CONC_def,CONC_WEAKEN], 873 `PREFIX (v1 * l) u` 874 by PROVE_TAC 875 [CONC_ASSOC,PREFIX_TRICHOTOMY,PREFIX_def,PREFIX_CONC,PREFIX_REFL] 876 THEN FULL_SIMP_TAC std_ss [CONC_ASSOC] 877 THEN `?v2'. (v1 * l * v2' = u) /\ PREFIX (l * v2') (l * v2)` 878 by PROVE_TAC[PREFIX_FUSION_LEMMA] 879 THEN `WUS_SEM (WEAKEN(l * v2')) r'` by PROVE_TAC[] 880 THEN `WUS_SEM (l * WEAKEN v2') r'` by PROVE_TAC[WEAKEN_CONC] 881 THEN Q.EXISTS_TAC `v1` 882 THEN Q.EXISTS_TAC `WEAKEN v2'` 883 THEN Q.EXISTS_TAC `l` 884 THEN `l * WEAKEN v2' = WEAKEN(l * v2')` by PROVE_TAC[WEAKEN_CONC] 885 THEN RW_TAC std_ss [GSYM CONC_ASSOC] 886 THEN REWRITE_TAC[WEAKEN_CONC], 887 FULL_SIMP_TAC list_ss [STRICT_PREFIX_def] 888 THEN RES_TAC 889 THEN Q.EXISTS_TAC `WEAKEN u` 890 THEN Q.EXISTS_TAC `v2` 891 THEN Q.EXISTS_TAC `W[]` 892 THEN RW_TAC list_ss [WEAKEN_def,CONC_def,CONC_WEAKEN], 893 RES_TAC 894 THEN Q.EXISTS_TAC `WEAKEN u` 895 THEN Q.EXISTS_TAC `v2` 896 THEN Q.EXISTS_TAC `W[]` 897 THEN RW_TAC list_ss [WEAKEN_def,CONC_def,CONC_WEAKEN]]); 898 899val TightPrefix_WS_CATN = 900 prove 901 (``(!w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r) 902 ==> 903 !n w. 904 WUS_SEM w (WS_CATN n r) 905 ==> 906 !u. PREFIX u w ==> WUS_SEM (WEAKEN u) (WS_CATN n r)``, 907 DISCH_TAC 908 THEN Induct 909 THEN RW_TAC list_ss [WS_CATN_def] 910 THEN RES_TAC 911 THEN IMP_RES_TAC TightPrefix_S_CAT); 912 913val PREFIX_N_EMPTY = 914 store_thm 915 ("PREFIX_N_EMPTY", 916 ``!w. PREFIX w (N[]) = (w = N[])``, 917 Cases_on `w` 918 THEN RW_TAC list_ss [CONC_def,WEAKEN_def,PREFIX_def] 919 THEN EQ_TAC 920 THEN RW_TAC list_ss [] 921 THENL 922 [Cases_on `u` 923 THEN FULL_SIMP_TAC list_ss [CONC_def,A_11,A_distinct], 924 Q.EXISTS_TAC `N[]` 925 THEN RW_TAC list_ss [CONC_def]]); 926 927val PREFIX_W_EMPTY = 928 store_thm 929 ("PREFIX_W_EMPTY", 930 ``!w. PREFIX w (W[]) ==> (WEAKEN w = W[])``, 931 Cases_on `w` 932 THEN RW_TAC list_ss [CONC_def,WEAKEN_def,PREFIX_def] 933 THEN Cases_on `u` 934 THEN FULL_SIMP_TAC list_ss [CONC_def,A_11,A_distinct]); 935 936val TightPrefix_S_REPEAT = 937 prove 938 (``!r. 939 (!w. S_CLOCK_FREE r /\ WUS_SEM w r ==> 940 !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r) ==> 941 !w. S_CLOCK_FREE (S_REPEAT r) /\ WUS_SEM w (S_REPEAT r) ==> 942 !u. PREFIX u w ==> WUS_SEM (WEAKEN u) (S_REPEAT r)``, 943 RW_TAC std_ss [S_CLOCK_FREE_def] 944 THEN `!w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r` 945 by PROVE_TAC[] 946 THEN IMP_RES_TAC TightPrefix_WS_CATN 947 THEN FULL_SIMP_TAC list_ss [WUS_SEM_REPEAT_WS_CATN] 948 THEN RW_TAC list_ss [] 949 THEN RES_TAC 950 THEN ZAP_TAC std_ss [PREFIX_N_EMPTY] 951 THEN FULL_SIMP_TAC list_ss [PREFIX_N_EMPTY,WEAKEN_def,A_distinct] 952 THEN Q.EXISTS_TAC `0` 953 THEN RW_TAC list_ss [WS_CATN_def,TightTrueEmpty]); 954 955val TightPrefix = 956 prove 957 (``!r. S_CLOCK_FREE r 958 ==> 959 !w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r``, 960 INDUCT_THEN sere_induct ASSUME_TAC 961 THENL 962 [(* S_BOOL b *) 963 PROVE_TAC[TightPrefix_S_BOOL], 964 (* S_CAT (r,r') *) 965 RW_TAC std_ss [S_CLOCK_FREE_def] 966 THEN `!w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r` 967 by PROVE_TAC[] 968 THEN `!w. WUS_SEM w r' ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r'` 969 by PROVE_TAC[] 970 THEN IMP_RES_TAC TightPrefix_S_CAT, 971 (* S_FUSION (r,r') *) 972 RW_TAC std_ss [S_CLOCK_FREE_def] 973 THEN `!w. WUS_SEM w r ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r` 974 by PROVE_TAC[] 975 THEN `!w. WUS_SEM w r' ==> !u. PREFIX u w ==> WUS_SEM (WEAKEN u) r'` 976 by PROVE_TAC[] 977 THEN IMP_RES_TAC TightPrefix_S_FUSION, 978 (* S_OR (r,r') *) 979 RW_TAC std_ss [WUS_SEM_def,S_CLOCK_FREE_def] 980 THEN PROVE_TAC[], 981 (* S_AND (r,r') *) 982 RW_TAC std_ss [WUS_SEM_def,S_CLOCK_FREE_def] 983 THEN PROVE_TAC[], 984 (* S_EMPTY *) 985 RW_TAC std_ss [WUS_SEM_def,S_CLOCK_FREE_def] 986 THEN Cases_on `u` 987 THEN FULL_SIMP_TAC list_ss [PREFIX_def,CONC_def,WEAKEN_def,A_distinct] 988 THEN Cases_on `u` 989 THEN FULL_SIMP_TAC list_ss 990 [PREFIX_def,CONC_def,WEAKEN_def,A_distinct,A_11], 991 (* S_REPEAT r *) 992 PROVE_TAC[TightPrefix_S_REPEAT], 993 (* S_CLOCK (r,c) *) 994 RW_TAC std_ss [S_CLOCK_FREE_def]]); 995 996val NEUTRAL_CONC_EQ = 997 store_thm 998 ("NEUTRAL_CONC_EQ", 999 ``!w v1 v2. (N w = v1 * v2) ==> ?w1 w2. (v1 = N w1) /\ (v2 = N w2)``, 1000 Cases_on `v1` THEN Cases_on `v2` 1001 THEN RW_TAC list_ss [CONC_def]); 1002 1003 1004val FOLDL_NW_FALSE = 1005 prove 1006 (``~(N w = FOLDL $* (W l) vlist)``, 1007 Induct_on `vlist` 1008 THEN RW_TAC list_ss [CONC_def]); 1009 1010val FOLDL_NS_FALSE = 1011 prove 1012 (``~(N w = FOLDL $* (S l) vlist)``, 1013 Induct_on `vlist` 1014 THEN RW_TAC list_ss [CONC_def]); 1015 1016val US_SEM_WUS_SEM_CATN = 1017 store_thm 1018 ("US_SEM_WUS_SEM_CATN", 1019 ``(!w. US_SEM w r = WUS_SEM (N w) r) 1020 ==> 1021 !n w. US_SEM w (WS_CATN n r) = WUS_SEM (N w) (WS_CATN n r)``, 1022 DISCH_TAC 1023 THEN Induct 1024 THEN RW_TAC list_ss [WS_CATN_def,US_SEM,WUS_SEM_def] 1025 THEN EQ_TAC 1026 THEN RW_TAC list_ss [] 1027 THENL 1028 [Q.EXISTS_TAC `N v1` THEN Q.EXISTS_TAC `N v2` 1029 THEN PROVE_TAC[CONC_def], 1030 Cases_on `v1` THEN Cases_on `v2` 1031 THEN FULL_SIMP_TAC list_ss [CONC_def,A_11,A_distinct,TOP_FREE_APPEND] 1032 THEN PROVE_TAC[]]); 1033 1034(*****************************************************************************) 1035(* Because this proof is tweaked from one for an earlier version with a *) 1036(* ``TOP_FREE w`` hypothesis, it is likely that it is more complicated *) 1037(* than needed. *) 1038(*****************************************************************************) 1039local 1040open FinitePathTheory; 1041val SIMP = 1042 RW_TAC list_ss 1043 [S_CLOCK_FREE_def,US_SEM_def,WUS_SEM_def,IS_STRONG_def,LEN_def,A_ELEM_def, 1044 ELEM_def,HEAD_def,RESTN_def]; 1045in 1046val TightNeutralEquiv = 1047 prove 1048 (``!r. S_CLOCK_FREE r ==> !w. US_SEM w r = WUS_SEM (N w) r``, 1049 INDUCT_THEN sere_induct ASSUME_TAC 1050 THENL 1051 [(* S_BOOL b *) 1052 SIMP, 1053 (* S_CAT (r,r') *) 1054 SIMP 1055 THEN EQ_TAC 1056 THEN RW_TAC list_ss [] 1057 THENL 1058 [Q.EXISTS_TAC `N v1` THEN Q.EXISTS_TAC `N v2` 1059 THEN RW_TAC list_ss [CONC_def], 1060 IMP_RES_TAC NEUTRAL_CONC_EQ 1061 THEN RW_TAC list_ss [] 1062 THEN FULL_SIMP_TAC list_ss [A_11,CONC_def] 1063 THEN Q.EXISTS_TAC `w1` THEN Q.EXISTS_TAC `w2` 1064 THEN RW_TAC list_ss []] 1065 THEN PROVE_TAC[TOP_FREE_APPEND], 1066 (* S_FUSION (r,r') *) 1067 SIMP 1068 THEN EQ_TAC 1069 THEN RW_TAC list_ss [] 1070 THEN FULL_SIMP_TAC list_ss [TOP_FREE_APPEND] 1071 THENL 1072 [Q.EXISTS_TAC `N v1` THEN Q.EXISTS_TAC `N v2` THEN Q.EXISTS_TAC `N[l]` 1073 THEN ZAP_TAC list_ss [CONC_def,IS_LETTER_def,TOP_FREE_APPEND] 1074 THEN RW_TAC list_ss [CONC_def] 1075 THEN `TOP_FREE([l]++v2)` by PROVE_TAC[TOP_FREE_APPEND] 1076 THEN FULL_SIMP_TAC list_ss [] 1077 THEN PROVE_TAC[], 1078 IMP_RES_TAC NEUTRAL_CONC_EQ 1079 THEN IMP_RES_TAC(GSYM NEUTRAL_CONC_EQ) 1080 THEN RW_TAC list_ss [] 1081 THEN FULL_SIMP_TAC list_ss [A_11,CONC_def,IS_LETTER_def] 1082 THEN RW_TAC list_ss [] 1083 THEN Q.EXISTS_TAC `w1'` THEN Q.EXISTS_TAC `w2` THEN Q.EXISTS_TAC `l` 1084 THEN FULL_SIMP_TAC list_ss [TOP_FREE_APPEND] 1085 THEN `TOP_FREE([l]++w2)` by PROVE_TAC[TOP_FREE_APPEND] 1086 THEN FULL_SIMP_TAC list_ss [] 1087 THEN PROVE_TAC[], 1088 IMP_RES_TAC NEUTRAL_CONC_EQ 1089 THEN IMP_RES_TAC(GSYM NEUTRAL_CONC_EQ) 1090 THEN RW_TAC list_ss [] 1091 THEN FULL_SIMP_TAC list_ss [A_distinct]], 1092 (* S_OR (r,r') *) 1093 SIMP, 1094 (* S_AND (r,r') *) 1095 SIMP, 1096 (* S_EMPTY *) 1097 SIMP, 1098 (* S_REPEAT r *) 1099 RW_TAC list_ss 1100 [WUS_SEM_REPEAT_WS_CATN,S_CLOCK_FREE_def,US_SEM_REPEAT_CATN] 1101 THEN EQ_TAC 1102 THEN RW_TAC list_ss [] 1103 THENL 1104 [`!w. US_SEM w r = WUS_SEM (N w) r` by PROVE_TAC[] 1105 THEN POP_ASSUM 1106 (fn th => ASSUME_TAC(GSYM(MATCH_MP US_SEM_WUS_SEM_CATN th))) 1107 THEN RW_TAC list_ss [US_SEM_WS_CATN] 1108 THEN Cases_on `n=0` 1109 THEN RW_TAC list_ss [] 1110 THEN FULL_SIMP_TAC list_ss [S_CATN_def,US_SEM] 1111 THEN `?m. n = SUC m` by Cooper.COOPER_TAC 1112 THEN DISJ2_TAC 1113 THEN Q.EXISTS_TAC `m` 1114 THEN RW_TAC list_ss [] 1115 THEN FULL_SIMP_TAC list_ss [S_CATN_def,US_SEM] 1116 THEN PROVE_TAC[], 1117 Q.EXISTS_TAC `0` 1118 THEN RW_TAC list_ss [S_CATN_def,US_SEM], 1119 `!w. US_SEM w r = WUS_SEM (N w) r` by PROVE_TAC[] 1120 THEN POP_ASSUM 1121 (fn th => ASSUME_TAC(GSYM(MATCH_MP US_SEM_WUS_SEM_CATN th))) 1122 THEN `US_SEM w (WS_CATN n r)` by PROVE_TAC[] 1123 THEN FULL_SIMP_TAC list_ss [US_SEM_WS_CATN] 1124 THEN PROVE_TAC[]], 1125 (* S_CLOCK (r,c) *) 1126 RW_TAC std_ss [S_CLOCK_FREE_def]]); 1127end; 1128 1129val _ = export_theory(); 1130 1131