header {* Representing Intensional Logic *} theory Intensional imports Main begin text {* Intensional is a generic theory allowing lifting of types. *} axclass world \ type text {* @{term world} is a type class of possible worlds. It is a subclass of all HOL types @{term type}. No axioms are provided, since its only purpose is to avoid silly use of the @{term Intensional} syntax. *} section{* Abstract Syntax *} types ('w,'a) expr = "'w \ 'a" 'w form = "('w, bool) expr" text {* The intention is that @{typ 'a} will be used for unliftet types (class @{term type}), while @{typ 'w} is liftet (class @{term world}). *} consts Valid :: "('w::world) form \ bool" const :: "'a \ ('w::world, 'a) expr" lift :: "['a \ 'b, ('w::world, 'a) expr] \ ('w,'b) expr" lift2 :: "['a \ 'b \ 'c, ('w::world,'a) expr, ('w,'b) expr] \ ('w,'c) expr" lift3 :: "['a \ 'b => 'c \ 'd, ('w::world,'a) expr, ('w,'b) expr, ('w,'c) expr] \ ('w,'d) expr" lift4 :: "['a \ 'b => 'c \ 'd \ 'e, ('w::world,'a) expr, ('w,'b) expr, ('w,'c) expr,('w,'d) expr] \ ('w,'e) expr" text{* @{term "Valid F"} asserts that the lifted formula @{term F} holds everywhere. @{term const} allows lifting of a constant, while @{term lift}, @{term lift2} and @{term lift3} allows lifting of functions with arity 1,2 and 3 respectively.*} consts RAll :: "('a \ ('w::world) form) \ 'w form" (binder "Rall " 10) REx :: "('a \ ('w::world) form) \ 'w form" (binder "Rex " 10) REx1 :: "('a \ ('w::world) form) \ 'w form" (binder "Rex! " 10) text{* @{term RAll}, @{term REx} and @{term REx1} introduces "rigid" quantification on logical level. @{term RAll} is universal quantification, @{term REx} is existential quantifcatoin while @{term REx1} requires one and only one witness. *} section{* Concrete Syntax *} nonterminals lift liftargs text{* @{term lift} is introduced of lifted expressions. The idea is to use Isabelle's macro mechanism to convert between the concrete and abstract syntax. *} syntax "" :: "id \ lift" ("_") "" :: "longid \ lift" ("_") "" :: "var \ lift" ("_") "_applC" :: "[lift, cargs] \ lift" ("(1_/ _)" [1000, 1000] 999) "" :: "lift \ lift" ("'(_')") "_lambda" :: "[idts, 'a] \ lift" ("(3%_./ _)" [0, 3] 3) "_constrain" :: "[lift, type] \ lift" ("(_::_)" [4, 0] 3) "" :: "lift \ liftargs" ("_") "_liftargs" :: "[lift, liftargs] \ liftargs" ("_,/ _") "_Valid" :: "lift \ bool" ("(|- _)" 5) "_holdsAt" :: "['a, lift] \ bool" ("(_ |= _)" [100,10] 10) (* Syntax for lifted expressions outside the scope of \ or \.*) "LIFT" :: "lift \ 'a" ("LIFT _") (* generic syntax for lifted constants and functions *) "_const" :: "'a \ lift" ("(#_)" [1000] 999) "_lift" :: "['a, lift] \ lift" ("(_<_>)" [1000] 999) "_lift2" :: "['a, lift, lift] \ lift" ("(_<_,/ _>)" [1000] 999) "_lift3" :: "['a, lift, lift, lift] \ lift" ("(_<_,/ _,/ _>)" [1000] 999) "_lift4" :: "['a, lift, lift, lift,lift] \ lift" ("(_<_,/ _,/ _,/ _>)" [1000] 999) (* concrete syntax for common infix functions: reuse same symbol *) "_liftEqu" :: "[lift, lift] \ lift" ("(_ =/ _)" [50,51] 50) "_liftNeq" :: "[lift, lift] \ lift" ("(_ ~=/ _)" [50,51] 50) "_liftNot" :: "lift \ lift" ("(~ _)" [40] 40) "_liftAnd" :: "[lift, lift] \ lift" ("(_ &/ _)" [36,35] 35) "_liftOr" :: "[lift, lift] \ lift" ("(_ |/ _)" [31,30] 30) "_liftImp" :: "[lift, lift] \ lift" ("(_ -->/ _)" [26,25] 25) "_liftIf" :: "[lift, lift, lift] \ lift" ("(if (_)/ then (_)/ else (_))" 10) "_liftPlus" :: "[lift, lift] \ lift" ("(_ +/ _)" [66,65] 65) "_liftMinus" :: "[lift, lift] \ lift" ("(_ -/ _)" [66,65] 65) "_liftTimes" :: "[lift, lift] \ lift" ("(_ */ _)" [71,70] 70) "_liftDiv" :: "[lift, lift] \ lift" ("(_ div _)" [71,70] 70) "_liftMod" :: "[lift, lift] \ lift" ("(_ mod _)" [71,70] 70) "_liftLess" :: "[lift, lift] \ lift" ("(_/ < _)" [50, 51] 50) "_liftLeq" :: "[lift, lift] \ lift" ("(_/ <= _)" [50, 51] 50) "_liftMem" :: "[lift, lift] \ lift" ("(_/ : _)" [50, 51] 50) "_liftNotMem" :: "[lift, lift] \ lift" ("(_/ ~: _)" [50, 51] 50) "_liftFinset" :: "liftargs => lift" ("{(_)}") (** TODO: syntax for lifted collection / comprehension **) "_liftPair" :: "[lift,liftargs] \ lift" ("(1'(_,/ _'))") (* infix syntax for list operations *) "_liftCons" :: "[lift, lift] \ lift" ("(_ #/ _)" [65,66] 65) "_liftApp" :: "[lift, lift] \ lift" ("(_ @/ _)" [65,66] 65) "_liftList" :: "liftargs \ lift" ("[(_)]") (* Rigid quantification (syntax level) *) "_ARAll" :: "[idts, lift] \ lift" ("(3! _./ _)" [0, 10] 10) "_AREx" :: "[idts, lift] \ lift" ("(3? _./ _)" [0, 10] 10) "_AREx1" :: "[idts, lift] \ lift" ("(3?! _./ _)" [0, 10] 10) "_RAll" :: "[idts, lift] \ lift" ("(3ALL _./ _)" [0, 10] 10) "_REx" :: "[idts, lift] \ lift" ("(3EX _./ _)" [0, 10] 10) "_REx1" :: "[idts, lift] \ lift" ("(3EX! _./ _)" [0, 10] 10) translations "_const" \ "const" "_lift" \ "lift" "_lift2" \ "lift2" "_lift3" \ "lift3" "_lift4" \ "lift4" "_Valid" \ "Valid" "_RAll x A" \ "Rall x. A" "_REx x A" \ "Rex x. A" "_REx1 x A" \ "Rex! x. A" "_ARAll" \ "_RAll" "_AREx" \ "_REx" "_AREx1" \ "_REx1" "w |= A" \ "A w" "LIFT A" \ "A::_\_" "_liftEqu" \ "_lift2 (op =)" "_liftNeq u v" \ "_liftNot (_liftEqu u v)" "_liftNot" \ "_lift Not" "_liftAnd" \ "_lift2 (op &)" "_liftOr" \ "_lift2 (op | )" "_liftImp" \ "_lift2 (op -->)" "_liftIf" \ "_lift3 If" "_liftPlus" \ "_lift2 (op +)" "_liftMinus" \ "_lift2 (op -)" "_liftTimes" \ "_lift2 (op *)" "_liftDiv" \ "_lift2 (op div)" "_liftMod" \ "_lift2 (op mod)" "_liftLess" \ "_lift2 (op <)" "_liftLeq" \ "_lift2 (op <=)" "_liftMem" \ "_lift2 (op :)" "_liftNotMem x xs" \ "_liftNot (_liftMem x xs)" "_liftFinset (_liftargs x xs)" \ "_lift2 insert x (_liftFinset xs)" "_liftFinset x" \ "_lift2 insert x (_const {})" "_liftPair x (_liftargs y z)" \ "_liftPair x (_liftPair y z)" "_liftPair" \ "_lift2 Pair" "_liftCons" \ "lift2 Cons" "_liftApp" \ "lift2 (op @)" "_liftList (_liftargs x xs)" \ "_liftCons x (_liftList xs)" "_liftList x" \ "_liftCons x (_const [])" "w |= ~A" \ "_liftNot A w" "w |= A & B" \ "_liftAnd A B w" "w |= A | B" \ "_liftOr A B w" "w |= A --> B" \ "_liftImp A B w" "w |= u = v" \ "_liftEqu u v w" "w |= ALL x. A" \ "_RAll x A w" "w |= EX x. A" \ "_REx x A w" "w |= EX! x. A" \ "_REx1 x A w" syntax (xsymbols) "_Valid" :: "lift \ bool" ("(\ _)" 5) "_holdsAt" :: "['a, lift] \ bool" ("(_ \ _)" [100,10] 10) "_liftNeq" :: "[lift, lift] \ lift" (infixl "\" 50) "_liftNot" :: "lift \ lift" ("\ _" [40] 40) "_liftAnd" :: "[lift, lift] \ lift" (infixr "\" 35) "_liftOr" :: "[lift, lift] \ lift" (infixr "\" 30) "_liftImp" :: "[lift, lift] \ lift" (infixr "\" 25) "_RAll" :: "[idts, lift] \ lift" ("(3\_./ _)" [0, 10] 10) "_REx" :: "[idts, lift] \ lift" ("(3\_./ _)" [0, 10] 10) "_REx1" :: "[idts, lift] \ lift" ("(3\!_./ _)" [0, 10] 10) "_liftLeq" :: "[lift, lift] \ lift" ("(_/ \ _)" [50, 51] 50) "_liftMem" :: "[lift, lift] \ lift" ("(_/ \ _)" [50, 51] 50) "_liftNotMem" :: "[lift, lift] \ lift" ("(_/ \ _)" [50, 51] 50) syntax (HTML output) "_liftNeq" :: "[lift, lift] \ lift" (infixl "\" 50) "_liftNot" :: "lift \ lift" ("\ _" [40] 40) "_liftAnd" :: "[lift, lift] \ lift" (infixr "\" 35) "_liftOr" :: "[lift, lift] \ lift" (infixr "\" 30) "_RAll" :: "[idts, lift] \ lift" ("(3\_./ _)" [0, 10] 10) "_REx" :: "[idts, lift] \ lift" ("(3\_./ _)" [0, 10] 10) "_REx1" :: "[idts, lift] \ lift" ("(3\!_./ _)" [0, 10] 10) "_liftLeq" :: "[lift, lift] \ lift" ("(_/ \ _)" [50, 51] 50) "_liftMem" :: "[lift, lift] \ lift" ("(_/ \ _)" [50, 51] 50) "_liftNotMem" :: "[lift, lift] \ lift" ("(_/ \ _)" [50, 51] 50) section {* Definitions *} defs Valid_def: "|- A == ALL w. w |= A" unl_con: "LIFT #c w == c" unl_lift: "LIFT f w == f (x w)" unl_lift2: "LIFT f w == f (x w) (y w)" unl_lift3: "LIFT f w == f (x w) (y w) (z w)" unl_lift4: "LIFT f w == f (x w) (y w) (z w) (zz w)" (* Cannot use defs here - must look into *) axioms unl_Rall: "w \ ALL x. A x == ALL x. (w \ A x)" unl_Rex: "w \ EX x. A x == EX x. (w \ A x)" unl_Rex1: "w \ EX! x. A x == EX! x. (w \ A x)" section {* Lemmas and Tactics *} lemma intD[dest]: "\ A \ w \ A" proof - assume a:"\ A" from a have "ALL w. w \ A" by (auto simp add: Valid_def) thus ?thesis .. qed lemma intI[simp]: assumes P1:"(\ w. w \ A)" shows "\ A" proof - fix w from P1 have "A w" by blast thus ?thesis by (auto simp add: Valid_def) qed lemma inteq_reflection[simp]: assumes P1: "\ x=y" shows "(x \ y)" proof - from P1 have "ALL w. w |= x=y" by (unfold Valid_def) hence P2: "ALL w. x w = y w" by (unfold unl_lift2) hence P3:"x=y" proof - from P2 have "\ w. x w = y w" .. thus ?thesis by (rule ext) qed thus "x \ y" by (rule "eq_reflection") qed lemma int_simps1 [simp]: "|- (x=x) = #True" by (simp add: Valid_def unl_lift2 unl_con) lemma int_simps2 [simp]: "\ (\ #True) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps3 [simp]: "\ (\ #False) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps4 [simp]: "\ (\\ P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps5 [simp]: "\ ((\ P) = P) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps6 [simp]: "\ (P = (\P)) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps7 [simp]: "\ (P \ Q) = (P = (\ Q))" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps8 [simp]: "\ (#True=P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps9 [simp]: "\ (P=#True) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps10 [simp]: "\ (#True \ P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps11 [simp]: "\ (#False \ P) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps12 [simp]: "\ (P \ #True) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps13 [simp]: "\ (P \ P) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps14 [simp]: "\ (P \ #False) = (\P)" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps15 [simp]: "\ (P \ ~P) = (\P)" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps16 [simp]: "\ (P \ #True) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps17 [simp]: "\ (#True \ P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps18 [simp]: "\ (P \ #False) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps19 [simp]: "\ (#False \ P) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps20 [simp]: "\ (P \ P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps21 [simp]: "\ (P \ ~P) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps22 [simp]: "\ (\P \ P) = #False" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps23 [simp]: "\ (P \ #True) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps24 [simp]: "\ (#True \ P) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps25 [simp]: "\ (P \ #False) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps26 [simp]: "\ (#False \ P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps27 [simp]: "\ (P \ P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps28 [simp]: "\ (P \ \P) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps29 [simp]: "\ (\P \ P) = #True" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps30 [simp]: "\ (\ x. P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con unl_Rall) lemma int_simps31 [simp]: "\ (\ x. P) = P" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con unl_Rex) lemma int_simps32 [simp]: "\ (\Q \ \P) = (P \ Q)" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemma int_simps33 [simp]: "\ (P \ Q \ R) = ((P \ R) \ (Q \ R))" by (auto simp add: Valid_def unl_lift2 unl_lift unl_con) lemmas int_simps = int_simps1 int_simps2 int_simps3 int_simps4 int_simps5 int_simps6 int_simps7 int_simps8 int_simps9 int_simps10 int_simps11 int_simps12 int_simps13 int_simps14 int_simps15 int_simps16 int_simps17 int_simps18 int_simps19 int_simps20 int_simps21 int_simps22 int_simps23 int_simps24 int_simps25 int_simps26 int_simps27 int_simps28 int_simps29 int_simps30 int_simps31 int_simps32 int_simps33 lemma Not_Rall: "\ (\(\ x. F x)) = (\ x. \F x)" proof - have "\ w. w \ ((\ (\ x. F x)) = (\x. \ F x))" proof fix w have s1: "w \ (\ (\ x. F x)) \ w \ (\x. \ F x)" proof - assume a1: "w \ (\ (\ x. F x))" hence "\ RAll F w" by (unfold unl_lift) hence "\ (\x. F x w)" by (unfold unl_Rall) hence "\x. w \ \ F x" by (simp add: unl_Rex unl_lift) thus ?thesis by (unfold unl_Rex) qed moreover have s2: "w \ (\x. \ F x) \ w \ \ RAll F" proof - assume a2: "w \ (\x. \ F x)" hence "\ x. w \ \ F x" by (unfold unl_Rex) hence "\ x. \ F x w" by (unfold unl_lift) hence "\ (\x. F x w)" by simp hence "\ RAll F w" by (unfold unl_Rall) thus "w \ \ RAll F" by (unfold unl_lift) qed ultimately have "(w \ \ RAll F) = (w \ (\x. \ F x))" .. thus "w \ ((\ (\ x. F x)) = (\x. \ F x))" by (unfold unl_lift2) qed thus ?thesis by (unfold Valid_def) qed lemma Not_Rex: "\ (\(\ x. F x)) = (\ x. \F x)" proof - have "\ w. w \ ((\ REx F) = (\ x. \ F x))" proof fix w have l2r: "(w \ (\ REx F)) \ (w \ (\ x. \ F x))" proof - assume l2a1: "(w \ (\ REx F))" from l2a1 have "\ (\ x. F x w)" by (simp add: unl_Rex unl_lift) hence "\ x. (\ F x w)" by simp hence "\ x. (w \ \ F x)" by (auto simp add: unl_lift) thus "w \ (\ x. \ F x)" by (unfold unl_Rall) qed moreover have r2l: "(w \ (\ x. \ F x)) \ (w \ (\ REx F))" proof - assume l2a1: "(w \ (\ x. \ F x))" hence "\ x. (w \ \ F x)" by (unfold unl_Rall) hence "\ x. (\ F x w)" by (unfold unl_lift) hence "\ (\ x. F x w)" by (simp add: unl_Rex unl_lift) thus ?thesis by (simp add: unl_Rex unl_lift) qed ultimately have "(w \ (\ REx F)) = (w \ (\ x. \ F x))" .. thus "w \ (\ REx F) = (\ x. \ F x)" by (unfold unl_lift2) qed thus ?thesis by (unfold Valid_def) qed lemma TrueW: "\ #True" proof - have "\ w. True" by blast hence "\ w. w \ (#True)" by (unfold unl_con) thus ?thesis by (unfold Valid_def) qed lemmas intensional_rews[simp] = unl_con unl_lift unl_lift2 unl_lift3 unl_lift4 unl_Rall unl_Rex unl_Rex1 subsection {* Functions to \emph{unlift} intensional implications into HOL rules *} text{* Basic unlifting introduces a parameter @{term w} and applies basic rewrites, e.g @{term "\ F = G"} becomes @{term "F w = G w"} and @{term "\ F \ G"} becomes @{term "F w \ G w"}. *} method_setup int_unlift = {* let fun int_unlift_tac args ctxt = let val intensional_rews = ProofContext.get_thms ctxt (PureThy.Name "intensional_rews") val intI = ProofContext.get_thm ctxt (PureThy.Name "intI") in (Method.METHOD (fn chained_facts => (fn th => Seq.single (rewrite_rule intensional_rews ((intI RS th) handle _ => th))))) end in int_unlift_tac end *} "int_unlift tactic lifted to being a method." lemma int_eq: "\ X = Y \ X = Y" by auto lemma int_iffI: assumes h1: "\ F \ G" and h2: "\ G \ F" shows "\ F = G" proof (int_unlift,rule iffI) fix w assume "w \ F" with h1[THEN intD] show "w \ G" by auto next fix w assume "w \ G" with h2[THEN intD] show "w \ F" by auto qed lemma int_iffD1: assumes h: "\ F = G" shows "\ F \ G" using h[THEN intD] by auto lemma int_iffD2: assumes h: "\ F = G" shows "\ G \ F" using h[THEN intD] by auto lemma lift_imp_trans: assumes h1: "\ A \ B" and h2: "\ B \ C" shows "\ A \ C" using h1 h2 by (unfold Valid_def) (auto) lemma lift_imp_neg: assumes h1: "\ A \ B" shows "\ \B \ \A" using h1 by (unfold Valid_def) (auto) lemma lift_and_com: "\ (A \ B) = (B \ A)" by (unfold Valid_def) (auto) section "Not working" text{* Turn @{term "\ F = G"} into meta-level rewrite rule @{term "F \ G"} *} (* Fix: Cannot get this to work - even by applying rules directly without using tactic - see below *) (* method_setup int_rewrite = {* let fun int_rewrite_tac args ctxt = let val intensional_rews = ProofContext.get_thms ctxt (PureThy.Name "intensional_rews") in (Method.METHOD (fn chained_facts => (fn th => Seq.single (rewrite_rule intensional_rews ((th RS thm "inteq_reflection") handle _ => th))))) end in int_rewrite_tac end *} "int_unlift tactic lifted to being a method." *) (* lemma assumes H:"\ F = G" shows "F \ G" proof - from H show "F \ G" by (rule inteq_reflection) qed *) subsubsection {* Flattening *} text{* Flatting turns \ into \ and eliminates conjunctions in the antecedent. E.g. @{term "P \ Q \ (R \ S \ T)"} becomes @{term "\ P; Q; R \ S \ \ T"}. Flattening can be useful with \emph{intensional} lemmas (after unlifting). Naive resolution with mp and conjI may run away because of higher-order unification, therefore the code is a little awkward.*} (* Fix: doesn't works Note: WHY not "apply (rule impI | erule conjE)+" : examples where this run away because of higher-order unification *) end