src/HOL/HOL.thy
changeset 60758 d8d85a8172b5
parent 60183 4cd4c204578c
child 60759 36d9f215c982
equal deleted inserted replaced
60757:c09598a97436 60758:d8d85a8172b5
     1 (*  Title:      HOL/HOL.thy
     1 (*  Title:      HOL/HOL.thy
     2     Author:     Tobias Nipkow, Markus Wenzel, and Larry Paulson
     2     Author:     Tobias Nipkow, Markus Wenzel, and Larry Paulson
     3 *)
     3 *)
     4 
     4 
     5 section {* The basis of Higher-Order Logic *}
     5 section \<open>The basis of Higher-Order Logic\<close>
     6 
     6 
     7 theory HOL
     7 theory HOL
     8 imports Pure "~~/src/Tools/Code_Generator"
     8 imports Pure "~~/src/Tools/Code_Generator"
     9 keywords
     9 keywords
    10   "try" "solve_direct" "quickcheck" "print_coercions" "print_claset"
    10   "try" "solve_direct" "quickcheck" "print_coercions" "print_claset"
    51     @{plugin quickcheck_full_exhaustive},
    51     @{plugin quickcheck_full_exhaustive},
    52     @{plugin quickcheck_narrowing}]
    52     @{plugin quickcheck_narrowing}]
    53 \<close>
    53 \<close>
    54 
    54 
    55 
    55 
    56 subsection {* Primitive logic *}
    56 subsection \<open>Primitive logic\<close>
    57 
    57 
    58 subsubsection {* Core syntax *}
    58 subsubsection \<open>Core syntax\<close>
    59 
    59 
    60 setup {* Axclass.class_axiomatization (@{binding type}, []) *}
    60 setup \<open>Axclass.class_axiomatization (@{binding type}, [])\<close>
    61 default_sort type
    61 default_sort type
    62 setup {* Object_Logic.add_base_sort @{sort type} *}
    62 setup \<open>Object_Logic.add_base_sort @{sort type}\<close>
    63 
    63 
    64 axiomatization where fun_arity: "OFCLASS('a \<Rightarrow> 'b, type_class)"
    64 axiomatization where fun_arity: "OFCLASS('a \<Rightarrow> 'b, type_class)"
    65 instance "fun" :: (type, type) type by (rule fun_arity)
    65 instance "fun" :: (type, type) type by (rule fun_arity)
    66 
    66 
    67 axiomatization where itself_arity: "OFCLASS('a itself, type_class)"
    67 axiomatization where itself_arity: "OFCLASS('a itself, type_class)"
    88   All           :: "('a => bool) => bool"           (binder "ALL " 10)
    88   All           :: "('a => bool) => bool"           (binder "ALL " 10)
    89   Ex            :: "('a => bool) => bool"           (binder "EX " 10)
    89   Ex            :: "('a => bool) => bool"           (binder "EX " 10)
    90   Ex1           :: "('a => bool) => bool"           (binder "EX! " 10)
    90   Ex1           :: "('a => bool) => bool"           (binder "EX! " 10)
    91 
    91 
    92 
    92 
    93 subsubsection {* Additional concrete syntax *}
    93 subsubsection \<open>Additional concrete syntax\<close>
    94 
    94 
    95 notation (output)
    95 notation (output)
    96   eq  (infix "=" 50)
    96   eq  (infix "=" 50)
    97 
    97 
    98 abbreviation
    98 abbreviation
   125 notation (xsymbols)
   125 notation (xsymbols)
   126   iff  (infixr "\<longleftrightarrow>" 25)
   126   iff  (infixr "\<longleftrightarrow>" 25)
   127 
   127 
   128 syntax "_The" :: "[pttrn, bool] => 'a"  ("(3THE _./ _)" [0, 10] 10)
   128 syntax "_The" :: "[pttrn, bool] => 'a"  ("(3THE _./ _)" [0, 10] 10)
   129 translations "THE x. P" == "CONST The (%x. P)"
   129 translations "THE x. P" == "CONST The (%x. P)"
   130 print_translation {*
   130 print_translation \<open>
   131   [(@{const_syntax The}, fn _ => fn [Abs abs] =>
   131   [(@{const_syntax The}, fn _ => fn [Abs abs] =>
   132       let val (x, t) = Syntax_Trans.atomic_abs_tr' abs
   132       let val (x, t) = Syntax_Trans.atomic_abs_tr' abs
   133       in Syntax.const @{syntax_const "_The"} $ x $ t end)]
   133       in Syntax.const @{syntax_const "_The"} $ x $ t end)]
   134 *}  -- {* To avoid eta-contraction of body *}
   134 \<close>  -- \<open>To avoid eta-contraction of body\<close>
   135 
   135 
   136 nonterminal letbinds and letbind
   136 nonterminal letbinds and letbind
   137 syntax
   137 syntax
   138   "_bind"       :: "[pttrn, 'a] => letbind"              ("(2_ =/ _)" 10)
   138   "_bind"       :: "[pttrn, 'a] => letbind"              ("(2_ =/ _)" 10)
   139   ""            :: "letbind => letbinds"                 ("_")
   139   ""            :: "letbind => letbinds"                 ("_")
   163   All  (binder "! " 10) and
   163   All  (binder "! " 10) and
   164   Ex  (binder "? " 10) and
   164   Ex  (binder "? " 10) and
   165   Ex1  (binder "?! " 10)
   165   Ex1  (binder "?! " 10)
   166 
   166 
   167 
   167 
   168 subsubsection {* Axioms and basic definitions *}
   168 subsubsection \<open>Axioms and basic definitions\<close>
   169 
   169 
   170 axiomatization where
   170 axiomatization where
   171   refl: "t = (t::'a)" and
   171   refl: "t = (t::'a)" and
   172   subst: "s = t \<Longrightarrow> P s \<Longrightarrow> P t" and
   172   subst: "s = t \<Longrightarrow> P s \<Longrightarrow> P t" and
   173   ext: "(!!x::'a. (f x ::'b) = g x) ==> (%x. f x) = (%x. g x)"
   173   ext: "(!!x::'a. (f x ::'b) = g x) ==> (%x. f x) = (%x. g x)"
   174     -- {*Extensionality is built into the meta-logic, and this rule expresses
   174     -- \<open>Extensionality is built into the meta-logic, and this rule expresses
   175          a related property.  It is an eta-expanded version of the traditional
   175          a related property.  It is an eta-expanded version of the traditional
   176          rule, and similar to the ABS rule of HOL*} and
   176          rule, and similar to the ABS rule of HOL\<close> and
   177 
   177 
   178   the_eq_trivial: "(THE x. x = a) = (a::'a)"
   178   the_eq_trivial: "(THE x. x = a) = (a::'a)"
   179 
   179 
   180 axiomatization where
   180 axiomatization where
   181   impI: "(P ==> Q) ==> P-->Q" and
   181   impI: "(P ==> Q) ==> P-->Q" and
   207 axiomatization undefined :: 'a
   207 axiomatization undefined :: 'a
   208 
   208 
   209 class default = fixes default :: 'a
   209 class default = fixes default :: 'a
   210 
   210 
   211 
   211 
   212 subsection {* Fundamental rules *}
   212 subsection \<open>Fundamental rules\<close>
   213 
   213 
   214 subsubsection {* Equality *}
   214 subsubsection \<open>Equality\<close>
   215 
   215 
   216 lemma sym: "s = t ==> t = s"
   216 lemma sym: "s = t ==> t = s"
   217   by (erule subst) (rule refl)
   217   by (erule subst) (rule refl)
   218 
   218 
   219 lemma ssubst: "t = s ==> P s ==> P t"
   219 lemma ssubst: "t = s ==> P s ==> P t"
   228 lemma meta_eq_to_obj_eq:
   228 lemma meta_eq_to_obj_eq:
   229   assumes meq: "A == B"
   229   assumes meq: "A == B"
   230   shows "A = B"
   230   shows "A = B"
   231   by (unfold meq) (rule refl)
   231   by (unfold meq) (rule refl)
   232 
   232 
   233 text {* Useful with @{text erule} for proving equalities from known equalities. *}
   233 text \<open>Useful with @{text erule} for proving equalities from known equalities.\<close>
   234      (* a = b
   234      (* a = b
   235         |   |
   235         |   |
   236         c = d   *)
   236         c = d   *)
   237 lemma box_equals: "[| a=b;  a=c;  b=d |] ==> c=d"
   237 lemma box_equals: "[| a=b;  a=c;  b=d |] ==> c=d"
   238 apply (rule trans)
   238 apply (rule trans)
   239 apply (rule trans)
   239 apply (rule trans)
   240 apply (rule sym)
   240 apply (rule sym)
   241 apply assumption+
   241 apply assumption+
   242 done
   242 done
   243 
   243 
   244 text {* For calculational reasoning: *}
   244 text \<open>For calculational reasoning:\<close>
   245 
   245 
   246 lemma forw_subst: "a = b ==> P b ==> P a"
   246 lemma forw_subst: "a = b ==> P b ==> P a"
   247   by (rule ssubst)
   247   by (rule ssubst)
   248 
   248 
   249 lemma back_subst: "P a ==> a = b ==> P b"
   249 lemma back_subst: "P a ==> a = b ==> P b"
   250   by (rule subst)
   250   by (rule subst)
   251 
   251 
   252 
   252 
   253 subsubsection {* Congruence rules for application *}
   253 subsubsection \<open>Congruence rules for application\<close>
   254 
   254 
   255 text {* Similar to @{text AP_THM} in Gordon's HOL. *}
   255 text \<open>Similar to @{text AP_THM} in Gordon's HOL.\<close>
   256 lemma fun_cong: "(f::'a=>'b) = g ==> f(x)=g(x)"
   256 lemma fun_cong: "(f::'a=>'b) = g ==> f(x)=g(x)"
   257 apply (erule subst)
   257 apply (erule subst)
   258 apply (rule refl)
   258 apply (rule refl)
   259 done
   259 done
   260 
   260 
   261 text {* Similar to @{text AP_TERM} in Gordon's HOL and FOL's @{text subst_context}. *}
   261 text \<open>Similar to @{text AP_TERM} in Gordon's HOL and FOL's @{text subst_context}.\<close>
   262 lemma arg_cong: "x=y ==> f(x)=f(y)"
   262 lemma arg_cong: "x=y ==> f(x)=f(y)"
   263 apply (erule subst)
   263 apply (erule subst)
   264 apply (rule refl)
   264 apply (rule refl)
   265 done
   265 done
   266 
   266 
   272 lemma cong: "[| f = g; (x::'a) = y |] ==> f x = g y"
   272 lemma cong: "[| f = g; (x::'a) = y |] ==> f x = g y"
   273 apply (erule subst)+
   273 apply (erule subst)+
   274 apply (rule refl)
   274 apply (rule refl)
   275 done
   275 done
   276 
   276 
   277 ML {* fun cong_tac ctxt = Cong_Tac.cong_tac ctxt @{thm cong} *}
   277 ML \<open>fun cong_tac ctxt = Cong_Tac.cong_tac ctxt @{thm cong}\<close>
   278 
   278 
   279 
   279 
   280 subsubsection {* Equality of booleans -- iff *}
   280 subsubsection \<open>Equality of booleans -- iff\<close>
   281 
   281 
   282 lemma iffI: assumes "P ==> Q" and "Q ==> P" shows "P=Q"
   282 lemma iffI: assumes "P ==> Q" and "Q ==> P" shows "P=Q"
   283   by (iprover intro: iff [THEN mp, THEN mp] impI assms)
   283   by (iprover intro: iff [THEN mp, THEN mp] impI assms)
   284 
   284 
   285 lemma iffD2: "[| P=Q; Q |] ==> P"
   285 lemma iffD2: "[| P=Q; Q |] ==> P"
   299     and minor: "[| P --> Q; Q --> P |] ==> R"
   299     and minor: "[| P --> Q; Q --> P |] ==> R"
   300   shows R
   300   shows R
   301   by (iprover intro: minor impI major [THEN iffD2] major [THEN iffD1])
   301   by (iprover intro: minor impI major [THEN iffD2] major [THEN iffD1])
   302 
   302 
   303 
   303 
   304 subsubsection {*True*}
   304 subsubsection \<open>True\<close>
   305 
   305 
   306 lemma TrueI: "True"
   306 lemma TrueI: "True"
   307   unfolding True_def by (rule refl)
   307   unfolding True_def by (rule refl)
   308 
   308 
   309 lemma eqTrueI: "P ==> P = True"
   309 lemma eqTrueI: "P ==> P = True"
   311 
   311 
   312 lemma eqTrueE: "P = True ==> P"
   312 lemma eqTrueE: "P = True ==> P"
   313   by (erule iffD2) (rule TrueI)
   313   by (erule iffD2) (rule TrueI)
   314 
   314 
   315 
   315 
   316 subsubsection {*Universal quantifier*}
   316 subsubsection \<open>Universal quantifier\<close>
   317 
   317 
   318 lemma allI: assumes "!!x::'a. P(x)" shows "ALL x. P(x)"
   318 lemma allI: assumes "!!x::'a. P(x)" shows "ALL x. P(x)"
   319   unfolding All_def by (iprover intro: ext eqTrueI assms)
   319   unfolding All_def by (iprover intro: ext eqTrueI assms)
   320 
   320 
   321 lemma spec: "ALL x::'a. P(x) ==> P(x)"
   321 lemma spec: "ALL x::'a. P(x) ==> P(x)"
   335     and minor: "[| P(x); ALL x. P(x) |] ==> R"
   335     and minor: "[| P(x); ALL x. P(x) |] ==> R"
   336   shows R
   336   shows R
   337   by (iprover intro: minor major major [THEN spec])
   337   by (iprover intro: minor major major [THEN spec])
   338 
   338 
   339 
   339 
   340 subsubsection {* False *}
   340 subsubsection \<open>False\<close>
   341 
   341 
   342 text {*
   342 text \<open>
   343   Depends upon @{text spec}; it is impossible to do propositional
   343   Depends upon @{text spec}; it is impossible to do propositional
   344   logic before quantifiers!
   344   logic before quantifiers!
   345 *}
   345 \<close>
   346 
   346 
   347 lemma FalseE: "False ==> P"
   347 lemma FalseE: "False ==> P"
   348   apply (unfold False_def)
   348   apply (unfold False_def)
   349   apply (erule spec)
   349   apply (erule spec)
   350   done
   350   done
   351 
   351 
   352 lemma False_neq_True: "False = True ==> P"
   352 lemma False_neq_True: "False = True ==> P"
   353   by (erule eqTrueE [THEN FalseE])
   353   by (erule eqTrueE [THEN FalseE])
   354 
   354 
   355 
   355 
   356 subsubsection {* Negation *}
   356 subsubsection \<open>Negation\<close>
   357 
   357 
   358 lemma notI:
   358 lemma notI:
   359   assumes "P ==> False"
   359   assumes "P ==> False"
   360   shows "~P"
   360   shows "~P"
   361   apply (unfold not_def)
   361   apply (unfold not_def)
   381 
   381 
   382 lemma notI2: "(P \<Longrightarrow> \<not> Pa) \<Longrightarrow> (P \<Longrightarrow> Pa) \<Longrightarrow> \<not> P"
   382 lemma notI2: "(P \<Longrightarrow> \<not> Pa) \<Longrightarrow> (P \<Longrightarrow> Pa) \<Longrightarrow> \<not> P"
   383   by (erule notE [THEN notI]) (erule meta_mp)
   383   by (erule notE [THEN notI]) (erule meta_mp)
   384 
   384 
   385 
   385 
   386 subsubsection {*Implication*}
   386 subsubsection \<open>Implication\<close>
   387 
   387 
   388 lemma impE:
   388 lemma impE:
   389   assumes "P-->Q" "P" "Q ==> R"
   389   assumes "P-->Q" "P" "Q ==> R"
   390   shows "R"
   390   shows "R"
   391 by (iprover intro: assms mp)
   391 by (iprover intro: assms mp)
   412 
   412 
   413 lemma eq_neq_eq_imp_neq: "[| x = a ; a ~= b; b = y |] ==> x ~= y"
   413 lemma eq_neq_eq_imp_neq: "[| x = a ; a ~= b; b = y |] ==> x ~= y"
   414   by (erule subst, erule ssubst, assumption)
   414   by (erule subst, erule ssubst, assumption)
   415 
   415 
   416 
   416 
   417 subsubsection {*Existential quantifier*}
   417 subsubsection \<open>Existential quantifier\<close>
   418 
   418 
   419 lemma exI: "P x ==> EX x::'a. P x"
   419 lemma exI: "P x ==> EX x::'a. P x"
   420 apply (unfold Ex_def)
   420 apply (unfold Ex_def)
   421 apply (iprover intro: allI allE impI mp)
   421 apply (iprover intro: allI allE impI mp)
   422 done
   422 done
   428 apply (rule major [unfolded Ex_def, THEN spec, THEN mp])
   428 apply (rule major [unfolded Ex_def, THEN spec, THEN mp])
   429 apply (iprover intro: impI [THEN allI] minor)
   429 apply (iprover intro: impI [THEN allI] minor)
   430 done
   430 done
   431 
   431 
   432 
   432 
   433 subsubsection {*Conjunction*}
   433 subsubsection \<open>Conjunction\<close>
   434 
   434 
   435 lemma conjI: "[| P; Q |] ==> P&Q"
   435 lemma conjI: "[| P; Q |] ==> P&Q"
   436 apply (unfold and_def)
   436 apply (unfold and_def)
   437 apply (iprover intro: impI [THEN allI] mp)
   437 apply (iprover intro: impI [THEN allI] mp)
   438 done
   438 done
   459 lemma context_conjI:
   459 lemma context_conjI:
   460   assumes "P" "P ==> Q" shows "P & Q"
   460   assumes "P" "P ==> Q" shows "P & Q"
   461 by (iprover intro: conjI assms)
   461 by (iprover intro: conjI assms)
   462 
   462 
   463 
   463 
   464 subsubsection {*Disjunction*}
   464 subsubsection \<open>Disjunction\<close>
   465 
   465 
   466 lemma disjI1: "P ==> P|Q"
   466 lemma disjI1: "P ==> P|Q"
   467 apply (unfold or_def)
   467 apply (unfold or_def)
   468 apply (iprover intro: allI impI mp)
   468 apply (iprover intro: allI impI mp)
   469 done
   469 done
   480   shows "R"
   480   shows "R"
   481 by (iprover intro: minorP minorQ impI
   481 by (iprover intro: minorP minorQ impI
   482                  major [unfolded or_def, THEN spec, THEN mp, THEN mp])
   482                  major [unfolded or_def, THEN spec, THEN mp, THEN mp])
   483 
   483 
   484 
   484 
   485 subsubsection {*Classical logic*}
   485 subsubsection \<open>Classical logic\<close>
   486 
   486 
   487 lemma classical:
   487 lemma classical:
   488   assumes prem: "~P ==> P"
   488   assumes prem: "~P ==> P"
   489   shows "P"
   489   shows "P"
   490 apply (rule True_or_False [THEN disjE, THEN eqTrueE])
   490 apply (rule True_or_False [THEN disjE, THEN eqTrueE])
   518       and p2: "~P ==> ~Q"
   518       and p2: "~P ==> ~Q"
   519   shows "P"
   519   shows "P"
   520 by (iprover intro: classical p1 p2 notE)
   520 by (iprover intro: classical p1 p2 notE)
   521 
   521 
   522 
   522 
   523 subsubsection {*Unique existence*}
   523 subsubsection \<open>Unique existence\<close>
   524 
   524 
   525 lemma ex1I:
   525 lemma ex1I:
   526   assumes "P a" "!!x. P(x) ==> x=a"
   526   assumes "P a" "!!x. P(x) ==> x=a"
   527   shows "EX! x. P(x)"
   527   shows "EX! x. P(x)"
   528 by (unfold Ex1_def, iprover intro: assms exI conjI allI impI)
   528 by (unfold Ex1_def, iprover intro: assms exI conjI allI impI)
   529 
   529 
   530 text{*Sometimes easier to use: the premises have no shared variables.  Safe!*}
   530 text\<open>Sometimes easier to use: the premises have no shared variables.  Safe!\<close>
   531 lemma ex_ex1I:
   531 lemma ex_ex1I:
   532   assumes ex_prem: "EX x. P(x)"
   532   assumes ex_prem: "EX x. P(x)"
   533       and eq: "!!x y. [| P(x); P(y) |] ==> x=y"
   533       and eq: "!!x y. [| P(x); P(y) |] ==> x=y"
   534   shows "EX! x. P(x)"
   534   shows "EX! x. P(x)"
   535 by (iprover intro: ex_prem [THEN exE] ex1I eq)
   535 by (iprover intro: ex_prem [THEN exE] ex1I eq)
   548 apply (rule exI)
   548 apply (rule exI)
   549 apply assumption
   549 apply assumption
   550 done
   550 done
   551 
   551 
   552 
   552 
   553 subsubsection {*Classical intro rules for disjunction and existential quantifiers*}
   553 subsubsection \<open>Classical intro rules for disjunction and existential quantifiers\<close>
   554 
   554 
   555 lemma disjCI:
   555 lemma disjCI:
   556   assumes "~Q ==> P" shows "P|Q"
   556   assumes "~Q ==> P" shows "P|Q"
   557 apply (rule classical)
   557 apply (rule classical)
   558 apply (iprover intro: assms disjI1 disjI2 notI elim: notE)
   558 apply (iprover intro: assms disjI1 disjI2 notI elim: notE)
   559 done
   559 done
   560 
   560 
   561 lemma excluded_middle: "~P | P"
   561 lemma excluded_middle: "~P | P"
   562 by (iprover intro: disjCI)
   562 by (iprover intro: disjCI)
   563 
   563 
   564 text {*
   564 text \<open>
   565   case distinction as a natural deduction rule.
   565   case distinction as a natural deduction rule.
   566   Note that @{term "~P"} is the second case, not the first
   566   Note that @{term "~P"} is the second case, not the first
   567 *}
   567 \<close>
   568 lemma case_split [case_names True False]:
   568 lemma case_split [case_names True False]:
   569   assumes prem1: "P ==> Q"
   569   assumes prem1: "P ==> Q"
   570       and prem2: "~P ==> Q"
   570       and prem2: "~P ==> Q"
   571   shows "Q"
   571   shows "Q"
   572 apply (rule excluded_middle [THEN disjE])
   572 apply (rule excluded_middle [THEN disjE])
   609 apply (rule ccontr)
   609 apply (rule ccontr)
   610 apply (iprover intro: assms exI allI notI notE [of "\<exists>x. P x"])
   610 apply (iprover intro: assms exI allI notI notE [of "\<exists>x. P x"])
   611 done
   611 done
   612 
   612 
   613 
   613 
   614 subsubsection {* Intuitionistic Reasoning *}
   614 subsubsection \<open>Intuitionistic Reasoning\<close>
   615 
   615 
   616 lemma impE':
   616 lemma impE':
   617   assumes 1: "P --> Q"
   617   assumes 1: "P --> Q"
   618     and 2: "Q ==> R"
   618     and 2: "Q ==> R"
   619     and 3: "P --> Q ==> P"
   619     and 3: "P --> Q ==> P"
   653 lemmas [trans] = trans
   653 lemmas [trans] = trans
   654   and [sym] = sym not_sym
   654   and [sym] = sym not_sym
   655   and [Pure.elim?] = iffD1 iffD2 impE
   655   and [Pure.elim?] = iffD1 iffD2 impE
   656 
   656 
   657 
   657 
   658 subsubsection {* Atomizing meta-level connectives *}
   658 subsubsection \<open>Atomizing meta-level connectives\<close>
   659 
   659 
   660 axiomatization where
   660 axiomatization where
   661   eq_reflection: "x = y \<Longrightarrow> x \<equiv> y" (*admissible axiom*)
   661   eq_reflection: "x = y \<Longrightarrow> x \<equiv> y" (*admissible axiom*)
   662 
   662 
   663 lemma atomize_all [atomize]: "(!!x. P x) == Trueprop (ALL x. P x)"
   663 lemma atomize_all [atomize]: "(!!x. P x) == Trueprop (ALL x. P x)"
   688 qed
   688 qed
   689 
   689 
   690 lemma atomize_eq [atomize, code]: "(x == y) == Trueprop (x = y)"
   690 lemma atomize_eq [atomize, code]: "(x == y) == Trueprop (x = y)"
   691 proof
   691 proof
   692   assume "x == y"
   692   assume "x == y"
   693   show "x = y" by (unfold `x == y`) (rule refl)
   693   show "x = y" by (unfold \<open>x == y\<close>) (rule refl)
   694 next
   694 next
   695   assume "x = y"
   695   assume "x = y"
   696   then show "x == y" by (rule eq_reflection)
   696   then show "x == y" by (rule eq_reflection)
   697 qed
   697 qed
   698 
   698 
   715 
   715 
   716 lemmas [symmetric, rulify] = atomize_all atomize_imp
   716 lemmas [symmetric, rulify] = atomize_all atomize_imp
   717   and [symmetric, defn] = atomize_all atomize_imp atomize_eq
   717   and [symmetric, defn] = atomize_all atomize_imp atomize_eq
   718 
   718 
   719 
   719 
   720 subsubsection {* Atomizing elimination rules *}
   720 subsubsection \<open>Atomizing elimination rules\<close>
   721 
   721 
   722 lemma atomize_exL[atomize_elim]: "(!!x. P x ==> Q) == ((EX x. P x) ==> Q)"
   722 lemma atomize_exL[atomize_elim]: "(!!x. P x ==> Q) == ((EX x. P x) ==> Q)"
   723   by rule iprover+
   723   by rule iprover+
   724 
   724 
   725 lemma atomize_conjL[atomize_elim]: "(A ==> B ==> C) == (A & B ==> C)"
   725 lemma atomize_conjL[atomize_elim]: "(A ==> B ==> C) == (A & B ==> C)"
   729   by rule iprover+
   729   by rule iprover+
   730 
   730 
   731 lemma atomize_elimL[atomize_elim]: "(!!B. (A ==> B) ==> B) == Trueprop A" ..
   731 lemma atomize_elimL[atomize_elim]: "(!!B. (A ==> B) ==> B) == Trueprop A" ..
   732 
   732 
   733 
   733 
   734 subsection {* Package setup *}
   734 subsection \<open>Package setup\<close>
   735 
   735 
   736 ML_file "Tools/hologic.ML"
   736 ML_file "Tools/hologic.ML"
   737 
   737 
   738 
   738 
   739 subsubsection {* Sledgehammer setup *}
   739 subsubsection \<open>Sledgehammer setup\<close>
   740 
   740 
   741 text {*
   741 text \<open>
   742 Theorems blacklisted to Sledgehammer. These theorems typically produce clauses
   742 Theorems blacklisted to Sledgehammer. These theorems typically produce clauses
   743 that are prolific (match too many equality or membership literals) and relate to
   743 that are prolific (match too many equality or membership literals) and relate to
   744 seldom-used facts. Some duplicate other rules.
   744 seldom-used facts. Some duplicate other rules.
   745 *}
   745 \<close>
   746 
   746 
   747 named_theorems no_atp "theorems that should be filtered out by Sledgehammer"
   747 named_theorems no_atp "theorems that should be filtered out by Sledgehammer"
   748 
   748 
   749 
   749 
   750 subsubsection {* Classical Reasoner setup *}
   750 subsubsection \<open>Classical Reasoner setup\<close>
   751 
   751 
   752 lemma imp_elim: "P --> Q ==> (~ R ==> P) ==> (Q ==> R) ==> R"
   752 lemma imp_elim: "P --> Q ==> (~ R ==> P) ==> (Q ==> R) ==> R"
   753   by (rule classical) iprover
   753   by (rule classical) iprover
   754 
   754 
   755 lemma swap: "~ P ==> (~ R ==> P) ==> R"
   755 lemma swap: "~ P ==> (~ R ==> P) ==> R"
   756   by (rule classical) iprover
   756   by (rule classical) iprover
   757 
   757 
   758 lemma thin_refl:
   758 lemma thin_refl:
   759   "\<And>X. \<lbrakk> x=x; PROP W \<rbrakk> \<Longrightarrow> PROP W" .
   759   "\<And>X. \<lbrakk> x=x; PROP W \<rbrakk> \<Longrightarrow> PROP W" .
   760 
   760 
   761 ML {*
   761 ML \<open>
   762 structure Hypsubst = Hypsubst
   762 structure Hypsubst = Hypsubst
   763 (
   763 (
   764   val dest_eq = HOLogic.dest_eq
   764   val dest_eq = HOLogic.dest_eq
   765   val dest_Trueprop = HOLogic.dest_Trueprop
   765   val dest_Trueprop = HOLogic.dest_Trueprop
   766   val dest_imp = HOLogic.dest_imp
   766   val dest_imp = HOLogic.dest_imp
   784   val hyp_subst_tacs = [Hypsubst.hyp_subst_tac]
   784   val hyp_subst_tacs = [Hypsubst.hyp_subst_tac]
   785 );
   785 );
   786 
   786 
   787 structure Basic_Classical: BASIC_CLASSICAL = Classical;
   787 structure Basic_Classical: BASIC_CLASSICAL = Classical;
   788 open Basic_Classical;
   788 open Basic_Classical;
   789 *}
   789 \<close>
   790 
   790 
   791 setup {*
   791 setup \<open>
   792   (*prevent substitution on bool*)
   792   (*prevent substitution on bool*)
   793   let
   793   let
   794     fun non_bool_eq (@{const_name HOL.eq}, Type (_, [T, _])) = T <> @{typ bool}
   794     fun non_bool_eq (@{const_name HOL.eq}, Type (_, [T, _])) = T <> @{typ bool}
   795       | non_bool_eq _ = false;
   795       | non_bool_eq _ = false;
   796     fun hyp_subst_tac' ctxt =
   796     fun hyp_subst_tac' ctxt =
   799         then Hypsubst.hyp_subst_tac ctxt i
   799         then Hypsubst.hyp_subst_tac ctxt i
   800         else no_tac);
   800         else no_tac);
   801   in
   801   in
   802     Context_Rules.addSWrapper (fn ctxt => fn tac => hyp_subst_tac' ctxt ORELSE' tac)
   802     Context_Rules.addSWrapper (fn ctxt => fn tac => hyp_subst_tac' ctxt ORELSE' tac)
   803   end
   803   end
   804 *}
   804 \<close>
   805 
   805 
   806 declare iffI [intro!]
   806 declare iffI [intro!]
   807   and notI [intro!]
   807   and notI [intro!]
   808   and impI [intro!]
   808   and impI [intro!]
   809   and disjCI [intro!]
   809   and disjCI [intro!]
   822   and exI [intro]
   822   and exI [intro]
   823 
   823 
   824 declare exE [elim!]
   824 declare exE [elim!]
   825   allE [elim]
   825   allE [elim]
   826 
   826 
   827 ML {* val HOL_cs = claset_of @{context} *}
   827 ML \<open>val HOL_cs = claset_of @{context}\<close>
   828 
   828 
   829 lemma contrapos_np: "~ Q ==> (~ P ==> Q) ==> P"
   829 lemma contrapos_np: "~ Q ==> (~ P ==> Q) ==> P"
   830   apply (erule swap)
   830   apply (erule swap)
   831   apply (erule (1) meta_mp)
   831   apply (erule (1) meta_mp)
   832   done
   832   done
   846   shows R
   846   shows R
   847 apply (rule ex1E [OF major])
   847 apply (rule ex1E [OF major])
   848 apply (rule prem)
   848 apply (rule prem)
   849 apply assumption
   849 apply assumption
   850 apply (rule allI)+
   850 apply (rule allI)+
   851 apply (tactic {* eresolve_tac @{context} [Classical.dup_elim @{context} @{thm allE}] 1 *})
   851 apply (tactic \<open>eresolve_tac @{context} [Classical.dup_elim @{context} @{thm allE}] 1\<close>)
   852 apply iprover
   852 apply iprover
   853 done
   853 done
   854 
   854 
   855 ML {*
   855 ML \<open>
   856   structure Blast = Blast
   856   structure Blast = Blast
   857   (
   857   (
   858     structure Classical = Classical
   858     structure Classical = Classical
   859     val Trueprop_const = dest_Const @{const Trueprop}
   859     val Trueprop_const = dest_Const @{const Trueprop}
   860     val equality_name = @{const_name HOL.eq}
   860     val equality_name = @{const_name HOL.eq}
   862     val notE = @{thm notE}
   862     val notE = @{thm notE}
   863     val ccontr = @{thm ccontr}
   863     val ccontr = @{thm ccontr}
   864     val hyp_subst_tac = Hypsubst.blast_hyp_subst_tac
   864     val hyp_subst_tac = Hypsubst.blast_hyp_subst_tac
   865   );
   865   );
   866   val blast_tac = Blast.blast_tac;
   866   val blast_tac = Blast.blast_tac;
   867 *}
   867 \<close>
   868 
   868 
   869 
   869 
   870 subsubsection {*THE: definite description operator*}
   870 subsubsection \<open>THE: definite description operator\<close>
   871 
   871 
   872 lemma the_equality [intro]:
   872 lemma the_equality [intro]:
   873   assumes "P a"
   873   assumes "P a"
   874       and "!!x. P x ==> x=a"
   874       and "!!x. P x ==> x=a"
   875   shows "(THE x. P x) = a"
   875   shows "(THE x. P x) = a"
   898 
   898 
   899 lemma the_sym_eq_trivial: "(THE y. x=y) = x"
   899 lemma the_sym_eq_trivial: "(THE y. x=y) = x"
   900   by blast
   900   by blast
   901 
   901 
   902 
   902 
   903 subsubsection {* Simplifier *}
   903 subsubsection \<open>Simplifier\<close>
   904 
   904 
   905 lemma eta_contract_eq: "(%s. f s) = f" ..
   905 lemma eta_contract_eq: "(%s. f s) = f" ..
   906 
   906 
   907 lemma simp_thms:
   907 lemma simp_thms:
   908   shows not_not: "(~ ~ P) = P"
   908   shows not_not: "(~ ~ P) = P"
   978 
   978 
   979 lemma imp_conjR: "(P --> (Q&R)) = ((P-->Q) & (P-->R))" by iprover
   979 lemma imp_conjR: "(P --> (Q&R)) = ((P-->Q) & (P-->R))" by iprover
   980 lemma imp_conjL: "((P&Q) -->R)  = (P --> (Q --> R))" by iprover
   980 lemma imp_conjL: "((P&Q) -->R)  = (P --> (Q --> R))" by iprover
   981 lemma imp_disjL: "((P|Q) --> R) = ((P-->R)&(Q-->R))" by iprover
   981 lemma imp_disjL: "((P|Q) --> R) = ((P-->R)&(Q-->R))" by iprover
   982 
   982 
   983 text {* These two are specialized, but @{text imp_disj_not1} is useful in @{text "Auth/Yahalom"}. *}
   983 text \<open>These two are specialized, but @{text imp_disj_not1} is useful in @{text "Auth/Yahalom"}.\<close>
   984 lemma imp_disj_not1: "(P --> Q | R) = (~Q --> P --> R)" by blast
   984 lemma imp_disj_not1: "(P --> Q | R) = (~Q --> P --> R)" by blast
   985 lemma imp_disj_not2: "(P --> Q | R) = (~R --> P --> Q)" by blast
   985 lemma imp_disj_not2: "(P --> Q | R) = (~R --> P --> Q)" by blast
   986 
   986 
   987 lemma imp_disj1: "((P-->Q)|R) = (P--> Q|R)" by blast
   987 lemma imp_disj1: "((P-->Q)|R) = (P--> Q|R)" by blast
   988 lemma imp_disj2: "(Q|(P-->R)) = (P--> Q|R)" by blast
   988 lemma imp_disj2: "(Q|(P-->R)) = (P--> Q|R)" by blast
   993 lemma de_Morgan_disj: "(~(P | Q)) = (~P & ~Q)" by iprover
   993 lemma de_Morgan_disj: "(~(P | Q)) = (~P & ~Q)" by iprover
   994 lemma de_Morgan_conj: "(~(P & Q)) = (~P | ~Q)" by blast
   994 lemma de_Morgan_conj: "(~(P & Q)) = (~P | ~Q)" by blast
   995 lemma not_imp: "(~(P --> Q)) = (P & ~Q)" by blast
   995 lemma not_imp: "(~(P --> Q)) = (P & ~Q)" by blast
   996 lemma not_iff: "(P~=Q) = (P = (~Q))" by blast
   996 lemma not_iff: "(P~=Q) = (P = (~Q))" by blast
   997 lemma disj_not1: "(~P | Q) = (P --> Q)" by blast
   997 lemma disj_not1: "(~P | Q) = (P --> Q)" by blast
   998 lemma disj_not2: "(P | ~Q) = (Q --> P)"  -- {* changes orientation :-( *}
   998 lemma disj_not2: "(P | ~Q) = (Q --> P)"  -- \<open>changes orientation :-(\<close>
   999   by blast
   999   by blast
  1000 lemma imp_conv_disj: "(P --> Q) = ((~P) | Q)" by blast
  1000 lemma imp_conv_disj: "(P --> Q) = ((~P) | Q)" by blast
  1001 
  1001 
  1002 lemma iff_conv_conj_imp: "(P = Q) = ((P --> Q) & (Q --> P))" by iprover
  1002 lemma iff_conv_conj_imp: "(P = Q) = ((P --> Q) & (Q --> P))" by iprover
  1003 
  1003 
  1004 
  1004 
  1005 lemma cases_simp: "((P --> Q) & (~P --> Q)) = Q"
  1005 lemma cases_simp: "((P --> Q) & (~P --> Q)) = Q"
  1006   -- {* Avoids duplication of subgoals after @{text split_if}, when the true and false *}
  1006   -- \<open>Avoids duplication of subgoals after @{text split_if}, when the true and false\<close>
  1007   -- {* cases boil down to the same thing. *}
  1007   -- \<open>cases boil down to the same thing.\<close>
  1008   by blast
  1008   by blast
  1009 
  1009 
  1010 lemma not_all: "(~ (! x. P(x))) = (? x.~P(x))" by blast
  1010 lemma not_all: "(~ (! x. P(x))) = (? x.~P(x))" by blast
  1011 lemma imp_all: "((! x. P x) --> Q) = (? x. P x --> Q)" by blast
  1011 lemma imp_all: "((! x. P x) --> Q) = (? x. P x --> Q)" by blast
  1012 lemma not_ex: "(~ (? x. P(x))) = (! x.~P(x))" by iprover
  1012 lemma not_ex: "(~ (? x. P(x))) = (! x.~P(x))" by iprover
  1016 declare All_def [no_atp]
  1016 declare All_def [no_atp]
  1017 
  1017 
  1018 lemma ex_disj_distrib: "(? x. P(x) | Q(x)) = ((? x. P(x)) | (? x. Q(x)))" by iprover
  1018 lemma ex_disj_distrib: "(? x. P(x) | Q(x)) = ((? x. P(x)) | (? x. Q(x)))" by iprover
  1019 lemma all_conj_distrib: "(!x. P(x) & Q(x)) = ((! x. P(x)) & (! x. Q(x)))" by iprover
  1019 lemma all_conj_distrib: "(!x. P(x) & Q(x)) = ((! x. P(x)) & (! x. Q(x)))" by iprover
  1020 
  1020 
  1021 text {*
  1021 text \<open>
  1022   \medskip The @{text "&"} congruence rule: not included by default!
  1022   \medskip The @{text "&"} congruence rule: not included by default!
  1023   May slow rewrite proofs down by as much as 50\% *}
  1023   May slow rewrite proofs down by as much as 50\%\<close>
  1024 
  1024 
  1025 lemma conj_cong:
  1025 lemma conj_cong:
  1026     "(P = P') ==> (P' ==> (Q = Q')) ==> ((P & Q) = (P' & Q'))"
  1026     "(P = P') ==> (P' ==> (Q = Q')) ==> ((P & Q) = (P' & Q'))"
  1027   by iprover
  1027   by iprover
  1028 
  1028 
  1029 lemma rev_conj_cong:
  1029 lemma rev_conj_cong:
  1030     "(Q = Q') ==> (Q' ==> (P = P')) ==> ((P & Q) = (P' & Q'))"
  1030     "(Q = Q') ==> (Q' ==> (P = P')) ==> ((P & Q) = (P' & Q'))"
  1031   by iprover
  1031   by iprover
  1032 
  1032 
  1033 text {* The @{text "|"} congruence rule: not included by default! *}
  1033 text \<open>The @{text "|"} congruence rule: not included by default!\<close>
  1034 
  1034 
  1035 lemma disj_cong:
  1035 lemma disj_cong:
  1036     "(P = P') ==> (~P' ==> (Q = Q')) ==> ((P | Q) = (P' | Q'))"
  1036     "(P = P') ==> (~P' ==> (Q = Q')) ==> ((P | Q) = (P' | Q'))"
  1037   by blast
  1037   by blast
  1038 
  1038 
  1039 
  1039 
  1040 text {* \medskip if-then-else rules *}
  1040 text \<open>\medskip if-then-else rules\<close>
  1041 
  1041 
  1042 lemma if_True [code]: "(if True then x else y) = x"
  1042 lemma if_True [code]: "(if True then x else y) = x"
  1043   by (unfold If_def) blast
  1043   by (unfold If_def) blast
  1044 
  1044 
  1045 lemma if_False [code]: "(if False then x else y) = y"
  1045 lemma if_False [code]: "(if False then x else y) = y"
  1068 lemma if_eq_cancel: "(if x = y then y else x) = x"
  1068 lemma if_eq_cancel: "(if x = y then y else x) = x"
  1069 by (simplesubst split_if, blast)
  1069 by (simplesubst split_if, blast)
  1070 
  1070 
  1071 lemma if_bool_eq_conj:
  1071 lemma if_bool_eq_conj:
  1072 "(if P then Q else R) = ((P-->Q) & (~P-->R))"
  1072 "(if P then Q else R) = ((P-->Q) & (~P-->R))"
  1073   -- {* This form is useful for expanding @{text "if"}s on the RIGHT of the @{text "==>"} symbol. *}
  1073   -- \<open>This form is useful for expanding @{text "if"}s on the RIGHT of the @{text "==>"} symbol.\<close>
  1074   by (rule split_if)
  1074   by (rule split_if)
  1075 
  1075 
  1076 lemma if_bool_eq_disj: "(if P then Q else R) = ((P&Q) | (~P&R))"
  1076 lemma if_bool_eq_disj: "(if P then Q else R) = ((P&Q) | (~P&R))"
  1077   -- {* And this form is useful for expanding @{text "if"}s on the LEFT. *}
  1077   -- \<open>And this form is useful for expanding @{text "if"}s on the LEFT.\<close>
  1078   by (simplesubst split_if) blast
  1078   by (simplesubst split_if) blast
  1079 
  1079 
  1080 lemma Eq_TrueI: "P ==> P == True" by (unfold atomize_eq) iprover
  1080 lemma Eq_TrueI: "P ==> P == True" by (unfold atomize_eq) iprover
  1081 lemma Eq_FalseI: "~P ==> P == False" by (unfold atomize_eq) iprover
  1081 lemma Eq_FalseI: "~P ==> P == False" by (unfold atomize_eq) iprover
  1082 
  1082 
  1083 text {* \medskip let rules for simproc *}
  1083 text \<open>\medskip let rules for simproc\<close>
  1084 
  1084 
  1085 lemma Let_folded: "f x \<equiv> g x \<Longrightarrow>  Let x f \<equiv> Let x g"
  1085 lemma Let_folded: "f x \<equiv> g x \<Longrightarrow>  Let x f \<equiv> Let x g"
  1086   by (unfold Let_def)
  1086   by (unfold Let_def)
  1087 
  1087 
  1088 lemma Let_unfold: "f x \<equiv> g \<Longrightarrow>  Let x f \<equiv> g"
  1088 lemma Let_unfold: "f x \<equiv> g \<Longrightarrow>  Let x f \<equiv> g"
  1089   by (unfold Let_def)
  1089   by (unfold Let_def)
  1090 
  1090 
  1091 text {*
  1091 text \<open>
  1092   The following copy of the implication operator is useful for
  1092   The following copy of the implication operator is useful for
  1093   fine-tuning congruence rules.  It instructs the simplifier to simplify
  1093   fine-tuning congruence rules.  It instructs the simplifier to simplify
  1094   its premise.
  1094   its premise.
  1095 *}
  1095 \<close>
  1096 
  1096 
  1097 definition simp_implies :: "[prop, prop] => prop"  (infixr "=simp=>" 1) where
  1097 definition simp_implies :: "[prop, prop] => prop"  (infixr "=simp=>" 1) where
  1098   "simp_implies \<equiv> op ==>"
  1098   "simp_implies \<equiv> op ==>"
  1099 
  1099 
  1100 lemma simp_impliesI:
  1100 lemma simp_impliesI:
  1157 lemma ex_comm:
  1157 lemma ex_comm:
  1158   "(\<exists>x y. P x y) = (\<exists>y x. P x y)"
  1158   "(\<exists>x y. P x y) = (\<exists>y x. P x y)"
  1159   by blast
  1159   by blast
  1160 
  1160 
  1161 ML_file "Tools/simpdata.ML"
  1161 ML_file "Tools/simpdata.ML"
  1162 ML {* open Simpdata *}
  1162 ML \<open>open Simpdata\<close>
  1163 
  1163 
  1164 setup {*
  1164 setup \<open>
  1165   map_theory_simpset (put_simpset HOL_basic_ss) #>
  1165   map_theory_simpset (put_simpset HOL_basic_ss) #>
  1166   Simplifier.method_setup Splitter.split_modifiers
  1166   Simplifier.method_setup Splitter.split_modifiers
  1167 *}
  1167 \<close>
  1168 
  1168 
  1169 simproc_setup defined_Ex ("EX x. P x") = {* fn _ => Quantifier1.rearrange_ex *}
  1169 simproc_setup defined_Ex ("EX x. P x") = \<open>fn _ => Quantifier1.rearrange_ex\<close>
  1170 simproc_setup defined_All ("ALL x. P x") = {* fn _ => Quantifier1.rearrange_all *}
  1170 simproc_setup defined_All ("ALL x. P x") = \<open>fn _ => Quantifier1.rearrange_all\<close>
  1171 
  1171 
  1172 text {* Simproc for proving @{text "(y = x) == False"} from premise @{text "~(x = y)"}: *}
  1172 text \<open>Simproc for proving @{text "(y = x) == False"} from premise @{text "~(x = y)"}:\<close>
  1173 
  1173 
  1174 simproc_setup neq ("x = y") = {* fn _ =>
  1174 simproc_setup neq ("x = y") = \<open>fn _ =>
  1175 let
  1175 let
  1176   val neq_to_EQ_False = @{thm not_sym} RS @{thm Eq_FalseI};
  1176   val neq_to_EQ_False = @{thm not_sym} RS @{thm Eq_FalseI};
  1177   fun is_neq eq lhs rhs thm =
  1177   fun is_neq eq lhs rhs thm =
  1178     (case Thm.prop_of thm of
  1178     (case Thm.prop_of thm of
  1179       _ $ (Not $ (eq' $ l' $ r')) =>
  1179       _ $ (Not $ (eq' $ l' $ r')) =>
  1186         (case find_first (is_neq eq lhs rhs) (Simplifier.prems_of ss) of
  1186         (case find_first (is_neq eq lhs rhs) (Simplifier.prems_of ss) of
  1187           SOME thm => SOME (thm RS neq_to_EQ_False)
  1187           SOME thm => SOME (thm RS neq_to_EQ_False)
  1188         | NONE => NONE)
  1188         | NONE => NONE)
  1189      | _ => NONE);
  1189      | _ => NONE);
  1190 in proc end;
  1190 in proc end;
  1191 *}
  1191 \<close>
  1192 
  1192 
  1193 simproc_setup let_simp ("Let x f") = {*
  1193 simproc_setup let_simp ("Let x f") = \<open>
  1194 let
  1194 let
  1195   val (f_Let_unfold, x_Let_unfold) =
  1195   val (f_Let_unfold, x_Let_unfold) =
  1196     let val [(_ $ (f $ x) $ _)] = Thm.prems_of @{thm Let_unfold}
  1196     let val [(_ $ (f $ x) $ _)] = Thm.prems_of @{thm Let_unfold}
  1197     in apply2 (Thm.cterm_of @{context}) (f, x) end
  1197     in apply2 (Thm.cterm_of @{context}) (f, x) end
  1198   val (f_Let_folded, x_Let_folded) =
  1198   val (f_Let_folded, x_Let_folded) =
  1251                          (g_Let_folded, Thm.cterm_of ctxt abs_g')];
  1251                          (g_Let_folded, Thm.cterm_of ctxt abs_g')];
  1252                   in SOME (rl OF [Thm.transitive fx_g g_g'x]) end
  1252                   in SOME (rl OF [Thm.transitive fx_g g_g'x]) end
  1253               end
  1253               end
  1254           | _ => NONE)
  1254           | _ => NONE)
  1255       end
  1255       end
  1256 end *}
  1256 end\<close>
  1257 
  1257 
  1258 lemma True_implies_equals: "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
  1258 lemma True_implies_equals: "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
  1259 proof
  1259 proof
  1260   assume "True \<Longrightarrow> PROP P"
  1260   assume "True \<Longrightarrow> PROP P"
  1261   from this [OF TrueI] show "PROP P" .
  1261   from this [OF TrueI] show "PROP P" .
  1281   "!!P Q. (EX x. P & Q x)   = (P & (EX x. Q x))"
  1281   "!!P Q. (EX x. P & Q x)   = (P & (EX x. Q x))"
  1282   "!!P Q. (EX x. P x | Q)   = ((EX x. P x) | Q)"
  1282   "!!P Q. (EX x. P x | Q)   = ((EX x. P x) | Q)"
  1283   "!!P Q. (EX x. P | Q x)   = (P | (EX x. Q x))"
  1283   "!!P Q. (EX x. P | Q x)   = (P | (EX x. Q x))"
  1284   "!!P Q. (EX x. P x --> Q) = ((ALL x. P x) --> Q)"
  1284   "!!P Q. (EX x. P x --> Q) = ((ALL x. P x) --> Q)"
  1285   "!!P Q. (EX x. P --> Q x) = (P --> (EX x. Q x))"
  1285   "!!P Q. (EX x. P --> Q x) = (P --> (EX x. Q x))"
  1286   -- {* Miniscoping: pushing in existential quantifiers. *}
  1286   -- \<open>Miniscoping: pushing in existential quantifiers.\<close>
  1287   by (iprover | blast)+
  1287   by (iprover | blast)+
  1288 
  1288 
  1289 lemma all_simps:
  1289 lemma all_simps:
  1290   "!!P Q. (ALL x. P x & Q)   = ((ALL x. P x) & Q)"
  1290   "!!P Q. (ALL x. P x & Q)   = ((ALL x. P x) & Q)"
  1291   "!!P Q. (ALL x. P & Q x)   = (P & (ALL x. Q x))"
  1291   "!!P Q. (ALL x. P & Q x)   = (P & (ALL x. Q x))"
  1292   "!!P Q. (ALL x. P x | Q)   = ((ALL x. P x) | Q)"
  1292   "!!P Q. (ALL x. P x | Q)   = ((ALL x. P x) | Q)"
  1293   "!!P Q. (ALL x. P | Q x)   = (P | (ALL x. Q x))"
  1293   "!!P Q. (ALL x. P | Q x)   = (P | (ALL x. Q x))"
  1294   "!!P Q. (ALL x. P x --> Q) = ((EX x. P x) --> Q)"
  1294   "!!P Q. (ALL x. P x --> Q) = ((EX x. P x) --> Q)"
  1295   "!!P Q. (ALL x. P --> Q x) = (P --> (ALL x. Q x))"
  1295   "!!P Q. (ALL x. P --> Q x) = (P --> (ALL x. Q x))"
  1296   -- {* Miniscoping: pushing in universal quantifiers. *}
  1296   -- \<open>Miniscoping: pushing in universal quantifiers.\<close>
  1297   by (iprover | blast)+
  1297   by (iprover | blast)+
  1298 
  1298 
  1299 lemmas [simp] =
  1299 lemmas [simp] =
  1300   triv_forall_equality (*prunes params*)
  1300   triv_forall_equality (*prunes params*)
  1301   True_implies_equals implies_True_equals (*prune True in asms*)
  1301   True_implies_equals implies_True_equals (*prune True in asms*)
  1328   simp_thms
  1328   simp_thms
  1329 
  1329 
  1330 lemmas [cong] = imp_cong simp_implies_cong
  1330 lemmas [cong] = imp_cong simp_implies_cong
  1331 lemmas [split] = split_if
  1331 lemmas [split] = split_if
  1332 
  1332 
  1333 ML {* val HOL_ss = simpset_of @{context} *}
  1333 ML \<open>val HOL_ss = simpset_of @{context}\<close>
  1334 
  1334 
  1335 text {* Simplifies x assuming c and y assuming ~c *}
  1335 text \<open>Simplifies x assuming c and y assuming ~c\<close>
  1336 lemma if_cong:
  1336 lemma if_cong:
  1337   assumes "b = c"
  1337   assumes "b = c"
  1338       and "c \<Longrightarrow> x = u"
  1338       and "c \<Longrightarrow> x = u"
  1339       and "\<not> c \<Longrightarrow> y = v"
  1339       and "\<not> c \<Longrightarrow> y = v"
  1340   shows "(if b then x else y) = (if c then u else v)"
  1340   shows "(if b then x else y) = (if c then u else v)"
  1341   using assms by simp
  1341   using assms by simp
  1342 
  1342 
  1343 text {* Prevents simplification of x and y:
  1343 text \<open>Prevents simplification of x and y:
  1344   faster and allows the execution of functional programs. *}
  1344   faster and allows the execution of functional programs.\<close>
  1345 lemma if_weak_cong [cong]:
  1345 lemma if_weak_cong [cong]:
  1346   assumes "b = c"
  1346   assumes "b = c"
  1347   shows "(if b then x else y) = (if c then x else y)"
  1347   shows "(if b then x else y) = (if c then x else y)"
  1348   using assms by (rule arg_cong)
  1348   using assms by (rule arg_cong)
  1349 
  1349 
  1350 text {* Prevents simplification of t: much faster *}
  1350 text \<open>Prevents simplification of t: much faster\<close>
  1351 lemma let_weak_cong:
  1351 lemma let_weak_cong:
  1352   assumes "a = b"
  1352   assumes "a = b"
  1353   shows "(let x = a in t x) = (let x = b in t x)"
  1353   shows "(let x = a in t x) = (let x = b in t x)"
  1354   using assms by (rule arg_cong)
  1354   using assms by (rule arg_cong)
  1355 
  1355 
  1356 text {* To tidy up the result of a simproc.  Only the RHS will be simplified. *}
  1356 text \<open>To tidy up the result of a simproc.  Only the RHS will be simplified.\<close>
  1357 lemma eq_cong2:
  1357 lemma eq_cong2:
  1358   assumes "u = u'"
  1358   assumes "u = u'"
  1359   shows "(t \<equiv> u) \<equiv> (t \<equiv> u')"
  1359   shows "(t \<equiv> u) \<equiv> (t \<equiv> u')"
  1360   using assms by simp
  1360   using assms by simp
  1361 
  1361 
  1362 lemma if_distrib:
  1362 lemma if_distrib:
  1363   "f (if c then x else y) = (if c then f x else f y)"
  1363   "f (if c then x else y) = (if c then f x else f y)"
  1364   by simp
  1364   by simp
  1365 
  1365 
  1366 text{*As a simplification rule, it replaces all function equalities by
  1366 text\<open>As a simplification rule, it replaces all function equalities by
  1367   first-order equalities.*}
  1367   first-order equalities.\<close>
  1368 lemma fun_eq_iff: "f = g \<longleftrightarrow> (\<forall>x. f x = g x)"
  1368 lemma fun_eq_iff: "f = g \<longleftrightarrow> (\<forall>x. f x = g x)"
  1369   by auto
  1369   by auto
  1370 
  1370 
  1371 
  1371 
  1372 subsubsection {* Generic cases and induction *}
  1372 subsubsection \<open>Generic cases and induction\<close>
  1373 
  1373 
  1374 text {* Rule projections: *}
  1374 text \<open>Rule projections:\<close>
  1375 ML {*
  1375 ML \<open>
  1376 structure Project_Rule = Project_Rule
  1376 structure Project_Rule = Project_Rule
  1377 (
  1377 (
  1378   val conjunct1 = @{thm conjunct1}
  1378   val conjunct1 = @{thm conjunct1}
  1379   val conjunct2 = @{thm conjunct2}
  1379   val conjunct2 = @{thm conjunct2}
  1380   val mp = @{thm mp}
  1380   val mp = @{thm mp}
  1381 );
  1381 );
  1382 *}
  1382 \<close>
  1383 
  1383 
  1384 context
  1384 context
  1385 begin
  1385 begin
  1386 
  1386 
  1387 qualified definition "induct_forall P \<equiv> \<forall>x. P x"
  1387 qualified definition "induct_forall P \<equiv> \<forall>x. P x"
  1433 lemmas induct_conj = induct_forall_conj induct_implies_conj induct_conj_curry
  1433 lemmas induct_conj = induct_forall_conj induct_implies_conj induct_conj_curry
  1434 
  1434 
  1435 lemma induct_trueI: "induct_true"
  1435 lemma induct_trueI: "induct_true"
  1436   by (simp add: induct_true_def)
  1436   by (simp add: induct_true_def)
  1437 
  1437 
  1438 text {* Method setup. *}
  1438 text \<open>Method setup.\<close>
  1439 
  1439 
  1440 ML_file "~~/src/Tools/induct.ML"
  1440 ML_file "~~/src/Tools/induct.ML"
  1441 ML {*
  1441 ML \<open>
  1442 structure Induct = Induct
  1442 structure Induct = Induct
  1443 (
  1443 (
  1444   val cases_default = @{thm case_split}
  1444   val cases_default = @{thm case_split}
  1445   val atomize = @{thms induct_atomize}
  1445   val atomize = @{thms induct_atomize}
  1446   val rulify = @{thms induct_rulify'}
  1446   val rulify = @{thms induct_rulify'}
  1448   val equal_def = @{thm induct_equal_def}
  1448   val equal_def = @{thm induct_equal_def}
  1449   fun dest_def (Const (@{const_name induct_equal}, _) $ t $ u) = SOME (t, u)
  1449   fun dest_def (Const (@{const_name induct_equal}, _) $ t $ u) = SOME (t, u)
  1450     | dest_def _ = NONE
  1450     | dest_def _ = NONE
  1451   fun trivial_tac ctxt = match_tac ctxt @{thms induct_trueI}
  1451   fun trivial_tac ctxt = match_tac ctxt @{thms induct_trueI}
  1452 )
  1452 )
  1453 *}
  1453 \<close>
  1454 
  1454 
  1455 ML_file "~~/src/Tools/induction.ML"
  1455 ML_file "~~/src/Tools/induction.ML"
  1456 
  1456 
  1457 declaration {*
  1457 declaration \<open>
  1458   fn _ => Induct.map_simpset (fn ss => ss
  1458   fn _ => Induct.map_simpset (fn ss => ss
  1459     addsimprocs
  1459     addsimprocs
  1460       [Simplifier.simproc_global @{theory} "swap_induct_false"
  1460       [Simplifier.simproc_global @{theory} "swap_induct_false"
  1461          ["induct_false ==> PROP P ==> PROP Q"]
  1461          ["induct_false ==> PROP P ==> PROP Q"]
  1462          (fn _ =>
  1462          (fn _ =>
  1477                 in if is_conj P then SOME @{thm induct_conj_curry} else NONE end
  1477                 in if is_conj P then SOME @{thm induct_conj_curry} else NONE end
  1478               | _ => NONE))]
  1478               | _ => NONE))]
  1479     |> Simplifier.set_mksimps (fn ctxt =>
  1479     |> Simplifier.set_mksimps (fn ctxt =>
  1480         Simpdata.mksimps Simpdata.mksimps_pairs ctxt #>
  1480         Simpdata.mksimps Simpdata.mksimps_pairs ctxt #>
  1481         map (rewrite_rule ctxt (map Thm.symmetric @{thms induct_rulify_fallback}))))
  1481         map (rewrite_rule ctxt (map Thm.symmetric @{thms induct_rulify_fallback}))))
  1482 *}
  1482 \<close>
  1483 
  1483 
  1484 text {* Pre-simplification of induction and cases rules *}
  1484 text \<open>Pre-simplification of induction and cases rules\<close>
  1485 
  1485 
  1486 lemma [induct_simp]: "(\<And>x. induct_equal x t \<Longrightarrow> PROP P x) \<equiv> PROP P t"
  1486 lemma [induct_simp]: "(\<And>x. induct_equal x t \<Longrightarrow> PROP P x) \<equiv> PROP P t"
  1487   unfolding induct_equal_def
  1487   unfolding induct_equal_def
  1488 proof
  1488 proof
  1489   assume r: "\<And>x. x = t \<Longrightarrow> PROP P x"
  1489   assume r: "\<And>x. x = t \<Longrightarrow> PROP P x"
  1536 end
  1536 end
  1537 
  1537 
  1538 ML_file "~~/src/Tools/induct_tacs.ML"
  1538 ML_file "~~/src/Tools/induct_tacs.ML"
  1539 
  1539 
  1540 
  1540 
  1541 subsubsection {* Coherent logic *}
  1541 subsubsection \<open>Coherent logic\<close>
  1542 
  1542 
  1543 ML_file "~~/src/Tools/coherent.ML"
  1543 ML_file "~~/src/Tools/coherent.ML"
  1544 ML {*
  1544 ML \<open>
  1545 structure Coherent = Coherent
  1545 structure Coherent = Coherent
  1546 (
  1546 (
  1547   val atomize_elimL = @{thm atomize_elimL};
  1547   val atomize_elimL = @{thm atomize_elimL};
  1548   val atomize_exL = @{thm atomize_exL};
  1548   val atomize_exL = @{thm atomize_exL};
  1549   val atomize_conjL = @{thm atomize_conjL};
  1549   val atomize_conjL = @{thm atomize_conjL};
  1550   val atomize_disjL = @{thm atomize_disjL};
  1550   val atomize_disjL = @{thm atomize_disjL};
  1551   val operator_names = [@{const_name HOL.disj}, @{const_name HOL.conj}, @{const_name Ex}];
  1551   val operator_names = [@{const_name HOL.disj}, @{const_name HOL.conj}, @{const_name Ex}];
  1552 );
  1552 );
  1553 *}
  1553 \<close>
  1554 
  1554 
  1555 
  1555 
  1556 subsubsection {* Reorienting equalities *}
  1556 subsubsection \<open>Reorienting equalities\<close>
  1557 
  1557 
  1558 ML {*
  1558 ML \<open>
  1559 signature REORIENT_PROC =
  1559 signature REORIENT_PROC =
  1560 sig
  1560 sig
  1561   val add : (term -> bool) -> theory -> theory
  1561   val add : (term -> bool) -> theory -> theory
  1562   val proc : morphism -> Proof.context -> cterm -> thm option
  1562   val proc : morphism -> Proof.context -> cterm -> thm option
  1563 end;
  1563 end;
  1582       case Thm.term_of ct of
  1582       case Thm.term_of ct of
  1583         (_ $ t $ u) => if matches thy u then NONE else SOME meta_reorient
  1583         (_ $ t $ u) => if matches thy u then NONE else SOME meta_reorient
  1584       | _ => NONE
  1584       | _ => NONE
  1585     end;
  1585     end;
  1586 end;
  1586 end;
  1587 *}
  1587 \<close>
  1588 
  1588 
  1589 
  1589 
  1590 subsection {* Other simple lemmas and lemma duplicates *}
  1590 subsection \<open>Other simple lemmas and lemma duplicates\<close>
  1591 
  1591 
  1592 lemma ex1_eq [iff]: "EX! x. x = t" "EX! x. t = x"
  1592 lemma ex1_eq [iff]: "EX! x. x = t" "EX! x. t = x"
  1593   by blast+
  1593   by blast+
  1594 
  1594 
  1595 lemma choice_eq: "(ALL x. EX! y. P x y) = (EX! f. ALL x. P x (f x))"
  1595 lemma choice_eq: "(ALL x. EX! y. P x y) = (EX! f. ALL x. P x (f x))"
  1614   "(\<not>(P \<and> Q)) = (\<not> P \<or> \<not> Q)" "(\<not> (P \<or> Q)) = (\<not> P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)"
  1614   "(\<not>(P \<and> Q)) = (\<not> P \<or> \<not> Q)" "(\<not> (P \<or> Q)) = (\<not> P \<and> \<not>Q)" "(P \<longrightarrow> Q) = (\<not>P \<or> Q)"
  1615   "(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not>(P = Q)) = ((P \<and> \<not> Q) \<or> (\<not>P \<and> Q))"
  1615   "(P = Q) = ((P \<and> Q) \<or> (\<not>P \<and> \<not> Q))" "(\<not>(P = Q)) = ((P \<and> \<not> Q) \<or> (\<not>P \<and> Q))"
  1616   "(\<not> \<not>(P)) = P"
  1616   "(\<not> \<not>(P)) = P"
  1617 by blast+
  1617 by blast+
  1618 
  1618 
  1619 subsection {* Basic ML bindings *}
  1619 subsection \<open>Basic ML bindings\<close>
  1620 
  1620 
  1621 ML {*
  1621 ML \<open>
  1622 val FalseE = @{thm FalseE}
  1622 val FalseE = @{thm FalseE}
  1623 val Let_def = @{thm Let_def}
  1623 val Let_def = @{thm Let_def}
  1624 val TrueI = @{thm TrueI}
  1624 val TrueI = @{thm TrueI}
  1625 val allE = @{thm allE}
  1625 val allE = @{thm allE}
  1626 val allI = @{thm allI}
  1626 val allI = @{thm allI}
  1665 val spec = @{thm spec}
  1665 val spec = @{thm spec}
  1666 val ssubst = @{thm ssubst}
  1666 val ssubst = @{thm ssubst}
  1667 val subst = @{thm subst}
  1667 val subst = @{thm subst}
  1668 val sym = @{thm sym}
  1668 val sym = @{thm sym}
  1669 val trans = @{thm trans}
  1669 val trans = @{thm trans}
  1670 *}
  1670 \<close>
  1671 
  1671 
  1672 ML_file "Tools/cnf.ML"
  1672 ML_file "Tools/cnf.ML"
  1673 
  1673 
  1674 
  1674 
  1675 section {* @{text NO_MATCH} simproc *}
  1675 section \<open>@{text NO_MATCH} simproc\<close>
  1676 
  1676 
  1677 text {*
  1677 text \<open>
  1678  The simplification procedure can be used to avoid simplification of terms of a certain form
  1678  The simplification procedure can be used to avoid simplification of terms of a certain form
  1679 *}
  1679 \<close>
  1680 
  1680 
  1681 definition NO_MATCH :: "'a \<Rightarrow> 'b \<Rightarrow> bool" where "NO_MATCH pat val \<equiv> True"
  1681 definition NO_MATCH :: "'a \<Rightarrow> 'b \<Rightarrow> bool" where "NO_MATCH pat val \<equiv> True"
  1682 
  1682 
  1683 lemma NO_MATCH_cong[cong]: "NO_MATCH pat val = NO_MATCH pat val" by (rule refl)
  1683 lemma NO_MATCH_cong[cong]: "NO_MATCH pat val = NO_MATCH pat val" by (rule refl)
  1684 
  1684 
  1685 declare [[coercion_args NO_MATCH - -]]
  1685 declare [[coercion_args NO_MATCH - -]]
  1686 
  1686 
  1687 simproc_setup NO_MATCH ("NO_MATCH pat val") = {* fn _ => fn ctxt => fn ct =>
  1687 simproc_setup NO_MATCH ("NO_MATCH pat val") = \<open>fn _ => fn ctxt => fn ct =>
  1688   let
  1688   let
  1689     val thy = Proof_Context.theory_of ctxt
  1689     val thy = Proof_Context.theory_of ctxt
  1690     val dest_binop = Term.dest_comb #> apfst (Term.dest_comb #> snd)
  1690     val dest_binop = Term.dest_comb #> apfst (Term.dest_comb #> snd)
  1691     val m = Pattern.matches thy (dest_binop (Thm.term_of ct))
  1691     val m = Pattern.matches thy (dest_binop (Thm.term_of ct))
  1692   in if m then NONE else SOME @{thm NO_MATCH_def} end
  1692   in if m then NONE else SOME @{thm NO_MATCH_def} end
  1693 *}
  1693 \<close>
  1694 
  1694 
  1695 text {*
  1695 text \<open>
  1696   This setup ensures that a rewrite rule of the form @{term "NO_MATCH pat val \<Longrightarrow> t"}
  1696   This setup ensures that a rewrite rule of the form @{term "NO_MATCH pat val \<Longrightarrow> t"}
  1697   is only applied, if the pattern @{term pat} does not match the value @{term val}.
  1697   is only applied, if the pattern @{term pat} does not match the value @{term val}.
  1698 *}
  1698 \<close>
  1699 
  1699 
  1700 
  1700 
  1701 subsection {* Code generator setup *}
  1701 subsection \<open>Code generator setup\<close>
  1702 
  1702 
  1703 subsubsection {* Generic code generator preprocessor setup *}
  1703 subsubsection \<open>Generic code generator preprocessor setup\<close>
  1704 
  1704 
  1705 lemma conj_left_cong:
  1705 lemma conj_left_cong:
  1706   "P \<longleftrightarrow> Q \<Longrightarrow> P \<and> R \<longleftrightarrow> Q \<and> R"
  1706   "P \<longleftrightarrow> Q \<Longrightarrow> P \<and> R \<longleftrightarrow> Q \<and> R"
  1707   by (fact arg_cong)
  1707   by (fact arg_cong)
  1708 
  1708 
  1709 lemma disj_left_cong:
  1709 lemma disj_left_cong:
  1710   "P \<longleftrightarrow> Q \<Longrightarrow> P \<or> R \<longleftrightarrow> Q \<or> R"
  1710   "P \<longleftrightarrow> Q \<Longrightarrow> P \<or> R \<longleftrightarrow> Q \<or> R"
  1711   by (fact arg_cong)
  1711   by (fact arg_cong)
  1712 
  1712 
  1713 setup {*
  1713 setup \<open>
  1714   Code_Preproc.map_pre (put_simpset HOL_basic_ss) #>
  1714   Code_Preproc.map_pre (put_simpset HOL_basic_ss) #>
  1715   Code_Preproc.map_post (put_simpset HOL_basic_ss) #>
  1715   Code_Preproc.map_post (put_simpset HOL_basic_ss) #>
  1716   Code_Simp.map_ss (put_simpset HOL_basic_ss #>
  1716   Code_Simp.map_ss (put_simpset HOL_basic_ss #>
  1717   Simplifier.add_cong @{thm conj_left_cong} #>
  1717   Simplifier.add_cong @{thm conj_left_cong} #>
  1718   Simplifier.add_cong @{thm disj_left_cong})
  1718   Simplifier.add_cong @{thm disj_left_cong})
  1719 *}
  1719 \<close>
  1720 
  1720 
  1721 
  1721 
  1722 subsubsection {* Equality *}
  1722 subsubsection \<open>Equality\<close>
  1723 
  1723 
  1724 class equal =
  1724 class equal =
  1725   fixes equal :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
  1725   fixes equal :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
  1726   assumes equal_eq: "equal x y \<longleftrightarrow> x = y"
  1726   assumes equal_eq: "equal x y \<longleftrightarrow> x = y"
  1727 begin
  1727 begin
  1738 end
  1738 end
  1739 
  1739 
  1740 declare eq_equal [symmetric, code_post]
  1740 declare eq_equal [symmetric, code_post]
  1741 declare eq_equal [code]
  1741 declare eq_equal [code]
  1742 
  1742 
  1743 setup {*
  1743 setup \<open>
  1744   Code_Preproc.map_pre (fn ctxt =>
  1744   Code_Preproc.map_pre (fn ctxt =>
  1745     ctxt addsimprocs [Simplifier.simproc_global_i @{theory} "equal" [@{term HOL.eq}]
  1745     ctxt addsimprocs [Simplifier.simproc_global_i @{theory} "equal" [@{term HOL.eq}]
  1746       (fn _ => fn Const (_, Type ("fun", [Type _, _])) => SOME @{thm eq_equal} | _ => NONE)])
  1746       (fn _ => fn Const (_, Type ("fun", [Type _, _])) => SOME @{thm eq_equal} | _ => NONE)])
  1747 *}
  1747 \<close>
  1748 
  1748 
  1749 
  1749 
  1750 subsubsection {* Generic code generator foundation *}
  1750 subsubsection \<open>Generic code generator foundation\<close>
  1751 
  1751 
  1752 text {* Datatype @{typ bool} *}
  1752 text \<open>Datatype @{typ bool}\<close>
  1753 
  1753 
  1754 code_datatype True False
  1754 code_datatype True False
  1755 
  1755 
  1756 lemma [code]:
  1756 lemma [code]:
  1757   shows "False \<and> P \<longleftrightarrow> False"
  1757   shows "False \<and> P \<longleftrightarrow> False"
  1769   shows "(False \<longrightarrow> P) \<longleftrightarrow> True"
  1769   shows "(False \<longrightarrow> P) \<longleftrightarrow> True"
  1770     and "(True \<longrightarrow> P) \<longleftrightarrow> P"
  1770     and "(True \<longrightarrow> P) \<longleftrightarrow> P"
  1771     and "(P \<longrightarrow> False) \<longleftrightarrow> \<not> P"
  1771     and "(P \<longrightarrow> False) \<longleftrightarrow> \<not> P"
  1772     and "(P \<longrightarrow> True) \<longleftrightarrow> True" by simp_all
  1772     and "(P \<longrightarrow> True) \<longleftrightarrow> True" by simp_all
  1773 
  1773 
  1774 text {* More about @{typ prop} *}
  1774 text \<open>More about @{typ prop}\<close>
  1775 
  1775 
  1776 lemma [code nbe]:
  1776 lemma [code nbe]:
  1777   shows "(True \<Longrightarrow> PROP Q) \<equiv> PROP Q"
  1777   shows "(True \<Longrightarrow> PROP Q) \<equiv> PROP Q"
  1778     and "(PROP Q \<Longrightarrow> True) \<equiv> Trueprop True"
  1778     and "(PROP Q \<Longrightarrow> True) \<equiv> Trueprop True"
  1779     and "(P \<Longrightarrow> R) \<equiv> Trueprop (P \<longrightarrow> R)" by (auto intro!: equal_intr_rule)
  1779     and "(P \<Longrightarrow> R) \<equiv> Trueprop (P \<longrightarrow> R)" by (auto intro!: equal_intr_rule)
  1782   "Trueprop True \<equiv> Code_Generator.holds"
  1782   "Trueprop True \<equiv> Code_Generator.holds"
  1783   by (auto intro!: equal_intr_rule holds)
  1783   by (auto intro!: equal_intr_rule holds)
  1784 
  1784 
  1785 declare Trueprop_code [symmetric, code_post]
  1785 declare Trueprop_code [symmetric, code_post]
  1786 
  1786 
  1787 text {* Equality *}
  1787 text \<open>Equality\<close>
  1788 
  1788 
  1789 declare simp_thms(6) [code nbe]
  1789 declare simp_thms(6) [code nbe]
  1790 
  1790 
  1791 instantiation itself :: (type) equal
  1791 instantiation itself :: (type) equal
  1792 begin
  1792 begin
  1801 
  1801 
  1802 lemma equal_itself_code [code]:
  1802 lemma equal_itself_code [code]:
  1803   "equal TYPE('a) TYPE('a) \<longleftrightarrow> True"
  1803   "equal TYPE('a) TYPE('a) \<longleftrightarrow> True"
  1804   by (simp add: equal)
  1804   by (simp add: equal)
  1805 
  1805 
  1806 setup {* Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>type \<Rightarrow> 'a \<Rightarrow> bool"}) *}
  1806 setup \<open>Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>type \<Rightarrow> 'a \<Rightarrow> bool"})\<close>
  1807 
  1807 
  1808 lemma equal_alias_cert: "OFCLASS('a, equal_class) \<equiv> ((op = :: 'a \<Rightarrow> 'a \<Rightarrow> bool) \<equiv> equal)" (is "?ofclass \<equiv> ?equal")
  1808 lemma equal_alias_cert: "OFCLASS('a, equal_class) \<equiv> ((op = :: 'a \<Rightarrow> 'a \<Rightarrow> bool) \<equiv> equal)" (is "?ofclass \<equiv> ?equal")
  1809 proof
  1809 proof
  1810   assume "PROP ?ofclass"
  1810   assume "PROP ?ofclass"
  1811   show "PROP ?equal"
  1811   show "PROP ?equal"
  1812     by (tactic {* ALLGOALS (resolve_tac @{context} [Thm.unconstrainT @{thm eq_equal}]) *})
  1812     by (tactic \<open>ALLGOALS (resolve_tac @{context} [Thm.unconstrainT @{thm eq_equal}])\<close>)
  1813       (fact `PROP ?ofclass`)
  1813       (fact \<open>PROP ?ofclass\<close>)
  1814 next
  1814 next
  1815   assume "PROP ?equal"
  1815   assume "PROP ?equal"
  1816   show "PROP ?ofclass" proof
  1816   show "PROP ?ofclass" proof
  1817   qed (simp add: `PROP ?equal`)
  1817   qed (simp add: \<open>PROP ?equal\<close>)
  1818 qed
  1818 qed
  1819 
  1819 
  1820 setup {* Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>equal \<Rightarrow> 'a \<Rightarrow> bool"}) *}
  1820 setup \<open>Sign.add_const_constraint (@{const_name equal}, SOME @{typ "'a\<Colon>equal \<Rightarrow> 'a \<Rightarrow> bool"})\<close>
  1821 
  1821 
  1822 setup {* Nbe.add_const_alias @{thm equal_alias_cert} *}
  1822 setup \<open>Nbe.add_const_alias @{thm equal_alias_cert}\<close>
  1823 
  1823 
  1824 text {* Cases *}
  1824 text \<open>Cases\<close>
  1825 
  1825 
  1826 lemma Let_case_cert:
  1826 lemma Let_case_cert:
  1827   assumes "CASE \<equiv> (\<lambda>x. Let x f)"
  1827   assumes "CASE \<equiv> (\<lambda>x. Let x f)"
  1828   shows "CASE x \<equiv> f x"
  1828   shows "CASE x \<equiv> f x"
  1829   using assms by simp_all
  1829   using assms by simp_all
  1830 
  1830 
  1831 setup {*
  1831 setup \<open>
  1832   Code.add_case @{thm Let_case_cert} #>
  1832   Code.add_case @{thm Let_case_cert} #>
  1833   Code.add_undefined @{const_name undefined}
  1833   Code.add_undefined @{const_name undefined}
  1834 *}
  1834 \<close>
  1835 
  1835 
  1836 declare [[code abort: undefined]]
  1836 declare [[code abort: undefined]]
  1837 
  1837 
  1838 
  1838 
  1839 subsubsection {* Generic code generator target languages *}
  1839 subsubsection \<open>Generic code generator target languages\<close>
  1840 
  1840 
  1841 text {* type @{typ bool} *}
  1841 text \<open>type @{typ bool}\<close>
  1842 
  1842 
  1843 code_printing
  1843 code_printing
  1844   type_constructor bool \<rightharpoonup>
  1844   type_constructor bool \<rightharpoonup>
  1845     (SML) "bool" and (OCaml) "bool" and (Haskell) "Bool" and (Scala) "Boolean"
  1845     (SML) "bool" and (OCaml) "bool" and (Haskell) "Bool" and (Scala) "Boolean"
  1846 | constant True \<rightharpoonup>
  1846 | constant True \<rightharpoonup>
  1883 
  1883 
  1884 code_identifier
  1884 code_identifier
  1885   code_module Pure \<rightharpoonup>
  1885   code_module Pure \<rightharpoonup>
  1886     (SML) HOL and (OCaml) HOL and (Haskell) HOL and (Scala) HOL
  1886     (SML) HOL and (OCaml) HOL and (Haskell) HOL and (Scala) HOL
  1887 
  1887 
  1888 text {* using built-in Haskell equality *}
  1888 text \<open>using built-in Haskell equality\<close>
  1889 
  1889 
  1890 code_printing
  1890 code_printing
  1891   type_class equal \<rightharpoonup> (Haskell) "Eq"
  1891   type_class equal \<rightharpoonup> (Haskell) "Eq"
  1892 | constant HOL.equal \<rightharpoonup> (Haskell) infix 4 "=="
  1892 | constant HOL.equal \<rightharpoonup> (Haskell) infix 4 "=="
  1893 | constant HOL.eq \<rightharpoonup> (Haskell) infix 4 "=="
  1893 | constant HOL.eq \<rightharpoonup> (Haskell) infix 4 "=="
  1894 
  1894 
  1895 text {* undefined *}
  1895 text \<open>undefined\<close>
  1896 
  1896 
  1897 code_printing
  1897 code_printing
  1898   constant undefined \<rightharpoonup>
  1898   constant undefined \<rightharpoonup>
  1899     (SML) "!(raise/ Fail/ \"undefined\")"
  1899     (SML) "!(raise/ Fail/ \"undefined\")"
  1900     and (OCaml) "failwith/ \"undefined\""
  1900     and (OCaml) "failwith/ \"undefined\""
  1901     and (Haskell) "error/ \"undefined\""
  1901     and (Haskell) "error/ \"undefined\""
  1902     and (Scala) "!sys.error(\"undefined\")"
  1902     and (Scala) "!sys.error(\"undefined\")"
  1903 
  1903 
  1904 
  1904 
  1905 subsubsection {* Evaluation and normalization by evaluation *}
  1905 subsubsection \<open>Evaluation and normalization by evaluation\<close>
  1906 
  1906 
  1907 method_setup eval = {*
  1907 method_setup eval = \<open>
  1908   let
  1908   let
  1909     fun eval_tac ctxt =
  1909     fun eval_tac ctxt =
  1910       let val conv = Code_Runtime.dynamic_holds_conv ctxt
  1910       let val conv = Code_Runtime.dynamic_holds_conv ctxt
  1911       in
  1911       in
  1912         CONVERSION (Conv.params_conv ~1 (K (Conv.concl_conv ~1 conv)) ctxt) THEN'
  1912         CONVERSION (Conv.params_conv ~1 (K (Conv.concl_conv ~1 conv)) ctxt) THEN'
  1913         resolve_tac ctxt [TrueI]
  1913         resolve_tac ctxt [TrueI]
  1914       end
  1914       end
  1915   in
  1915   in
  1916     Scan.succeed (SIMPLE_METHOD' o eval_tac)
  1916     Scan.succeed (SIMPLE_METHOD' o eval_tac)
  1917   end
  1917   end
  1918 *} "solve goal by evaluation"
  1918 \<close> "solve goal by evaluation"
  1919 
  1919 
  1920 method_setup normalization = {*
  1920 method_setup normalization = \<open>
  1921   Scan.succeed (fn ctxt =>
  1921   Scan.succeed (fn ctxt =>
  1922     SIMPLE_METHOD'
  1922     SIMPLE_METHOD'
  1923       (CHANGED_PROP o
  1923       (CHANGED_PROP o
  1924         (CONVERSION (Nbe.dynamic_conv ctxt)
  1924         (CONVERSION (Nbe.dynamic_conv ctxt)
  1925           THEN_ALL_NEW (TRY o resolve_tac ctxt [TrueI]))))
  1925           THEN_ALL_NEW (TRY o resolve_tac ctxt [TrueI]))))
  1926 *} "solve goal by normalization"
  1926 \<close> "solve goal by normalization"
  1927 
  1927 
  1928 
  1928 
  1929 subsection {* Counterexample Search Units *}
  1929 subsection \<open>Counterexample Search Units\<close>
  1930 
  1930 
  1931 subsubsection {* Quickcheck *}
  1931 subsubsection \<open>Quickcheck\<close>
  1932 
  1932 
  1933 quickcheck_params [size = 5, iterations = 50]
  1933 quickcheck_params [size = 5, iterations = 50]
  1934 
  1934 
  1935 
  1935 
  1936 subsubsection {* Nitpick setup *}
  1936 subsubsection \<open>Nitpick setup\<close>
  1937 
  1937 
  1938 named_theorems nitpick_unfold "alternative definitions of constants as needed by Nitpick"
  1938 named_theorems nitpick_unfold "alternative definitions of constants as needed by Nitpick"
  1939   and nitpick_simp "equational specification of constants as needed by Nitpick"
  1939   and nitpick_simp "equational specification of constants as needed by Nitpick"
  1940   and nitpick_psimp "partial equational specification of constants as needed by Nitpick"
  1940   and nitpick_psimp "partial equational specification of constants as needed by Nitpick"
  1941   and nitpick_choice_spec "choice specification of constants as needed by Nitpick"
  1941   and nitpick_choice_spec "choice specification of constants as needed by Nitpick"
  1942 
  1942 
  1943 declare if_bool_eq_conj [nitpick_unfold, no_atp]
  1943 declare if_bool_eq_conj [nitpick_unfold, no_atp]
  1944         if_bool_eq_disj [no_atp]
  1944         if_bool_eq_disj [no_atp]
  1945 
  1945 
  1946 
  1946 
  1947 subsection {* Preprocessing for the predicate compiler *}
  1947 subsection \<open>Preprocessing for the predicate compiler\<close>
  1948 
  1948 
  1949 named_theorems code_pred_def "alternative definitions of constants for the Predicate Compiler"
  1949 named_theorems code_pred_def "alternative definitions of constants for the Predicate Compiler"
  1950   and code_pred_inline "inlining definitions for the Predicate Compiler"
  1950   and code_pred_inline "inlining definitions for the Predicate Compiler"
  1951   and code_pred_simp "simplification rules for the optimisations in the Predicate Compiler"
  1951   and code_pred_simp "simplification rules for the optimisations in the Predicate Compiler"
  1952 
  1952 
  1953 
  1953 
  1954 subsection {* Legacy tactics and ML bindings *}
  1954 subsection \<open>Legacy tactics and ML bindings\<close>
  1955 
  1955 
  1956 ML {*
  1956 ML \<open>
  1957   (* combination of (spec RS spec RS ...(j times) ... spec RS mp) *)
  1957   (* combination of (spec RS spec RS ...(j times) ... spec RS mp) *)
  1958   local
  1958   local
  1959     fun wrong_prem (Const (@{const_name All}, _) $ Abs (_, _, t)) = wrong_prem t
  1959     fun wrong_prem (Const (@{const_name All}, _) $ Abs (_, _, t)) = wrong_prem t
  1960       | wrong_prem (Bound _) = true
  1960       | wrong_prem (Bound _) = true
  1961       | wrong_prem _ = false;
  1961       | wrong_prem _ = false;
  1969     val nnf_ss =
  1969     val nnf_ss =
  1970       simpset_of (put_simpset HOL_basic_ss @{context} addsimps @{thms simp_thms nnf_simps});
  1970       simpset_of (put_simpset HOL_basic_ss @{context} addsimps @{thms simp_thms nnf_simps});
  1971   in
  1971   in
  1972     fun nnf_conv ctxt = Simplifier.rewrite (put_simpset nnf_ss ctxt);
  1972     fun nnf_conv ctxt = Simplifier.rewrite (put_simpset nnf_ss ctxt);
  1973   end
  1973   end
  1974 *}
  1974 \<close>
  1975 
  1975 
  1976 hide_const (open) eq equal
  1976 hide_const (open) eq equal
  1977 
  1977 
  1978 end
  1978 end