src/FOL/FOL.thy
changeset 61487 f8cb97e0fd0b
parent 60770 240563fbf41d
child 62020 5d208fd2507d
equal deleted inserted replaced
61486:3590367b0ce9 61487:f8cb97e0fd0b
    15 
    15 
    16 
    16 
    17 subsection \<open>The classical axiom\<close>
    17 subsection \<open>The classical axiom\<close>
    18 
    18 
    19 axiomatization where
    19 axiomatization where
    20   classical: "(~P ==> P) ==> P"
    20   classical: "(\<not> P \<Longrightarrow> P) \<Longrightarrow> P"
    21 
    21 
    22 
    22 
    23 subsection \<open>Lemmas and proof tools\<close>
    23 subsection \<open>Lemmas and proof tools\<close>
    24 
    24 
    25 lemma ccontr: "(\<not> P \<Longrightarrow> False) \<Longrightarrow> P"
    25 lemma ccontr: "(\<not> P \<Longrightarrow> False) \<Longrightarrow> P"
    26   by (erule FalseE [THEN classical])
    26   by (erule FalseE [THEN classical])
    27 
    27 
    28 (*** Classical introduction rules for | and EX ***)
    28 
    29 
    29 subsubsection \<open>Classical introduction rules for @{text "\<or>"} and @{text "\<exists>"}\<close>
    30 lemma disjCI: "(~Q ==> P) ==> P|Q"
    30 
       
    31 lemma disjCI: "(\<not> Q \<Longrightarrow> P) \<Longrightarrow> P \<or> Q"
    31   apply (rule classical)
    32   apply (rule classical)
    32   apply (assumption | erule meta_mp | rule disjI1 notI)+
    33   apply (assumption | erule meta_mp | rule disjI1 notI)+
    33   apply (erule notE disjI2)+
    34   apply (erule notE disjI2)+
    34   done
    35   done
    35 
    36 
    36 (*introduction rule involving only EX*)
    37 text \<open>Introduction rule involving only @{text "\<exists>"}\<close>
    37 lemma ex_classical:
    38 lemma ex_classical:
    38   assumes r: "~(EX x. P(x)) ==> P(a)"
    39   assumes r: "\<not> (\<exists>x. P(x)) \<Longrightarrow> P(a)"
    39   shows "EX x. P(x)"
    40   shows "\<exists>x. P(x)"
    40   apply (rule classical)
    41   apply (rule classical)
    41   apply (rule exI, erule r)
    42   apply (rule exI, erule r)
    42   done
    43   done
    43 
    44 
    44 (*version of above, simplifying ~EX to ALL~ *)
    45 text \<open>Version of above, simplifying @{text "\<not>\<exists>"} to @{text "\<forall>\<not>"}.\<close>
    45 lemma exCI:
    46 lemma exCI:
    46   assumes r: "ALL x. ~P(x) ==> P(a)"
    47   assumes r: "\<forall>x. \<not> P(x) \<Longrightarrow> P(a)"
    47   shows "EX x. P(x)"
    48   shows "\<exists>x. P(x)"
    48   apply (rule ex_classical)
    49   apply (rule ex_classical)
    49   apply (rule notI [THEN allI, THEN r])
    50   apply (rule notI [THEN allI, THEN r])
    50   apply (erule notE)
    51   apply (erule notE)
    51   apply (erule exI)
    52   apply (erule exI)
    52   done
    53   done
    53 
    54 
    54 lemma excluded_middle: "~P | P"
    55 lemma excluded_middle: "\<not> P \<or> P"
    55   apply (rule disjCI)
    56   apply (rule disjCI)
    56   apply assumption
    57   apply assumption
    57   done
    58   done
    58 
    59 
    59 lemma case_split [case_names True False]:
    60 lemma case_split [case_names True False]:
    60   assumes r1: "P ==> Q"
    61   assumes r1: "P \<Longrightarrow> Q"
    61     and r2: "~P ==> Q"
    62     and r2: "\<not> P \<Longrightarrow> Q"
    62   shows Q
    63   shows Q
    63   apply (rule excluded_middle [THEN disjE])
    64   apply (rule excluded_middle [THEN disjE])
    64   apply (erule r2)
    65   apply (erule r2)
    65   apply (erule r1)
    66   apply (erule r1)
    66   done
    67   done
    67 
    68 
    68 ML \<open>
    69 ML \<open>
    69   fun case_tac ctxt a fixes =
    70   fun case_tac ctxt a fixes =
    70     Rule_Insts.res_inst_tac ctxt [((("P", 0), Position.none), a)] fixes @{thm case_split}
    71     Rule_Insts.res_inst_tac ctxt [((("P", 0), Position.none), a)] fixes @{thm case_split};
    71 \<close>
    72 \<close>
    72 
    73 
    73 method_setup case_tac = \<open>
    74 method_setup case_tac = \<open>
    74   Args.goal_spec -- Scan.lift (Args.name_inner_syntax -- Parse.for_fixes) >>
    75   Args.goal_spec -- Scan.lift (Args.name_inner_syntax -- Parse.for_fixes) >>
    75     (fn (quant, (s, fixes)) => fn ctxt => SIMPLE_METHOD'' quant (case_tac ctxt s fixes))
    76     (fn (quant, (s, fixes)) => fn ctxt => SIMPLE_METHOD'' quant (case_tac ctxt s fixes))
    76 \<close> "case_tac emulation (dynamic instantiation!)"
    77 \<close> "case_tac emulation (dynamic instantiation!)"
    77 
    78 
    78 
    79 
    79 (*** Special elimination rules *)
    80 subsection \<open>Special elimination rules\<close>
    80 
    81 
    81 
    82 text \<open>Classical implies (@{text "\<longrightarrow>"}) elimination.\<close>
    82 (*Classical implies (-->) elimination. *)
       
    83 lemma impCE:
    83 lemma impCE:
    84   assumes major: "P-->Q"
    84   assumes major: "P \<longrightarrow> Q"
    85     and r1: "~P ==> R"
    85     and r1: "\<not> P \<Longrightarrow> R"
    86     and r2: "Q ==> R"
    86     and r2: "Q \<Longrightarrow> R"
    87   shows R
    87   shows R
    88   apply (rule excluded_middle [THEN disjE])
    88   apply (rule excluded_middle [THEN disjE])
    89    apply (erule r1)
    89    apply (erule r1)
    90   apply (rule r2)
    90   apply (rule r2)
    91   apply (erule major [THEN mp])
    91   apply (erule major [THEN mp])
    92   done
    92   done
    93 
    93 
    94 (*This version of --> elimination works on Q before P.  It works best for
    94 text \<open>
    95   those cases in which P holds "almost everywhere".  Can't install as
    95   This version of @{text "\<longrightarrow>"} elimination works on @{text Q} before @{text
    96   default: would break old proofs.*)
    96   P}. It works best for those cases in which P holds ``almost everywhere''.
       
    97   Can't install as default: would break old proofs.
       
    98 \<close>
    97 lemma impCE':
    99 lemma impCE':
    98   assumes major: "P-->Q"
   100   assumes major: "P \<longrightarrow> Q"
    99     and r1: "Q ==> R"
   101     and r1: "Q \<Longrightarrow> R"
   100     and r2: "~P ==> R"
   102     and r2: "\<not> P \<Longrightarrow> R"
   101   shows R
   103   shows R
   102   apply (rule excluded_middle [THEN disjE])
   104   apply (rule excluded_middle [THEN disjE])
   103    apply (erule r2)
   105    apply (erule r2)
   104   apply (rule r1)
   106   apply (rule r1)
   105   apply (erule major [THEN mp])
   107   apply (erule major [THEN mp])
   106   done
   108   done
   107 
   109 
   108 (*Double negation law*)
   110 text \<open>Double negation law.\<close>
   109 lemma notnotD: "~~P ==> P"
   111 lemma notnotD: "\<not> \<not> P \<Longrightarrow> P"
   110   apply (rule classical)
   112   apply (rule classical)
   111   apply (erule notE)
   113   apply (erule notE)
   112   apply assumption
   114   apply assumption
   113   done
   115   done
   114 
   116 
   115 lemma contrapos2:  "[| Q; ~ P ==> ~ Q |] ==> P"
   117 lemma contrapos2:  "\<lbrakk>Q; \<not> P \<Longrightarrow> \<not> Q\<rbrakk> \<Longrightarrow> P"
   116   apply (rule classical)
   118   apply (rule classical)
   117   apply (drule (1) meta_mp)
   119   apply (drule (1) meta_mp)
   118   apply (erule (1) notE)
   120   apply (erule (1) notE)
   119   done
   121   done
   120 
   122 
   121 (*** Tactics for implication and contradiction ***)
   123 
   122 
   124 subsubsection \<open>Tactics for implication and contradiction\<close>
   123 (*Classical <-> elimination.  Proof substitutes P=Q in
   125 
   124     ~P ==> ~Q    and    P ==> Q  *)
   126 text \<open>
       
   127   Classical @{text "\<longleftrightarrow>"} elimination. Proof substitutes @{text "P = Q"} in
       
   128   @{text "\<not> P \<Longrightarrow> \<not> Q"} and @{text "P \<Longrightarrow> Q"}.
       
   129 \<close>
   125 lemma iffCE:
   130 lemma iffCE:
   126   assumes major: "P<->Q"
   131   assumes major: "P \<longleftrightarrow> Q"
   127     and r1: "[| P; Q |] ==> R"
   132     and r1: "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> R"
   128     and r2: "[| ~P; ~Q |] ==> R"
   133     and r2: "\<lbrakk>\<not> P; \<not> Q\<rbrakk> \<Longrightarrow> R"
   129   shows R
   134   shows R
   130   apply (rule major [unfolded iff_def, THEN conjE])
   135   apply (rule major [unfolded iff_def, THEN conjE])
   131   apply (elim impCE)
   136   apply (elim impCE)
   132      apply (erule (1) r2)
   137      apply (erule (1) r2)
   133     apply (erule (1) notE)+
   138     apply (erule (1) notE)+
   135   done
   140   done
   136 
   141 
   137 
   142 
   138 (*Better for fast_tac: needs no quantifier duplication!*)
   143 (*Better for fast_tac: needs no quantifier duplication!*)
   139 lemma alt_ex1E:
   144 lemma alt_ex1E:
   140   assumes major: "EX! x. P(x)"
   145   assumes major: "\<exists>! x. P(x)"
   141     and r: "!!x. [| P(x);  ALL y y'. P(y) & P(y') --> y=y' |] ==> R"
   146     and r: "\<And>x. \<lbrakk>P(x);  \<forall>y y'. P(y) \<and> P(y') \<longrightarrow> y = y'\<rbrakk> \<Longrightarrow> R"
   142   shows R
   147   shows R
   143   using major
   148   using major
   144 proof (rule ex1E)
   149 proof (rule ex1E)
   145   fix x
   150   fix x
   146   assume * : "\<forall>y. P(y) \<longrightarrow> y = x"
   151   assume * : "\<forall>y. P(y) \<longrightarrow> y = x"
   147   assume "P(x)"
   152   assume "P(x)"
   148   then show R
   153   then show R
   149   proof (rule r)
   154   proof (rule r)
   150     { fix y y'
   155     {
       
   156       fix y y'
   151       assume "P(y)" and "P(y')"
   157       assume "P(y)" and "P(y')"
   152       with * have "x = y" and "x = y'" by - (tactic "IntPr.fast_tac @{context} 1")+
   158       with * have "x = y" and "x = y'"
       
   159         by - (tactic "IntPr.fast_tac @{context} 1")+
   153       then have "y = y'" by (rule subst)
   160       then have "y = y'" by (rule subst)
   154     } note r' = this
   161     } note r' = this
   155     show "\<forall>y y'. P(y) \<and> P(y') \<longrightarrow> y = y'" by (intro strip, elim conjE) (rule r')
   162     show "\<forall>y y'. P(y) \<and> P(y') \<longrightarrow> y = y'"
       
   163       by (intro strip, elim conjE) (rule r')
   156   qed
   164   qed
   157 qed
   165 qed
   158 
   166 
   159 lemma imp_elim: "P --> Q ==> (~ R ==> P) ==> (Q ==> R) ==> R"
   167 lemma imp_elim: "P \<longrightarrow> Q \<Longrightarrow> (\<not> R \<Longrightarrow> P) \<Longrightarrow> (Q \<Longrightarrow> R) \<Longrightarrow> R"
   160   by (rule classical) iprover
   168   by (rule classical) iprover
   161 
   169 
   162 lemma swap: "~ P ==> (~ R ==> P) ==> R"
   170 lemma swap: "\<not> P \<Longrightarrow> (\<not> R \<Longrightarrow> P) \<Longrightarrow> R"
   163   by (rule classical) iprover
   171   by (rule classical) iprover
   164 
   172 
   165 
   173 
   166 section \<open>Classical Reasoner\<close>
   174 section \<open>Classical Reasoner\<close>
   167 
   175 
   205   );
   213   );
   206   val blast_tac = Blast.blast_tac;
   214   val blast_tac = Blast.blast_tac;
   207 \<close>
   215 \<close>
   208 
   216 
   209 
   217 
   210 lemma ex1_functional: "[| EX! z. P(a,z);  P(a,b);  P(a,c) |] ==> b = c"
   218 lemma ex1_functional: "\<lbrakk>\<exists>! z. P(a,z); P(a,b); P(a,c)\<rbrakk> \<Longrightarrow> b = c"
   211   by blast
   219   by blast
   212 
   220 
   213 (* Elimination of True from asumptions: *)
   221 text \<open>Elimination of @{text True} from assumptions:\<close>
   214 lemma True_implies_equals: "(True ==> PROP P) == PROP P"
   222 lemma True_implies_equals: "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
   215 proof
   223 proof
   216   assume "True \<Longrightarrow> PROP P"
   224   assume "True \<Longrightarrow> PROP P"
   217   from this and TrueI show "PROP P" .
   225   from this and TrueI show "PROP P" .
   218 next
   226 next
   219   assume "PROP P"
   227   assume "PROP P"
   220   then show "PROP P" .
   228   then show "PROP P" .
   221 qed
   229 qed
   222 
   230 
   223 lemma uncurry: "P --> Q --> R ==> P & Q --> R"
   231 lemma uncurry: "P \<longrightarrow> Q \<longrightarrow> R \<Longrightarrow> P \<and> Q \<longrightarrow> R"
   224   by blast
   232   by blast
   225 
   233 
   226 lemma iff_allI: "(!!x. P(x) <-> Q(x)) ==> (ALL x. P(x)) <-> (ALL x. Q(x))"
   234 lemma iff_allI: "(\<And>x. P(x) \<longleftrightarrow> Q(x)) \<Longrightarrow> (\<forall>x. P(x)) \<longleftrightarrow> (\<forall>x. Q(x))"
   227   by blast
   235   by blast
   228 
   236 
   229 lemma iff_exI: "(!!x. P(x) <-> Q(x)) ==> (EX x. P(x)) <-> (EX x. Q(x))"
   237 lemma iff_exI: "(\<And>x. P(x) \<longleftrightarrow> Q(x)) \<Longrightarrow> (\<exists>x. P(x)) \<longleftrightarrow> (\<exists>x. Q(x))"
   230   by blast
   238   by blast
   231 
   239 
   232 lemma all_comm: "(ALL x y. P(x,y)) <-> (ALL y x. P(x,y))" by blast
   240 lemma all_comm: "(\<forall>x y. P(x,y)) \<longleftrightarrow> (\<forall>y x. P(x,y))"
   233 
   241   by blast
   234 lemma ex_comm: "(EX x y. P(x,y)) <-> (EX y x. P(x,y))" by blast
   242 
   235 
   243 lemma ex_comm: "(\<exists>x y. P(x,y)) \<longleftrightarrow> (\<exists>y x. P(x,y))"
   236 
   244   by blast
   237 
   245 
   238 (*** Classical simplification rules ***)
   246 
   239 
   247 
   240 (*Avoids duplication of subgoals after expand_if, when the true and false
   248 subsection \<open>Classical simplification rules\<close>
   241   cases boil down to the same thing.*)
   249 
   242 lemma cases_simp: "(P --> Q) & (~P --> Q) <-> Q" by blast
   250 text \<open>
   243 
   251   Avoids duplication of subgoals after @{text expand_if}, when the true and
   244 
   252   false cases boil down to the same thing.
   245 (*** Miniscoping: pushing quantifiers in
   253 \<close>
   246      We do NOT distribute of ALL over &, or dually that of EX over |
   254 
   247      Baaz and Leitsch, On Skolemization and Proof Complexity (1994)
   255 lemma cases_simp: "(P \<longrightarrow> Q) \<and> (\<not> P \<longrightarrow> Q) \<longleftrightarrow> Q"
   248      show that this step can increase proof length!
   256   by blast
   249 ***)
   257 
   250 
   258 
   251 (*existential miniscoping*)
   259 subsubsection \<open>Miniscoping: pushing quantifiers in\<close>
       
   260 
       
   261 text \<open>
       
   262   We do NOT distribute of @{text "\<forall>"} over @{text "\<and>"}, or dually that of
       
   263   @{text "\<exists>"} over @{text "\<or>"}.
       
   264 
       
   265   Baaz and Leitsch, On Skolemization and Proof Complexity (1994) show that
       
   266   this step can increase proof length!
       
   267 \<close>
       
   268 
       
   269 text \<open>Existential miniscoping.\<close>
   252 lemma int_ex_simps:
   270 lemma int_ex_simps:
   253   "!!P Q. (EX x. P(x) & Q) <-> (EX x. P(x)) & Q"
   271   "\<And>P Q. (\<exists>x. P(x) \<and> Q) \<longleftrightarrow> (\<exists>x. P(x)) \<and> Q"
   254   "!!P Q. (EX x. P & Q(x)) <-> P & (EX x. Q(x))"
   272   "\<And>P Q. (\<exists>x. P \<and> Q(x)) \<longleftrightarrow> P \<and> (\<exists>x. Q(x))"
   255   "!!P Q. (EX x. P(x) | Q) <-> (EX x. P(x)) | Q"
   273   "\<And>P Q. (\<exists>x. P(x) \<or> Q) \<longleftrightarrow> (\<exists>x. P(x)) \<or> Q"
   256   "!!P Q. (EX x. P | Q(x)) <-> P | (EX x. Q(x))"
   274   "\<And>P Q. (\<exists>x. P \<or> Q(x)) \<longleftrightarrow> P \<or> (\<exists>x. Q(x))"
   257   by iprover+
   275   by iprover+
   258 
   276 
   259 (*classical rules*)
   277 text \<open>Classical rules.\<close>
   260 lemma cla_ex_simps:
   278 lemma cla_ex_simps:
   261   "!!P Q. (EX x. P(x) --> Q) <-> (ALL x. P(x)) --> Q"
   279   "\<And>P Q. (\<exists>x. P(x) \<longrightarrow> Q) \<longleftrightarrow> (\<forall>x. P(x)) \<longrightarrow> Q"
   262   "!!P Q. (EX x. P --> Q(x)) <-> P --> (EX x. Q(x))"
   280   "\<And>P Q. (\<exists>x. P \<longrightarrow> Q(x)) \<longleftrightarrow> P \<longrightarrow> (\<exists>x. Q(x))"
   263   by blast+
   281   by blast+
   264 
   282 
   265 lemmas ex_simps = int_ex_simps cla_ex_simps
   283 lemmas ex_simps = int_ex_simps cla_ex_simps
   266 
   284 
   267 (*universal miniscoping*)
   285 text \<open>Universal miniscoping.\<close>
   268 lemma int_all_simps:
   286 lemma int_all_simps:
   269   "!!P Q. (ALL x. P(x) & Q) <-> (ALL x. P(x)) & Q"
   287   "\<And>P Q. (\<forall>x. P(x) \<and> Q) \<longleftrightarrow> (\<forall>x. P(x)) \<and> Q"
   270   "!!P Q. (ALL x. P & Q(x)) <-> P & (ALL x. Q(x))"
   288   "\<And>P Q. (\<forall>x. P \<and> Q(x)) \<longleftrightarrow> P \<and> (\<forall>x. Q(x))"
   271   "!!P Q. (ALL x. P(x) --> Q) <-> (EX x. P(x)) --> Q"
   289   "\<And>P Q. (\<forall>x. P(x) \<longrightarrow> Q) \<longleftrightarrow> (\<exists> x. P(x)) \<longrightarrow> Q"
   272   "!!P Q. (ALL x. P --> Q(x)) <-> P --> (ALL x. Q(x))"
   290   "\<And>P Q. (\<forall>x. P \<longrightarrow> Q(x)) \<longleftrightarrow> P \<longrightarrow> (\<forall>x. Q(x))"
   273   by iprover+
   291   by iprover+
   274 
   292 
   275 (*classical rules*)
   293 text \<open>Classical rules.\<close>
   276 lemma cla_all_simps:
   294 lemma cla_all_simps:
   277   "!!P Q. (ALL x. P(x) | Q) <-> (ALL x. P(x)) | Q"
   295   "\<And>P Q. (\<forall>x. P(x) \<or> Q) \<longleftrightarrow> (\<forall>x. P(x)) \<or> Q"
   278   "!!P Q. (ALL x. P | Q(x)) <-> P | (ALL x. Q(x))"
   296   "\<And>P Q. (\<forall>x. P \<or> Q(x)) \<longleftrightarrow> P \<or> (\<forall>x. Q(x))"
   279   by blast+
   297   by blast+
   280 
   298 
   281 lemmas all_simps = int_all_simps cla_all_simps
   299 lemmas all_simps = int_all_simps cla_all_simps
   282 
   300 
   283 
   301 
   284 (*** Named rewrite rules proved for IFOL ***)
   302 subsubsection \<open>Named rewrite rules proved for IFOL\<close>
   285 
   303 
   286 lemma imp_disj1: "(P-->Q) | R <-> (P-->Q | R)" by blast
   304 lemma imp_disj1: "(P \<longrightarrow> Q) \<or> R \<longleftrightarrow> (P \<longrightarrow> Q \<or> R)" by blast
   287 lemma imp_disj2: "Q | (P-->R) <-> (P-->Q | R)" by blast
   305 lemma imp_disj2: "Q \<or> (P \<longrightarrow> R) \<longleftrightarrow> (P \<longrightarrow> Q \<or> R)" by blast
   288 
   306 
   289 lemma de_Morgan_conj: "(~(P & Q)) <-> (~P | ~Q)" by blast
   307 lemma de_Morgan_conj: "(\<not> (P \<and> Q)) \<longleftrightarrow> (\<not> P \<or> \<not> Q)" by blast
   290 
   308 
   291 lemma not_imp: "~(P --> Q) <-> (P & ~Q)" by blast
   309 lemma not_imp: "\<not> (P \<longrightarrow> Q) \<longleftrightarrow> (P \<and> \<not> Q)" by blast
   292 lemma not_iff: "~(P <-> Q) <-> (P <-> ~Q)" by blast
   310 lemma not_iff: "\<not> (P \<longleftrightarrow> Q) \<longleftrightarrow> (P \<longleftrightarrow> \<not> Q)" by blast
   293 
   311 
   294 lemma not_all: "(~ (ALL x. P(x))) <-> (EX x.~P(x))" by blast
   312 lemma not_all: "(\<not> (\<forall>x. P(x))) \<longleftrightarrow> (\<exists>x. \<not> P(x))" by blast
   295 lemma imp_all: "((ALL x. P(x)) --> Q) <-> (EX x. P(x) --> Q)" by blast
   313 lemma imp_all: "((\<forall>x. P(x)) \<longrightarrow> Q) \<longleftrightarrow> (\<exists>x. P(x) \<longrightarrow> Q)" by blast
   296 
   314 
   297 
   315 
   298 lemmas meta_simps =
   316 lemmas meta_simps =
   299   triv_forall_equality (* prunes params *)
   317   triv_forall_equality  -- \<open>prunes params\<close>
   300   True_implies_equals  (* prune asms `True' *)
   318   True_implies_equals  -- \<open>prune asms @{text True}\<close>
   301 
   319 
   302 lemmas IFOL_simps =
   320 lemmas IFOL_simps =
   303   refl [THEN P_iff_T] conj_simps disj_simps not_simps
   321   refl [THEN P_iff_T] conj_simps disj_simps not_simps
   304   imp_simps iff_simps quant_simps
   322   imp_simps iff_simps quant_simps
   305 
   323 
   306 lemma notFalseI: "~False" by iprover
   324 lemma notFalseI: "\<not> False" by iprover
   307 
   325 
   308 lemma cla_simps_misc:
   326 lemma cla_simps_misc:
   309   "~(P&Q) <-> ~P | ~Q"
   327   "\<not> (P \<and> Q) \<longleftrightarrow> \<not> P \<or> \<not> Q"
   310   "P | ~P"
   328   "P \<or> \<not> P"
   311   "~P | P"
   329   "\<not> P \<or> P"
   312   "~ ~ P <-> P"
   330   "\<not> \<not> P \<longleftrightarrow> P"
   313   "(~P --> P) <-> P"
   331   "(\<not> P \<longrightarrow> P) \<longleftrightarrow> P"
   314   "(~P <-> ~Q) <-> (P<->Q)" by blast+
   332   "(\<not> P \<longleftrightarrow> \<not> Q) \<longleftrightarrow> (P \<longleftrightarrow> Q)" by blast+
   315 
   333 
   316 lemmas cla_simps =
   334 lemmas cla_simps =
   317   de_Morgan_conj de_Morgan_disj imp_disj1 imp_disj2
   335   de_Morgan_conj de_Morgan_disj imp_disj1 imp_disj2
   318   not_imp not_all not_ex cases_simp cla_simps_misc
   336   not_imp not_all not_ex cases_simp cla_simps_misc
   319 
   337 
   320 
   338 
   321 ML_file "simpdata.ML"
   339 ML_file "simpdata.ML"
   322 
   340 
   323 simproc_setup defined_Ex ("EX x. P(x)") = \<open>fn _ => Quantifier1.rearrange_ex\<close>
   341 simproc_setup defined_Ex ("\<exists>x. P(x)") = \<open>fn _ => Quantifier1.rearrange_ex\<close>
   324 simproc_setup defined_All ("ALL x. P(x)") = \<open>fn _ => Quantifier1.rearrange_all\<close>
   342 simproc_setup defined_All ("\<forall>x. P(x)") = \<open>fn _ => Quantifier1.rearrange_all\<close>
   325 
   343 
   326 ML \<open>
   344 ML \<open>
   327 (*intuitionistic simprules only*)
   345 (*intuitionistic simprules only*)
   328 val IFOL_ss =
   346 val IFOL_ss =
   329   put_simpset FOL_basic_ss @{context}
   347   put_simpset FOL_basic_ss @{context}
   347 ML_file "~~/src/Tools/eqsubst.ML"
   365 ML_file "~~/src/Tools/eqsubst.ML"
   348 
   366 
   349 
   367 
   350 subsection \<open>Other simple lemmas\<close>
   368 subsection \<open>Other simple lemmas\<close>
   351 
   369 
   352 lemma [simp]: "((P-->R) <-> (Q-->R)) <-> ((P<->Q) | R)"
   370 lemma [simp]: "((P \<longrightarrow> R) \<longleftrightarrow> (Q \<longrightarrow> R)) \<longleftrightarrow> ((P \<longleftrightarrow> Q) \<or> R)"
   353 by blast
   371   by blast
   354 
   372 
   355 lemma [simp]: "((P-->Q) <-> (P-->R)) <-> (P --> (Q<->R))"
   373 lemma [simp]: "((P \<longrightarrow> Q) \<longleftrightarrow> (P \<longrightarrow> R)) \<longleftrightarrow> (P \<longrightarrow> (Q \<longleftrightarrow> R))"
   356 by blast
   374   by blast
   357 
   375 
   358 lemma not_disj_iff_imp: "~P | Q <-> (P-->Q)"
   376 lemma not_disj_iff_imp: "\<not> P \<or> Q \<longleftrightarrow> (P \<longrightarrow> Q)"
   359 by blast
   377   by blast
   360 
   378 
   361 (** Monotonicity of implications **)
   379 
   362 
   380 subsubsection \<open>Monotonicity of implications\<close>
   363 lemma conj_mono: "[| P1-->Q1; P2-->Q2 |] ==> (P1&P2) --> (Q1&Q2)"
   381 
   364 by fast (*or (IntPr.fast_tac 1)*)
   382 lemma conj_mono: "\<lbrakk>P1 \<longrightarrow> Q1; P2 \<longrightarrow> Q2\<rbrakk> \<Longrightarrow> (P1 \<and> P2) \<longrightarrow> (Q1 \<and> Q2)"
   365 
   383   by fast (*or (IntPr.fast_tac 1)*)
   366 lemma disj_mono: "[| P1-->Q1; P2-->Q2 |] ==> (P1|P2) --> (Q1|Q2)"
   384 
   367 by fast (*or (IntPr.fast_tac 1)*)
   385 lemma disj_mono: "\<lbrakk>P1 \<longrightarrow> Q1; P2 \<longrightarrow> Q2\<rbrakk> \<Longrightarrow> (P1 \<or> P2) \<longrightarrow> (Q1 \<or> Q2)"
   368 
   386   by fast (*or (IntPr.fast_tac 1)*)
   369 lemma imp_mono: "[| Q1-->P1; P2-->Q2 |] ==> (P1-->P2)-->(Q1-->Q2)"
   387 
   370 by fast (*or (IntPr.fast_tac 1)*)
   388 lemma imp_mono: "\<lbrakk>Q1 \<longrightarrow> P1; P2 \<longrightarrow> Q2\<rbrakk> \<Longrightarrow> (P1 \<longrightarrow> P2) \<longrightarrow> (Q1 \<longrightarrow> Q2)"
   371 
   389   by fast (*or (IntPr.fast_tac 1)*)
   372 lemma imp_refl: "P-->P"
   390 
   373 by (rule impI, assumption)
   391 lemma imp_refl: "P \<longrightarrow> P"
   374 
   392   by (rule impI)
   375 (*The quantifier monotonicity rules are also intuitionistically valid*)
   393 
   376 lemma ex_mono: "(!!x. P(x) --> Q(x)) ==> (EX x. P(x)) --> (EX x. Q(x))"
   394 text \<open>The quantifier monotonicity rules are also intuitionistically valid.\<close>
   377 by blast
   395 lemma ex_mono: "(\<And>x. P(x) \<longrightarrow> Q(x)) \<Longrightarrow> (\<exists>x. P(x)) \<longrightarrow> (\<exists>x. Q(x))"
   378 
   396   by blast
   379 lemma all_mono: "(!!x. P(x) --> Q(x)) ==> (ALL x. P(x)) --> (ALL x. Q(x))"
   397 
   380 by blast
   398 lemma all_mono: "(\<And>x. P(x) \<longrightarrow> Q(x)) \<Longrightarrow> (\<forall>x. P(x)) \<longrightarrow> (\<forall>x. Q(x))"
       
   399   by blast
   381 
   400 
   382 
   401 
   383 subsection \<open>Proof by cases and induction\<close>
   402 subsection \<open>Proof by cases and induction\<close>
   384 
   403 
   385 text \<open>Proper handling of non-atomic rule statements.\<close>
   404 text \<open>Proper handling of non-atomic rule statements.\<close>