theory HOL imports Pure Try0 Tools.Code_Generator
keywords "try""solve_direct""quickcheck""print_coercions""print_claset" "print_induct_rules" :: diag and "quickcheck_params" :: thy_decl
abbrevs "?<" = "∃\<le>1" begin
text‹
definition of the logic is based on Mike Gordon's technical report cite‹"Gordon-TR68"› that
the first implementation of HOL. However, there are a number of differences.
particular, we start with the definite description operator and introduce Hilbert's ‹ε› operator
much later. Moreover, axiom ‹(P ⟶ Q) ⟶ (Q ⟶ P) ⟶ (P = Q)› is derived from the other
. The fact that this axiom is derivable was first noticed by Bruno Barras (for Mike Gordon's
of HOL systems) and later independently by Alexander Maletzky (for Isabelle/HOL). ›
subsubsection‹Core syntax›
setup‹Axclass.class_axiomatization (🚫‹type›, [])›
default_sort type setup‹Object_Logic.add_base_sort 🚫‹type››
(ASCII)
All (binder ‹ALL › 10) and
Ex (binder ‹EX › 10)
(input)
All (binder ‹! › 10) and
Ex (binder ‹? › 10)
‹Axioms and basic definitions›
where
refl: "t = (t::'a)" and
subst: "s = t ==> P s ==> P t" and
ext: "(∧x::'a. (f x ::'b) = g x) ==> (λx. f x) = (λx. g x)" ―‹Extensionality is built into the meta-logic, and this rule expresses
a related property. It is an eta-expanded version of the traditional
rule, and similar to the ABS rule of HOL› and
the_eq_trivial: "(THE x. x = a) = (a::'a)"
where
impI: "(P ==> Q) ==> P ⟶ Q" and
mp: "[P ⟶ Q; P]==> Q" and
True_or_False: "(P = True) ∨ (P = False)"
If :: "bool → 'a → 'a → 'a" (‹(‹notation=‹mixfix if expression››if (_)/ then (_)/ else (_))› [0, 0, 10] 10)
where "If P x y ≡ (THE z::'a. (P = True ⟶ z = x) ∧ (P = False ⟶ z = y))"
Let :: "'a → ('a → 'b) → 'b"
where "Let s f ≡ f s"
"_Let (_binds b bs) e" ⇌ "_Let b (_Let bs e)"
"let x = a in e" ⇌ "CONST Let a (λx. e)"
undefined :: 'a
default = fixes default :: 'a
‹Fundamental rules›
‹Equality›
sym: "s = t ==> t = s"
by (erule subst) (rule refl)
ssubst: "t = s ==> P s ==> P t"
by (drule sym) (erule subst)
trans: "[r = s; s = t]==> r = t"
by (erule subst)
trans_sym [Pure.elim?]: "r = s ==> t = s ==> r = t"
by (rule trans [OF _ sym])
meta_eq_to_obj_eq:
assumes "A ≡ B"
shows "A = B"
unfolding assms by (rule refl)
‹Useful with ‹erule› for proving equalities from known equalities.›
(* a = b
| |
c = d *) lemma box_equals: "[a = b; a = c; b = d]==> c = d" by (iprover intro: sym trans)
text‹For calculational reasoning:›
lemma forw_subst: "a = b ==> P b ==> P a" by (rule ssubst)
lemma back_subst: "P a ==> a = b ==> P b" by (rule subst)
subsubsection‹Congruence rules for application›
text‹Similar to ‹AP_THM› in Gordon's HOL.› lemma fun_cong: "(f :: 'a → 'b) = g ==> f x = g x" by (iprover intro: refl elim: subst)
text‹Similar to ‹AP_TERM› in Gordon's HOL and FOL's ‹subst_context›.› lemma arg_cong: "x = y ==> f x = f y" by (iprover intro: refl elim: subst)
lemma arg_cong2: "[a = b; c = d]==> f a c = f b d" by (iprover intro: refl elim: subst)
lemma arg_cong3: "[x = x'; y = y'; z = z']==> f x y z = f x' y' z'" by (iprover intro: refl elim: subst)
lemma arg_cong4: "[w = w'; x = x'; y = y'; z = z']==> f w x y z = f w' x' y' z'" by (iprover intro: refl elim: subst)
lemma cong: "[f = g; (x::'a) = y]==> f x = g y" by (iprover intro: refl elim: subst)
ML ‹fun cong_tac ctxt = Cong_Tac.cong_tac ctxt @{thm cong}›
subsubsection‹Equality of booleans -- iff›
lemma iffD2: "[P = Q; Q]==> P" by (erule ssubst)
lemma rev_iffD2: "[Q; P = Q]==> P" by (erule iffD2)
lemma iffD1: "Q = P ==> Q ==> P" by (drule sym) (rule iffD2)
lemma rev_iffD1: "Q ==> Q = P ==> P" by (drule sym) (rule rev_iffD2)
lemma iffE: assumes major: "P = Q" and minor: "[P ⟶ Q; Q ⟶ P]==> R" shows R by (iprover intro: minor impI major [THEN iffD2] major [THEN iffD1])
subsubsection‹True (1)›
lemma TrueI: True unfolding True_def by (rule refl)
lemma impE: assumes"P ⟶ Q" P "Q ==> R" shows R by (iprover intro: assms mp)
text‹Reduces ‹Q› to ‹P ⟶ Q›, allowing substitution in ‹P›.› lemma rev_mp: "[P; P ⟶ Q]==> Q" by (rule mp)
lemma contrapos_nn: assumes major: "¬ Q" and minor: "P ==> Q" shows"¬ P" by (iprover intro: notI minor major [THENnotE])
text‹Not used at all, but we already have the other 3 combinations.› lemma contrapos_pn: assumes major: "Q" and minor: "P ==>¬ Q" shows"¬ P" by (iprover intro: notI minor major notE)
lemma not_sym: "t ≠ s ==> s ≠ t" by (erule contrapos_nn) (erule sym)
lemma eq_neq_eq_imp_neq: "[x = a; a ≠ b; b = y]==> x ≠ y" by (erule subst, erule ssubst, assumption)
subsubsection‹Disjunction (1)›
lemma disjE: assumes major: "P ∨ Q" and minorP: "P ==> R" and minorQ: "Q ==> R" shows R by (iprover intro: minorP minorQ impI
major [unfolded or_def, THEN spec, THEN mp, THEN mp])
subsubsection‹Derivation of ‹iffI››
text‹In an intuitionistic version of HOL ‹iffI› needs to be an axiom.›
lemma iffI: assumes"P ==> Q"and"Q ==> P" shows"P = Q" proof (rule disjE[OF True_or_False[of P]]) assume1: "P = True" note Q = assms(1)[OF eqTrueE[OF this]] from1show ?thesis proof (rule ssubst) from True_or_False[of Q] show"True = Q" proof (rule disjE) assume"Q = True" thus ?thesis by(rule sym) next assume"Q = False" with Q have False by (rule rev_iffD1) thus ?thesis by (rule FalseE) qed qed next assume2: "P = False" thus ?thesis proof (rule ssubst) from True_or_False[of Q] show"False = Q" proof (rule disjE) assume"Q = True" from2 assms(2)[OF eqTrueE[OF this]] have False by (rule iffD1) thus ?thesis by (rule FalseE) next assume"Q = False" thus ?thesis by(rule sym) qed qed qed
subsubsection‹True (2)›
lemma eqTrueI: "P ==> P = True" by (iprover intro: iffI TrueI)
subsubsection‹Universal quantifier (2)›
lemma allI: assumes"∧x::'a. P x" shows"∀x. P x" unfolding All_def by (iprover intro: ext eqTrueI assms)
subsubsection‹Existential quantifier›
lemma exI: "P x ==>∃x::'a. P x" unfolding Ex_def by (iprover intro: allI allE impI mp)
lemma exE: assumes major: "∃x::'a. P x" and minor: "∧x. P x ==> Q" shows"Q" by (rule major [unfolded Ex_def, THEN spec, THEN mp]) (iprover intro: impI [THEN allI] minor)
subsubsection‹Conjunction›
lemma conjI: "[P; Q]==> P ∧ Q" unfolding and_def by (iprover intro: impI [THEN allI] mp)
lemma conjE: assumes major: "P ∧ Q" and minor: "[P; Q]==> R" shows R proof (rule minor) show P by (rule major [THEN conjunct1]) show Q by (rule major [THEN conjunct2]) qed
lemma context_conjI: assumes P "P ==> Q" shows"P ∧ Q" by (iprover intro: conjI assms)
subsubsection‹Disjunction (2)›
lemma disjI1: "P ==> P ∨ Q" unfolding or_def by (iprover intro: allI impI mp)
lemma disjI2: "Q ==> P ∨ Q" unfolding or_def by (iprover intro: allI impI mp)
subsubsection‹Classical logic›
lemma classical: assumes"¬ P ==> P" shows P proof (rule True_or_False [THEN disjE]) show P if"P = True" using that by (iprover intro: eqTrueE) show P if"P = False" proof (intro notI assms) assume P with that show False by (iprover elim: subst) qed qed
lemmas ccontr = FalseE [THEN classical]
text‹‹notE› with premises exchanged; it discharges ‹¬ R› so that it can be used to
make elimination rules.› lemma rev_notE: assumes premp: P and premnot: "¬ R ==>¬ P" shows R by (iprover intro: ccontr notE [OF premnot premp])
text‹Double negation law.› lemma notnotD: "¬¬ P ==> P" by (iprover intro: ccontr notE )
lemma contrapos_pp: assumes p1: Q and p2: "¬ P ==>¬ Q" shows P by (iprover intro: classical p1 p2 notE)
subsubsection‹Unique existence›
lemma Uniq_I [intro?]: assumes"∧x y. [P x; P y]==> y = x" shows"Uniq P" unfolding Uniq_def by (iprover intro: assms allI impI)
lemma Uniq_D [dest?]: "[Uniq P; P a; P b]==> a=b" unfolding Uniq_def by (iprover dest: spec mp)
lemma ex1I: assumes"P a""∧x. P x ==> x = a" shows"∃!x. P x" unfolding Ex1_def by (iprover intro: assms exI conjI allI impI)
text‹Sometimes easier to use: the premises have no shared variables. Safe!› lemma ex_ex1I: assumes ex_prem: "∃x. P x" and eq: "∧x y. [P x; P y]==> x = y" shows"∃!x. P x" by (iprover intro: ex_prem [THEN exE] ex1I eq)
lemma ex1E: assumes major: "∃!x. P x"and minor: "∧x. [P x; ∀y. P y ⟶ y = x]==> R" shows R proof (rule major [unfolded Ex1_def, THEN exE]) show"∧x. P x ∧ (∀y. P y ⟶ y = x) ==> R" by (iprover intro: minor elim: conjE) qed
lemma ex1_implies_ex: "∃!x. P x ==>∃x. P x" by (iprover intro: exI elim: ex1E)
subsubsection‹Classical intro rules for disjunction and existential quantifiers›
lemma excluded_middle: "¬ P ∨ P" by (iprover intro: disjCI)
text‹
case distinction as a natural deduction rule.
Note that ‹¬ P› is the second case, not the first. › lemma case_split [case_names True False]: assumes"P ==> Q""¬ P ==> Q" shows Q using excluded_middle [of P] by (iprover intro: assms elim: disjE)
text‹Classical implies (‹⟶›) elimination.› lemma impCE: assumes major: "P ⟶ Q" and minor: "¬ P ==> R""Q ==> R" shows R using excluded_middle [of P] by (iprover intro: minor major [THEN mp] elim: disjE)+
text‹
This version of ‹⟶› elimination works on ‹Q› before ‹P›. It works best for
those cases in which ‹P› holds "almost everywhere". Can't install as
default: would break old proofs. › lemma impCE': assumes major: "P ⟶ Q" and minor: "Q ==> R""¬ P ==> R" shows R using assms by (elim impCE)
text‹The analogous introduction rule for conjunction, above, is even constructive› lemma context_disjE: assumes major: "P ∨ Q"and minor: "P ==> R""¬P ==> Q ==> R" shows R by (iprover intro: disjE [OF major] disjE [OF excluded_middle] assms)
text‹Classical ‹⟷› elimination.› lemma iffCE: assumes major: "P = Q" and minor: "[P; Q]==> R""[¬ P; ¬ Q]==> R" shows R by (rule major [THEN iffE]) (iprover intro: minor elim: impCE notE)
lemma exCI: assumes"∀x. ¬ P x ==> P a" shows"∃x. P x" by (rule ccontr) (iprover intro: assms exI allI notI notE [of "∃x. P x"])
subsubsection‹Intuitionistic Reasoning›
lemma impE': assumes1: "P ⟶ Q" and2: "Q ==> R" and3: "P ⟶ Q ==> P" shows R proof - from3and1have P . with1have Q by (rule impE) with2show R . qed
lemma allE': assumes1: "∀x. P x" and2: "P x ==>∀x. P x ==> Q" shows Q proof - from1have"P x"by (rule spec) from this and1show Q by (rule 2) qed
lemmanotE': assumes1: "¬ P" and2: "¬ P ==> P" shows R proof - from2and1have P . with1show R by (rule notE) qed
lemma TrueE: "True ==> P ==> P" . lemma notFalseE: "¬ False ==> P ==> P" .
lemmas [Pure.elim!] = disjE iffE FalseE conjE exE TrueE notFalseE and [Pure.intro!] = iffI conjI impI TrueI notI allI refl and [Pure.elim 2] = allE notE' impE' and [Pure.intro] = exI disjI2 disjI1
lemmas [trans] = trans and [sym] = sym not_sym and [Pure.elim?] = iffD1 iffD2 impE
subsubsection‹Atomizing meta-level connectives›
axiomatizationwhere
eq_reflection: "x = y ==> x ≡ y"―‹admissible axiom›
lemma atomize_all [atomize]: "(∧x. P x) ≡ Trueprop (∀x. P x)" proof assume"∧x. P x" thenshow"∀x. P x" .. next assume"∀x. P x" thenshow"∧x. P x"by (rule allE) qed
lemma atomize_imp [atomize]: "(A ==> B) ≡ Trueprop (A ⟶ B)" proof assume r: "A ==> B" show"A ⟶ B"by (rule impI) (rule r) next assume"A ⟶ B"and A thenshow B by (rule mp) qed
lemma atomize_not: "(A ==> False) ≡ Trueprop (¬ A)" proof assume r: "A ==> False" show"¬ A"by (rule notI) (rule r) next assume"¬ A"and A thenshow False by (rule notE) qed
lemma atomize_conj [atomize]: "(A &&& B) ≡ Trueprop (A ∧ B)" proof assume conj: "A &&& B" show"A ∧ B" proof (rule conjI) from conj show A by (rule conjunctionD1) from conj show B by (rule conjunctionD2) qed next assume conj: "A ∧ B" show"A &&& B" proof - from conj show A .. from conj show B .. qed qed
text‹
Theorems blacklisted to Sledgehammer. These theorems typically produce clauses
that are prolific (match too many equality or membership literals) and relate to
seldom-used facts. Some duplicate other rules. ›
named_theorems no_atp "theorems that should be filtered out by Sledgehammer"
subsubsection‹Classical Reasoner setup›
lemma imp_elim: "P ⟶ Q ==> (¬ R ==> P) ==> (Q ==> R) ==> R" by (rule classical) iprover
lemma swap: "¬ P ==> (¬ R ==> P) ==> R" by (rule classical) iprover
lemma thin_refl: "[x = x; PROP W]==> PROP W" .
ML ‹
Hypsubst = Hypsubst
val dest_eq = HOLogic.dest_eq
val dest_Trueprop = HOLogic.dest_Trueprop
val dest_imp = HOLogic.dest_imp
val eq_reflection = @{thm eq_reflection}
val rev_eq_reflection = @{thm meta_eq_to_obj_eq}
val imp_intr = @{thm impI}
val rev_mp = @{thm rev_mp}
val subst = @{thm subst}
val sym = @{thm sym}
val thin_refl = @{thm thin_refl};
;
Hypsubst;
Classical = Classical
val imp_elim = @{thm imp_elim}
val not_elim = @{thm notE}
val swap = @{thm swap}
val classical = @{thm classical}
val sizef = Drule.size_of_thm
val hyp_subst_tacs = [Hypsubst.hyp_subst_tac]
;
lemmasubst_all: \<open>(\<And>x.x=a\<Longrightarrow>PROPPx)\<equiv>PROPPa\<close> \<open>(\<And>x.a=x\<Longrightarrow>PROPPx)\<equiv>PROPPa\<close> proof- show\<open>(\<And>x.x=a\<Longrightarrow>PROPPx)\<equiv>PROPPa\<close> proof(ruleequal_intr_rule) assume*:\<open>\<And>x.x=a\<Longrightarrow>PROPPx\<close> show\<open>PROPPa\<close>
by (rule *) (rule refl) next fix x assume‹PROP P a›and‹x = a› from‹x = a›have‹x ≡ a› by (rule eq_reflection) with‹PROP P a›show‹PROP P x› by simp qed show‹(∧x. a = x ==> PROP P x) ≡ PROP P a› proof (rule equal_intr_rule) assume *: ‹∧x. a = x ==> PROP P x› show‹PROP P a› by (rule *) (rule refl) next fix x assume‹PROP P a›and‹a = x› from‹a = x›have‹a ≡ x› by (rule eq_reflection) with‹PROP P a›show‹PROP P x› by simp qed qed
lemma simp_thms: shows not_not: "(¬¬ P) = P" and Not_eq_iff: "((¬ P) = (¬ Q)) = (P = Q)" and "(P ≠ Q) = (P = (¬ Q))" "(P ∨¬P) = True""(¬ P ∨ P) = True" "(x = x) = True" and not_True_eq_False [code]: "(¬ True) = False" and not_False_eq_True [code]: "(¬ False) = True" and "(¬ P) ≠ P""P ≠ (¬ P)" "(True = P) = P" and eq_True: "(P = True) = P" and"(False = P) = (¬ P)" and eq_False: "(P = False) = (¬ P)" and "(True ⟶ P) = P""(False ⟶ P) = True" "(P ⟶ True) = True""(P ⟶ P) = True" "(P ⟶ False) = (¬ P)""(P ⟶¬ P) = (¬ P)" "(P ∧ True) = P""(True ∧ P) = P" "(P ∧ False) = False""(False ∧ P) = False" "(P ∧ P) = P""(P ∧ (P ∧ Q)) = (P ∧ Q)" "(P ∧¬ P) = False""(¬ P ∧ P) = False" "(P ∨ True) = True""(True ∨ P) = True" "(P ∨ False) = P""(False ∨ P) = P" "(P ∨ P) = P""(P ∨ (P ∨ Q)) = (P ∨ Q)"and "(∀x. P) = P""(∃x. P) = P""∃x. x = t""∃x. t = x" and "∧P. (∃x. x = t ∧ P x) = P t" "∧P. (∃x. t = x ∧ P x) = P t" "∧P. (∀x. x = t ⟶ P x) = P t" "∧P. (∀x. t = x ⟶ P x) = P t" "(∀x. x ≠ t) = False""(∀x. t ≠ x) = False" by (blast, blast, blast, blast, blast, iprover+)
lemma disj_absorb: "A ∨ A ⟷ A" by blast
lemma disj_left_absorb: "A ∨ (A ∨ B) ⟷ A ∨ B" by blast
lemma conj_absorb: "A ∧ A ⟷ A" by blast
lemma conj_left_absorb: "A ∧ (A ∧ B) ⟷ A ∧ B" by blast
lemma eq_ac: shows eq_commute: "a = b ⟷ b = a" and iff_left_commute: "(P ⟷ (Q ⟷ R)) ⟷ (Q ⟷ (P ⟷ R))" and iff_assoc: "((P ⟷ Q) ⟷ R) ⟷ (P ⟷ (Q ⟷ R))" by (iprover, blast+)
text‹These two are specialized, but ‹imp_disj_not1› is useful in ‹Auth/Yahalom›.› lemma imp_disj_not1: "(P ⟶ Q ∨ R) ⟷ (¬ Q ⟶ P ⟶ R)"by blast lemma imp_disj_not2: "(P ⟶ Q ∨ R) ⟷ (¬ R ⟶ P ⟶ Q)"by blast
lemma cases_simp: "(P ⟶ Q) ∧ (¬ P ⟶ Q) ⟷ Q" ―‹Avoids duplication of subgoals after ‹if_split›, when the true and false› ―‹cases boil down to the same thing.› by blast
lemma not_all: "¬ (∀x. P x) ⟷ (∃x. ¬ P x)"by blast lemma imp_all: "((∀x. P x) ⟶ Q) ⟷ (∃x. P x ⟶ Q)"by blast lemma not_ex: "¬ (∃x. P x) ⟷ (∀x. ¬ P x)"by iprover lemma imp_ex: "((∃x. P x) ⟶ Q) ⟷ (∀x. P x ⟶ Q)"by iprover lemma all_not_ex: "(∀x. P x) ⟷¬ (∃x. ¬ P x)"by blast
declare All_def [no_atp]
lemma ex_disj_distrib: "(∃x. P x ∨ Q x) ⟷ (∃x. P x) ∨ (∃x. Q x)"by iprover lemma all_conj_distrib: "(∀x. P x ∧ Q x) ⟷ (∀x. P x) ∧ (∀x. Q x)"by iprover lemma all_imp_conj_distrib: "(∀x. P x ⟶ Q x ∧ R x) ⟷ (∀x. P x ⟶ Q x) ∧ (∀x. P x ⟶R x)" by iprover
text‹ ┉ The ‹∧› congruence rule: not included by default!
May slow rewrite proofs down by as much as 50\%›
text‹The ‹|› congruence rule: not included by default!›
lemma disj_cong: "P = P' ==> (¬ P' ==> Q = Q') ==> (P ∨ Q) = (P' ∨ Q')" by blast
text‹┉ if-then-else rules›
lemma if_True [code]: "(if True then x else y) = x" unfolding If_def by blast
lemma if_False [code]: "(if False then x else y) = y" unfolding If_def by blast
lemma if_P: "P ==> (if P then x else y) = x" unfolding If_def by blast
lemma if_not_P: "¬ P ==> (if P then x else y) = y" unfolding If_def by blast
lemma if_split: "P (if Q then x else y) = ((Q ⟶ P x) ∧ (¬ Q ⟶ P y))" proof (rule case_split [of Q]) show ?thesis if Q using that by (simplesubst if_P) blast+ show ?thesis if"¬ Q" using that by (simplesubst if_not_P) blast+ qed
lemma if_split_asm: "P (if Q then x else y) = (¬ ((Q ∧¬ P x) ∨ (¬ Q ∧¬ P y)))" by (simplesubst if_split) blast
lemmas if_splits [no_atp] = if_split if_split_asm
lemma if_cancel: "(if c then x else x) = x" by (simplesubst if_split) blast
lemma if_eq_cancel: "(if x = y then y else x) = x" by (simplesubst if_split) blast
lemma if_bool_eq_conj: "(if P then Q else R) = ((P ⟶ Q) ∧ (¬ P ⟶ R))" ―‹This form is useful for expanding ‹if›s on the RIGHT of the ‹==>› symbol.› by (rule if_split)
lemma if_bool_eq_disj: "(if P then Q else R) = ((P ∧ Q) ∨ (¬ P ∧ R))" ―‹And this form is useful for expanding ‹if›s on the LEFT.› by (simplesubst if_split) blast
lemma Eq_TrueI: "P ==> P ≡ True"unfolding atomize_eq by iprover lemma Eq_FalseI: "¬ P ==> P ≡ False"unfolding atomize_eq by iprover
text‹┉ let rules for simproc›
lemma Let_folded: "f x ≡ g x ==> Let x f ≡ Let x g" by (unfold Let_def)
lemma Let_unfold: "f x ≡ g ==> Let x f ≡ g" by (unfold Let_def)
text \<open>
The following copy of the implication operator is useful for
fine-tuning congruence rules. It instructs the simplifier to simplify
its premise.
\<close>
lemma simp_impliesI:
assumes PQ: "(PROP P \<Longrightarrow> PROP Q)"
shows "PROP P =simp=> PROP Q"
unfolding simp_implies_def
by (iprover intro: PQ)
lemma simp_impliesE:
assumes PQ: "PROP P =simp=> PROP Q" and P: "PROP P" and QR: "PROP Q \<Longrightarrow> PROP R"
shows "PROP R"
by (iprover intro: QR P PQ [unfolded simp_implies_def])
lemma simp_implies_cong:
assumes PP' :"PROP P \<equiv> PROP P'" and P'QQ': "PROP P' \<Longrightarrow> (PROP Q \<equiv> PROP Q')"
shows "(PROP P =simp=> PROP Q) \<equiv> (PROP P' =simp=> PROP Q')"
unfolding simp_implies_def
proof (rule equal_intr_rule)
assume PQ: "PROP P \<Longrightarrow> PROP Q" and P': "PROP P'"
from PP' [symmetric] and P' have "PROP P"
by (rule equal_elim_rule1)
then have "PROP Q" by (rule PQ)
with P'QQ' [OF P'] show "PROP Q'" by (rule equal_elim_rule1)
next
assume P'Q': "PROP P' \<Longrightarrow> PROP Q'" and P: "PROP P"
from PP' and P have P': "PROP P'" by (rule equal_elim_rule1)
then have "PROP Q'" by (rule P'Q')
with P'QQ' [OF P', symmetric] show "PROP Q"
by (rule equal_elim_rule1)
qed
lemma uncurry:
assumes "P \<longrightarrow> Q \<longrightarrow> R"
shows "P \<and> Q \<longrightarrow> R"
using assms by blast
lemma iff_allI:
assumes "\<And>x. P x = Q x"
shows "(\<forall>x. P x) = (\<forall>x. Q x)"
using assms by blast
lemma iff_exI:
assumes "\<And>x. P x = Q x"
shows "(\<exists>x. P x) = (\<exists>x. Q x)"
using assms by blast
lemma all_comm: "(\<forall>x y. P x y) = (\<forall>y x. P x y)"
by blast
lemma ex_comm: "(\<exists>x y. P x y) = (\<exists>y x. P x y)"
by blast
ML_file \<open>Tools/simpdata.ML\<close>
ML \<open>open Simpdata\<close>
simproc_setup defined_Ex ("\<exists>x. P x") = \<open>K Quantifier1.rearrange_Ex\<close>
simproc_setup defined_All ("\<forall>x. P x") = \<open>K Quantifier1.rearrange_All\<close>
simproc_setup defined_all("\<And>x. PROP P x") = \<open>K Quantifier1.rearrange_all\<close>
text \<open>Simproc for proving \<open>(y = x) \<equiv> False\<close> from premise \<open>\<not> (x = y)\<close>:\<close>
simproc_setup neq ("x = y") = \<open> let
val neq_to_EQ_False = @{thm not_sym} RS @{thm Eq_FalseI};
fun is_neq eq lhs rhs thm =
(case Thm.prop_of thm of
_ $ (Not $ (eq' $ l' $ r')) => Not = HOLogic.Not andalso eq' = eq andalso
r' aconv lhs andalso l' aconv rhs
| _ => false);
fun proc ss ct =
(case Thm.term_of ct of eq $ lhs $ rhs =>
(case find_first (is_neq eq lhs rhs) (Simplifier.prems_of ss) of
SOME thm => SOME (thm RS neq_to_EQ_False)
| NONE => NONE)
| _ => NONE);
in K proc end
\<close>
simproc_setup let_simp ("Let x f") = \<open> let
fun count_loose (Bound i) k = if i >= k then 1 else 0
| count_loose (s $ t) k = count_loose s k + count_loose t k
| count_loose (Abs (_, _, t)) k = count_loose t (k + 1)
| count_loose _ _ = 0;
fun is_trivial_let \<^Const_>\<open>Let _ _ for x t\<close> =
(case t of
Abs (_, _, t') => count_loose t'0 <= 1
| _ => true);
in
K (fn ctxt => fn ct => if is_trivial_let (Thm.term_of ct)
then SOME @{thm Let_def} (*no or one ocurrence of bound variable*)
else let (*Norbert Schirmer's case*)
val t = Thm.term_of ct;
val (t', ctxt') = yield_singleton (Variable.import_terms false) t ctxt;
in
Option.map (hd o Variable.export ctxt' ctxt o single)
(case t' of \<^Const_>\<open>Let _ _ for x f\<close> => (* x and f are already in normal form *) if is_Free x orelse is_Bound x orelse is_Const x
then SOME @{thm Let_def}
else let
val n = case f of (Abs (x, _, _)) => x | _ => "x";
val cx = Thm.cterm_of ctxt x;
val xT = Thm.typ_of_cterm cx;
val cf = Thm.cterm_of ctxt f;
val fx_g = Simplifier.rewrite ctxt (Thm.apply cf cx);
val (_ $ _ $ g) = Thm.prop_of fx_g;
val g' = abstract_over (x, g);
val abs_g'= Abs (n, xT, g');
in if g aconv g' then let
val rl =
infer_instantiate ctxt [(("f", 0), cf), (("x", 0), cx)] @{thm Let_unfold};
in SOME (rl OF [fx_g]) end
else if (Envir.beta_eta_contract f) aconv (Envir.beta_eta_contract abs_g')
then NONE (*avoid identity conversion*)
else let
val g'x = abs_g' $ x;
val g_g'x = Thm.symmetric (Thm.beta_conversion false (Thm.cterm_of ctxt g'x));
val rl =
@{thm Let_folded} |> infer_instantiate ctxt
[(("f", 0), Thm.cterm_of ctxt f),
(("x", 0), cx),
(("g", 0), Thm.cterm_of ctxt abs_g')];
in SOME (rl OF [Thm.transitive fx_g g_g'x]) end
end
| _ => NONE)
end)
end
\<close>
lemma True_implies_equals: "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
proof
assume "True \<Longrightarrow> PROP P"
from this [OF TrueI] show "PROP P" .
next
assume "PROP P"
then show "PROP P" .
qed
lemma implies_True_equals: "(PROP P \<Longrightarrow> True) \<equiv> Trueprop True"
by standard (intro TrueI)
lemma False_implies_equals: "(False \<Longrightarrow> P) \<equiv> Trueprop True"
by standard simp_all
(* It seems that making this a simp rule is slower than using the simproc below *)
lemma implies_False_swap: "(False \<Longrightarrow> PROP P \<Longrightarrow> PROP Q) \<equiv> (PROP P \<Longrightarrow> False \<Longrightarrow> PROP Q)"
by (rule swap_prems_eq)
simproc_setup eliminate_false_implies ("False \<Longrightarrow> PROP P") = \<open> let
fun conv n = if n > 1 then
Conv.rewr_conv @{thm Pure.swap_prems_eq}
then_conv Conv.arg_conv (conv (n - 1))
then_conv Conv.rewr_conv @{thm HOL.implies_True_equals}
else
Conv.rewr_conv @{thm HOL.False_implies_equals}
in
fn _ => fn _ => fn ct => let
val t = Thm.term_of ct
val n = length (Logic.strip_imp_prems t)
in
(case Logic.strip_imp_concl t of
\<^Const_>\<open>Trueprop for _\<close> => SOME (conv n ct)
| _ => NONE)
end
end
\<close>
lemma ex_simps: "\<And>P Q. (\<exists>x. P x \<and> Q) = ((\<exists>x. P x) \<and> Q)" "\<And>P Q. (\<exists>x. P \<and> Q x) = (P \<and> (\<exists>x. Q x))" "\<And>P Q. (\<exists>x. P x \<or> Q) = ((\<exists>x. P x) \<or> Q)" "\<And>P Q. (\<exists>x. P \<or> Q x) = (P \<or> (\<exists>x. Q x))" "\<And>P Q. (\<exists>x. P x \<longrightarrow> Q) = ((\<forall>x. P x) \<longrightarrow> Q)" "\<And>P Q. (\<exists>x. P \<longrightarrow> Q x) = (P \<longrightarrow> (\<exists>x. Q x))"
\<comment> \<open>Miniscoping: pushing in existential quantifiers.\<close>
by (iprover | blast)+
lemma all_simps: "\<And>P Q. (\<forall>x. P x \<and> Q) = ((\<forall>x. P x) \<and> Q)" "\<And>P Q. (\<forall>x. P \<and> Q x) = (P \<and> (\<forall>x. Q x))" "\<And>P Q. (\<forall>x. P x \<or> Q) = ((\<forall>x. P x) \<or> Q)" "\<And>P Q. (\<forall>x. P \<or> Q x) = (P \<or> (\<forall>x. Q x))" "\<And>P Q. (\<forall>x. P x \<longrightarrow> Q) = ((\<exists>x. P x) \<longrightarrow> Q)" "\<And>P Q. (\<forall>x. P \<longrightarrow> Q x) = (P \<longrightarrow> (\<forall>x. Q x))"
\<comment> \<open>Miniscoping: pushing in universal quantifiers.\<close>
by (iprover | blast)+
lemmas [simp] =
triv_forall_equality \<comment> \<open>prunes params\<close>
True_implies_equals implies_True_equals \<comment> \<open>prune \<open>True\<close> in asms\<close>
False_implies_equals \<comment> \<open>prune \<open>False\<close> in asms\<close>
if_True
if_False
if_cancel
if_eq_cancel
imp_disjL \<comment> \<open>In general it seems wrong to add distributive laws by default: they
might cause exponential blow-up. But \<open>imp_disjL\<close> has been in for a while and cannot be removed without affecting existing proofs. Moreover,
rewriting by \<open>(P \<or> Q \<longrightarrow> R) = ((P \<longrightarrow> R) \<and> (Q \<longrightarrow> R))\<close> might be justified on the
grounds that it allows simplification of \<open>R\<close> in the two cases.\<close>
conj_assoc
disj_assoc
de_Morgan_conj
de_Morgan_disj
imp_disj1
imp_disj2
not_imp
disj_not1
not_all
not_ex
cases_simp
the_eq_trivial
the_sym_eq_trivial
ex_simps
all_simps
simp_thms
subst_all
ML \<open>val HOL_ss = simpset_of \<^context>\<close>
text \<open>Simplifies \<open>x\<close> assuming \<open>c\<close> and \<open>y\<close> assuming \<open>\<not> c\<close>.\<close>
lemma if_cong:
assumes "b = c" and"c \<Longrightarrow> x = u" and"\<not> c \<Longrightarrow> y = v"
shows "(if b then x else y) = (if c then u else v)"
using assms by simp
text \<open>Prevents simplification of \<open>x\<close> and \<open>y\<close>:
faster and allows the execution of functional programs.\<close>
lemma if_weak_cong [cong]:
assumes "b = c"
shows "(if b then x else y) = (if c then x else y)"
using assms by (rule arg_cong)
text \<open>Prevents simplification of t: much faster\<close>
lemma let_weak_cong:
assumes "a = b"
shows "(let x = a in t x) = (let x = b in t x)"
using assms by (rule arg_cong)
text \<open>To tidy up the result of a simproc. Only the RHS will be simplified.\<close>
lemma eq_cong2:
assumes "u = u'"
shows "(t \<equiv> u) \<equiv> (t \<equiv> u')"
using assms by simp
lemma if_distrib: "f (if c then x else y) = (if c then f x else f y)"
by simp
lemma if_distribR: "(if b then f else g) x = (if b then f x else g x)"
by simp
lemma all_if_distrib: "(\<forall>x. if x = a then P x else Q x) \<longleftrightarrow> P a \<and> (\<forall>x. x\<noteq>a \<longrightarrow> Q x)"
by auto
lemma ex_if_distrib: "(\<exists>x. if x = a then P x else Q x) \<longleftrightarrow> P a \<or> (\<exists>x. x\<noteq>a \<and> Q x)"
by auto
lemma if_if_eq_conj: "(if P then if Q then x else y else y) = (if P \<and> Q then x else y)"
by simp
text \<open>As a simplification rule, it replaces all function equalities by
first-order equalities.\<close>
lemma fun_eq_iff: "f = g \<longleftrightarrow> (\<forall>x. f x = g x)"
by auto
subsubsection \<open>Generic cases and induction\<close>
text \<open>Rule projections:\<close>
ML \<open>
structure Project_Rule = Project_Rule
(
val conjunct1 = @{thm conjunct1}
val conjunct2 = @{thm conjunct2}
val mp = @{thm mp}
);
\<close>
context
begin
qualified definition "induct_forall P \<equiv> \<forall>x. P x"
qualified definition "induct_implies A B \<equiv> A \<longrightarrow> B"
qualified definition "induct_equal x y \<equiv> x = y"
qualified definition "induct_conj A B \<equiv> A \<and> B"
qualified definition "induct_true \<equiv> True"
qualified definition "induct_false \<equiv> False"
lemma induct_forall_eq: "(\<And>x. P x) \<equiv> Trueprop (induct_forall (\<lambda>x. P x))"
by (unfold atomize_all induct_forall_def)
lemma induct_implies_eq: "(A \<Longrightarrow> B) \<equiv> Trueprop (induct_implies A B)"
by (unfold atomize_imp induct_implies_def)
lemma induct_equal_eq: "(x \<equiv> y) \<equiv> Trueprop (induct_equal x y)"
by (unfold atomize_eq induct_equal_def)
lemma induct_conj_eq: "(A &&& B) \<equiv> Trueprop (induct_conj A B)"
by (unfold atomize_conj induct_conj_def)
lemma induct_forall_conj: "induct_forall (\<lambda>x. induct_conj (A x) (B x)) =
induct_conj (induct_forall A) (induct_forall B)"
by (unfold induct_forall_def induct_conj_def) iprover
lemma induct_implies_conj: "induct_implies C (induct_conj A B) =
induct_conj (induct_implies C A) (induct_implies C B)"
by (unfold induct_implies_def induct_conj_def) iprover
lemma induct_conj_curry: "(induct_conj A B \<Longrightarrow> PROP C) \<equiv> (A \<Longrightarrow> B \<Longrightarrow> PROP C)"
proof
assume r: "induct_conj A B \<Longrightarrow> PROP C"
assume ab: A B
show "PROP C" by (rule r) (simp add: induct_conj_def ab)
next
assume r: "A \<Longrightarrow> B \<Longrightarrow> PROP C"
assume ab: "induct_conj A B"
show "PROP C" by (rule r) (simp_all add: ab [unfolded induct_conj_def])
qed
text \<open>Pre-simplification of induction and cases rules\<close>
lemma [induct_simp]: "(\<And>x. induct_equal x t \<Longrightarrow> PROP P x) \<equiv> PROP P t"
unfolding induct_equal_def
proof
assume r: "\<And>x. x = t \<Longrightarrow> PROP P x"
show "PROP P t" by (rule r [OF refl])
next
fix x
assume "PROP P t""x = t"
then show "PROP P x" by simp
qed
lemma [induct_simp]: "(\<And>x. induct_equal t x \<Longrightarrow> PROP P x) \<equiv> PROP P t"
unfolding induct_equal_def
proof
assume r: "\<And>x. t = x \<Longrightarrow> PROP P x"
show "PROP P t" by (rule r [OF refl])
next
fix x
assume "PROP P t""t = x"
then show "PROP P x" by simp
qed
lemma [induct_simp]: "(induct_true \<Longrightarrow> PROP P) \<equiv> PROP P"
unfolding induct_true_def
proof
assume "True \<Longrightarrow> PROP P"
then show "PROP P" using TrueI .
next
assume "PROP P"
then show "PROP P" .
qed
lemma [induct_simp]: "(PROP P \<Longrightarrow> induct_true) \<equiv> Trueprop induct_true"
unfolding induct_true_def
by (iprover intro: equal_intr_rule)
ML \<open>
signature REORIENT_PROC =
sig
val add : (term -> bool) -> theory -> theory
val proc : Simplifier.proc
end;
structure Reorient_Proc : REORIENT_PROC =
struct
structure Data = Theory_Data
(
type T = ((term -> bool) * stamp) list;
val empty = [];
fun merge data : T = Library.merge (eq_snd (op =)) data;
);
fun add m = Data.map (cons (m, stamp ()));
fun matches thy t = exists (fn (m, _) => m t) (Data.get thy);
val meta_reorient = @{thm eq_commute [THEN eq_reflection]};
fun proc ctxt ct = let
val thy = Proof_Context.theory_of ctxt;
in case Thm.term_of ct of
(_ $ t $ u) => if matches thy u then NONE else SOME meta_reorient
| _ => NONE
end;
end;
\<close>
subsection \<open>Other simple lemmas and lemma duplicates\<close>
lemma eq_iff_swap: "(x = y \<longleftrightarrow> P) \<Longrightarrow> (y = x \<longleftrightarrow> P)"
by blast
lemma all_cong1: "(\<And>x. P x = P' x) \<Longrightarrow> (\<forall>x. P x) = (\<forall>x. P' x)"
by auto
lemma ex_cong1: "(\<And>x. P x = P' x) \<Longrightarrow> (\<exists>x. P x) = (\<exists>x. P' x)"
by auto
lemma all_cong: "(\<And>x. Q x \<Longrightarrow> P x = P' x) \<Longrightarrow> (\<forall>x. Q x \<longrightarrow> P x) = (\<forall>x. Q x \<longrightarrow> P' x)"
by auto
lemma ex_cong: "(\<And>x. Q x \<Longrightarrow> P x = P' x) \<Longrightarrow> (\<exists>x. Q x \<and> P x) = (\<exists>x. Q x \<and> P' x)"
by auto
lemma ex1_eq [iff]: "\<exists>!x. x = t""\<exists>!x. t = x"
by blast+
lemma choice_eq: "(\<forall>x. \<exists>!y. P x y) = (\<exists>!f. \<forall>x. P x (f x))" (is "?lhs = ?rhs")
proof (intro iffI allI)
assume L: ?lhs
then have *: "\<forall>x. P x (THE y. P x y)"
by (best intro: theI')
show ?rhs
by (rule ex1I) (use L * in \<open>fast+\<close>)
next
fix x
assume R: ?rhs
then obtain f where f: "\<forall>x. P x (f x)"and f1: "\<And>y. (\<forall>x. P x (y x)) \<Longrightarrow> y = f"
by (blast elim: ex1E)
show "\<exists>!y. P x y"
proof (rule ex1I)
show "P x (f x)"
using f by blast
show "y = f x"if"P x y" for y
proof -
have "P z (if z = x then y else f z)" for z
using f that by (auto split: if_split)
with f1 [of "\<lambda>z. if z = x then y else f z"] f
show ?thesis
by (auto simp add: split: if_split_asm dest: fun_cong)
qed
qed
qed
ML \<open>
val FalseE = @{thm FalseE}
val Let_def = @{thm Let_def}
val TrueI = @{thm TrueI}
val allE = @{thm allE}
val allI = @{thm allI}
val all_dupE = @{thm all_dupE}
val arg_cong = @{thm arg_cong}
val box_equals = @{thm box_equals}
val ccontr = @{thm ccontr}
val classical = @{thm classical}
val conjE = @{thm conjE}
val conjI = @{thm conjI}
val conjunct1 = @{thm conjunct1}
val conjunct2 = @{thm conjunct2}
val disjCI = @{thm disjCI}
val disjE = @{thm disjE}
val disjI1 = @{thm disjI1}
val disjI2 = @{thm disjI2}
val eq_reflection = @{thm eq_reflection}
val ex1E = @{thm ex1E}
val ex1I = @{thm ex1I}
val ex1_implies_ex = @{thm ex1_implies_ex}
val exE = @{thm exE}
val exI = @{thm exI}
val excluded_middle = @{thm excluded_middle}
val ext = @{thm ext}
val fun_cong = @{thm fun_cong}
val iffD1 = @{thm iffD1}
val iffD2 = @{thm iffD2}
val iffI = @{thm iffI}
val impE = @{thm impE}
val impI = @{thm impI}
val meta_eq_to_obj_eq = @{thm meta_eq_to_obj_eq}
val mp = @{thm mp}
val notE = @{thm notE}
val notI = @{thm notI}
val not_all = @{thm not_all}
val not_ex = @{thm not_ex}
val not_iff = @{thm not_iff}
val not_not = @{thm not_not}
val not_sym = @{thm not_sym}
val refl = @{thm refl}
val rev_mp = @{thm rev_mp}
val spec = @{thm spec}
val ssubst = @{thm ssubst}
val subst = @{thm subst}
val sym = @{thm sym}
val trans = @{thm trans}
\<close>
locale cnf
begin
lemma clause2raw_notE: "\<lbrakk>P; \<not>P\<rbrakk> \<Longrightarrow> False" by auto
lemma clause2raw_not_disj: "\<lbrakk>\<not> P; \<not> Q\<rbrakk> \<Longrightarrow> \<not> (P \<or> Q)" by auto
lemma clause2raw_not_not: "P \<Longrightarrow> \<not>\<not> P" by auto
lemma iff_refl: "(P::bool) = P" by auto
lemma iff_trans: "[| (P::bool) = Q; Q = R |] ==> P = R" by auto
lemma conj_cong: "[| P = P'; Q = Q' |] ==> (P \<and> Q) = (P' \<and> Q')" by auto
lemma disj_cong: "[| P = P'; Q = Q' |] ==> (P \<or> Q) = (P' \<or> Q')" by auto
lemma make_nnf_imp: "[| (\<not>P) = P'; Q = Q' |] ==> (P \<longrightarrow> Q) = (P' \<or> Q')" by auto
lemma make_nnf_iff: "[| P = P'; (\<not>P) = NP; Q = Q'; (\<not>Q) = NQ |] ==> (P = Q) = ((P' \<or> NQ) \<and> (NP \<or> Q'))" by auto
lemma make_nnf_not_false: "(\<not>False) = True" by auto
lemma make_nnf_not_true: "(\<not>True) = False" by auto
lemma make_nnf_not_conj: "[| (\<not>P) = P'; (\<not>Q) = Q' |] ==> (\<not>(P \<and> Q)) = (P' \<or> Q')" by auto
lemma make_nnf_not_disj: "[| (\<not>P) = P'; (\<not>Q) = Q' |] ==> (\<not>(P \<or> Q)) = (P' \<and> Q')" by auto
lemma make_nnf_not_imp: "[| P = P'; (\<not>Q) = Q' |] ==> (\<not>(P \<longrightarrow> Q)) = (P' \<and> Q')" by auto
lemma make_nnf_not_iff: "[| P = P'; (\<not>P) = NP; Q = Q'; (\<not>Q) = NQ |] ==> (\<not>(P = Q)) = ((P' \<or> Q') \<and> (NP \<or> NQ))" by auto
lemma make_nnf_not_not: "P = P' ==> (\<not>\<not>P) = P'" by auto
lemma simp_TF_conj_True_l: "[| P = True; Q = Q' |] ==> (P \<and> Q) = Q'" by auto
lemma simp_TF_conj_True_r: "[| P = P'; Q = True |] ==> (P \<and> Q) = P'" by auto
lemma simp_TF_conj_False_l: "P = False ==> (P \<and> Q) = False" by auto
lemma simp_TF_conj_False_r: "Q = False ==> (P \<and> Q) = False" by auto
lemma simp_TF_disj_True_l: "P = True ==> (P \<or> Q) = True" by auto
lemma simp_TF_disj_True_r: "Q = True ==> (P \<or> Q) = True" by auto
lemma simp_TF_disj_False_l: "[| P = False; Q = Q' |] ==> (P \<or> Q) = Q'" by auto
lemma simp_TF_disj_False_r: "[| P = P'; Q = False |] ==> (P \<or> Q) = P'" by auto
lemma make_cnfx_disj_ex_l: "((\<exists>(x::bool). P x) \<or> Q) = (\<exists>x. P x \<or> Q)" by auto
lemma make_cnfx_disj_ex_r: "(P \<or> (\<exists>(x::bool). Q x)) = (\<exists>x. P \<or> Q x)" by auto
lemma make_cnfx_newlit: "(P \<or> Q) = (\<exists>x. (P \<or> x) \<and> (Q \<or> \<not>x))" by auto
lemma make_cnfx_ex_cong: "(\<forall>(x::bool). P x = Q x) \<Longrightarrow> (\<exists>x. P x) = (\<exists>x. Q x)" by auto
lemma weakening_thm: "[| P; Q |] ==> Q" by auto
lemma cnftac_eq_imp: "[| P = Q; P |] ==> Q" by auto
text \<open>
The simplification procedure can be used to avoid simplification of terms
of a certain form.
\<close>
definition NO_MATCH :: "'a \<Rightarrow> 'b \<Rightarrow> bool"
where "NO_MATCH pat val \<equiv> True"
lemma NO_MATCH_cong[cong]: "NO_MATCH pat val = NO_MATCH pat val"
by (rule refl)
declare [[coercion_args NO_MATCH - -]]
simproc_setup NO_MATCH ("NO_MATCH pat val") = \<open>K (fn ctxt => fn ct => let
val thy = Proof_Context.theory_of ctxt
val dest_binop = Term.dest_comb #> apfst (Term.dest_comb #> snd)
val m = Pattern.matches thy (dest_binop (Thm.term_of ct))
in if m then NONE else SOME @{thm NO_MATCH_def} end)
\<close>
text \<open>
This setup ensures that a rewrite rule of the form \<^term>\<open>NO_MATCH pat val \<Longrightarrow> t\<close>
is only applied, if the pattern \<open>pat\<close> does not match the value \<open>val\<close>.
\<close>
text\<open>
Tagging a premise of a simp rule with ASSUMPTION forces the simplifier not to simplify the argument and to solve it by an assumption.
\<close>
definition ASSUMPTION :: "bool \<Rightarrow> bool"
where "ASSUMPTION A \<equiv> A"
lemma ASSUMPTION_cong[cong]: "ASSUMPTION A = ASSUMPTION A"
by (rule refl)
lemma ASSUMPTION_I: "A \<Longrightarrow> ASSUMPTION A"
by (simp add: ASSUMPTION_def)
lemma ASSUMPTION_D: "ASSUMPTION A \<Longrightarrow> A"
by (simp add: ASSUMPTION_def)
setup \<open>Sign.add_const_constraint (\<^const_name>\<open>equal\<close>, SOME \<^typ>\<open>'a::type \<Rightarrow> 'a \<Rightarrow> bool\<close>)\<close>
lemma equal_alias_cert: "OFCLASS('a, equal_class) \<equiv> (((=) :: 'a \<Rightarrow> 'a \<Rightarrow> bool) \<equiv> equal)"
(is "?ofclass \<equiv> ?equal")
proof
assume "PROP ?ofclass"
show "PROP ?equal"
by (tactic \<open>ALLGOALS (resolve_tac \<^context> [Thm.unconstrainT @{thm eq_equal}])\<close>)
(fact \<open>PROP ?ofclass\<close>)
next
assume "PROP ?equal"
show "PROP ?ofclass" proof
qed (simp add: \<open>PROP ?equal\<close>)
qed
setup \<open>Sign.add_const_constraint (\<^const_name>\<open>equal\<close>, SOME \<^typ>\<open>'a::equal \<Rightarrow> 'a \<Rightarrow> bool\<close>)\<close>
text \<open>\<open>undefined\<close>\<close>
code_printing
constant undefined \<rightharpoonup>
(SML) "!(raise/ Fail/ \"undefined\")" and (OCaml) "failwith/ \"undefined\"" and (Haskell) "error/ \"undefined\"" and (Scala) "!sys.error(\"undefined\")"
subsubsection \<open>Evaluation and normalization by evaluation\<close>
method_setup eval = \<open> let
fun eval_tac ctxt = let val conv = Code_Runtime.dynamic_holds_conv
in
CONVERSION (Conv.params_conv ~1 (Conv.concl_conv ~1 o conv) ctxt) THEN'
resolve_tac ctxt [TrueI]
end
in
Scan.succeed (SIMPLE_METHOD' o eval_tac)
end
\<close> "solve goal by evaluation"
method_setup normalization = \<open>
Scan.succeed (fn ctxt =>
SIMPLE_METHOD'
(CHANGED_PROP o
(CONVERSION (Nbe.dynamic_conv ctxt)
THEN_ALL_NEW (TRY o resolve_tac ctxt [TrueI]))))
\<close> "solve goal by normalization"
named_theorems nitpick_unfold "alternative definitions of constants as needed by Nitpick" and nitpick_simp "equational specification of constants as needed by Nitpick" and nitpick_psimp "partial equational specification of constants as needed by Nitpick" and nitpick_choice_spec "choice specification of constants as needed by Nitpick"
declare if_bool_eq_conj [nitpick_unfold, no_atp] and if_bool_eq_disj [no_atp]
subsection \<open>Preprocessing for the predicate compiler\<close>
named_theorems code_pred_def "alternative definitions of constants for the Predicate Compiler" and code_pred_inline "inlining definitions for the Predicate Compiler" and code_pred_simp "simplification rules for the optimisations in the Predicate Compiler"
subsection \<open>Legacy tactics and ML bindings\<close>
ML \<open>
(* combination of (spec RS spec RS ...(j times) ... spec RS mp) *)
local
fun wrong_prem \<^Const_>\<open>All _ for \<open>Abs (_, _, t)\<close>\<close> = wrong_prem t
| wrong_prem (Bound _) = true
| wrong_prem _ = false;
val filter_right = filter (not o wrong_prem o HOLogic.dest_Trueprop o hd o Thm.take_prems_of 1);
fun smp i = funpow i (fn m => filter_right ([spec] RL m)) [mp];
in
fun smp_tac ctxt j = EVERY' [dresolve_tac ctxt (smp j), assume_tac ctxt];
end;
local
val nnf_ss =
simpset_of (put_simpset HOL_basic_ss \<^context>
|> Simplifier.add_simps @{thms simp_thms nnf_simps});
in
fun nnf_conv ctxt = Simplifier.rewrite (put_simpset nnf_ss ctxt);
end
\<close>
hide_const (open) eqequal
end
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.138Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.