section ‹Decreasing Diagrams›
theory Decreasing_Diagrams_II
imports
Decreasing_Diagrams_II_Aux
"HOL-Cardinals.Wellorder_Extension"
"Abstract-Rewriting.Abstract_Rewriting"
begin
subsection ‹Greek accents›
datatype accent = Acute | Grave | Macron
lemma UNIV_accent: "UNIV = { Acute, Grave, Macron }"
using accent.nchotomy by blast
lemma finite_accent: "finite (UNIV :: accent set)"
by (simp add: UNIV_accent)
type_synonym 'a letter = "accent × 'a"
definition letter_less :: "('a × 'a) set ⇒ ('a letter × 'a letter) set" where
[simp]: "letter_less R = {(a,b). (snd a, snd b) ∈ R}"
lemma mono_letter_less: "mono letter_less"
by (auto simp add: mono_def)
subsection ‹Comparing Greek strings›
type_synonym 'a greek = "'a letter list"
definition adj_msog :: "'a greek ⇒ 'a greek ⇒ ('a letter × 'a greek) ⇒ ('a letter × 'a greek)"
where
"adj_msog xs zs l ≡
case l of (y,ys) ⇒ (y, case fst y of Acute ⇒ ys @ zs | Grave ⇒ xs @ ys | Macron ⇒ ys)"
definition ms_of_greek :: "'a greek ⇒ ('a letter × 'a greek) multiset" where
"ms_of_greek as = mset
(map (λ(xs, y, zs) ⇒ adj_msog xs zs (y, [])) (list_splits as))"
lemma adj_msog_adj_msog[simp]:
"adj_msog xs zs (adj_msog xs' zs' y) = adj_msog (xs @ xs') (zs' @ zs) y"
by (auto simp: adj_msog_def split: accent.splits prod.splits)
lemma compose_adj_msog[simp]: "adj_msog xs zs ∘ adj_msog xs' zs' = adj_msog (xs @ xs') (zs' @ zs)"
by (simp add: comp_def)
lemma adj_msog_single:
"adj_msog xs zs (x,[]) = (x, (case fst x of Grave ⇒ xs | Acute ⇒ zs | Macron ⇒ []))"
by (simp add: adj_msog_def split: accent.splits)
lemma ms_of_greek_elem:
assumes "(x,xs) ∈ set_mset (ms_of_greek ys)"
shows "x ∈ set ys"
using assms by (auto dest: elem_list_splits_elem simp: adj_msog_def ms_of_greek_def)
lemma ms_of_greek_shorter:
assumes "(x, t) ∈# ms_of_greek s"
shows "length s > length t"
using assms[unfolded ms_of_greek_def in_multiset_in_set]
by (auto simp: elem_list_splits_length adj_msog_def split: accent.splits)
lemma msog_append: "ms_of_greek (xs @ ys) = image_mset (adj_msog [] ys) (ms_of_greek xs) +
image_mset (adj_msog xs []) (ms_of_greek ys)"
by (auto simp: ms_of_greek_def list_splits_append multiset.map_comp comp_def prod.case_distrib)
definition nest :: "('a × 'a) set ⇒ ('a greek × 'a greek) set ⇒ ('a greek × 'a greek) set" where
[simp]: "nest r s = {(a,b). (ms_of_greek a, ms_of_greek b) ∈ mult (letter_less r <*lex*> s)}"
lemma mono_nest: "mono (nest r)"
unfolding mono_def
proof (intro allI impI subsetI)
fix R S x
assume 1: "R ⊆ S" and 2: "x ∈ nest r R"
from 1 have "mult (letter_less r <*lex*> R) ⊆ mult (letter_less r <*lex*> S)"
using mono_mult mono_lex2[of "letter_less r"] unfolding mono_def by blast
with 2 show "x ∈ nest r S" by auto
qed
lemma nest_mono[mono_set]: "x ⊆ y ⟹ (a,b) ∈ nest r x ⟶ (a,b) ∈ nest r y"
using mono_nest[unfolded mono_def, rule_format, of x y r] by blast
definition greek_less :: "('a × 'a) set ⇒ ('a greek × 'a greek) set" where
"greek_less r = lfp (nest r)"
lemma greek_less_unfold:
"greek_less r = nest r (greek_less r)"
using mono_nest[of r] lfp_unfold[of "nest r"] by (simp add: greek_less_def)
subsection ‹Preservation of strict partial orders›
lemma strict_order_letter_less:
assumes "strict_order r"
shows "strict_order (letter_less r)"
using assms unfolding irrefl_def trans_def letter_less_def by fast
lemma strict_order_nest:
assumes r: "strict_order r" and R: "strict_order R"
shows "strict_order (nest r R)"
proof -
have "strict_order (mult (letter_less r <*lex*> R))"
using strict_order_letter_less[of r] irrefl_lex_prod[of "letter_less r" R]
trans_lex_prod[of "letter_less r" R] strict_order_mult[of "letter_less r <*lex*> R"] assms
by fast
from this show "strict_order (nest r R)" unfolding nest_def trans_def irrefl_def by fast
qed
lemma strict_order_greek_less:
assumes "strict_order r"
shows "strict_order (greek_less r)"
by (simp add: greek_less_def strict_order_lfp[OF mono_nest strict_order_nest[OF assms]])
lemma trans_letter_less:
assumes "trans r"
shows "trans (letter_less r)"
using assms unfolding trans_def letter_less_def by fast
lemma trans_order_nest: "trans (nest r R)"
using trans_mult unfolding nest_def trans_def by fast
lemma trans_greek_less[simp]: "trans (greek_less r)"
by (subst greek_less_unfold) (rule trans_order_nest)
lemma mono_greek_less: "mono greek_less"
unfolding greek_less_def mono_def
proof (intro allI impI lfp_mono)
fix r s :: "('a × 'a) set" and R :: "('a greek × 'a greek) set"
assume "r ⊆ s"
then have "letter_less r <*lex*> R ⊆ letter_less s <*lex*> R"
using mono_letter_less mono_lex1 unfolding mono_def by metis
then show "nest r R ⊆ nest s R" using mono_mult unfolding nest_def mono_def by blast
qed
subsection ‹Involution›
definition inv_letter :: "'a letter ⇒ 'a letter" where
"inv_letter l ≡
case l of (a, x) ⇒ (case a of Grave ⇒ Acute | Acute ⇒ Grave | Macron ⇒ Macron, x)"
lemma inv_letter_pair[simp]:
"inv_letter (a, x) = (case a of Grave ⇒ Acute | Acute ⇒ Grave | Macron ⇒ Macron, x)"
by (simp add: inv_letter_def)
lemma snd_inv_letter[simp]:
"snd (inv_letter x) = snd x"
by (simp add: inv_letter_def split: prod.splits)
lemma inv_letter_invol[simp]:
"inv_letter (inv_letter x) = x"
by (simp add: inv_letter_def split: prod.splits accent.splits)
lemma inv_letter_mono[simp]:
assumes "(x, y) ∈ letter_less r"
shows "(inv_letter x, inv_letter y) ∈ letter_less r"
using assms by simp
definition inv_greek :: "'a greek ⇒ 'a greek" where
"inv_greek s = rev (map inv_letter s)"
lemma inv_greek_invol[simp]:
"inv_greek (inv_greek s) = s"
by (simp add: inv_greek_def rev_map comp_def)
lemma inv_greek_append:
"inv_greek (s @ t) = inv_greek t @ inv_greek s"
by (simp add: inv_greek_def)
definition inv_msog :: "('a letter × 'a greek) multiset ⇒ ('a letter × 'a greek) multiset" where
"inv_msog M = image_mset (λ(x, t). (inv_letter x, inv_greek t)) M"
lemma inv_msog_invol[simp]:
"inv_msog (inv_msog M) = M"
by (simp add: inv_msog_def multiset.map_comp comp_def prod.case_distrib)
lemma ms_of_greek_inv_greek:
"ms_of_greek (inv_greek M) = inv_msog (ms_of_greek M)"
unfolding inv_msog_def inv_greek_def ms_of_greek_def list_splits_rev list_splits_map mset_map
multiset.map_comp mset_rev inv_letter_def adj_msog_def
by (rule cong[OF cong[OF refl[of "image_mset"]] refl]) (auto split: accent.splits)
lemma inv_greek_mono:
assumes "trans r" and "(s, t) ∈ greek_less r"
shows "(inv_greek s, inv_greek t) ∈ greek_less r"
using assms(2)
proof (induct "length s + length t" arbitrary: s t rule: less_induct)
note * = trans_lex_prod[OF trans_letter_less[OF ‹trans r›] trans_greek_less[of r]]
case (less s t)
have "(inv_msog (ms_of_greek s), inv_msog (ms_of_greek t)) ∈ mult (letter_less r <*lex*> greek_less r)"
unfolding inv_msog_def
proof (induct rule: mult_of_image_mset[OF * *])
case (1 x y) thus ?case
by (auto intro: less(1) split: prod.splits dest!: ms_of_greek_shorter)
next
case 2 thus ?case using less(2) by (subst(asm) greek_less_unfold) simp
qed
thus ?case by (subst greek_less_unfold) (auto simp: ms_of_greek_inv_greek)
qed
subsection ‹Monotonicity of @{term "greek_less r"}›
lemma greek_less_rempty[simp]:
"(a,[]) ∈ greek_less r ⟷ False"
by (subst greek_less_unfold) (auto simp: ms_of_greek_def)
lemma greek_less_nonempty:
assumes "b ≠ []"
shows "(a,b) ∈ greek_less r ⟷ (a,b) ∈ nest r (greek_less r)"
by (subst greek_less_unfold) simp
lemma greek_less_lempty[simp]:
"([],b) ∈ greek_less r ⟷ b ≠ []"
proof
assume "([],b) ∈ greek_less r"
then show "b ≠ []" using greek_less_rempty by fast
next
assume "b ≠ []"
then show "([],b) ∈ greek_less r"
unfolding greek_less_nonempty[OF ‹b ≠ []›] by (simp add: ms_of_greek_def)
qed
lemma greek_less_singleton:
"(a, b) ∈ letter_less r ⟹ ([a], [b]) ∈ greek_less r"
by (subst greek_less_unfold) (auto split: accent.splits simp: adj_msog_def ms_of_greek_def)
lemma ms_of_greek_cons:
"ms_of_greek (x # s) = {# adj_msog [] s (x,[]) #} + image_mset (adj_msog [x] []) (ms_of_greek s)"
using msog_append[of "[x]" s]
by (auto simp add: adj_msog_def ms_of_greek_def accent.splits)
lemma greek_less_cons_mono:
assumes "trans r"
shows "(s, t) ∈ greek_less r ⟹ (x # s, x # t) ∈ greek_less r"
proof (induct "length s + length t" arbitrary: s t rule: less_induct)
note * = trans_lex_prod[OF trans_letter_less[OF ‹trans r›] trans_greek_less[of r]]
case (less s t)
{
fix M have "(M + image_mset (adj_msog [x] []) (ms_of_greek s),
M + image_mset (adj_msog [x] []) (ms_of_greek t)) ∈ mult (letter_less r <*lex*> greek_less r)"
proof (rule mult_on_union, induct rule: mult_of_image_mset[OF * *])
case (1 x y) thus ?case unfolding adj_msog_def
by (auto intro: less(1) split: prod.splits accent.splits dest!: ms_of_greek_shorter)
next
case 2 thus ?case using less(2) by (subst(asm) greek_less_unfold) simp
qed
}
moreover {
fix N have "({# adj_msog [] s (x,[]) #} + N,{# adj_msog [] t (x,[]) #} + N) ∈
(mult (letter_less r <*lex*> greek_less r))⇧="
by (auto simp: adj_msog_def less split: accent.splits) }
ultimately show ?case using transD[OF trans_mult]
by (subst greek_less_unfold) (fastforce simp: ms_of_greek_cons)
qed
lemma greek_less_app_mono2:
assumes "trans r" and "(s, t) ∈ greek_less r"
shows "(p @ s, p @ t) ∈ greek_less r"
using assms by (induct p) (auto simp add: greek_less_cons_mono)
lemma greek_less_app_mono1:
assumes "trans r" and "(s, t) ∈ greek_less r"
shows "(s @ p, t @ p) ∈ greek_less r"
using inv_greek_mono[of r "inv_greek p @ inv_greek s" "inv_greek p @ inv_greek t"]
by (simp add: assms inv_greek_append inv_greek_mono greek_less_app_mono2)
subsection ‹Well-founded-ness of @{term "greek_less r"}›
lemma greek_embed:
assumes "trans r"
shows "list_emb (λa b. (a, b): reflcl (letter_less r)) a b ⟹ (a, b) ∈ reflcl (greek_less r)"
proof (induct rule: list_emb.induct)
case (list_emb_Cons a b y) thus ?case
using trans_greek_less[unfolded trans_def] ‹trans r›
greek_less_app_mono1[of r "[]" "[y]" a] greek_less_app_mono2[of r a b "[y]"] by auto
next
case (list_emb_Cons2 x y a b) thus ?case
using trans_greek_less[unfolded trans_def] ‹trans r› greek_less_singleton[of x y r]
greek_less_app_mono1[of r "[x]" "[y]" a] greek_less_app_mono2[of r a b "[y]"] by auto
qed simp
lemma wqo_letter_less:
assumes t: "trans r" and w: "wqo_on (λa b. (a, b) ∈ r⇧=) UNIV"
shows "wqo_on (λa b. (a, b) ∈ (letter_less r)⇧=) UNIV"
proof (rule wqo_on_hom[of _ id _ "prod_le (=) (λa b. (a, b) ∈ r⇧=)", unfolded image_id id_apply])
show "wqo_on (prod_le ((=) :: accent ⇒ accent ⇒ bool) (λa b. (a, b) ∈ r⇧=)) UNIV"
by (rule dickson[OF finite_eq_wqo_on[OF finite_accent] w, unfolded UNIV_Times_UNIV])
qed (insert t, auto simp: transp_on_def trans_def prod_le_def)
lemma wf_greek_less:
assumes "wf r" and "trans r"
shows "wf (greek_less r)"
proof -
obtain q where "r ⊆ q" and "well_order q" by (metis total_well_order_extension ‹wf r›)
define q' where "q' = q - Id"
from ‹well_order q› have "reflcl q' = q"
by (auto simp add: well_order_on_def linear_order_on_def partial_order_on_def preorder_on_def
refl_on_def q'_def)
from ‹well_order q› have "trans q'" and "irrefl q'"
unfolding well_order_on_def linear_order_on_def partial_order_on_def preorder_on_def antisym_def
trans_def irrefl_def q'_def by blast+
from ‹r ⊆ q› ‹wf r› have "r ⊆ q'" by (auto simp add: q'_def)
have "wqo_on (λa b. (a,b) ∈ (greek_less q')⇧=) UNIV"
proof (intro wqo_on_hom[of "(λa b. (a, b) ∈ (greek_less q')⇧=)" "id" UNIV
"list_emb (λa b. (a, b) ∈ (letter_less q')⇧=)", unfolded surj_id])
show "transp_on (λa b. (a, b) ∈ (greek_less q')⇧=) UNIV"
using trans_greek_less[of q'] unfolding trans_def transp_on_def by blast
next
show "∀x∈UNIV. ∀y∈UNIV. list_emb (λa b. (a, b) ∈ (letter_less q')⇧=) x y ⟶
(id x, id y) ∈ (greek_less q')⇧="
using greek_embed[OF ‹trans q'›] by auto
next
show "wqo_on (list_emb (λa b. (a, b) ∈ (letter_less q')⇧=)) UNIV"
using higman[OF wqo_letter_less[OF ‹trans q'›]] ‹well_order q› ‹reflcl q' = q›
by (auto simp: well_order_implies_wqo)
qed
with wqo_on_imp_wfp_on[OF this] strict_order_strict[OF strict_order_greek_less]
‹irrefl q'› ‹trans q'›
have "wfp_on (λa b. (a, b) ∈ greek_less q') UNIV" by force
then show ?thesis
using mono_greek_less ‹r ⊆ q'› wf_subset unfolding wf_iff_wfp_on[symmetric] mono_def by metis
qed
subsection ‹Basic Comparisons›
lemma pairwise_imp_mult:
assumes "N ≠ {#}" and "∀x ∈ set_mset M. ∃y ∈ set_mset N. (x, y) ∈ r"
shows "(M, N) ∈ mult r"
using assms one_step_implies_mult[of _ _ _ "{#}"] by auto
lemma singleton_greek_less:
assumes as: "snd ` set as ⊆ under r b"
shows "(as, [(a,b)]) ∈ greek_less r"
proof -
{
fix e assume "e ∈ set_mset (ms_of_greek as)"
with as ms_of_greek_elem[of _ _ as]
have "(e, ((a,b),[])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover have "ms_of_greek [(a,b)] = {# ((a,b),[]) #}"
by (auto simp: ms_of_greek_def adj_msog_def split: accent.splits)
ultimately show ?thesis
by (subst greek_less_unfold) (auto intro!: pairwise_imp_mult)
qed
lemma peak_greek_less:
assumes as: "snd ` set as ⊆ under r a" and b': "b' ∈ {[(Grave,b)],[]}"
and cs: "snd ` set cs ⊆ under r a ∪ under r b" and a': "a' ∈ {[(Acute,a)],[]}"
and bs: "snd ` set bs ⊆ under r b"
shows "(as @ b' @ cs @ a' @ bs, [(Acute,a),(Grave,b)]) ∈ greek_less r"
proof -
let ?A = "(Acute,a)" and ?B = "(Grave,b)"
have "(ms_of_greek (as @ b' @ cs @ a' @ bs), ms_of_greek [?A,?B]) ∈ mult (letter_less r <*lex*> greek_less r)"
proof (intro pairwise_imp_mult)
{
fix e assume "e ∈ set_mset (ms_of_greek as)"
with as ms_of_greek_elem[of _ _ as]
have "(adj_msog [] (b' @ cs @ a' @ bs) e, (?A,[?B])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek b')"
with b' singleton_greek_less[OF as] ms_of_greek_elem[of _ _ b']
have "(adj_msog as (cs @ a' @ bs) e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def ms_of_greek_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek cs)"
with cs ms_of_greek_elem[of _ _ cs]
have "(adj_msog (as @ b') (a' @ bs) e, (?A,[?B])) ∈ letter_less r <*lex*> greek_less r ∨
(adj_msog (as @ b') (a' @ bs) e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek a')"
with a' singleton_greek_less[OF bs] ms_of_greek_elem[of _ _ a']
have "(adj_msog (as @ b' @ cs) bs e, (?A,[?B])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def ms_of_greek_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek bs)"
with bs ms_of_greek_elem[of _ _ bs]
have "(adj_msog (as @ b' @ cs @ a') [] e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover have "ms_of_greek [?A,?B] = {# (?B,[?A]), (?A,[?B]) #}"
by (simp add: adj_msog_def ms_of_greek_def)
ultimately show "∀x∈set_mset (ms_of_greek (as @ b' @ cs @ a' @ bs)).
∃y∈set_mset (ms_of_greek [?A,?B]). (x, y) ∈ letter_less r <*lex*> greek_less r"
by (auto simp: msog_append) blast
qed (auto simp: ms_of_greek_def)
then show ?thesis by (subst greek_less_unfold) auto
qed
lemma rcliff_greek_less1:
assumes "trans r"
and as: "snd ` set as ⊆ under r a ∩ under r b" and b': "b' ∈ {[(Grave,b)],[]}"
and cs: "snd ` set cs ⊆ under r b" and a': "a' = [(Macron,a)]"
and bs: "snd ` set bs ⊆ under r b"
shows "(as @ b' @ cs @ a' @ bs, [(Macron,a),(Grave,b)]) ∈ greek_less r"
proof -
let ?A = "(Macron,a)" and ?B = "(Grave,b)"
have *: "ms_of_greek [?A,?B] = {#(?B,[?A]), (?A,[])#}" "ms_of_greek [?A] = {#(?A,[])#}"
by (simp_all add: ms_of_greek_def adj_msog_def)
then have **: "ms_of_greek [(Macron, a), (Grave, b)] - {#((Macron, a), [])#} ≠ {#}"
by (auto)
{
fix e assume "e ∈ set_mset (ms_of_greek as)"
with as ms_of_greek_elem[of _ _ as]
have "(adj_msog [] (b' @ cs @ a' @ bs) e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (force simp: adj_msog_def under_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek b')"
with b' singleton_greek_less as ms_of_greek_elem[of _ _ b']
have "(adj_msog as (cs @ a' @ bs) e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def ms_of_greek_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek cs)"
with cs ms_of_greek_elem[of _ _ cs]
have "(adj_msog (as @ b') (a' @ bs) e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek bs)"
with bs ms_of_greek_elem[of _ _ bs]
have "(adj_msog (as @ b' @ cs @ a') [] e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover have "ms_of_greek [?A,?B] = {# (?B,[?A]), (?A,[]) #}"
by (simp add: adj_msog_def ms_of_greek_def)
ultimately have "∀x∈set_mset (ms_of_greek (as @ b' @ cs @ a' @ bs) - {#(?A,[])#}).
∃y∈set_mset (ms_of_greek [?A,?B] - {#(?A,[])#}). (x, y) ∈ letter_less r <*lex*> greek_less r"
unfolding msog_append by (auto simp: a' msog_append ac_simps * adj_msog_single)
from one_step_implies_mult[OF ** this,of "{#(?A,[])#}"]
have "(ms_of_greek (as @ b' @ cs @ a' @ bs), ms_of_greek [?A,?B]) ∈ mult (letter_less r <*lex*> greek_less r)"
unfolding a' msog_append by (auto simp: a' ac_simps * adj_msog_single)
then show ?thesis
by (subst greek_less_unfold) auto
qed
lemma rcliff_greek_less2:
assumes "trans r"
and as: "snd ` set as ⊆ under r a" and b': "b' ∈ {[(Grave,b)],[]}"
and cs: "snd ` set cs ⊆ under r a ∪ under r b"
shows "(as @ b' @ cs, [(Macron,a),(Grave,b)]) ∈ greek_less r"
proof -
let ?A = "(Macron,a)" and ?B = "(Grave,b)"
have "(ms_of_greek (as @ b' @ cs), ms_of_greek [?A,?B]) ∈ mult (letter_less r <*lex*> greek_less r)"
proof (intro pairwise_imp_mult)
{
fix e assume "e ∈ set_mset (ms_of_greek as)"
with as ms_of_greek_elem[of _ _ as]
have "(adj_msog [] (b' @ cs) e, (?A,[])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek b')"
with b' singleton_greek_less[OF as] ms_of_greek_elem[of _ _ b']
have "(adj_msog as (cs) e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def ms_of_greek_def)
}
moreover {
fix e assume "e ∈ set_mset (ms_of_greek cs)"
with cs ms_of_greek_elem[of _ _ cs]
have "(adj_msog (as @ b') [] e, (?A,[])) ∈ letter_less r <*lex*> greek_less r ∨
(adj_msog (as @ b') [] e, (?B,[?A])) ∈ letter_less r <*lex*> greek_less r"
by (cases e) (fastforce simp: adj_msog_def under_def)
}
moreover have *: "ms_of_greek [?A,?B] = {# (?B,[?A]), (?A,[]) #}"
by (simp add: adj_msog_def ms_of_greek_def)
ultimately show "∀x∈set_mset (ms_of_greek (as @ b' @ cs)).
∃y∈set_mset (ms_of_greek [?A,?B]). (x, y) ∈ letter_less r <*lex*> greek_less r"
by (auto simp: msog_append adj_msog_single ac_simps *) blast
qed (auto simp: ms_of_greek_def)
then show ?thesis by (subst greek_less_unfold) auto
qed
lemma snd_inv_greek [simp]: "snd ` set (inv_greek as) = snd ` set as"
by (force simp: inv_greek_def)
lemma lcliff_greek_less1:
assumes "trans r"
and as: "snd ` set as ⊆ under r a" and b': "b' = [(Macron,b)]"
and cs: "snd ` set cs ⊆ under r a" and a': "a' ∈ {[(Acute,a)],[]}"
and bs: "snd ` set bs ⊆ under r a ∩ under r b"
shows "(as @ b' @ cs @ a' @ bs, [(Acute,a),(Macron,b)]) ∈ greek_less r"
proof -
have *: "inv_greek [(Acute,a),(Macron,b)] = [(Macron,b),(Grave,a)]" by (simp add: inv_greek_def)
have "(inv_greek (inv_greek (as @ b' @ cs @ a' @ bs)),
inv_greek (inv_greek ([(Acute,a),(Macron,b)]))) ∈ greek_less r"
apply (rule inv_greek_mono[OF ‹trans r›])
apply (unfold inv_greek_append append_assoc *)
apply (insert assms)
apply (rule rcliff_greek_less1, auto simp: inv_greek_def)
done
then show ?thesis by simp
qed
lemma lcliff_greek_less2:
assumes "trans r"
and cs: "snd ` set cs ⊆ under r a ∪ under r b" and a': "a' ∈ {[(Acute,a)],[]}"
and bs: "snd ` set bs ⊆ under r b"
shows "(cs @ a' @ bs, [(Acute,a),(Macron,b)]) ∈ greek_less r"
proof -
have *: "inv_greek [(Acute,a),(Macron,b)] = [(Macron,b),(Grave,a)]" by (simp add: inv_greek_def)
have "(inv_greek (inv_greek (cs @ a' @ bs)),
inv_greek (inv_greek ([(Acute,a),(Macron,b)]))) ∈ greek_less r"
apply (rule inv_greek_mono[OF ‹trans r›])
apply (unfold inv_greek_append append_assoc *)
apply (insert assms)
apply (rule rcliff_greek_less2, auto simp: inv_greek_def)
done
then show ?thesis by simp
qed
subsection ‹Labeled abstract rewriting›
context
fixes L R E :: "'b ⇒ 'a rel"
begin
definition lstep :: "'b letter ⇒ 'a rel" where
[simp]: "lstep x = (case x of (a, i) ⇒ (case a of Acute ⇒ (L i)¯ | Grave ⇒ R i | Macron ⇒ E i))"
fun lconv :: "'b greek ⇒ 'a rel" where
"lconv [] = Id"
| "lconv (x # xs) = lstep x O lconv xs"
lemma lconv_append[simp]:
"lconv (xs @ ys) = lconv xs O lconv ys"
by (induct xs) auto
lemma conversion_join_or_peak_or_cliff:
obtains (join) as bs cs where "set as ⊆ {Grave}" and "set bs ⊆ {Macron}" and "set cs ⊆ {Acute}"
and "ds = as @ bs @ cs"
| (peak) as bs where "ds = as @ ([Acute] @ [Grave]) @ bs"
| (lcliff) as bs where "ds = as @ ([Acute] @ [Macron]) @ bs"
| (rcliff) as bs where "ds = as @ ([Macron] @ [Grave]) @ bs"
proof (induct ds arbitrary: thesis)
case (Cons d ds thesis) note IH = this show ?case
proof (rule IH(1))
fix as bs assume "ds = as @ ([Acute] @ [Grave]) @ bs" then show ?case
using IH(3)[of "d # as" bs] by simp
next
fix as bs assume "ds = as @ ([Acute] @ [Macron]) @ bs" then show ?case
using IH(4)[of "d # as" bs] by simp
next
fix as bs assume "ds = as @ ([Macron] @ [Grave]) @ bs" then show ?case
using IH(5)[of "d # as" bs] by simp
next
fix as bs cs assume *: "set as ⊆ {Grave}" "set bs ⊆ {Macron}" "set cs ⊆ {Acute}" "ds = as @ bs @ cs"
show ?case
proof (cases d)
case Grave thus ?thesis using * IH(2)[of "d # as" bs cs] by simp
next
case Macron show ?thesis
proof (cases as)
case Nil thus ?thesis using * Macron IH(2)[of as "d # bs" cs] by simp
next
case (Cons a as) thus ?thesis using * Macron IH(5)[of "[]" "as @ bs @ cs"] by simp
qed
next
case Acute show ?thesis
proof (cases as)
case Nil note as = this show ?thesis
proof (cases bs)
case Nil thus ?thesis using * as Acute IH(2)[of "[]" "[]" "d # cs"] by simp
next
case (Cons b bs) thus ?thesis using * as Acute IH(4)[of "[]" "bs @ cs"] by simp
qed
next
case (Cons a as) thus ?thesis using * Acute IH(3)[of "[]" "as @ bs @ cs"] by simp
qed
qed
qed
qed auto
lemma map_eq_append_split:
assumes "map f xs = ys1 @ ys2"
obtains xs1 xs2 where "ys1 = map f xs1" "ys2 = map f xs2" "xs = xs1 @ xs2"
proof (insert assms, induct ys1 arbitrary: xs thesis)
case (Cons y ys) note IH = this show ?case
proof (cases xs)
case (Cons x xs') show ?thesis
proof (rule IH(1))
fix xs1 xs2 assume "ys = map f xs1" "ys2 = map f xs2" "xs' = xs1 @ xs2" thus ?thesis
using Cons IH(2)[of "x # xs1" xs2] IH(3) by simp
next
show "map f xs' = ys @ ys2" using Cons IH(3) by simp
qed
qed (insert Cons, simp)
qed auto
lemmas map_eq_append_splits = map_eq_append_split map_eq_append_split[OF sym]
abbreviation "conversion' M ≡ ((⋃i ∈ M. R i) ∪ (⋃i ∈ M. E i) ∪ (⋃i ∈ M. L i)¯)⇧*"
abbreviation "valley' M ≡ (⋃i ∈ M. R i)⇧* O (⋃i ∈ M. E i)⇧* O ((⋃i ∈ M. L i)¯)⇧*"
lemma conversion_to_lconv:
assumes "(u, v) ∈ conversion' M"
obtains xs where "snd ` set xs ⊆ M" and "(u, v) ∈ lconv xs"
using assms
proof (induct arbitrary: thesis rule: converse_rtrancl_induct)
case base show ?case using base[of "[]"] by simp
next
case (step u' x)
from step(1) obtain p where "snd p ∈ M" and "(u', x) ∈ lstep p"
by (force split: accent.splits)
moreover obtain xs where "snd ` set xs ⊆ M" "(x, v) ∈ lconv xs" by (rule step(3))
ultimately show ?case using step(4)[of "p # xs"] by auto
qed
definition lpeak :: "'b rel ⇒ 'b ⇒ 'b ⇒ 'b greek ⇒ bool" where
"lpeak r a b xs ⟷ (∃as b' cs a' bs. snd ` set as ⊆ under r a ∧ b' ∈ {[(Grave,b)],[]} ∧
snd ` set cs ⊆ under r a ∪ under r b ∧ a' ∈ {[(Acute,a)],[]} ∧
snd ` set bs ⊆ under r b ∧ xs = as @ b' @ cs @ a' @ bs)"
definition lcliff :: "'b rel ⇒ 'b ⇒ 'b ⇒ 'b greek ⇒ bool" where
"lcliff r a b xs ⟷ (∃as b' cs a' bs. snd ` set as ⊆ under r a ∧ b' = [(Macron,b)] ∧
snd ` set cs ⊆ under r a ∧ a' ∈ {[(Acute,a)],[]} ∧
snd ` set bs ⊆ under r a ∩ under r b ∧ xs = as @ b' @ cs @ a' @ bs) ∨
(∃cs a' bs. snd ` set cs ⊆ under r a ∪ under r b ∧ a' ∈ {[(Acute,a)],[]} ∧
snd ` set bs ⊆ under r b ∧ xs = cs @ a' @ bs)"
definition rcliff :: "'b rel ⇒ 'b ⇒ 'b ⇒ 'b greek ⇒ bool" where
"rcliff r a b xs ⟷ (∃as b' cs a' bs. snd ` set as ⊆ under r a ∩ under r b ∧ b' ∈ {[(Grave,b)],[]} ∧
snd ` set cs ⊆ under r b ∧ a' = [(Macron,a)] ∧
snd ` set bs ⊆ under r b ∧ xs = as @ b' @ cs @ a' @ bs) ∨
(∃as b' cs. snd ` set as ⊆ under r a ∧ b' ∈ {[(Grave,b)],[]} ∧
snd ` set cs ⊆ under r a ∪ under r b ∧ xs = as @ b' @ cs)"
lemma dd_commute_modulo_conv[case_names wf trans peak lcliff rcliff]:
assumes "wf r" and "trans r"
and pk: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ R b ⟹ ∃xs. lpeak r a b xs ∧ (t, u) ∈ lconv xs"
and lc: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ E b ⟹ ∃xs. lcliff r a b xs ∧ (t, u) ∈ lconv xs"
and rc: "⋀a b s t u. (s, t) ∈ (E a)¯ ⟹ (s, u) ∈ R b ⟹ ∃xs. rcliff r a b xs ∧ (t, u) ∈ lconv xs"
shows "conversion' UNIV ⊆ valley' UNIV"
proof (intro subrelI)
fix u v
assume "(u,v) ∈ conversion' UNIV"
then obtain xs where "(u, v) ∈ lconv xs" by (auto intro: conversion_to_lconv[of u v])
then show "(u, v) ∈ valley' UNIV"
proof (induct xs rule: wf_induct[of "greek_less r"])
case 1 thus ?case using wf_greek_less[OF ‹wf r› ‹trans r›] .
next
case (2 xs) show ?case
proof (rule conversion_join_or_peak_or_cliff[of "map fst xs"])
fix as bs cs
assume *: "set as ⊆ {Grave}" "set bs ⊆ {Macron}" "set cs ⊆ {Acute}" "map fst xs = as @ bs @ cs"
then show "(u, v) ∈ valley' UNIV"
proof (elim map_eq_append_splits)
fix as' bs' cs' bcs'
assume as: "set as ⊆ {Grave}" "as = map fst as'" and
bs: "set bs ⊆ {Macron}" "bs = map fst bs'" and
cs: "set cs ⊆ {Acute}" "cs = map fst cs'" and
xs: "xs = as' @ bcs'" "bcs' = bs' @ cs'"
from as(1)[unfolded as(2)] have as': "⋀x y. (x,y) ∈ lconv as' ⟹ (x,y) ∈ (⋃a. R a)⇧*"
proof (induct as')
case (Cons x' xs)
have "⋀x y z i. (x,y) ∈ R i ⟹ (y,z) ∈ (⋃a. R a)⇧* ⟹ (x,z) ∈ (⋃a. R a)⇧*"
by (rule rtrancl_trans) auto
with Cons show ?case by auto
qed simp
from bs(1)[unfolded bs(2)] have bs': "⋀x y. (x,y) ∈ lconv bs' ⟹ (x,y) ∈ (⋃a. E a)⇧*"
proof (induct bs')
case (Cons x' xs)
have "⋀x y z i. (x,y) ∈ E i ⟹ (y,z) ∈ (⋃a. E a)⇧* ⟹ (x,z) ∈ (⋃a. E a)⇧*"
by (rule rtrancl_trans) auto
with Cons show ?case by auto
qed simp
from cs(1)[unfolded cs(2)] have cs': "⋀x y. (x,y) ∈ lconv cs' ⟹ (x,y) ∈ ((⋃a. L a)¯)⇧*"
proof (induct cs')
case (Cons x' xs)
have "⋀x y z i. (x,y) ∈ (L i)¯ ⟹ (y,z) ∈ ((⋃a. L a)¯)⇧* ⟹ (x,z) ∈ ((⋃a. L a)¯)⇧*"
by (rule rtrancl_trans) auto
with Cons show ?case by auto
qed simp
from 2(2) as' bs' cs' show "(u, v) ∈ valley' UNIV"
unfolding xs lconv_append by auto (meson relcomp.simps)
qed
next
fix as bs assume *: "map fst xs = as @ ([Acute] @ [Grave]) @ bs"
{
fix p a b q t' s' u'
assume xs: "xs = p @ [(Acute,a),(Grave,b)] @ q" and p: "(u,t') ∈ lconv p"
and a: "(s',t') ∈ L a" and b: "(s',u') ∈ R b" and q: "(u',v) ∈ lconv q"
obtain js where lp: "lpeak r a b js" and js: "(t',u') ∈ lconv js" using pk[OF a b] by auto
from lp have "(js, [(Acute,a),(Grave,b)]) ∈ greek_less r"
unfolding lpeak_def using peak_greek_less[of _ r a _ b] by fastforce
then have "(p @ js @ q, xs) ∈ greek_less r" unfolding xs
by (intro greek_less_app_mono1 greek_less_app_mono2 ‹trans r›) auto
moreover have "(u, v) ∈ lconv (p @ js @ q)"
using p q js by auto
ultimately have "(u, v) ∈ valley' UNIV" using 2(1) by blast
}
with * show "(u, v) ∈ valley' UNIV" using 2(2)
by (auto elim!: map_eq_append_splits relcompEpair simp del: append.simps) simp
next
fix as bs assume *: "map fst xs = as @ ([Acute] @ [Macron]) @ bs"
{
fix p a b q t' s' u'
assume xs: "xs = p @ [(Acute,a),(Macron,b)] @ q" and p: "(u,t') ∈ lconv p"
and a: "(s',t') ∈ L a" and b: "(s',u') ∈ E b" and q: "(u',v) ∈ lconv q"
obtain js where lp: "lcliff r a b js" and js: "(t',u') ∈ lconv js" using lc[OF a b] by auto
from lp have "(js, [(Acute,a),(Macron,b)]) ∈ greek_less r"
unfolding lcliff_def
using lcliff_greek_less1[OF ‹trans r›, of _ a _ b] lcliff_greek_less2[OF ‹trans r›, of _ a b]
by fastforce
then have "(p @ js @ q, xs) ∈ greek_less r" unfolding xs
by (intro greek_less_app_mono1 greek_less_app_mono2 ‹trans r›) auto
moreover have "(u, v) ∈ lconv (p @ js @ q)"
using p q js by auto
ultimately have "(u, v) ∈ valley' UNIV" using 2(1) by blast
}
with * show "(u, v) ∈ valley' UNIV" using 2(2)
by (auto elim!: map_eq_append_splits relcompEpair simp del: append.simps) simp
next
fix as bs assume *: "map fst xs = as @ ([Macron] @ [Grave]) @ bs"
{
fix p a b q t' s' u'
assume xs: "xs = p @ [(Macron,a),(Grave,b)] @ q" and p: "(u,t') ∈ lconv p"
and a: "(s',t') ∈ (E a)¯" and b: "(s',u') ∈ R b" and q: "(u',v) ∈ lconv q"
obtain js where lp: "rcliff r a b js" and js: "(t',u') ∈ lconv js" using rc[OF a b] by auto
from lp have "(js, [(Macron,a),(Grave,b)]) ∈ greek_less r"
unfolding rcliff_def
using rcliff_greek_less1[OF ‹trans r›, of _ a b] rcliff_greek_less2[OF ‹trans r›, of _ a _ b]
by fastforce
then have "(p @ js @ q, xs) ∈ greek_less r" unfolding xs
by (intro greek_less_app_mono1 greek_less_app_mono2 ‹trans r›) auto
moreover have "(u, v) ∈ lconv (p @ js @ q)"
using p q js by auto
ultimately have "(u, v) ∈ valley' UNIV" using 2(1) by blast
}
with * show "(u, v) ∈ valley' UNIV" using 2(2)
by (auto elim!: map_eq_append_splits relcompEpair simp del: append.simps) simp
qed
qed
qed
section ‹Results›
subsection ‹Church-Rosser modulo›
text ‹Decreasing diagrams for Church-Rosser modulo, commutation version.›
lemma dd_commute_modulo[case_names wf trans peak lcliff rcliff]:
assumes "wf r" and "trans r"
and pk: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ R b ⟹
(t, u) ∈ conversion' (under r a) O (R b)⇧= O conversion' (under r a ∪ under r b) O
((L a)¯)⇧= O conversion' (under r b)"
and lc: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ E b ⟹
(t, u) ∈ conversion' (under r a) O E b O conversion' (under r a) O
((L a)¯)⇧= O conversion' (under r a ∩ under r b) ∨
(t, u) ∈ conversion' (under r a ∪ under r b) O ((L a )¯)⇧= O conversion' (under r b)"
and rc: "⋀a b s t u. (s, t) ∈ (E a)¯ ⟹ (s, u) ∈ R b ⟹
(t, u) ∈ conversion' (under r a ∩ under r b) O (R b)⇧= O conversion' (under r b) O
E a O conversion' (under r b) ∨
(t, u) ∈ conversion' (under r a) O (R b)⇧= O conversion' (under r a ∪ under r b)"
shows "conversion' UNIV ⊆ valley' UNIV"
proof (cases rule: dd_commute_modulo_conv[of r])
case (peak a b s t u)
{
fix w x y z
assume "(t, w) ∈ conversion' (under r a)"
from conversion_to_lconv[OF this]
obtain as where "snd ` set as ⊆ under r a" "(t, w) ∈ lconv as" by auto
moreover assume "(w, x) ∈ (R b)⇧="
then obtain b' where "b' ∈ {[(Grave,b)],[]}" "(w, x) ∈ lconv b'" by fastforce
moreover assume "(x, y) ∈ conversion' (under r a ∪ under r b)"
from conversion_to_lconv[OF this]
obtain cs where "snd ` set cs ⊆ under r a ∪ under r b" "(x, y) ∈ lconv cs" by auto
moreover assume "(y, z) ∈ ((L a)¯)⇧="
then obtain a' where "a' ∈ {[(Acute,a)],[]}" "(y, z) ∈ lconv a'" by fastforce
moreover assume "(z, u) ∈ conversion' (under r b)"
from conversion_to_lconv[OF this]
obtain bs where "snd ` set bs ⊆ under r b" "(z, u) ∈ lconv bs" by auto
ultimately have "∃xs. lpeak r a b xs ∧ (t, u) ∈ lconv xs"
by (intro exI[of _ "as @ b' @ cs @ a' @ bs"], unfold lconv_append lpeak_def) blast
}
then show ?case using pk[OF peak] by blast
next
case (lcliff a b s t u)
{
fix w x y z
assume "(t, w) ∈ conversion' (under r a)"
from conversion_to_lconv[OF this]
obtain as where "snd ` set as ⊆ under r a" "(t, w) ∈ lconv as" by auto
moreover assume "(w, x) ∈ E b"
then obtain b' where "b' = [(Macron,b)]" "(w, x) ∈ lconv b'" by fastforce
moreover assume "(x, y) ∈ conversion' (under r a)"
from conversion_to_lconv[OF this]
obtain cs where "snd ` set cs ⊆ under r a" "(x, y) ∈ lconv cs" by auto
moreover assume "(y, z) ∈ ((L a)¯)⇧="
then obtain a' where "a' ∈ {[(Acute,a)],[]}" "(y, z) ∈ lconv a'" by fastforce
moreover assume "(z, u) ∈ conversion' (under r a ∩ under r b)"
from conversion_to_lconv[OF this]
obtain bs where "snd ` set bs ⊆ under r a ∩ under r b" "(z, u) ∈ lconv bs" by auto
ultimately have "∃xs. lcliff r a b xs ∧ (t, u) ∈ lconv xs"
by (intro exI[of _ "as @ b' @ cs @ a' @ bs"], unfold lconv_append lcliff_def) blast
}
moreover {
fix w x
assume "(t, w) ∈ conversion' (under r a ∪ under r b)"
from conversion_to_lconv[OF this]
obtain cs where "snd ` set cs ⊆ under r a ∪ under r b" "(t, w) ∈ lconv cs" by auto
moreover assume "(w, x) ∈ ((L a)¯)⇧="
then obtain a' where "a' ∈ {[(Acute,a)],[]}" "(w, x) ∈ lconv a'" by fastforce
moreover assume "(x, u) ∈ conversion' (under r b)"
from conversion_to_lconv[OF this]
obtain bs where "snd ` set bs ⊆ under r b" "(x, u) ∈ lconv bs" by auto
ultimately have "∃xs. lcliff r a b xs ∧ (t, u) ∈ lconv xs"
by (intro exI[of _ "cs @ a' @ bs"], unfold lconv_append lcliff_def) blast
}
ultimately show ?case using lc[OF lcliff] by blast
next
case (rcliff a b s t u)
{
fix w x y z
assume "(t, w) ∈ conversion' (under r a ∩ under r b)"
from conversion_to_lconv[OF this]
obtain as where "snd ` set as ⊆ under r a ∩ under r b" "(t, w) ∈ lconv as" by auto
moreover assume "(w, x) ∈ (R b)⇧="
then obtain b' where "b' ∈ {[(Grave,b)],[]}" "(w, x) ∈ lconv b'" by fastforce
moreover assume "(x, y) ∈ conversion' (under r b)"
from conversion_to_lconv[OF this]
obtain cs where "snd ` set cs ⊆ under r b" "(x, y) ∈ lconv cs" by auto
moreover assume "(y, z) ∈ E a"
then obtain a' where "a' = [(Macron,a)]" "(y, z) ∈ lconv a'" by fastforce
moreover assume "(z, u) ∈ conversion' (under r b)"
from conversion_to_lconv[OF this]
obtain bs where "snd ` set bs ⊆ under r b" "(z, u) ∈ lconv bs" by auto
ultimately have "∃xs. rcliff r a b xs ∧ (t, u) ∈ lconv xs"
by (intro exI[of _ "as @ b' @ cs @ a' @ bs"], unfold lconv_append rcliff_def) blast
}
moreover {
fix w x
assume "(t, w) ∈ conversion' (under r a)"
from conversion_to_lconv[OF this]
obtain as where "snd ` set as ⊆ under r a" "(t, w) ∈ lconv as" by auto
moreover assume "(w, x) ∈ (R b)⇧="
then obtain b' where "b' ∈ {[(Grave,b)],[]}" "(w, x) ∈ lconv b'" by fastforce
moreover assume "(x, u) ∈ conversion' (under r a ∪ under r b)"
from conversion_to_lconv[OF this]
obtain cs where "snd ` set cs ⊆ under r a ∪ under r b" "(x, u) ∈ lconv cs" by auto
ultimately have "∃xs. rcliff r a b xs ∧ (t, u) ∈ lconv xs"
by (intro exI[of _ "as @ b' @ cs"], unfold lconv_append rcliff_def) blast
}
ultimately show ?case using rc[OF rcliff] by blast
qed fact+
end
text ‹Decreasing diagrams for Church-Rosser modulo.›
lemma dd_cr_modulo[case_names wf trans symE peak cliff]:
assumes "wf r" and "trans r" and E: "⋀i. sym (E i)"
and pk: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ L b ⟹
(t, u) ∈ conversion' L L E (under r a) O (L b)⇧= O conversion' L L E (under r a ∪ under r b) O
((L a)¯)⇧= O conversion' L L E (under r b)"
and cl: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ E b ⟹
(t, u) ∈ conversion' L L E (under r a) O E b O conversion' L L E (under r a) O
((L a)¯)⇧= O conversion' L L E (under r a ∩ under r b) ∨
(t, u) ∈ conversion' L L E (under r a ∪ under r b) O ((L a )¯)⇧= O conversion' L L E (under r b)"
shows "conversion' L L E UNIV ⊆ valley' L L E UNIV"
proof (induct rule: dd_commute_modulo[of r])
note E' = E[unfolded sym_conv_converse_eq]
case (rcliff a b s t u) show ?case
using cl[OF rcliff(2) rcliff(1)[unfolded E'], unfolded converse_iff[of t u,symmetric]]
by (auto simp only: ac_simps E' converse_inward)
qed fact+
subsection ‹Commutation and confluence›
abbreviation "conversion'' L R M ≡ ((⋃i ∈ M. R i) ∪ (⋃i ∈ M. L i)¯)⇧*"
abbreviation "valley'' L R M ≡ (⋃i ∈ M. R i)⇧* O ((⋃i ∈ M. L i)¯)⇧*"
text ‹Decreasing diagrams for commutation.›
lemma dd_commute[case_names wf trans peak]:
assumes "wf r" and "trans r"
and pk: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ R b ⟹
(t, u) ∈ conversion'' L R (under r a) O (R b)⇧= O conversion'' L R (under r a ∪ under r b) O
((L a)¯)⇧= O conversion'' L R (under r b)"
shows "commute (⋃i. L i) (⋃i. R i)"
proof -
have "((⋃i. L i)¯)⇧* O (⋃i. R i)⇧* ⊆ conversion'' L R UNIV" by regexp
also have "… ⊆ valley'' L R UNIV"
using dd_commute_modulo[OF assms(1,2), of L R "λ_. {}"] pk by auto
finally show ?thesis by (simp only: commute_def)
qed
text ‹Decreasing diagrams for confluence.›
lemmas dd_cr[case_names wf trans peak] =
dd_commute[of _ L L for L, unfolded CR_iff_self_commute[symmetric]]
subsection ‹Extended decreasing diagrams›
context
fixes r q :: "'b rel"
assumes "wf r" and "trans r" and "trans q" and "refl q" and compat: "r O q ⊆ r"
begin
private abbreviation (input) down :: "('b ⇒ 'a rel) ⇒ ('b ⇒ 'a rel)" where
"down L ≡ λi. ⋃j ∈ under q i. L j"
private lemma Union_down: "(⋃i. down L i) = (⋃i. L i)"
using ‹refl q› by (auto simp: refl_on_def under_def)
text ‹Extended decreasing diagrams for commutation.›
lemma edd_commute[case_names wf transr transq reflq compat peak]:
assumes pk: "⋀a b s t u. (s, t) ∈ L a ⟹ (s, u) ∈ R b ⟹
(t, u) ∈ conversion'' L R (under r a) O (down R b)⇧= O conversion'' L R (under r a ∪ under r b) O
((down L a)¯)⇧= O conversion'' L R (under r b)"
shows "commute (⋃i. L i) (⋃i. R i)"
unfolding Union_down[of L, symmetric] Union_down[of R, symmetric]
proof (induct rule: dd_commute[of r "down L" "down R"])
case (peak a b s t u)
then obtain a' b' where a': "(a', a) ∈ q" "(s, t) ∈ L a'" and b': "(b', b) ∈ q" "(s, u) ∈ R b'"
by (auto simp: under_def)
have "⋀a' a. (a',a) ∈ q ⟹ under r a' ⊆ under r a" using compat by (auto simp: under_def)
then have aux1: "⋀a' a L. (a',a) ∈ q ⟹ (⋃i ∈ under r a'. L i) ⊆ (⋃i ∈ under r a. L i)" by auto
have aux2: "⋀a' a L. (a',a) ∈ q ⟹ down L a' ⊆ down L a"
using ‹trans q› by (auto simp: under_def trans_def)
have aux3: "⋀a L. (⋃i ∈ under r a. L i) ⊆ (⋃i ∈ under r a. down L i)"
using ‹refl q› by (auto simp: under_def refl_on_def)
from aux1[OF a'(1), of L] aux1[OF a'(1), of R] aux2[OF a'(1), of L]
aux1[OF b'(1), of L] aux1[OF b'(1), of R] aux2[OF b'(1), of R]
aux3[of L] aux3[of R]
show ?case
by (intro subsetD[OF _ pk[OF ‹(s, t) ∈ L a'› ‹(s, u) ∈ R b'›]], unfold UN_Un)
(intro relcomp_mono rtrancl_mono Un_mono iffD2[OF converse_mono]; fast)
qed fact+
text ‹Extended decreasing diagrams for confluence.›
lemmas edd_cr[case_names wf transr transq reflq compat peak] =
edd_commute[of L L for L, unfolded CR_iff_self_commute[symmetric]]
end
end