diff --git a/thys/Decreasing-Diagrams-II/Decreasing_Diagrams_II_Aux.thy b/thys/Decreasing-Diagrams-II/Decreasing_Diagrams_II_Aux.thy --- a/thys/Decreasing-Diagrams-II/Decreasing_Diagrams_II_Aux.thy +++ b/thys/Decreasing-Diagrams-II/Decreasing_Diagrams_II_Aux.thy @@ -1,261 +1,261 @@ (* Title: Decreasing Diagrams II Author: Bertram Felgenhauer (2015) Maintainer: Bertram Felgenhauer License: LGPL or BSD License clarification: This file is also licensed under the BSD license to facilitate reuse and moving snippets from here to more suitable places. *) section \Preliminaries\ theory Decreasing_Diagrams_II_Aux imports Well_Quasi_Orders.Multiset_Extension Well_Quasi_Orders.Well_Quasi_Orders begin subsection \Trivialities\ (* move to Relation.thy? *) abbreviation "strict_order R \ irrefl R \ trans R" (* move to Relation.thy? *) lemma strict_order_strict: "strict_order q \ strict (\a b. (a, b) \ q\<^sup>=) = (\a b. (a, b) \ q)" unfolding trans_def irrefl_def by fast (* move to Wellfounded.thy? *) lemma mono_lex1: "mono (\r. lex_prod r s)" by (auto simp add: mono_def) (* move to Wellfounded.thy? *) lemma mono_lex2: "mono (lex_prod r)" by (auto simp add: mono_def) lemmas converse_inward = rtrancl_converse[symmetric] converse_Un converse_UNION converse_relcomp converse_converse converse_Id subsection \Complete lattices and least fixed points\ context complete_lattice begin subsubsection \A chain-based induction principle\ abbreviation set_chain :: "'a set \ bool" where "set_chain C \ \x \ C. \y \ C. x \ y \ y \ x" lemma lfp_chain_induct: assumes mono: "mono f" and step: "\x. P x \ P (f x)" and chain: "\C. set_chain C \ \ x \ C. P x \ P (Sup C)" shows "P (lfp f)" unfolding lfp_eq_fixp[OF mono] proof (rule fixp_induct) show "monotone (\) (\) f" using mono unfolding order_class.mono_def monotone_def . next show "P (Sup {})" using chain[of "{}"] by simp next show "ccpo.admissible Sup (\) P" by (auto simp add: chain ccpo.admissible_def Complete_Partial_Order.chain_def) qed fact subsubsection \Preservation of transitivity, asymmetry, irreflexivity by suprema\ lemma trans_Sup_of_chain: assumes "set_chain C" and trans: "\R. R \ C \ trans R" shows "trans (Sup C)" proof (intro transI) fix x y z assume "(x,y) \ Sup C" and "(y,z) \ Sup C" from \(x,y) \ Sup C\ obtain R where "R \ C" and "(x,y) \ R" by blast from \(y,z) \ Sup C\ obtain S where "S \ C" and "(y,z) \ S" by blast from \R \ C\ and \S \ C\ and \set_chain C\ have "R \ S = R \ R \ S = S" by blast with \R \ C\ and \S \ C\ have "R \ S \ C" by fastforce with \(x,y) \ R\ and \(y,z) \ S\ and trans[of "R \ S"] have "(x,z) \ R \ S" unfolding trans_def by blast with \R \ S \ C\ show "(x,z) \ \C" by blast qed lemma asym_Sup_of_chain: assumes "set_chain C" and asym: "\ R. R \ C \ asym R" shows "asym (Sup C)" proof (intro asymI notI) fix a b assume "(a,b) \ Sup C" then obtain "R" where "R \ C" and "(a,b) \ R" by blast assume "(b,a) \ Sup C" then obtain "S" where "S \ C" and "(b,a) \ S" by blast from \R \ C\ and \S \ C\ and \set_chain C\ have "R \ S = R \ R \ S = S" by blast with \R \ C\ and \S \ C\ have "R \ S \ C" by fastforce with \(a,b) \ R\ and \(b,a) \ S\ and asym[THEN asymD] show "False" by blast qed lemma strict_order_lfp: assumes "mono f" and "\R. strict_order R \ strict_order (f R)" shows "strict_order (lfp f)" proof (intro lfp_chain_induct[of f strict_order]) fix C :: "('b \ 'b) set set" assume "set_chain C" and "\R \ C. strict_order R" from this show "strict_order (Sup C)" - using asym_on_iff_irrefl_on_if_trans[of _ UNIV] + using asym_on_iff_irrefl_on_if_trans_on[of UNIV] by (metis asym_Sup_of_chain trans_Sup_of_chain) qed fact+ lemma trans_lfp: assumes "mono f" and "\R. trans R \ trans (f R)" shows "trans (lfp f)" by (metis lfp_chain_induct[of f trans] assms trans_Sup_of_chain) end (* complete_lattice *) subsection \Multiset extension\ lemma mulex_iff_mult: "mulex r M N \ (M,N) \ mult {(M,N) . r M N}" by (auto simp add: mulex_on_def restrict_to_def mult_def mulex1_def tranclp_unfold) lemma multI: assumes "trans r" "M = I + K" "N = I + J" "J \ {#}" "\k \ set_mset K. \j \ set_mset J. (k,j) \ r" shows "(M,N) \ mult r" using assms one_step_implies_mult by blast lemma multE: assumes "trans r" and "(M,N) \ mult r" obtains I J K where "M = I + K" "N = I + J" "J \ {#}" "\k \ set_mset K. \j \ set_mset J. (k,j) \ r" using mult_implies_one_step[OF assms] by blast lemma mult_on_union: "(M,N) \ mult r \ (K + M, K + N) \ mult r" using mulex_on_union[of "\x y. (x,y) \ r" UNIV] by (auto simp: mulex_iff_mult) lemma mult_on_union': "(M,N) \ mult r \ (M + K, N + K) \ mult r" using mulex_on_union'[of "\x y. (x,y) \ r" UNIV] by (auto simp: mulex_iff_mult) lemma mult_on_add_mset: "(M,N) \ mult r \ (add_mset k M, add_mset k N) \ mult r" unfolding add_mset_add_single[of k M] add_mset_add_single[of k N] by (rule mult_on_union') lemma mult_empty[simp]: "(M,{#}) \ mult R" by (metis mult_def not_less_empty trancl.cases) lemma mult_singleton[simp]: "(x, y) \ r \ (add_mset x M, add_mset y M) \ mult r" unfolding add_mset_add_single[of x M] add_mset_add_single[of y M] apply (rule mult_on_union) using mult1_singleton[of x y r] by (auto simp add: mult_def mult_on_union) lemma empty_mult[simp]: "({#},N) \ mult R \ N \ {#}" using empty_mulex_on[of N UNIV "\M N. (M,N) \ R"] by (auto simp add: mulex_iff_mult) lemma trans_mult: "trans (mult R)" unfolding mult_def by simp lemma strict_order_mult: assumes "irrefl R" and "trans R" shows "irrefl (mult R)" and "trans (mult R)" proof - show "irrefl (mult R)" unfolding irrefl_def proof (intro allI notI, elim multE[OF \trans R\]) fix M I J K assume "M = I + J" "M = I + K" "J \ {#}" and *: "\k \ set_mset K. \j \ set_mset J. (k, j) \ R" from \M = I + J\ and \M = I + K\ have "J = K" by simp have "finite (set_mset J)" by simp then have "set_mset J = {}" using * unfolding \J = K\ by (induct rule: finite_induct) (simp, metis assms insert_absorb insert_iff insert_not_empty irrefl_def transD) then show "False" using \J \ {#}\ by simp qed qed (simp add: trans_mult) lemma mult_of_image_mset: assumes "trans R" and "trans R'" and "\x y. x \ set_mset N \ y \ set_mset M \ (x,y) \ R \ (f x, f y) \ R'" and "(N, M) \ mult R" shows "(image_mset f N, image_mset f M) \ mult R'" proof (insert assms(4), elim multE[OF assms(1)]) fix I J K assume "N = I + K" "M = I + J" "J \ {#}" "\k \ set_mset K. \j \ set_mset J. (k, j) \ R" thus "(image_mset f N, image_mset f M) \ mult R'" using assms(2,3) by (intro multI) (auto, blast) qed subsection \Incrementality of @{term mult1} and @{term mult}\ lemma mono_mult1: "mono mult1" unfolding mono_def mult1_def by blast lemma mono_mult: "mono mult" unfolding mono_def mult_def proof (intro allI impI subsetI) fix R S :: "'a rel" and x assume "R \ S" and "x \ (mult1 R)\<^sup>+" then show "x \ (mult1 S)\<^sup>+" using mono_mult1[unfolded mono_def] trancl_mono[of x "mult1 R" "mult1 S"] by auto qed subsection \Well-orders and well-quasi-orders\ lemma wf_iff_wfp_on: "wf p \ wfp_on (\a b. (a, b) \ p) UNIV" unfolding wfp_on_iff_inductive_on wf_def inductive_on_def by force lemma well_order_implies_wqo: assumes "well_order r" shows "wqo_on (\a b. (a, b) \ r) UNIV" proof (intro wqo_onI almost_full_onI) show "transp (\a b. (a, b) \ r)" using assms by (auto simp only: well_order_on_def linear_order_on_def partial_order_on_def preorder_on_def trans_def transp_def) next fix f :: "nat \ 'a" show "good (\a b. (a, b) \ r) f" using assms unfolding well_order_on_def wf_iff_wfp_on wfp_on_def not_ex not_all de_Morgan_conj proof (elim conjE allE exE) fix x assume "linear_order r" and "f x \ UNIV \ (f (Suc x), f x) \ r - Id" then have "(f x, f (Suc x)) \ r" using \linear_order r\ by (force simp: linear_order_on_def Relation.total_on_def partial_order_on_def preorder_on_def refl_on_def) then show "good (\a b. (a, b) \ r) f" by (auto simp: good_def) qed qed subsection \Splitting lists into prefix, element, and suffix\ fun list_splits :: "'a list \ ('a list \ 'a \ 'a list) list" where "list_splits [] = []" | "list_splits (x # xs) = ([], x, xs) # map (\(xs, x', xs'). (x # xs, x', xs')) (list_splits xs)" lemma list_splits_empty[simp]: "list_splits xs = [] \ xs = []" by (cases xs) simp_all lemma elem_list_splits_append: assumes "(ys, y, zs) \ set (list_splits xs)" shows "ys @ [y] @ zs = xs" using assms by (induct xs arbitrary: ys) auto lemma elem_list_splits_length: assumes "(ys, y, zs) \ set (list_splits xs)" shows "length ys < length xs" and "length zs < length xs" using elem_list_splits_append[OF assms] by auto lemma elem_list_splits_elem: assumes "(xs, y, ys) \ set (list_splits zs)" shows "y \ set zs" using elem_list_splits_append[OF assms] by force lemma list_splits_append: "list_splits (xs @ ys) = map (\(xs', x', ys'). (xs', x', ys' @ ys)) (list_splits xs) @ map (\(xs', x', ys'). (xs @ xs', x', ys')) (list_splits ys)" by (induct xs) auto lemma list_splits_rev: "list_splits (rev xs) = map (\(xs, x, ys). (rev ys, x, rev xs)) (rev (list_splits xs))" by (induct xs) (auto simp add: list_splits_append comp_def prod.case_distrib rev_map) lemma list_splits_map: "list_splits (map f xs) = map (\(xs, x, ys). (map f xs, f x, map f ys)) (list_splits xs)" by (induct xs) auto end (* Decreasing_Diagrams_II_Aux *)