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