theoryInductive imports Complete_Lattices Ctr_Sugar
keywords "inductive""coinductive""inductive_cases""inductive_simps" :: thy_defn and "monos"and "print_inductives" :: diag and "old_rep_datatype" :: thy_goal and "primrec" :: thy_defn begin
subsection‹
complete_lattice
l
where "lfp f = Inf {u. f u ≤
lfp_lowerbound: "f A ≤ A ==>
unfolding lfp_def by theorem lfp_induct:
lfp_greatest: "(∧
unfolding lfp_def by (rule Inf_greatest) simp
lfp_fixpoint:
assumes "mono f"
shows "f (lfp f) = lfp f"
unfolding lfp_def
java.lang.StringIndexOutOfBoundsException: Range [6, 5) out of bounds for length 26
subsetD, THEN CollectD, OF mono _ lfp]) (auto intro: hyp)
let ?a = "⊓?H"
java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
proof (rule Inf_greatest)
fix x
assume "x ∈ ?H"
then have "?a ≤ x" by (rule Inf_lower)
with ‹mono f› have "f ?a ≤ f x" ..
also from ‹x ∈ ?H› have "f x ≤ x" ..
finally show "f ?a ≤ x" .
qed
show "?a ≤ f ?a"
proof (rule Inf_lower)
from ‹mono f› and ‹f ?a ≤ ?a› have "f (f ?a) ≤ f ?a" ..
then show "f ?a ∈ ?H" ..
qed
lfp_unfold: "mono f ==> lfp f = f (lfp f)"
by (rule lfp_fixpoint [symmetric])
lfp_eqI: "mono F ==> F x = x ==> (∧z. F z = z ==> x ≤ z) ==> lfp F = x"
by (rule antisym) (simp_all add: lfp_lowerbound lfp_unfold[symmetric])
‹General induction rules for least fixed points›
lfp_ordinal_induct [case_names mono step union]:
fixes f :: "'a::complete_lattice → 'a"
assumes mono: "mono f"
and P_f: "∧S. P S ==> S ≤ lfp f ==> P (f S)"
and P_Union: "∧M. ∀S∈M. P S ==> P (Sup M)"
shows "P (lfp f)"
-
let ?M = "{S. S ≤ lfp f ∧ P S}"
from P_Union have "P (Sup ?M)" by simp
also have "Sup ?M = lfp f"
proof (rule antisym)
show "Sup ?M ≤ lfp f"
by (blast intro: Sup_least)
then have "f (Sup ?M) ≤ f (lfp f)"
by (rule mono [THEN monoD])
then have "f (Sup ?M) ≤ lfp f"
using mono [THEN lfp_unfold] by simp
then have "f (Sup ?M) ∈ ?M"
using P_Union by simp (intro P_f Sup_least, auto)
then have "f (Sup ?M) ≤ Sup ?M"
by (rule Sup_upper)
then show "lfp f ≤ Sup ?M"
by (rule lfp_lowerbound)
qed
finally show ?thesis .
lfp_induct:
assumes mono: "mono f"
and ind: "f (inf (lfp f) P) ≤ P"
shows "lfp f ≤ P"
(induct rule: lfp_ordinal_induct)
case mono
show ?case by fact
case (step S)
then show ?case
by (intro order_trans[OF _ ind] monoD[OF mono]) auto
case (union M)
then show ?case
by (auto intro: Sup_least)
lfp_induct_set:
assumes lfp: "a ∈ lfp f"
and mono: "mono f"
and hyp: "∧x. x ∈ f (lfp f ∩ {x. P x}) ==> P x"
shows "P a"
by (rule lfp_induct [THEN subsetD, THEN CollectD, OF mono _ lfp]) (auto intro: hyp)
lfp_ordinal_induct_set:
assumes mono: "mono f"
and P_f: "∧S. P S ==> P (f S)"
and P_Union: "∧M. ∀S∈M. P S ==> P (∪M)"
shows "P (lfp f)"
using assms by (rule lfp_ordinal_induct)
‹Definition forms of ‹lfp_unfold› and ‹lfp_induct›
def_lfp_unfold: "h ≡ lfp f ==> mono f ==> h = f h"
by (auto intro!: lfp_unfold)
def_lfp_induct: "A ≡ lfp f ==> mono f ==> f (inf A P) ≤ P ==> A ≤ P"
by (blast intro: lfp_induct)
def_lfp_induct_set:
"A ≡ lfp f ==> mono f ==> a ∈ A ==> (∧x. x ∈ f (A ∩ {x. P x}) ==> P x) ==> P a"
by (blast intro: lfp_induct_set)
‹Monotonicity of ‹lfp›!›
lfp_mono: "(∧Z. f Z ≤ g Z) ==> lfp f ≤ lfp g"
by (rule lfp_lowerbound [THEN lfp_greatest]) (blast intro: order_trans)
‹Greatest fixed points›
complete_lattice
gfp :: "('a → 'a) → 'a"
where "gfp f = Sup {u. u ≤ f u}"
gfp_upperbound: "X ≤ f X ==> X ≤ gfp f"
by (auto simp add: gfp_def intro: Sup_upper)
gfp_least: "(∧u. u ≤ f u ==> u ≤ X) ==> gfp f ≤ X"
by (auto simp add: gfp_def intro: Sup_least)
lfp_le_gfp: "mono f ==> lfp f ≤ gfp f"
by (rule gfp_upperbound) (simp add: lfp_fixpoint)
gfp_fixpoint:
assumes "mono f"
shows "f (gfp f) = gfp f"
unfolding gfp_def
(rule order_antisym)
let ?H = "{u. u ≤ f u}"
let ?a = "⊔?H"
show "?a \< bylfp_induct_set)
proof (rule Sup_least)
fix x
assume "x ∈ ?H"
then have "x \<letextMonotonicity of ‹lfp›!›
also from ‹x ∈ ?H› have "x ≤ ?a" by (rule Sup_upper)
with ‹mono f› have "f x ≤ f ?a" ..
finally show "x ≤ f ?a" .
qed
show "f ?a ≤ ?a"
proof (rule Sup_upper)
from ‹mono f› and ‹?a ≤ f ?a› have "f ?a ≤ f (f ?a)" ..
then show "f ?a ∈ ?H" ..
qed
gfp_unfold: "mono f ==> gfp f = f (gfp f)"
by (rule gfp_fixpoint [symmetric])
gfp_eqI: "mono F ==> F x = x ==> (∧z. F z = z ==> z ≤ x) ==> gfp F = x"
by (rule antisym) (simp_all add: gfp_upperbound gfp_unfold[symmetric])
‹Coinduction rules for greatest fixed points›
‹Weak version.›
weak_coinduct: "a ∈ X ==> X ⊆ f X ==> a ∈ gfp f"
by (rule gfp_upperbound [THEN subsetD]) auto
weak_coinduct_image: "a ∈ X ==> g`X ⊆ f (g`X) ==> g a ∈ gfp f"
apply (erule gfp_upperbound [THEN subsetD])
apply (erule imageI)
done
coinduct_lemma: "X ≤ f (sup X (gfp f)) ==> mono f ==> sup X (gfp f) ≤ f (sup X (gfp f))"
apply (frule gfp_unfold [THEN eq_refl])
apply (drule mono_sup)
apply (rule le_supI)
apply assumption
apply (rule order_trans)
apply (rule order_trans)
apply assumption
apply (rule sup_ge2)
apply assumption
done
‹Strong version, thanks to Coen and Frost.›
coinduct_set: "mono f ==> a ∈ X ==> X ⊆ f (X \<union by (rule lfp_lowerbound [THEN lfp_greatest]) (blast intro: order_trans)
by (rule weak_coinduct[rotated], rule coinduct_lemma) blast+
gfp_fun_UnI2: "mono f ==> a ∈ gfp f ==> a ∈ f (X ∪ gfp f)"
by (blast dest: gfp_fixpoint mono_Un)
gfp_ordinal_induct[case_names mono step union]:
fixes f :: "'a::complete_lattice → 'a"
assumes mono: "mono f"
and P_f: "∧S. P S ==> gfp f ≤ S ==> P (f S)"
and P_Union: "∧M. ∀S∈M. P S ==> P (Inf M)"
shows "P (gfp f)"
-
let ?M = "{S. gfp f ≤ S ∧ P S}"
from P_Union have "P (Inf ?M)" by simp
also have "Inf ?M = gfp f"
proof (rule antisym)
show "gfp f ≤ Inf ?M"
by (blast intro: Inf_greatest)
then have "f (gfp f) ≤ f (Inf ?M)"
by (rule mono [THEN monoD])
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
using mono [THEN gfp_unfold] by simp
then have "f (Inf ?M) ∈ ?M"
using P_Union by simp (intro P_f Inf_greatest, auto)
then have "Inf ?M ≤ f (Inf ?M)"
by (rule Inf_lower)
then show "Inf ?M ≤ gfp f"
by (rule gfp_upperbound)
qed
finally show ?thesis .
coinduct:
assumes mono: "mono f"
and ind: "X ≤ f (sup X (gfp f))"
shows "X ≤ gfp f"
(induct rule: gfp_ordinal_ind
case mono
show ?case by fact
case (step S)
then show ?case
case efinition gfp :: "('a → 'a) → 'a"
then show ?case
by (auto intro: mono Inf_greatest)
‹Even Stronger Coinduction Rule, by Martin Coen›
‹Weakens the condition term‹X ⊆ f X› to one expressed using both term‹lfp› and term‹gfp››
coinduct3_mono_lemma: "mono f ==> mono (λx. f x ∪ X ∪ B)"
by (iprover intro: subset_refl monoI Un_mono monoD)
coinduct3_lemma:
"X ⊆ f (lfp (λx. f x ∪ X ∪ gfp f)) ==> mono f ==>
lfp (λx. f x ∪ X ∪ gfp f) ⊆ f (lfp (λx. f x ∪ X ∪ gfp f))"
apply (rule subset_trans)
apply (erule coinduct3_mono_lemma [THEN lfp_unfold [THEN eq_refl]])
apply (rule Un_least [THEN Un_least])
apply (rule subset_refl, assumption)
apply (rule gfp_unfold [THEN equalityD1, THEN subset_trans], assumption)
apply (rule monoD, assumption)
apply (subst coinduct3_mono_lemma [THEN lfp_unfold], auto)
done
coinduct3: "mono f ==> a ∈ X ==> X ⊆ f (lfp (λx. f x ∪ X ∪ gfp f)) ==> a ∈ gfp f"
apply (rule coinduct3_lemma [THEN [2] weak_coinduct])
apply (rule coinduct3_mono_lemma [THEN lfp_unfold, THEN ssubst])
apply simp_all
done
‹Definition forms of ‹gfp_unfold› and ‹coinduct›, to control unfolding.›
def_gfp_unfold: "A ≡ gfp f ==> mono f ==> A = f A"
by (auto intro!: gfp_unfold)
def_coinduct: "A ≡ gfp f ==> mono f ==> X ≤ f (sup X A) ==> X ≤ A"
by (iprover intro!: coinduct)
def_coinduct_set: "A ≡ gfp f ==> mono f ==> a ∈ X ==> X ⊆ f (X ∪ A) ==> a ∈ A"
by (auto intro!: coinduct_set)
def_Collect_coinduct:
"A ≡ gfp (λw. Collect (P w)) ==> mono (λw. Collect (P w)) ==> a ∈ X ==>
(∧z. z ∈ X ==> P (X ∪ A) z) ==> a ∈ A"
by (erule def_coinduct_set) auto
def_coinduct3: "A ≡ gfp f ==> mono f ==> a ∈ X ==> X ⊆ f (lfp (λx. f x ∪ X ∪ A))==> a ∈ A"
by (auto intro!: coinduct3)
‹Monotonicity of term‹gfp›!›
gfp_mono: "(∧Z. f Z ≤ g Z) ==> gfp f ≤ gfp g"
by (rule gfp_upperbound [THEN gfp_least]) (blast intro: order_trans)
‹Rules for fixed point calculus›
lfp_rolling:
assumes "mono g" "mono f"
shows "g (lfp (λx. f (g x))) = lfp (λx. g (f x))"
(rule antisym)
have *: "mono (λx. f (g x))"
using assms by (auto simp: mono_def)
show "lfp (λx. g (f x)) ≤ g (lfp (λx. f (g x)))"
by (rule lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric])
show "g (lfp (λx. f (g x))) ≤ lfp (λx. g (f x))"
proof (rule lfp_greatest)
fix u
assume u: "g (f u) ≤ u"
then have "g (lfp (λx. f (g x))) ≤ g (f u)"
by (intro assms[THEN monoD] lfp_lowerbound)
with u show "g (lfp (λx. f (g x))) ≤ u"
by auto
qed
lfp_lfp:
assumes f: "∧x y w z. x ≤ y ==> w ≤ z ==> f x w ≤ f y z"
shows "lfp (λx. lfp (f x)) = lfp (λx. f x x)"
(rule antisym)
have *: "mono (λx. f x x)"
by (blast intro: monoI f)
show "lfp (λx. lfp (f x)) ≤ lfp (λx. f x x)"
by (intro lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric])
show "lfp (λx. lfp (f x)) ≥ lfp (λx. f x x)" (is "?F ≥ _")
proof (intro lfp_lowerbound)
have *: "?F = lfp (f ?F)"
by (rule lfp_unfold) (blast intro: monoI lfp_mono f)
also have "… = f ?F (lfp (f ?F))"
by (rule lfp_unfold) (blast intro: monoI lfp_mono f)
finally show "f ?F ?F ≤ ?F"
by (simp add: *[symmetric])
qed
gfp_rolling:
assumes "mono g" "mono f"
shows "g (gfp (λx. f (g x))) = gfp (λx. g (f x))"
(rule antisym)
have *: "mono (λx. f (g x))"
using assms by (auto simp: mono_def)
show "g (gfp (λx. f (g x))) ≤ gfp (λx. g (f x))"
by (rule gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric])
show "gfp (λx. g (f x)) ≤ g (gfp (λx. f (g x)))"
proof (rule gfp_least)
fix u
assume u: "u ≤ g (f u)"
then have "g (f u) ≤ g (gfp (λx. f (g x)))"
by (intro assms[THEN monoD] gfp_upperbound)
with u show "u ≤ g (gfp (λx. f (g x)))"
by auto
qed
gfp_gfp:
assumes f: "∧x y w z. x ≤ y ==> w ≤ z ==> f x w ≤ f y z"
shows "gfp (λx. gfp (f x)) = gfp (λx. f x x)"
(rule antisym)
have *: "mono (λx. f x x)"
by (blast intro: monoI f)
show "gfp (λx. f x x) ≤ gfp (λx. gfp (f x))"
by (intro gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric])
show "gfp (λx. gfp (f x)) ≤ gfp (λx. f x x)" (is "?F ≤ _")
proof (intro gfp_upperbound)
have *: "?F = gfp (f ?F)"
by (rule gfp_unfold) (blast intro: monoI gfp_mono f)
also have "… = f ?F (gfp (f ?F))"
by (rule gfp_unfold) (blast intro: monoI gfp_mono f)
finally show "?F ≤ f ?F ?F"
by (simp add: *[symmetric])
qed
Schroeder_Bernstein:
fixes f :: "'a → 'b" and g :: "'b → 'a"
and A :: "'a set" and B :: "'b set"
assumes inj1: "inj_on f A" and sub1: "f ` A ⊆ B"
and inj2: "inj_on g B" and sub2: "g ` B ⊆ A"
shows "∃h. bij_betw h A B"
(rule exI, rule bij_betw_imageI)
define X where "X = lfp (λX. A - (g ` (B - (f ` X))))"
define g' where "g' = the_inv_into (B - (f ` X)) g"
let ?h = "λz. if z ∈ X then f z else g' z"
have X: "X = A - (g ` (B - (f ` X)))"
unfolding X_def by (rule lfp_unfold) (blast intro: monoI)
then have X_compl: "A - X = g ` (B - (f ` X))"
using sub2 by blast
from inj2 have inj2': "inj_on g (B - (f ` X))"
by (rule inj_on_subset) auto
with X_compl have *: "g' ` (A - X) = B - (f ` X)"
by (simp add: g'_def)
from X have X_sub: "X ⊆ A" by auto
from X sub1 have fX_sub: "f ` X ⊆ B" by auto
show "?h ` A = B"
proof -
from X_sub have "?h ` A = ?h ` (X ∪ (A - X))" by auto
also have "… = ?h ` X ∪ ?h ` (A - X)" by (simp only: image_Un)
also have "?h ` X = f ` X" by auto
also from * have "?h ` (A - X) = B - (f ` X)" by auto
also from fX_sub have "f ` X ∪ (B - f ` X) = B" by blast
finally show ?thesis .
qed
show "inj_on ?h A"
proof -
from inj1 X_sub have on_X: "inj_on f X"
by (rule inj_on_subset)
have on_X_compl: "inj_on g' (A - X)"
unfolding g'_def X_compl
by (rule inj_on_the_inv_into) (rule inj2')
have impossible: False if eq: "f a = g' b" and a: "a ∈ X" and b: "b ∈ A - X" for a b
proof -
from a have fa: "f a ∈ f ` X" by (rule imageI)
from b have "g' b ∈ g' ` (A - X)" by (rule imageI)
with * have "g' b ∈ - (f ` X)" by simp
with eq fa show False by simp
qed
show ?thesis
proof (rule inj_onI)
fix a b
assume h: "?h a = ?h b"
assume "a ∈ A" and "b ∈ A"
then consider "a ∈ X" "b ∈ X" | "a ∈ A - X" "b ∈ A - X"
| "a ∈ X" "b ∈ A - X" | "a ∈ A - X" "b ∈ X"
by blast
then show "a = b"
proof cases
case 1
with h on_X show ?thesis by (simp add: inj_on_eq_iff)
next
case 2
with h on_X_compl show ?thesis by (simp add: inj_on_eq_iff)
next
case 3
with h impossible [of a b] have False by simp
then show ?thesis ..
next
case 4
with h impossible [of b a] have False by simp
then show ?thesis ..
qed
qed
qed
‹Lambda-abstractions with pattern matching:›
(ASCII)
"_lam_pats_syntax" :: "cases_syn → 'a → 'b" (‹(‹notation=abstraction›%_)› 10)
"_lam_pats_syntax" :: "cases_syn → 'a → 'b" (‹(‹notation=abstraction›λ_)› 10) ‹
let
fun fun_tr ctxt [cs] =
let
val x = Syntax.free (#1 (Name.variant "x" (Name.build_context (Term.declare_free_names cs))));
val ft = Case_Translation.case_tr true ctxt [x, cs];
in lambda x ft end
in [(syntax_const‹_lam_pats_syntax›, fun_tr)] end ›
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.41Angebot
¤
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.