diff --git a/thys/Weighted_Path_Order/Multiset_Extension2.thy b/thys/Weighted_Path_Order/Multiset_Extension2.thy --- a/thys/Weighted_Path_Order/Multiset_Extension2.thy +++ b/thys/Weighted_Path_Order/Multiset_Extension2.thy @@ -1,710 +1,710 @@ section \Multiset extension of order pairs in the other direction\ -text \Many term orders are formulated in the other direction, i.e., they use +text \Many term orders are formulated in the other direction, i.e., they use strong normalization of $>$ instead of well-foundedness of $<$. Here, we flip the direction of the multiset extension of two orders, connect it to existing interfaces, and prove some further properties of the multiset extension.\ theory Multiset_Extension2 imports List_Order Multiset_Extension_Pair begin subsection \List based characterization of @{const multpw}\ lemma multpw_listI: assumes "length xs = length ys" "X = mset xs" "Y = mset ys" "\i. i < length ys \ (xs ! i, ys ! i) \ ns" shows "(X, Y) \ multpw ns" using assms proof (induct xs arbitrary: ys X Y) case (Nil ys) then show ?case by (cases ys) (auto intro: multpw.intros) next case Cons1: (Cons x xs ys' X Y) then show ?case proof (cases ys') case (Cons y ys) then have "\i. i < length ys \ (xs ! i, ys ! i) \ ns" using Cons1(5) by fastforce then show ?thesis using Cons1(2,5) by (auto intro!: multpw.intros simp: Cons(1) Cons1) qed auto qed lemma multpw_listE: assumes "(X, Y) \ multpw ns" obtains xs ys where "length xs = length ys" "X = mset xs" "Y = mset ys" "\i. i < length ys \ (xs ! i, ys ! i) \ ns" using assms proof (induct X Y arbitrary: thesis rule: multpw.induct) case (add x y X Y) then obtain xs ys where "length xs = length ys" "X = mset xs" "Y = mset ys" "(\i. i < length ys \ (xs ! i, ys ! i) \ ns)" by blast then show ?case using add(1) by (intro add(4)[of "x # xs" "y # ys"]) (auto, case_tac i, auto) qed auto subsection\Definition of the multiset extension of $>$-orders\ -text\We define here the non-strict extension of the order pair $(\geqslant, >)$ -- +text\We define here the non-strict extension of the order pair $(\geqslant, >)$ -- usually written as (ns, s) in the sources -- by just flipping the directions twice.\ definition ns_mul_ext :: "'a rel \ 'a rel \ 'a multiset rel" where "ns_mul_ext ns s \ (mult2_alt_ns (ns\) (s\))\" lemma ns_mul_extI: assumes "A = A1 + A2" and "B = B1 + B2" and "(A1, B1) \ multpw ns" and "\b. b \# B2 \ \a. a \# A2 \ (a, b) \ s" shows "(A, B) \ ns_mul_ext ns s" using assms by (auto simp: ns_mul_ext_def multpw_converse intro!: mult2_alt_nsI) lemma ns_mul_extE: assumes "(A, B) \ ns_mul_ext ns s" obtains A1 A2 B1 B2 where "A = A1 + A2" and "B = B1 + B2" and "(A1, B1) \ multpw ns" and "\b. b \# B2 \ \a. a \# A2 \ (a, b) \ s" using assms by (auto simp: ns_mul_ext_def multpw_converse elim!: mult2_alt_nsE) lemmas ns_mul_extI_old = ns_mul_extI[OF _ _ multpw_listI[OF _ refl refl], rule_format] text\Same for the "greater than" order on multisets.\ definition s_mul_ext :: "'a rel \ 'a rel \ 'a multiset rel" where "s_mul_ext ns s \ (mult2_alt_s (ns\) (s\))\" lemma s_mul_extI: assumes "A = A1 + A2" and "B = B1 + B2" and "(A1, B1) \ multpw ns" and "A2 \ {#}" and "\b. b \# B2 \ \a. a \# A2 \ (a, b) \ s" shows "(A, B) \ s_mul_ext ns s" using assms by (auto simp: s_mul_ext_def multpw_converse intro!: mult2_alt_sI) lemma s_mul_extE: assumes "(A, B) \ s_mul_ext ns s" obtains A1 A2 B1 B2 where "A = A1 + A2" and "B = B1 + B2" and "(A1, B1) \ multpw ns" and "A2 \ {#}" and "\b. b \# B2 \ \a. a \# A2 \ (a, b) \ s" using assms by (auto simp: s_mul_ext_def multpw_converse elim!: mult2_alt_sE) lemmas s_mul_extI_old = s_mul_extI[OF _ _ multpw_listI[OF _ refl refl], rule_format] subsection\Basic properties\ lemma s_mul_ext_mono: assumes "ns \ ns'" "s \ s'" shows "s_mul_ext ns s \ s_mul_ext ns' s'" unfolding s_mul_ext_def using assms mono_mult2_alt[of "ns\" "ns'\" "s\" "s'\"] by simp lemma ns_mul_ext_mono: assumes "ns \ ns'" "s \ s'" shows "ns_mul_ext ns s \ ns_mul_ext ns' s'" unfolding ns_mul_ext_def using assms mono_mult2_alt[of "ns\" "ns'\" "s\" "s'\"] by simp lemma s_mul_ext_local_mono: assumes sub: "(set_mset xs \ set_mset ys) \ ns \ ns'" "(set_mset xs \ set_mset ys) \ s \ s'" and rel: "(xs,ys) \ s_mul_ext ns s" shows "(xs,ys) \ s_mul_ext ns' s'" using rel s_mul_ext_mono[OF sub] mult2_alt_local[of ys xs False "ns\" "s\"] by (auto simp: s_mul_ext_def converse_Int ac_simps converse_Times) lemma ns_mul_ext_local_mono: assumes sub: "(set_mset xs \ set_mset ys) \ ns \ ns'" "(set_mset xs \ set_mset ys) \ s \ s'" and rel: "(xs,ys) \ ns_mul_ext ns s" shows "(xs,ys) \ ns_mul_ext ns' s'" using rel ns_mul_ext_mono[OF sub] mult2_alt_local[of ys xs True "ns\" "s\"] by (auto simp: ns_mul_ext_def converse_Int ac_simps converse_Times) text\The empty multiset is the minimal element for these orders\ lemma ns_mul_ext_bottom: "(A,{#}) \ ns_mul_ext ns s" by (auto intro!: ns_mul_extI) lemma ns_mul_ext_bottom_uniqueness: assumes "({#},A) \ ns_mul_ext ns s" shows "A = {#}" using assms by (auto simp: ns_mul_ext_def mult2_alt_ns_def) lemma ns_mul_ext_bottom2: assumes "(A,B) \ ns_mul_ext ns s" and "B \ {#}" shows "A \ {#}" using assms by (auto simp: ns_mul_ext_def mult2_alt_ns_def) lemma s_mul_ext_bottom: assumes "A \ {#}" shows "(A,{#}) \ s_mul_ext ns s" using assms by (auto simp: s_mul_ext_def mult2_alt_s_def) lemma s_mul_ext_bottom_strict: "({#},A) \ s_mul_ext ns s" by (auto simp: s_mul_ext_def mult2_alt_s_def) text\Obvious introduction rules.\ lemma all_ns_ns_mul_ext: assumes "length as = length bs" and "\i. i < length bs \ (as ! i, bs ! i) \ ns" shows "(mset as, mset bs) \ ns_mul_ext ns s" using assms by (auto intro!: ns_mul_extI[of _ _ "{#}" _ _ "{#}"] multpw_listI) lemma all_s_s_mul_ext: assumes "A \ {#}" and "\b. b \# B \ (\a. a \# A \ (a,b) \ s)" shows "(A, B) \ s_mul_ext ns s" using assms by (auto intro!: s_mul_extI[of _ "{#}" _ _ "{#}"] multpw_listI) text\Being stricly lesser than implies being lesser than\ lemma s_ns_mul_ext: assumes "(A, B) \ s_mul_ext ns s" shows "(A, B) \ ns_mul_ext ns s" using assms by (simp add: s_mul_ext_def ns_mul_ext_def mult2_alt_s_implies_mult2_alt_ns) text\The non-strict order is reflexive.\ lemma multpw_refl': assumes "locally_refl ns A" shows "(A, A) \ multpw ns" proof - have "Restr Id (set_mset A) \ ns" using assms by (auto simp: locally_refl_def) from refl_multpw[of Id] multpw_local[of A A Id] mono_multpw[OF this] show ?thesis by (auto simp: refl_on_def) qed lemma ns_mul_ext_refl_local: assumes "locally_refl ns A" shows "(A, A) \ ns_mul_ext ns s" using assms by (auto intro!: ns_mul_extI[of A A "{#}" A A "{#}" ns s] multpw_refl') lemma ns_mul_ext_refl: assumes "refl ns" shows "(A, A) \ ns_mul_ext ns s" using assms ns_mul_ext_refl_local[of ns A s] unfolding refl_on_def locally_refl_def by auto text\The orders are union-compatible\ lemma ns_s_mul_ext_union_multiset_l: assumes "(A, B) \ ns_mul_ext ns s" and "C \ {#}" and "\d. d \# D \ (\c. c \# C \ (c,d) \ s)" shows "(A + C, B + D) \ s_mul_ext ns s" using assms unfolding ns_mul_ext_def s_mul_ext_def by (auto intro!: converseI mult2_alt_ns_s_add mult2_alt_sI[of _ "{#}" _ _ "{#}"]) lemma s_mul_ext_union_compat: assumes "(A, B) \ s_mul_ext ns s" and "locally_refl ns C" shows "(A + C, B + C) \ s_mul_ext ns s" using assms ns_mul_ext_refl_local[OF assms(2)] unfolding ns_mul_ext_def s_mul_ext_def by (auto intro!: converseI mult2_alt_s_ns_add) lemma ns_mul_ext_union_compat: assumes "(A, B) \ ns_mul_ext ns s" and "locally_refl ns C" shows "(A + C, B + C) \ ns_mul_ext ns s" using assms ns_mul_ext_refl_local[OF assms(2)] unfolding ns_mul_ext_def s_mul_ext_def by (auto intro!: converseI mult2_alt_ns_ns_add) context fixes NS :: "'a rel" assumes NS: "refl NS" begin lemma refl_imp_locally_refl: "locally_refl NS A" using NS unfolding refl_on_def locally_refl_def by auto lemma supseteq_imp_ns_mul_ext: assumes "A \# B" shows "(A, B) \ ns_mul_ext NS S" using assms by (auto intro!: ns_mul_extI[of A B "A - B" B B "{#}"] multpw_refl' refl_imp_locally_refl simp: subset_mset.add_diff_inverse) lemma supset_imp_s_mul_ext: assumes "A \# B" shows "(A, B) \ s_mul_ext NS S" using assms subset_mset.add_diff_inverse[of B A] by (auto intro!: s_mul_extI[of A B "A - B" B B "{#}"] multpw_refl' refl_imp_locally_refl - simp: Diff_eq_empty_iff_mset subset_mset.order.strict_iff_order) + simp: Diff_eq_empty_iff_mset) end definition mul_ext :: "('a \ 'a \ bool \ bool) \ 'a list \ 'a list \ bool \ bool" where "mul_ext f xs ys \ let s = {(x,y). fst (f x y)}; ns = {(x,y). snd (f x y)} in ((mset xs,mset ys) \ s_mul_ext ns s, (mset xs, mset ys) \ ns_mul_ext ns s)" definition "smulextp f m n \ (m, n) \ s_mul_ext {(x, y). snd (f x y)} {(x, y). fst (f x y)}" definition "nsmulextp f m n \ (m, n) \ ns_mul_ext {(x, y). snd (f x y)} {(x, y). fst (f x y)}" lemma smulextp_cong[fundef_cong]: assumes "xs1 = ys1" and "xs2 = ys2" and "\ x x'. x \# ys1 \ x' \# ys2 \ f x x' = g x x'" shows "smulextp f xs1 xs2 = smulextp g ys1 ys2" unfolding smulextp_def proof assume "(xs1, xs2) \ s_mul_ext {(x, y). snd (f x y)} {(x, y). fst (f x y)}" from s_mul_ext_local_mono[OF _ _ this, of "{(x, y). snd (g x y)}" "{(x, y). fst (g x y)}"] show "(ys1, ys2) \ s_mul_ext {(x, y). snd (g x y)} {(x, y). fst (g x y)}" - using assms by force -next + using assms by force +next assume "(ys1, ys2) \ s_mul_ext {(x, y). snd (g x y)} {(x, y). fst (g x y)}" from s_mul_ext_local_mono[OF _ _ this, of "{(x, y). snd (f x y)}" "{(x, y). fst (f x y)}"] show "(xs1, xs2) \ s_mul_ext {(x, y). snd (f x y)} {(x, y). fst (f x y)}" using assms by force qed lemma nsmulextp_cong[fundef_cong]: assumes "xs1 = ys1" and "xs2 = ys2" and "\ x x'. x \# ys1 \ x' \# ys2 \ f x x' = g x x'" shows "nsmulextp f xs1 xs2 = nsmulextp g ys1 ys2" unfolding nsmulextp_def proof assume "(xs1, xs2) \ ns_mul_ext {(x, y). snd (f x y)} {(x, y). fst (f x y)}" from ns_mul_ext_local_mono[OF _ _ this, of "{(x, y). snd (g x y)}" "{(x, y). fst (g x y)}"] show "(ys1, ys2) \ ns_mul_ext {(x, y). snd (g x y)} {(x, y). fst (g x y)}" - using assms by force -next + using assms by force +next assume "(ys1, ys2) \ ns_mul_ext {(x, y). snd (g x y)} {(x, y). fst (g x y)}" from ns_mul_ext_local_mono[OF _ _ this, of "{(x, y). snd (f x y)}" "{(x, y). fst (f x y)}"] show "(xs1, xs2) \ ns_mul_ext {(x, y). snd (f x y)} {(x, y). fst (f x y)}" using assms by force qed definition "mulextp f m n = (smulextp f m n, nsmulextp f m n)" lemma mulextp_cong[fundef_cong]: assumes "xs1 = ys1" and "xs2 = ys2" and "\ x x'. x \# ys1 \ x' \# ys2 \ f x x' = g x x'" shows "mulextp f xs1 xs2 = mulextp g ys1 ys2" - unfolding mulextp_def using assms by (auto cong: nsmulextp_cong smulextp_cong) + unfolding mulextp_def using assms by (auto cong: nsmulextp_cong smulextp_cong) lemma mset_s_mul_ext: "(mset xs, mset ys) \ s_mul_ext {(x, y). snd (f x y)} {(x, y).fst (f x y)} \ fst (mul_ext f xs ys)" by (auto simp: mul_ext_def Let_def) lemma mset_ns_mul_ext: "(mset xs, mset ys) \ ns_mul_ext {(x, y). snd (f x y)} {(x, y).fst (f x y)} \ snd (mul_ext f xs ys)" by (auto simp: mul_ext_def Let_def) lemma smulextp_mset_code: "smulextp f (mset xs) (mset ys) \ fst (mul_ext f xs ys)" unfolding smulextp_def mset_s_mul_ext .. lemma nsmulextp_mset_code: "nsmulextp f (mset xs) (mset ys) \ snd (mul_ext f xs ys)" unfolding nsmulextp_def mset_ns_mul_ext .. lemma nstri_mul_ext_map: assumes "\s t. s \ set ss \ t \ set ts \ fst (order s t) \ fst (order' (f s) (f t))" and "\s t. s \ set ss \ t \ set ts \ snd (order s t) \ snd (order' (f s) (f t))" and "snd (mul_ext order ss ts)" shows "snd (mul_ext order' (map f ss) (map f ts))" using assms mult2_alt_map[of "mset ts" "mset ss" "{(t, s). snd (order s t)}" f f "{(t, s). snd (order' s t)}" "{(t, s). fst (order s t)}" "{(t, s). fst (order' s t)}" True] by (auto simp: mul_ext_def ns_mul_ext_def converse_unfold) lemma stri_mul_ext_map: assumes "\s t. s \ set ss \ t \ set ts \ fst (order s t) \ fst (order' (f s) (f t))" and "\s t. s \ set ss \ t \ set ts \ snd (order s t) \ snd (order' (f s) (f t))" and "fst (mul_ext order ss ts)" shows "fst (mul_ext order' (map f ss) (map f ts))" using assms mult2_alt_map[of "mset ts" "mset ss" "{(t,s). snd (order s t)}" f f "{(t, s). snd (order' s t)}" "{(t, s). fst (order s t)}" "{(t, s). fst (order' s t)}" False] by (auto simp: mul_ext_def s_mul_ext_def converse_unfold) text \The non-strict order is transitive.\ lemma ns_mul_ext_trans: assumes "trans s" "trans ns" "compatible_l ns s" "compatible_r ns s" "refl ns" and "(A, B) \ ns_mul_ext ns s" and "(B, C) \ ns_mul_ext ns s" shows "(A, C) \ ns_mul_ext ns s" using assms unfolding compatible_l_def compatible_r_def ns_mul_ext_def using trans_mult2_ns[of "s\" "ns\"] by (auto simp: mult2_ns_eq_mult2_ns_alt converse_relcomp[symmetric]) (metis trans_def) text\The strict order is trans.\ lemma s_mul_ext_trans: assumes "trans s" "trans ns" "compatible_l ns s" "compatible_r ns s" "refl ns" and "(A, B) \ s_mul_ext ns s" and "(B, C) \ s_mul_ext ns s" shows "(A, C) \ s_mul_ext ns s" using assms unfolding compatible_l_def compatible_r_def s_mul_ext_def using trans_mult2_s[of "s\" "ns\"] by (auto simp: mult2_s_eq_mult2_s_alt converse_relcomp[symmetric]) (metis trans_def) text\The strict order is compatible on the left with the non strict one\ lemma s_ns_mul_ext_trans: assumes "trans s" "trans ns" "compatible_l ns s" "compatible_r ns s" "refl ns" and "(A, B) \ s_mul_ext ns s" and "(B, C) \ ns_mul_ext ns s" shows "(A, C) \ s_mul_ext ns s" using assms unfolding compatible_l_def compatible_r_def s_mul_ext_def ns_mul_ext_def using compat_mult2(1)[of "s\" "ns\"] by (auto simp: mult2_s_eq_mult2_s_alt mult2_ns_eq_mult2_ns_alt converse_relcomp[symmetric]) text\The strict order is compatible on the right with the non-strict one.\ lemma ns_s_mul_ext_trans: assumes "trans s" "trans ns" "compatible_l ns s" "compatible_r ns s" "refl ns" and "(A, B) \ ns_mul_ext ns s" and "(B, C) \ s_mul_ext ns s" shows "(A, C) \ s_mul_ext ns s" using assms unfolding compatible_l_def compatible_r_def s_mul_ext_def ns_mul_ext_def using compat_mult2(2)[of "s\" "ns\"] by (auto simp: mult2_s_eq_mult2_s_alt mult2_ns_eq_mult2_ns_alt converse_relcomp[symmetric]) text\@{const s_mul_ext} is strongly normalizing\ lemma SN_s_mul_ext_strong: assumes "order_pair s ns" and "\y. y \# M \ SN_on s {y}" shows "SN_on (s_mul_ext ns s) {M}" using mult2_s_eq_mult2_s_alt[of "ns\" "s\"] assms wf_below_pointwise[of "s\" "set_mset M"] unfolding SN_on_iff_wf_below s_mul_ext_def order_pair_def compat_pair_def pre_order_pair_def by (auto intro!: wf_below_mult2_s_local simp: converse_relcomp[symmetric]) lemma SN_s_mul_ext: assumes "order_pair s ns" "SN s" shows "SN (s_mul_ext ns s)" using SN_s_mul_ext_strong[OF assms(1)] assms(2) by (auto simp: SN_on_def) lemma (in order_pair) mul_ext_order_pair: "order_pair (s_mul_ext NS S) (ns_mul_ext NS S)" (is "order_pair ?S ?NS") proof from s_mul_ext_trans trans_S trans_NS compat_NS_S compat_S_NS refl_NS show "trans ?S" unfolding trans_def compatible_l_def compatible_r_def by blast next from ns_mul_ext_trans trans_S trans_NS compat_NS_S compat_S_NS refl_NS show "trans ?NS" unfolding trans_def compatible_l_def compatible_r_def by blast next from ns_s_mul_ext_trans trans_S trans_NS compat_NS_S compat_S_NS refl_NS show "?NS O ?S \ ?S" unfolding trans_def compatible_l_def compatible_r_def by blast next from s_ns_mul_ext_trans trans_S trans_NS compat_NS_S compat_S_NS refl_NS show "?S O ?NS \ ?S" unfolding trans_def compatible_l_def compatible_r_def by blast next from ns_mul_ext_refl[OF refl_NS, of _ S] show "refl ?NS" unfolding refl_on_def by fast qed lemma (in SN_order_pair) mul_ext_SN_order_pair: "SN_order_pair (s_mul_ext NS S) (ns_mul_ext NS S)" (is "SN_order_pair ?S ?NS") proof - from mul_ext_order_pair interpret order_pair ?S ?NS . have "order_pair S NS" by unfold_locales then interpret SN_ars ?S using SN_s_mul_ext[of S NS] SN by unfold_locales show ?thesis by unfold_locales qed lemma mul_ext_compat: assumes compat: "\ s t u. \s \ set ss; t \ set ts; u \ set us\ \ (snd (f s t) \ fst (f t u) \ fst (f s u)) \ (fst (f s t) \ snd (f t u) \ fst (f s u)) \ (snd (f s t) \ snd (f t u) \ snd (f s u)) \ (fst (f s t) \ fst (f t u) \ fst (f s u))" shows " (snd (mul_ext f ss ts) \ fst (mul_ext f ts us) \ fst (mul_ext f ss us)) \ (fst (mul_ext f ss ts) \ snd (mul_ext f ts us) \ fst (mul_ext f ss us)) \ (snd (mul_ext f ss ts) \ snd (mul_ext f ts us) \ snd (mul_ext f ss us)) \ (fst (mul_ext f ss ts) \ fst (mul_ext f ts us) \ fst (mul_ext f ss us)) " proof - let ?s = "{(x, y). fst (f x y)}\" and ?ns = "{(x, y). snd (f x y)}\" have [dest]: "(mset ts, mset ss) \ mult2_alt b2 ?ns ?s \ (mset us, mset ts) \ mult2_alt b1 ?ns ?s \ (mset us, mset ss) \ mult2_alt (b1 \ b2) ?ns ?s" for b1 b2 using assms by (auto intro!: trans_mult2_alt_local[of _ "mset ts"] simp: in_multiset_in_set) show ?thesis by (auto simp: mul_ext_def s_mul_ext_def ns_mul_ext_def Let_def) qed lemma mul_ext_cong[fundef_cong]: assumes "mset xs1 = mset ys1" and "mset xs2 = mset ys2" and "\ x x'. x \ set ys1 \ x' \ set ys2 \ f x x' = g x x'" shows "mul_ext f xs1 xs2 = mul_ext g ys1 ys2" using assms mult2_alt_map[of "mset xs2" "mset xs1" "{(x, y). snd (f x y)}\" id id "{(x, y). snd (g x y)}\" "{(x, y). fst (f x y)}\" "{(x, y). fst (g x y)}\"] mult2_alt_map[of "mset ys2" "mset ys1" "{(x, y). snd (g x y)}\" id id "{(x, y). snd (f x y)}\" "{(x, y). fst (g x y)}\" "{(x, y). fst (f x y)}\"] by (auto simp: mul_ext_def s_mul_ext_def ns_mul_ext_def Let_def in_multiset_in_set) lemma all_nstri_imp_mul_nstri: assumes "\ii. i < length ys \ (xs ! i, ys ! i) \ {(x,y). snd (f x y)}" by simp from all_ns_ns_mul_ext[OF assms(2) this] show ?thesis by (simp add: mul_ext_def) qed lemma relation_inter: shows "{(x,y). P x y} \ {(x,y). Q x y} = {(x,y). P x y \ Q x y}" by blast lemma mul_ext_unfold: "(x,y) \ {(a,b). fst (mul_ext g a b)} \ (mset x, mset y) \ (s_mul_ext {(a,b). snd (g a b)} {(a,b). fst (g a b)})" unfolding mul_ext_def by (simp add: Let_def) -text \The next lemma is a local version of strong-normalization of +text \The next lemma is a local version of strong-normalization of the multiset extension, where the base-order only has to be strongly normalizing on elements of the multisets. This will be crucial for orders that are defined recursively on terms, such as RPO or WPO.\ lemma mul_ext_SN: assumes "\x. snd (g x x)" and "\x y z. fst (g x y) \ snd (g y z) \ fst (g x z)" and "\x y z. snd (g x y) \ fst (g y z) \ fst (g x z)" and "\x y z. snd (g x y) \ snd (g y z) \ snd (g x z)" and "\x y z. fst (g x y) \ fst (g y z) \ fst (g x z)" shows "SN {(ys, xs). (\y\set ys. SN_on {(s ,t). fst (g s t)} {y}) \ fst (mul_ext g ys xs)}" proof - let ?R1 = "\xs ys. \y\ set ys. SN_on {(s ,t). fst (g s t)} {y}" let ?R2 = "\xs ys. fst (mul_ext g ys xs)" let ?s = "{(x,y). fst (g x y)}" and ?ns = "{(x,y). snd (g x y)}" have OP: "order_pair ?s ?ns" using assms(1-5) by unfold_locales ((unfold refl_on_def trans_def)?, blast)+ let ?R = "{(ys, xs). ?R1 xs ys \ ?R2 xs ys}" let ?Sn = "SN_on ?R" { fix ys xs assume R_ys_xs: "(ys, xs) \ ?R" let ?mys = "mset ys" let ?mxs = "mset xs" from R_ys_xs have HSN_ys: "\y. y \ set ys \ SN_on ?s {y}" by simp with in_multiset_in_set[of ys] have "\y. y \# ?mys \ SN_on ?s {y}" by simp from SN_s_mul_ext_strong[OF OP this] and mul_ext_unfold have "SN_on {(ys,xs). fst (mul_ext g ys xs)} {ys}" by fast from relation_inter[of ?R2 ?R1] and SN_on_weakening[OF this] have "SN_on ?R {ys}" by blast } then have Hyp: "\ys xs. (ys,xs) \ ?R \ SN_on ?R {ys}" by auto { fix ys have "SN_on ?R {ys}" proof (cases "\ xs. (ys, xs) \ ?R") case True with Hyp show ?thesis by simp next case False then show ?thesis by auto qed } then show ?thesis unfolding SN_on_def by simp qed lemma mul_ext_stri_imp_nstri: assumes "fst (mul_ext f as bs)" shows "snd (mul_ext f as bs)" using assms and s_ns_mul_ext unfolding mul_ext_def by (auto simp: Let_def) lemma ns_ns_mul_ext_union_compat: assumes "(A,B) \ ns_mul_ext ns s" and "(C,D) \ ns_mul_ext ns s" shows "(A + C, B + D) \ ns_mul_ext ns s" using assms by (auto simp: ns_mul_ext_def intro: mult2_alt_ns_ns_add) lemma s_ns_mul_ext_union_compat: assumes "(A,B) \ s_mul_ext ns s" and "(C,D) \ ns_mul_ext ns s" shows "(A + C, B + D) \ s_mul_ext ns s" using assms by (auto simp: s_mul_ext_def ns_mul_ext_def intro: mult2_alt_s_ns_add) lemma ns_ns_mul_ext_union_compat_rtrancl: assumes refl: "refl ns" and AB: "(A, B) \ (ns_mul_ext ns s)\<^sup>*" and CD: "(C, D) \ (ns_mul_ext ns s)\<^sup>*" shows "(A + C, B + D) \ (ns_mul_ext ns s)\<^sup>*" proof - { fix A B C assume "(A, B) \ (ns_mul_ext ns s)\<^sup>*" then have "(A + C, B + C) \ (ns_mul_ext ns s)\<^sup>*" proof (induct rule: rtrancl_induct) case (step B D) have "(C, C) \ ns_mul_ext ns s" by (rule ns_mul_ext_refl, insert refl, auto simp: locally_refl_def refl_on_def) from ns_ns_mul_ext_union_compat[OF step(2) this] step(3) show ?case by auto qed auto } from this[OF AB, of C] this[OF CD, of B] show ?thesis by (auto simp: ac_simps) qed subsection \Multisets as order on lists\ interpretation mul_ext_list: list_order_extension "\s ns. {(as, bs). (mset as, mset bs) \ s_mul_ext ns s}" "\s ns. {(as, bs). (mset as, mset bs) \ ns_mul_ext ns s}" proof - let ?m = "mset :: ('a list \ 'a multiset)" let ?S = "\s ns. {(as, bs). (?m as, ?m bs) \ s_mul_ext ns s}" let ?NS = "\s ns. {(as, bs). (?m as, ?m bs) \ ns_mul_ext ns s}" show "list_order_extension ?S ?NS" proof (rule list_order_extension.intro) fix s ns let ?s = "?S s ns" let ?ns = "?NS s ns" assume "SN_order_pair s ns" then interpret SN_order_pair s ns . interpret SN_order_pair "(s_mul_ext ns s)" "(ns_mul_ext ns s)" by (rule mul_ext_SN_order_pair) show "SN_order_pair ?s ?ns" proof show "refl ?ns" using refl_NS unfolding refl_on_def by blast show "?ns O ?s \ ?s" using compat_NS_S by blast show "?s O ?ns \ ?s" using compat_S_NS by blast show "trans ?ns" using trans_NS unfolding trans_def by blast show "trans ?s" using trans_S unfolding trans_def by blast show "SN ?s" using SN_inv_image[OF SN, of ?m, unfolded inv_image_def] . qed next fix S f NS as bs assume "\a b. (a, b) \ S \ (f a, f b) \ S" "\a b. (a, b) \ NS \ (f a, f b) \ NS" "(as, bs) \ ?S S NS" then show "(map f as, map f bs) \ ?S S NS" using mult2_alt_map[of _ _ "NS\" f f "NS\" "S\" "S\"] by (auto simp: mset_map s_mul_ext_def) next fix S f NS as bs assume "\a b. (a, b) \ S \ (f a, f b) \ S" "\a b. (a, b) \ NS \ (f a, f b) \ NS" "(as, bs) \ ?NS S NS" then show "(map f as, map f bs) \ ?NS S NS" using mult2_alt_map[of _ _ "NS\" f f "NS\" "S\" "S\"] by (auto simp: mset_map ns_mul_ext_def) next fix as bs :: "'a list" and NS S :: "'a rel" assume ass: "length as = length bs" "\i. i < length bs \ (as ! i, bs ! i) \ NS" show "(as, bs) \ ?NS S NS" by (rule, unfold split, rule all_ns_ns_mul_ext, insert ass, auto) qed qed lemma s_mul_ext_singleton [simp, intro]: assumes "(a, b) \ s" shows "({#a#}, {#b#}) \ s_mul_ext ns s" using assms by (auto simp: s_mul_ext_def mult2_alt_s_single) lemma ns_mul_ext_singleton [simp, intro]: "(a, b) \ ns \ ({#a#}, {#b#}) \ ns_mul_ext ns s" by (auto simp: ns_mul_ext_def multpw_converse intro: multpw_implies_mult2_alt_ns multpw_single) lemma ns_mul_ext_singleton2: "(a, b) \ s \ ({#a#}, {#b#}) \ ns_mul_ext ns s" by (intro s_ns_mul_ext s_mul_ext_singleton) lemma s_mul_ext_self_extend_left: assumes "A \ {#}" and "locally_refl W B" shows "(A + B, B) \ s_mul_ext W S" proof - have "(A + B, {#} + B) \ s_mul_ext W S" using assms by (intro s_mul_ext_union_compat) (auto dest: s_mul_ext_bottom) then show ?thesis by simp qed lemma s_mul_ext_ne_extend_left: assumes "A \ {#}" and "(B, C) \ ns_mul_ext W S" shows "(A + B, C) \ s_mul_ext W S" using assms proof - have "(A + B, {#} + C) \ s_mul_ext W S" using assms by (intro s_ns_mul_ext_union_compat) (auto simp: s_mul_ext_bottom dest: s_ns_mul_ext) then show ?thesis by (simp add: ac_simps) qed lemma s_mul_ext_extend_left: assumes "(B, C) \ s_mul_ext W S" shows "(A + B, C) \ s_mul_ext W S" using assms proof - have "(B + A, C + {#}) \ s_mul_ext W S" using assms by (intro s_ns_mul_ext_union_compat) (auto simp: ns_mul_ext_bottom dest: s_ns_mul_ext) then show ?thesis by (simp add: ac_simps) qed lemma mul_ext_mono: assumes "\x y. \x \ set xs; y \ set ys; fst (P x y)\ \ fst (P' x y)" and "\x y. \x \ set xs; y \ set ys; snd (P x y)\ \ snd (P' x y)" shows - "fst (mul_ext P xs ys) \ fst (mul_ext P' xs ys)" + "fst (mul_ext P xs ys) \ fst (mul_ext P' xs ys)" "snd (mul_ext P xs ys) \ snd (mul_ext P' xs ys)" unfolding mul_ext_def Let_def fst_conv snd_conv -proof - - assume mem: "(mset xs, mset ys) \ s_mul_ext {(x, y). snd (P x y)} {(x, y). fst (P x y)}" - show "(mset xs, mset ys) \ s_mul_ext {(x, y). snd (P' x y)} {(x, y). fst (P' x y)}" +proof - + assume mem: "(mset xs, mset ys) \ s_mul_ext {(x, y). snd (P x y)} {(x, y). fst (P x y)}" + show "(mset xs, mset ys) \ s_mul_ext {(x, y). snd (P' x y)} {(x, y). fst (P' x y)}" by (rule s_mul_ext_local_mono[OF _ _ mem], insert assms, auto) next - assume mem: "(mset xs, mset ys) \ ns_mul_ext {(x, y). snd (P x y)} {(x, y). fst (P x y)}" - show "(mset xs, mset ys) \ ns_mul_ext {(x, y). snd (P' x y)} {(x, y). fst (P' x y)}" + assume mem: "(mset xs, mset ys) \ ns_mul_ext {(x, y). snd (P x y)} {(x, y). fst (P x y)}" + show "(mset xs, mset ys) \ ns_mul_ext {(x, y). snd (P' x y)} {(x, y). fst (P' x y)}" by (rule ns_mul_ext_local_mono[OF _ _ mem], insert assms, auto) qed subsection \Special case: non-strict order is equality\ lemma ns_mul_ext_IdE: assumes "(M, N) \ ns_mul_ext Id R" obtains X and Y and Z where "M = X + Z" and "N = Y + Z" and "\y \ set_mset Y. \x \ set_mset X. (x, y) \ R" using assms by (auto simp: ns_mul_ext_def elim!: mult2_alt_nsE) (insert union_commute, blast) lemma ns_mul_ext_IdI: assumes "M = X + Z" and "N = Y + Z" and "\y \ set_mset Y. \x \ set_mset X. (x, y) \ R" shows "(M, N) \ ns_mul_ext Id R" using assms mult2_alt_nsI[of N Z Y M Z X Id "R\"] by (auto simp: ns_mul_ext_def) lemma s_mul_ext_IdE: assumes "(M, N) \ s_mul_ext Id R" obtains X and Y and Z where "X \ {#}" and "M = X + Z" and "N = Y + Z" and "\y \ set_mset Y. \x \ set_mset X. (x, y) \ R" using assms by (auto simp: s_mul_ext_def elim!: mult2_alt_sE) (metis union_commute) lemma s_mul_ext_IdI: assumes "X \ {#}" and "M = X + Z" and "N = Y + Z" and "\y \ set_mset Y. \x \ set_mset X. (x, y) \ R" shows "(M, N) \ s_mul_ext Id R" using assms mult2_alt_sI[of N Z Y M Z X Id "R\"] by (auto simp: s_mul_ext_def ac_simps) lemma mult_s_mul_ext_conv: assumes "trans R" shows "(mult (R\))\ = s_mul_ext Id R" using mult2_s_eq_mult2_s_alt[of Id "R\"] assms by (auto simp: s_mul_ext_def refl_Id mult2_s_def) lemma ns_mul_ext_Id_eq: "ns_mul_ext Id R = (s_mul_ext Id R)\<^sup>=" by (auto simp add: ns_mul_ext_def s_mul_ext_def mult2_alt_ns_conv) lemma subseteq_mset_imp_ns_mul_ext_Id: assumes "A \# B" shows "(B, A) \ ns_mul_ext Id R" proof - obtain C where [simp]: "B = C + A" using assms by (auto simp: mset_subset_eq_exists_conv ac_simps) have "(C + A, {#} + A) \ ns_mul_ext Id R" by (intro ns_mul_ext_IdI [of _ C A _ "{#}"]) auto then show ?thesis by simp qed lemma subset_mset_imp_s_mul_ext_Id: assumes "A \# B" shows "(B, A) \ s_mul_ext Id R" using assms by (intro supset_imp_s_mul_ext) (auto simp: refl_Id) end