lemma partial_order_on_acyclic: assumes"partial_order_on A r" shows"acyclic (r - Id)" by (metis acyclic_irrefl assms irrefl_diff_Id partial_order_on_def preorder_on_def trancl_id trans_diff_Id)
lemma finite_Linear_order_induct[consumes 3, case_names step]: assumes"Linear_order r" assumes"x ∈ Field r" assumes"finite r" assumes step: "∧x. [x ∈ Field r; ∧y. y ∈ aboveS r x ==> P y]==> P x" shows"P x" using assms(2) proof(induct rule: wf_induct[of "r-1 - Id"]) from assms(1,3) show"wf (r-1 - Id)" using linear_order_on_well_order_on linear_order_on_converse unfolding well_order_on_def by blast next case (2 x) thenshow ?case by - (rule step; auto simp: aboveS_def intro: FieldI2) qed
text‹
sometimes want a notion of monotonicity over some set.
›
definition mono_on :: "'a::order set ==> ('a ==> 'b::order) ==> bool"where "mono_on A f = (∀x∈A. ∀y∈A. x ≤ y ⟶ f x ≤ f y)"
(*>*) subsection‹ MaxR: maximum elements of linear orders ›
text‹
generalize the existing @{const "max"} and @{const "Max"} functions
work on orders defined over sets. See \S\ref{sec:cf-linear} for
-function related lemmas.
›
locale MaxR = fixes r :: "'a::finite rel" assumes r_Linear_order: "Linear_order r" begin
text‹
basic function chooses the largest of two elements:
›
definition maxR :: "'a ==> 'a ==> 'a"where "maxR x y = (if (x, y) ∈ r then y else x)" (*<*)
lemma maxR_domain: shows"{x, y} ⊆ A ==> maxR x y ∈ A" unfolding maxR_def by simp
lemma maxR_range: shows"maxR x y ∈ {x, y}" unfolding maxR_def by simp
lemma maxR_rangeD: "maxR x y ≠ x ==> maxR x y = y" "maxR x y ≠ y ==> maxR x y = x" unfolding maxR_def by auto
lemma maxR_idem: shows"maxR x x = x" unfolding maxR_def by simp
lemma maxR_absorb2: shows"(x, y) ∈ r ==> maxR x y = y" unfolding maxR_def by simp
lemma maxR_absorb1: shows"(y, x) ∈ r ==> maxR x y = x" using r_Linear_order unfolding maxR_def by (simp add: order_on_defs antisym_def)
lemma maxR_assoc: shows"{x,y,z} ⊆ Field r ==> maxR (maxR x y) z = maxR x (maxR y z)" using r_Linear_order unfolding maxR_def by simp (metis order_on_defs(1-3) total_on_def trans_def)
lemma maxR_commute: shows"{x,y} ⊆ Field r ==> maxR x y = maxR y x" using r_Linear_order unfolding maxR_def by (fastforce simp: order_on_defs antisym_def total_on_def)
hoist this to finite sets using the @{const "Finite_Set.fold"}
. For code generation purposes it seems inevitable that we
to fuse the fold and filter into a single total recursive
.
›
definition MaxR_f :: "'a ==> 'a option ==> 'a option"where "MaxR_f x acc = (if x ∈ Field r then Some (case acc of None ==> x | Some y ==> maxR x y) else acc)"
lemma shows insert: "MaxR_opt (insert x A) = (if x ∈ Field r then Some (case MaxR_opt A of None ==> x | Some y ==> maxR x y) else MaxR_opt A)" and range_Some[rule_format]: "MaxR_opt A = Some a ⟶ a ∈ A ∩ Field r" using finite[of A] by induct (auto simp: MaxR_opt_eq_fold' maxR_def MaxR_f_def split: option.splits)
lemma range_None: assumes"MaxR_opt A = None" shows"A ∩ Field r = {}" using assms by (metis Int_iff insert all_not_in_conv insert_absorb option.simps(3))
lemma domain_empty: assumes"A ∩ Field r = {}" shows"MaxR_opt A = None" using assms by (metis empty_iff option.exhaust range_Some)
lemmadomain: shows"MaxR_opt (A ∩ Field r) = MaxR_opt A" using finite[of A] by induct (simp_all add: insert)
lemmas MaxR_opt_code = MaxR_opt_eq_fold'[where A="set A", unfolded MaxR_f.fold_set_fold] for A
lemma range: shows"MaxR_opt A ∈ Some ` (A ∩ Field r) ∪ {None}" using range_Some notin_range_Some by fastforce
lemma union: shows"MaxR_opt (A ∪ B) = (case MaxR_opt A of None ==> MaxR_opt B | Some mA ==> Some (case MaxR_opt B of None ==> mA | Some mB ==> maxR mA mB))" using finite[of A] by induct (auto simp: maxR_assoc insert dest!: range_Some split: option.splits)
lemma mono: assumes"MaxR_opt A = Some x" shows"∃y. MaxR_opt (A ∪ B) = Some y ∧ (x, y) ∈ r" using finite[of B] proof induct case empty with assms show ?case using range_Some underS_incl_iff[OF r_Linear_order] by fastforce next note ins = insert case (insert b B) with assms r_Linear_order show ?case unfolding order_on_defs total_on_def by (fastforce simp: ins maxR_def elim: transE intro: FieldI1) qed
declare [[simproc del: eliminate_false_implies]]
lemma MaxR_opt_is_greatest: assumes"MaxR_opt A = Some x" assumes"y ∈ A ∩ Field r" shows"(y, x) ∈ r" using finite[of A] assms proof(induct arbitrary: x) note ins = insert case (insert a A) show ?case proof (cases "y = x") case True thus"(y, x) ∈ r" using r_Linear_order insert by (auto simp: order_on_defs refl_on_def) next case False show"(y, x) ∈ r" proof (rule ccontr) assume"(y, x) ∉ r" from insert have"x ∈ Field r""y ∈ Field r" by (auto simp: maxR_def ins dest!: range_None range_Some split: if_splits option.splits) from‹(y, x) ∉ r›and‹y ≠ x›and insert obtain z where z: "(x, z) ∉ r""(y, z) ∈ r""z ∈Field r" by (auto simp: maxR_def ins dest!: range_None range_Some split: if_splits option.splits) have"(x, y) ∈ r" using r_Linear_order ‹(y, x) ∉ r›‹x ∈ Field r›‹y ∈ Field r›‹y ≠ x› by (auto simp: order_on_defs total_on_def) have"trans r" using r_Linear_order by (auto simp: order_on_defs) from this and‹(x, y) ∈ r›and‹(y, z) ∈ r›have"(x, z) ∈ r" by (rule transD) with‹(x, z) ∉ r›show False by contradiction qed qed qed simp
lemma greatest_is_MaxR_opt: assumes"x ∈ A ∩ Field r" assumes"∀y ∈ A ∩ Field r. (y, x) ∈ r" shows"MaxR_opt A = Some x" using finite[of A] assms proof(induct arbitrary: x) note ins = insert case (insert a A) thenshow ?case using maxR_absorb1 maxR_absorb2 by (fastforce simp: maxR_def ins dest: range_None range_Some split: option.splits) qed simp
lemma subset: assumes"set_option (MaxR_opt B) ⊆ A" assumes"A ⊆ B" shows"MaxR_opt B = MaxR_opt A" using union[where A=A and B="B-A"] range[of "B - A"] assms by (auto simp: Un_absorb1 finite_subset maxR_def split: option.splits)
(*>*)
end
interpretation MaxR_empty: MaxR "{}" by unfold_locales simp
interpretation MaxR_singleton: MaxR "{(x,x)}"for x by unfold_locales simp
lemma MaxR_r_domain [iff]: assumes"MaxR r" shows"MaxR (Restr r A)" using assms Linear_order_Restr unfolding MaxR_def by blast
subsection‹ Linear orders from lists ›
text‹
the easiest way to specify a concrete linear order is with a
. Here these run from greatest to least.
›
primrec linord_of_listP :: "'a ==> 'a ==> 'a list ==> bool"where "linord_of_listP x y [] ⟷ False"
| "linord_of_listP x y (z # zs) ⟷ (z = y ∧ x ∈ set (z # zs)) ∨ linord_of_listP x y zs"
definition linord_of_list :: "'a list ==> 'a rel"where "linord_of_list xs ≡ {(x, y). linord_of_listP x y xs}"
lemma linord_of_list_singleton: "(x, y) ∈ linord_of_list [z] ⟷ x = z ∧ y = z" by (force simp: linord_of_list_linord_of_listP)
lemma linord_of_list_range: "linord_of_list xs ⊆ set xs × set xs" unfolding linord_of_list_def by (induct xs) auto
lemma linord_of_list_Field [simp]: "Field (linord_of_list xs) = set xs" unfolding linord_of_list_def by (induct xs) (auto simp: Field_def)
lemma linord_of_listP_append: "linord_of_listP x y (xs @ ys) ⟷ linord_of_listP x y xs ∨ linord_of_listP x y ys∨ (y ∈ set xs ∧ x ∈ set ys)" by (induct xs) auto
lemma linord_of_list_append: "(x, y) ∈ linord_of_list (xs @ ys) ⟷ (x, y) ∈ linord_of_list xs ∨ (x, y) ∈ linord_of_list ys ∨ (y ∈ set xs ∧ x ∈ set ys)" unfolding linord_of_list_def by (simp add: linord_of_listP_append)
lemma linord_of_list_total_on: shows"total_on (set xs) (linord_of_list xs)" unfolding total_on_def linord_of_list_def by (induct xs) auto
lemma linord_of_list_Restr: assumes"x ∉ C" notes in_set_remove1[simp del] (* suppress warning *) shows"Restr (linord_of_list (remove1 x xs)) C = Restr (linord_of_list xs) C" using assms unfolding linord_of_list_def by (induct xs) (auto iff: in_set_remove1)
lemma linord_of_list_nth: assumes"(xs ! i, xs ! j) ∈ linord_of_list xs" assumes"i < length xs""j < length xs" assumes"distinct xs" shows"j ≤ i" using %invisible assms proof(induct xs arbitrary: i j) case (Cons x xs i j) show ?case proof(cases "i < length xs") case True with Cons show ?thesis by (auto simp: linord_of_list_linord_of_listP nth_equal_first_eq less_Suc_eq_0_disj linord_of_listP_domain) next case False with Cons show ?thesis by fastforce qed qed simp
(*>*) text‹›
lemma linord_of_list_Linear_order: assumes"distinct xs" assumes"ys = set xs" shows"linear_order_on ys (linord_of_list xs)" using %invisible assms linord_of_list_range linord_of_list_refl_on linord_of_list_trans linord_of_list_antisym linord_of_list_total_on unfolding order_on_defs by force
text‹
finite linear order is generated by a list.
›
(*<*)
inductive sorted_on :: "'a rel ==> 'a list ==> bool"where
Nil [iff]: "sorted_on r []"
| Cons [intro!]: "[x ∈ Field r; ∀y∈set xs. (x, y) ∈ r; sorted_on r xs]==> sorted_on r (x # xs)"
inductive_cases sorted_on_inv[elim!]: "sorted_on r []" "sorted_on r (x # xs)"
primrec insort_key_on :: "'a rel ==> ('b ==> 'a) ==> 'b ==> 'b list ==> 'b list"where "insort_key_on r f x [] = [x]"
| "insort_key_on r f x (y # ys) = (if (f x, f y) ∈ r then (x # y # ys) else y # insort_key_on r f x ys)"
definition sort_key_on :: "'a rel ==> ('b ==> 'a) ==> 'b list ==> 'b list"where "sort_key_on r f xs = foldr (insort_key_on r f) xs []"
definition insort_insert_key_on :: "'a rel ==> ('b ==> 'a) ==> 'b ==> 'b list ==> 'b list"where "insort_insert_key_on r f x xs = (if f x ∈ f ` set xs then xs else insort_key_on r f x xs)"
abbreviation"sort_on r ≡ sort_key_on r (λx. x)" abbreviation"insort_on r ≡ insort_key_on r (λx. x)" abbreviation"insort_insert_on r ≡ insort_insert_key_on r (λx. x)"
context fixes r :: "'a rel" assumes"Linear_order r" begin
lemma sorted_on_single [iff]: shows"sorted_on r [x] ⟷ x ∈ Field r" by (metis empty_iff list.distinct(1) list.set(1) nth_Cons_0 sorted_on.simps)
lemma sorted_on_many: assumes"(x, y) ∈ r" assumes"sorted_on r (y # zs)" shows"sorted_on r (x # y # zs)" using assms ‹Linear_order r›unfolding order_on_defs by (auto elim: transE intro: FieldI1)
lemma sorted_on_Cons: shows"sorted_on r (x # xs) ⟷ (x ∈ Field r ∧ sorted_on r xs ∧ (∀y∈set xs. (x, y) ∈ r))" using‹Linear_order r›unfolding order_on_defs by (induct xs arbitrary: x) (auto elim: transE)
lemma sorted_on_distinct_set_unique: assumes"sorted_on r xs""distinct xs""sorted_on r ys""distinct ys""set xs = set ys" shows"xs = ys" proof - from assms have1: "length xs = length ys"by (auto dest!: distinct_card) from assms show ?thesis proof(induct rule: list_induct2[OF 1]) case (2 x xs y ys) with‹Linear_order r›show ?case unfolding order_on_defs by (simp add: sorted_on_Cons) (metis antisymD insertI1 insert_eq_iff) qed simp qed
lemma set_insort_on: shows"set (insort_key_on r f x xs) = insert x (set xs)" by (induct xs) auto
lemma sort_key_on_simps [simp]: shows"sort_key_on r f [] = []" "sort_key_on r f (x#xs) = insort_key_on r f x (sort_key_on r f xs)" by (simp_all add: sort_key_on_def)
lemma set_sort_on [simp]: shows"set (sort_key_on r f xs) = set xs" by (induct xs) (simp_all add: set_insort_on)
lemma distinct_insort_on: shows"distinct (insort_key_on r f x xs) = (x ∉ set xs ∧ distinct xs)" by(induct xs) (auto simp: set_insort_on)
lemma distinct_sort_on [simp]: shows"distinct (sort_key_on r f xs) = distinct xs" by (induct xs) (simp_all add: distinct_insort_on)
lemma sorted_on_insort_key_on: assumes"f ` set (x # xs) ⊆ Field r" shows"sorted_on r (map f (insort_key_on r f x xs)) = sorted_on r (map f xs)" using assms proof(induct xs) case (Cons x xs) with‹Linear_order r›show ?case unfolding order_on_defs by (auto 44 simp: sorted_on_Cons sorted_on_many set_insort_on refl_on_def total_on_def elim: transE) qed simp
lemma sorted_on_insort_on: assumes"set (x # xs) ⊆ Field r" shows"sorted_on r (insort_on r x xs) = sorted_on r xs" using sorted_on_insort_key_on[where f="λx. x"] assms by simp
theorem sorted_on_sort_key_on [simp]: assumes"f ` set xs ⊆ Field r" shows"sorted_on r (map f (sort_key_on r f xs))" using assms by (induct xs) (simp_all add: sorted_on_insort_key_on)
theorem sorted_on_sort_on [simp]: assumes"set xs ⊆ Field r" shows"sorted_on r (sort_on r xs)" using sorted_on_sort_key_on[where f="λx. x"] assms by simp
lemma finite_sorted_on_distinct_unique: assumes"A ⊆ Field r" assumes"finite A" shows"∃!xs. set xs = A ∧ sorted_on r xs ∧ distinct xs" proof - from‹finite A›obtain xs where"set xs = A ∧ distinct xs" using finite_distinct_list by blast with‹A ⊆ Field r›show ?thesis by (fastforce intro!: ex1I[where a="sort_on r xs"] simp: sorted_on_distinct_set_unique) qed
end
lemma sorted_on_linord_of_list_subseteq_r: assumes"Linear_order r" assumes"sorted_on r xs" assumes"distinct xs" shows"linord_of_list (rev xs) ⊆ r" using assms proof(induct xs) case (Cons x xs) thenhave"linord_of_list (rev xs) ⊆ r"by (simp add: sorted_on_Cons) with Cons.prems show ?case by (clarsimp simp: linord_of_list_append linord_of_list_singleton sorted_on_Cons)
(meson contra_subsetD subsetI underS_incl_iff) qed simp
lemma sorted_on_linord_of_list: assumes"Linear_order r" assumes"set xs = Field r" assumes"sorted_on r xs" assumes"distinct xs" shows"linord_of_list (rev xs) = r" proof(rule equalityI) from assms show"linord_of_list (rev xs) ⊆ r" using sorted_on_linord_of_list_subseteq_r by blast next
{ fix x y assume xy: "(x, y) ∈ r" with‹Linear_order r›have"(y, x) ∉ r - Id" using Linear_order_in_diff_Id by (fastforce intro: FieldI1) with linord_of_list_Linear_order[of "rev xs""Field r"] assms xy have"(x, y) ∈ linord_of_list (rev xs)" by simp (metis Diff_subset FieldI1 FieldI2 Linear_order_in_diff_Id linord_of_list_Field set_rev sorted_on_linord_of_list_subseteq_r subset_eq) } thenshow"r ⊆ linord_of_list (rev xs)"by clarsimp qed
lemma linord_of_listP_rev: assumes"z # zs ∈ set (subseqs xs)" assumes"y ∈ set zs" shows"linord_of_listP z y (rev xs)" using assms by (induct xs) (auto simp: Let_def linord_of_listP_append dest: subseqs_set)
lemma linord_of_list_sorted_on_subseqs: assumes"ys ∈ set (subseqs xs)" assumes"distinct xs" shows"sorted_on (linord_of_list (rev xs)) ys" using assms proof(induct ys) case (Cons y ys) thenshow ?case using linord_of_list_Linear_order[where xs="rev xs"and ys="Field (linord_of_list (rev xs))"] by (force simp: Cons_in_subseqsD sorted_on_Cons linord_of_list_linord_of_listP linord_of_listP_rev dest: subseqs_set) qed simp
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.