let string_INDUCT,string_RECURSION = define_type "string = String num";; parse_as_infix("&&",(16,"right"));; parse_as_infix("||",(15,"right"));; parse_as_infix("-->",(14,"right"));; parse_as_infix("<->",(13,"right"));; parse_as_prefix "Not";; parse_as_prefix "Box";; parse_as_prefix "Diamond";; let form_INDUCT,form_RECURSION = define_type "form = False | True | Atom string | Not form | && form form | || form form | --> form form | <-> form form | Box form | Diamond form";; let holds = define `(holds (W,R) V False w <=> F) /\ (holds (W,R) V True w <=> T) /\ (holds (W,R) V (Atom a) w <=> V a w) /\ (holds (W,R) V (Not p) w <=> ~(holds (W,R) V p w)) /\ (holds (W,R) V (p && q) w <=> holds (W,R) V p w /\ holds (W,R) V q w) /\ (holds (W,R) V (p || q) w <=> holds (W,R) V p w \/ holds (W,R) V q w) /\ (holds (W,R) V (p --> q) w <=> holds (W,R) V p w ==> holds (W,R) V q w) /\ (holds (W,R) V (p <-> q) w <=> holds (W,R) V p w <=> holds (W,R) V q w) /\ (holds (W,R) V (Box p) w <=> !w'. w' IN W /\ R w w' ==> holds (W,R) V p w') /\ (holds (W,R) V (Diamond p) w <=> ?w'. w' IN W /\ R w w' /\ holds (W,R) V p w')`;; let holds_in = new_definition `holds_in (W,R) p = !V w. w IN W ==> holds (W,R) V p w`;; parse_as_infix("|=",(11,"right"));; let valid = new_definition `L |= p <=> !f. L f ==> holds_in f p`;; let S4 = new_definition `S4(W,R) <=> ~(W = {}) /\ (!x y. R x y ==> x IN W /\ y IN W) /\ (!x. x IN W ==> R x x) /\ (!x y z. R x y /\ R y z ==> R x z)`;; let LTL = new_definition `LTL(W,R) <=> (W = UNIV) /\ !x y:num. R x y <=> x <= y`;; let GL = new_definition `GL(W,R) <=> ~(W = {}) /\ (!x y. R x y ==> x IN W /\ y IN W) /\ WF(\x y. R y x) /\ (!x y z:num. R x y /\ R y z ==> R x z)`;; let MODAL_TAC = REWRITE_TAC[valid; FORALL_PAIR_THM; holds_in; holds] THEN MESON_TAC[];; let MODAL_RULE tm = prove(tm,MODAL_TAC);; let TAUT_1 = MODAL_RULE `L |= Box True`;; let TAUT_2 = MODAL_RULE `L |= Box(A --> B) --> Box A --> Box B`;; let TAUT_3 = MODAL_RULE `L |= Diamond(A --> B) --> Box A --> Diamond B`;; let TAUT_4 = MODAL_RULE `L |= Box(A --> B) --> Diamond A --> Diamond B`;; let TAUT_5 = MODAL_RULE `L |= Box(A && B) --> Box A && Box B`;; let TAUT_6 = MODAL_RULE `L |= Diamond(A || B) --> Diamond A || Diamond B`;; let HOLDS_FORALL_LEMMA = prove (`!W R P. (!A V. P(holds (W,R) V A)) <=> (!p:W->bool. P p)`, REPEAT GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN GEN_TAC; SIMP_TAC[]] THEN POP_ASSUM(MP_TAC o SPECL [`Atom a`; `\a:string. (p:W->bool)`]) THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN REWRITE_TAC[holds] THEN REWRITE_TAC[ETA_AX]);; let MODAL_SCHEMA_TAC = REWRITE_TAC[holds_in; holds] THEN MP_TAC HOLDS_FORALL_LEMMA THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN DISCH_THEN(fun th -> REWRITE_TAC[th]);; let MODAL_REFL = prove (`!W R. (!w:W. w IN W ==> R w w) <=> !A. holds_in (W,R) (Box A --> A)`, MODAL_SCHEMA_TAC THEN MESON_TAC[]);; let MODAL_TRANS = prove (`!W R. (!w w' w'':W. w IN W /\ w' IN W /\ w'' IN W /\ R w w' /\ R w' w'' ==> R w w'') <=> (!A. holds_in (W,R) (Box A --> Box(Box A)))`, MODAL_SCHEMA_TAC THEN MESON_TAC[]);; let MODAL_SERIAL = prove (`!W R. (!w:W. w IN W ==> ?w'. w' IN W /\ R w w') <=> (!A. holds_in (W,R) (Box A --> Diamond A))`, MODAL_SCHEMA_TAC THEN MESON_TAC[]);; let MODAL_SYM = prove (`!W R. (!w w':W. w IN W /\ w' IN W /\ R w w' ==> R w' w) <=> (!A. holds_in (W,R) (A --> Box(Diamond A)))`, MODAL_SCHEMA_TAC THEN EQ_TAC THENL [MESON_TAC[]; REPEAT STRIP_TAC] THEN FIRST_X_ASSUM(MP_TAC o SPECL [`\v:W. v = w`; `w:W`]) THEN ASM_MESON_TAC[]);; let MODAL_WFTRANS = prove (`!W R. (!x y z:W. x IN W /\ y IN W /\ z IN W /\ R x y /\ R y z ==> R x z) /\ WF(\x y. x IN W /\ y IN W /\ R y x) <=> (!A. holds_in (W,R) (Box(Box A --> A) --> Box A))`, MODAL_SCHEMA_TAC THEN REWRITE_TAC[WF_IND] THEN EQ_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL [REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC; X_GEN_TAC `w:W` THEN FIRST_X_ASSUM(MP_TAC o SPECL [`\v:W. v IN W /\ R w v /\ !w''. w'' IN W /\ R v w'' ==> R w w''`; `w:W`]); X_GEN_TAC `P:W->bool` THEN DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `\x:W. !w:W. x IN W /\ R w x ==> P x`) THEN MATCH_MP_TAC MONO_FORALL] THEN ASM_MESON_TAC[]);;