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‹
The following copy of the implication operator is useful for
fine-tuning congruence rules. It instructs the simplifier to simplify
its premise. ›
lemma simp_impliesI: assumes PQ: "(PROP P ==> 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 ==> PROP R" shows"PROP R" by (iprover intro: QR P PQ [unfolded simp_implies_def])
lemma simp_implies_cong: assumes PP' :"PROP P ≡ PROP P'" and P'QQ': "PROP P' ==> (PROP Q ≡ PROP Q')" shows"(PROP P =simp=> PROP Q) ≡ (PROP P' =simp=> PROP Q')" unfolding simp_implies_def proof (rule equal_intr_rule) assume PQ: "PROP P ==> PROP Q" and P': "PROP P'" from PP' [symmetric] and P' have"PROP P" by (rule equal_elim_rule1) thenhave"PROP Q"by (rule PQ) with P'QQ' [OF P'] show"PROP Q'"by (rule equal_elim_rule1) next assume P'Q': "PROP P' ==> PROP Q'" and P: "PROP P" from PP' and P have P': "PROP P'"by (rule equal_elim_rule1) thenhave"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 ⟶ Q ⟶ R" shows"P ∧ Q ⟶ R" using assms by blast
lemma iff_allI: assumes"∧x. P x = Q x" shows"(∀x. P x) = (∀x. Q x)" using assms by blast
lemma iff_exI: assumes"∧x. P x = Q x" shows"(∃x. P x) = (∃x. Q x)" using assms by blast
lemma all_comm: "(∀x y. P x y) = (∀y x. P x y)" by blast
lemma ex_comm: "(∃x y. P x y) = (∃y x. P x y)" by blast
simproc_setup defined_Ex ("∃x. P x") = ‹K Quantifier1.rearrange_Ex› simproc_setup defined_All ("∀x. P x") = ‹K Quantifier1.rearrange_All› simproc_setup defined_all("∧x. PROP P x") = ‹K Quantifier1.rearrange_all›
text‹Simproc for proving ‹(y = x) ≡ False› from premise ‹¬ (x = y)›:›
simproc_setup neq ("x = y") = ‹
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 ›
simproc_setup let_simp ("Let x f") = ‹
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 🍋‹Let _ _ for x t› =
(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 🍋‹Let _ _ for x f› => (* 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 ›
lemma True_implies_equals: "(True ==> PROP P) ≡ PROP P" proof assume"True ==> PROP P" from this [OF TrueI] show"PROP P" . next assume"PROP P" thenshow"PROP P" . qed
lemma implies_True_equals: "(PROP P ==> True) ≡ Trueprop True" by standard (intro TrueI)
lemma False_implies_equals: "(False ==> P) ≡ 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 ==> PROP P ==> PROP Q) ≡ (PROP P ==> False ==> PROP Q)" by (rule swap_prems_eq)
simproc_setup eliminate_false_implies ("False ==> PROP P") = ‹ let funconvn= ifn>1then Conv.rewr_conv@{thmPure.swap_prems_eq} then_convConv.arg_conv(conv(n-1)) then_convConv.rewr_conv@{thmHOL.implies_True_equals} else Conv.rewr_conv@{thmHOL.False_implies_equals} in fn_=>fn_=>fnct=> let valt=Thm.term_ofct valn=length(Logic.strip_imp_premst) in (caseLogic.strip_imp_concltof \<^Const_>\<open>Truepropfor_\<close>=>SOME(convnct) |_=>NONE) end end \<close>
lemmainduct_conj_curry:"(induct_conjAB\<Longrightarrow>PROPC)\<equiv>(A\<Longrightarrow>B\<Longrightarrow>PROPC)" proof assumer:"induct_conjAB\<Longrightarrow>PROPC" assumeab:AB show"PROPC"by(ruler)(simpadd:induct_conj_defab) next assumer:"A\<Longrightarrow>B\<Longrightarrow>PROPC" assumeab:"induct_conjAB" show"PROPC"by(ruler)(simp_alladd:ab[unfoldedinduct_conj_def]) qed
lemma[induct_simp]:"(\<And>x.induct_equalxt\<Longrightarrow>PROPPx)\<equiv>PROPPt" unfoldinginduct_equal_def proof assumer:"\<And>x.x=t\<Longrightarrow>PROPPx" show"PROPPt"by(ruler[OFrefl]) next fixx assume"PROPPt""x=t" thenshow"PROPPx"bysimp qed
lemma[induct_simp]:"(\<And>x.induct_equaltx\<Longrightarrow>PROPPx)\<equiv>PROPPt" unfoldinginduct_equal_def proof assumer:"\<And>x.t=x\<Longrightarrow>PROPPx" show"PROPPt"by(ruler[OFrefl]) next fixx assume"PROPPt""t=x" thenshow"PROPPx"bysimp qed
lemma[induct_simp]:"(induct_true\<Longrightarrow>PROPP)\<equiv>PROPP" unfoldinginduct_true_def proof assume"True\<Longrightarrow>PROPP" thenshow"PROPP"usingTrueI. next assume"PROPP" thenshow"PROPP". qed
method_setupeval=\<open> let funeval_tacctxt= letvalconv=Code_Runtime.dynamic_holds_conv in CONVERSION(Conv.params_conv~1(Conv.concl_conv~1oconv)ctxt)THEN' resolve_tacctxt[TrueI] end in Scan.succeed(SIMPLE_METHOD'oeval_tac) end \<close>"solvegoalbyevaluation"
ML\<open>
(* combination of (spec RS spec RS ...(j times) ... spec RS mp) *) local fun wrong_prem 🍋‹All _ for ‹Abs (_, _, t)›› = 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 🍋
|> Simplifier.add_simps @{thms simp_thms nnf_simps}); in fun nnf_conv ctxt = Simplifier.rewrite (put_simpset nnf_ss ctxt); end ›
hide_const (open) eq equal
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.81 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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.