class enum = fixes enum :: "'a list" fixes enum_all :: "('a \ bool) \ bool" fixes enum_ex :: "('a \ bool) \ bool" assumes UNIV_enum: "UNIV = set enum" and enum_distinct: "distinct enum" assumes enum_all_UNIV: "enum_all P \ Ball UNIV P" assumes enum_ex_UNIV: "enum_ex P \ Bex UNIV P" \<comment> \<open>tailored towards simple instantiation\<close> begin
subclass finite proof qed (simp add: UNIV_enum)
lemma enum_UNIV: "set enum = UNIV" by (simp only: UNIV_enum)
lemma in_enum: "x \ set enum" by (simp add: enum_UNIV)
lemma enum_eq_I: assumes"\x. x \ set xs" shows"set enum = set xs" proof - from assms UNIV_eq_I have"UNIV = set xs"by auto with enum_UNIV show ?thesis by simp qed
lemma card_UNIV_length_enum: "card (UNIV :: 'a set) = length enum" by (simp add: UNIV_enum distinct_card enum_distinct)
lemma [code]: "The P = (case filter P enum of [x] \ x | _ \ enum_the P)" proof -
{ fix a assume filter_enum: "filter P enum = [a]" have"The P = a" proof (rule the_equality) fix x assume"P x" show"x = a" proof (rule ccontr) assume"x \ a" from filter_enum obtain us vs where enum_eq: "enum = us @ [a] @ vs" and"\ x \ set us. \ P x" and"\ x \ set vs. \ P x" and"P a" by (auto simp add: filter_eq_Cons_iff) (simp only: filter_empty_conv[symmetric]) with\<open>P x\<close> in_enum[of x, unfolded enum_eq] \<open>x \<noteq> a\<close> show "False" by auto qed next from filter_enum show"P a"by (auto simp add: filter_eq_Cons_iff) qed
} from this show ?thesis unfolding enum_the_def by (auto split: list.split) qed
subsubsection \<open>Equality and order on functions\<close>
instantiation"fun" :: (enum, equal) equal begin
definition "HOL.equal f g \ (\x \ set enum. f x = g x)"
instanceproof qed (simp_all add: equal_fun_def fun_eq_iff enum_UNIV)
end
lemma [code]: "HOL.equal f g \ enum_all (%x. f x = g x)" by (auto simp add: equal fun_eq_iff)
lemma [code nbe]: "HOL.equal (f :: _ \ _) f \ True" by (fact equal_refl)
lemma order_fun [code]: fixes f g :: "'a::enum \ 'b::order" shows"f \ g \ enum_all (\x. f x \ g x)" and"f < g \ f \ g \ enum_ex (\x. f x \ g x)" by (simp_all add: fun_eq_iff le_fun_def order_less_le)
subsubsection \<open>Operations on relations\<close>
primrec bacc :: "('a \ 'a) set \ nat \ 'a set" where "bacc r 0 = {x. \ y. (y, x) \ r}"
| "bacc r (Suc n) = (bacc r n \ {x. \y. (y, x) \ r \ y \ bacc r n})"
lemma bacc_subseteq_acc: "bacc r n \ Wellfounded.acc r" by (induct n) (auto intro: acc.intros)
lemma bacc_mono: "n \ m \ bacc r n \ bacc r m" by (induct rule: dec_induct) auto
lemma bacc_upper_bound: "bacc (r :: ('a \ 'a) set) (card (UNIV :: 'a::finite set)) = (\n. bacc r n)" proof - have"mono (bacc r)"unfolding mono_def by (simp add: bacc_mono) moreoverhave"\n. bacc r n = bacc r (Suc n) \ bacc r (Suc n) = bacc r (Suc (Suc n))" by auto moreoverhave"finite (range (bacc r))"by auto ultimatelyshow ?thesis by (intro finite_mono_strict_prefix_implies_finite_fixpoint)
(auto intro: finite_mono_remains_stable_implies_strict_prefix) qed
lemma acc_subseteq_bacc: assumes"finite r" shows"Wellfounded.acc r \ (\n. bacc r n)" proof fix x assume"x \ Wellfounded.acc r" thenhave"\n. x \ bacc r n" proof (induct x arbitrary: rule: acc.induct) case (accI x) thenhave"\y. \ n. (y, x) \ r \ y \ bacc r n" by simp from choice[OF this] obtain n where n: "\y. (y, x) \ r \ y \ bacc r (n y)" .. obtain n where"\y. (y, x) \ r \ y \ bacc r n" proof fix y assume y: "(y, x) \ r" with n have"y \ bacc r (n y)" by auto moreoverhave"n y <= Max ((\(y, x). n y) ` r)" using y \<open>finite r\<close> by (auto intro!: Max_ge) note bacc_mono[OF this, of r] ultimatelyshow"y \ bacc r (Max ((\(y, x). n y) ` r))" by auto qed thenshow ?case by (auto simp add: Let_def intro!: exI[of _ "Suc n"]) qed thenshow"x \ (\n. bacc r n)" by auto qed
lemma acc_bacc_eq: fixes A :: "('a :: finite \ 'a) set" assumes"finite A" shows"Wellfounded.acc A = bacc A (card (UNIV :: 'a set))" using assms by (metis acc_subseteq_bacc bacc_subseteq_acc bacc_upper_bound order_eq_iff)
subsection \<open>Default instances for \<^class>\<open>enum\<close>\<close>
lemma map_of_zip_enum_is_Some: assumes"length ys = length (enum :: 'a::enum list)" shows"\y. map_of (zip (enum :: 'a::enum list) ys) x = Some y" proof - from assms have"x \ set (enum :: 'a::enum list) \
(\<exists>y. map_of (zip (enum :: 'a::enum list) ys) x = Some y)" by (auto intro!: map_of_zip_is_Some) thenshow ?thesis using enum_UNIV by auto qed
lemma map_of_zip_enum_inject: fixes xs ys :: "'b::enum list" assumes length: "length xs = length (enum :: 'a::enum list)" "length ys = length (enum :: 'a::enum list)" and map_of: "the \ map_of (zip (enum :: 'a::enum list) xs) = the \ map_of (zip (enum :: 'a::enum list) ys)" shows"xs = ys" proof - have"map_of (zip (enum :: 'a list) xs) = map_of (zip (enum :: 'a list) ys)" proof fix x :: 'a from length map_of_zip_enum_is_Some obtain y1 y2 where"map_of (zip (enum :: 'a list) xs) x = Some y1" and"map_of (zip (enum :: 'a list) ys) x = Some y2"by blast moreoverfrom map_of have"the (map_of (zip (enum :: 'a::enum list) xs) x) = the (map_of (zip (enum :: 'a::enum list) ys) x)" by (auto dest: fun_cong) ultimatelyshow"map_of (zip (enum :: 'a::enum list) xs) x = map_of (zip (enum :: 'a::enum list) ys) x" by simp qed with length enum_distinct show"xs = ys"by (rule map_of_zip_inject) qed
definition all_n_lists :: "(('a :: enum) list \ bool) \ nat \ bool" where "all_n_lists P n \ (\xs \ set (List.n_lists n enum). P xs)"
lemma [code]: "all_n_lists P n \ (if n = 0 then P [] else enum_all (%x. all_n_lists (%xs. P (x # xs)) (n - 1)))" unfolding all_n_lists_def enum_all by (cases n) (auto simp add: enum_UNIV)
definition ex_n_lists :: "(('a :: enum) list \ bool) \ nat \ bool" where "ex_n_lists P n \ (\xs \ set (List.n_lists n enum). P xs)"
lemma [code]: "ex_n_lists P n \ (if n = 0 then P [] else enum_ex (%x. ex_n_lists (%xs. P (x # xs)) (n - 1)))" unfolding ex_n_lists_def enum_ex by (cases n) (auto simp add: enum_UNIV)
definition "enum_all P = all_n_lists (\bs. P (the \ map_of (zip enum bs))) (length (enum :: 'a list))"
definition "enum_ex P = ex_n_lists (\bs. P (the \ map_of (zip enum bs))) (length (enum :: 'a list))"
instanceproof show"UNIV = set (enum :: ('a \ 'b) list)" proof (rule UNIV_eq_I) fix f :: "'a \ 'b" have"f = the \ map_of (zip (enum :: 'a::enum list) (map f enum))" by (auto simp add: map_of_zip_map fun_eq_iff intro: in_enum) thenshow"f \ set enum" by (auto simp add: enum_fun_def set_n_lists intro: in_enum) qed next from map_of_zip_enum_inject show"distinct (enum :: ('a \ 'b) list)" by (auto intro!: inj_onI simp add: enum_fun_def
distinct_map distinct_n_lists enum_distinct set_n_lists) next fix P show"enum_all (P :: ('a \ 'b) \ bool) = Ball UNIV P" proof assume"enum_all P" show"Ball UNIV P" proof fix f :: "'a \ 'b" have f: "f = the \ map_of (zip (enum :: 'a::enum list) (map f enum))" by (auto simp add: map_of_zip_map fun_eq_iff intro: in_enum) from\<open>enum_all P\<close> have "P (the \<circ> map_of (zip enum (map f enum)))" unfolding enum_all_fun_def all_n_lists_def apply (simp add: set_n_lists) apply (erule_tac x="map f enum"in allE) apply (auto intro!: in_enum) done from this f show"P f"by auto qed next assume"Ball UNIV P" from this show"enum_all P" unfolding enum_all_fun_def all_n_lists_def by auto qed next fix P show"enum_ex (P :: ('a \ 'b) \ bool) = Bex UNIV P" proof assume"enum_ex P" from this show"Bex UNIV P" unfolding enum_ex_fun_def ex_n_lists_def by auto next assume"Bex UNIV P" from this obtain f where"P f" .. have f: "f = the \ map_of (zip (enum :: 'a::enum list) (map f enum))" by (auto simp add: map_of_zip_map fun_eq_iff intro: in_enum) from\<open>P f\<close> this have "P (the \<circ> map_of (zip (enum :: 'a::enum list) (map f enum)))" by auto from this show"enum_ex P" unfolding enum_ex_fun_def ex_n_lists_def apply (auto simp add: set_n_lists) apply (rule_tac x="map f enum"in exI) apply (auto intro!: in_enum) done qed qed
definition "enum_all P \ P a\<^sub>1 \ P a\<^sub>2 \ P a\<^sub>3"
definition "enum_ex P \ P a\<^sub>1 \ P a\<^sub>2 \ P a\<^sub>3"
instanceproof qed (simp_all only: enum_finite_3_def enum_all_finite_3_def enum_ex_finite_3_def UNIV_finite_3, simp_all)
end
lemma finite_3_not_eq_unfold: "x \ a\<^sub>1 \ x \ {a\<^sub>2, a\<^sub>3}" "x \ a\<^sub>2 \ x \ {a\<^sub>1, a\<^sub>3}" "x \ a\<^sub>3 \ x \ {a\<^sub>1, a\<^sub>2}" by (cases x; simp)+
instantiation finite_3 :: linorder begin
definition less_finite_3 :: "finite_3 \ finite_3 \ bool" where "x < y = (case x of a\<^sub>1 \ y \ a\<^sub>1 | a\<^sub>2 \ y = a\<^sub>3 | a\<^sub>3 \ False)"
definition less_eq_finite_3 :: "finite_3 \ finite_3 \ bool" where "x \ y \ x = y \ x < (y :: finite_3)"
instanceproof (intro_classes) qed (auto simp add: less_finite_3_def less_eq_finite_3_def split: finite_3.split_asm)
end
instance finite_3 :: wellorder proof(rule wf_wellorderI) have"inv_image less_than (case_finite_3 0 1 2) = {(x, y). x < y}" by(auto simp add: less_finite_3_def split: finite_3.splits) from this[symmetric] show"wf \" by simp qed intro_classes
class finite_lattice = finite + lattice + Inf + Sup + bot + top + assumes Inf_finite_empty: "Inf {} = Sup UNIV" assumes Inf_finite_insert: "Inf (insert a A) = a \ Inf A" assumes Sup_finite_empty: "Sup {} = Inf UNIV" assumes Sup_finite_insert: "Sup (insert a A) = a \ Sup A" assumes bot_finite_def: "bot = Inf UNIV" assumes top_finite_def: "top = Sup UNIV" begin
subclass complete_lattice proof fix x A show"x \ A \ \A \ x" by (metis Set.set_insert abel_semigroup.commute local.Inf_finite_insert local.inf.abel_semigroup_axioms local.inf.left_idem local.inf.orderI) show"x \ A \ x \ \A" by (metis Set.set_insert insert_absorb2 local.Sup_finite_insert local.sup.absorb_iff2) next fix A z have"\ UNIV = z \ \UNIV" by (subst Sup_finite_insert [symmetric], simp add: insert_UNIV) from this have [simp]: "z \ \UNIV" usinglocal.le_iff_sup by auto have"(\ x. x \ A \ z \ x) \ z \ \A" by (rule finite_induct [of A "\ A . (\ x. x \ A \ z \ x) \ z \ \A"])
(simp_all add: Inf_finite_empty Inf_finite_insert) from this show"(\x. x \ A \ z \ x) \ z \ \A" by simp
have"\ UNIV = z \ \UNIV" by (subst Inf_finite_insert [symmetric], simp add: insert_UNIV) from this have [simp]: "\UNIV \ z" by (simp add: local.inf.absorb_iff2) have"(\ x. x \ A \ x \ z) \ \A \ z" by (rule finite_induct [of A "\ A . (\ x. x \ A \ x \ z) \ \A \ z" ], simp_all add: Sup_finite_empty Sup_finite_insert) from this show" (\x. x \ A \ x \ z) \ \A \ z" by blast next show"\{} = \" by (simp add: Inf_finite_empty top_finite_def) show" \{} = \" by (simp add: Sup_finite_empty bot_finite_def) qed end
class finite_distrib_lattice = finite_lattice + distrib_lattice begin lemma finite_inf_Sup: "a \ (Sup A) = Sup {a \ b | b . b \ A}" proof (rule finite_induct [of A "\ A . a \ (Sup A) = Sup {a \ b | b . b \ A}"], simp_all) fix x::"'a" fix F assume"x \ F" assume [simp]: "a \ \F = \{a \ b |b. b \ F}" have [simp]: " insert (a \ x) {a \ b |b. b \ F} = {a \ b |b. b = x \ b \ F}" by blast have"a \ (x \ \F) = a \ x \ a \ \F" by (simp add: inf_sup_distrib1) alsohave"... = a \ x \ \{a \ b |b. b \ F}" by simp alsohave"... = \{a \ b |b. b = x \ b \ F}" by (unfold Sup_insert[THEN sym], simp) finallyshow"a \ (x \ \F) = \{a \ b |b. b = x \ b \ F}" by simp qed
lemma finite_Inf_Sup: "\(Sup ` A) \ \(Inf ` {f ` A |f. \Y\A. f Y \ Y})" proof (rule finite_induct [of A "\A. \(Sup ` A) \ \(Inf ` {f ` A |f. \Y\A. f Y \ Y})"], simp_all add: finite_UnionD) fix x::"'a set" fix F assume"x \ F" have [simp]: "{\x \ b |b . b \ Inf ` {f ` F |f. \Y\F. f Y \ Y} } = {\x \ (Inf (f ` F)) |f . (\Y\F. f Y \ Y)}" by auto
define fa where"fa = (\ (b::'a) f Y . (if Y = x then b else f Y))" have"\f b. \Y\F. f Y \ Y \ b \ x \ insert b (f ` (F \ {Y. Y \ x})) = insert (fa b f x) (fa b f ` F) \ fa b f x \ x \ (\Y\F. fa b f Y \ Y)" by (auto simp add: fa_def) from this have B: "\f b. \Y\F. f Y \ Y \ b \ x \ fa b f ` ({x} \ F) \ {insert (f x) (f ` F) |f. f x \ x \ (\Y\F. f Y \ Y)}" by blast have [simp]: "\f b. \Y\F. f Y \ Y \ b \ x \ b \ (\x\F. f x) \ \(Inf ` {insert (f x) (f ` F) |f. f x \ x \ (\Y\F. f Y \ Y)})" using B apply (rule SUP_upper2) using\<open>x \<notin> F\<close> apply (simp_all add: fa_def Inf_union_distrib) apply (simp add: image_mono Inf_superset_mono inf.coboundedI2) done assume"\(Sup ` F) \ \(Inf ` {f ` F |f. \Y\F. f Y \ Y})"
from this have"\x \ \(Sup ` F) \ \x \ \(Inf ` {f ` F |f. \Y\F. f Y \ Y})" using inf.coboundedI2 by auto alsohave"... = Sup {\x \ (Inf (f ` F)) |f . (\Y\F. f Y \ Y)}" by (simp add: finite_inf_Sup)
alsohave"... = Sup {Sup {Inf (f ` F) \ b | b . b \ x} |f . (\Y\F. f Y \ Y)}" by (subst inf_commute) (simp add: finite_inf_Sup)
alsohave"... \ \(Inf ` {insert (f x) (f ` F) |f. f x \ x \ (\Y\F. f Y \ Y)})" apply (rule Sup_least, clarsimp)+ apply (subst inf_commute, simp) done
finallyshow"\x \ \(Sup ` F) \ \(Inf ` {insert (f x) (f ` F) |f. f x \ x \ (\Y\F. f Y \ Y)})" by simp qed
subclass complete_distrib_lattice by (standard, rule finite_Inf_Sup) end
instantiation finite_3 :: finite_lattice begin
definition"\A = (if a\<^sub>1 \ A then a\<^sub>1 else if a\<^sub>2 \ A then a\<^sub>2 else a\<^sub>3)" definition"\A = (if a\<^sub>3 \ A then a\<^sub>3 else if a\<^sub>2 \ A then a\<^sub>2 else a\<^sub>1)" definition [simp]: "bot = a\<^sub>1" definition [simp]: "top = a\<^sub>3" definition [simp]: "inf = (min :: finite_3 \ _)" definition [simp]: "sup = (max :: finite_3 \ _)"
instance proof qed (auto simp add: Inf_finite_3_def Sup_finite_3_def max_def min_def less_eq_finite_3_def less_finite_3_def split: finite_3.split) end
lemma dvd_finite_3_unfold: "x dvd y \ x = a\<^sub>2 \ x = a\<^sub>3 \ y = a\<^sub>1" by (cases x) (auto simp add: dvd_def times_finite_3_def split: finite_3.splits)
instantiation finite_3 :: "{normalization_semidom, unique_euclidean_semiring}"begin definition [simp]: "normalize x = (case x of a\<^sub>3 \ a\<^sub>2 | _ \ x)" definition [simp]: "unit_factor = (id :: finite_3 \ _)" definition [simp]: "euclidean_size x = (case x of a\<^sub>1 \ 0 | _ \ 1)" definition [simp]: "division_segment (x :: finite_3) = 1" instance proof fix x :: finite_3 assume"x \ 0" thenshow"is_unit (unit_factor x)" by (cases x) (simp_all add: dvd_finite_3_unfold) qed
(subproofs \<open>auto simp add: divide_finite_3_def times_finite_3_def
dvd_finite_3_unfold inverse_finite_3_def plus_finite_3_def
split: finite_3.splits\<close>) end
definition "enum_all P \ P a\<^sub>1 \ P a\<^sub>2 \ P a\<^sub>3 \ P a\<^sub>4"
definition "enum_ex P \ P a\<^sub>1 \ P a\<^sub>2 \ P a\<^sub>3 \ P a\<^sub>4"
instanceproof qed (simp_all only: enum_finite_4_def enum_all_finite_4_def enum_ex_finite_4_def UNIV_finite_4, simp_all)
end
instantiation finite_4 :: finite_distrib_lattice begin
text\<open>\<^term>\<open>a\<^sub>1\<close> $<$ \<^term>\<open>a\<^sub>2\<close>,\<^term>\<open>a\<^sub>3\<close> $<$ \<^term>\<open>a\<^sub>4\<close>,
but \<^term>\<open>a\<^sub>2\<close> and \<^term>\<open>a\<^sub>3\<close> are incomparable.\<close>
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 ist noch experimentell.