Theory Omega_Omega
section ‹An ordinal partition theorem by Jean A. Larson›
text ‹Jean A. Larson,
A short proof of a partition theorem for the ordinal $\omega^\omega$.
\emph{Annals of Mathematical Logic}, 6:129--145, 1973.›
theory Omega_Omega
imports "HOL-Library.Product_Lexorder" Erdos_Milner
begin
abbreviation "list_of ≡ sorted_list_of_set"
subsection ‹Cantor normal form for ordinals below @{term "ω↑ω"}›
text ‹Unlike @{term Cantor_sum}, there is no list of ordinal exponents,
which are instead taken as consecutive. We obtain an order-isomorphism between @{term "ω↑ω"}
and increasing lists of natural numbers (ordered lexicographically).›
fun omega_sum_aux where
Nil: "omega_sum_aux 0 _ = 0"
| Suc: "omega_sum_aux (Suc n) [] = 0"
| Cons: "omega_sum_aux (Suc n) (m#ms) = (ω↑n) * (ord_of_nat m) + omega_sum_aux n ms"
abbreviation omega_sum where "omega_sum ms ≡ omega_sum_aux (length ms) ms"
text ‹A normal expansion has no leading zeroes›
inductive normal:: "nat list ⇒ bool" where
normal_Nil[iff]: "normal []"
| normal_Cons: "m > 0 ⟹ normal (m#ms)"
inductive_simps normal_Cons_iff [simp]: "normal (m#ms)"
lemma omega_sum_0_iff [simp]: "normal ns ⟹ omega_sum ns = 0 ⟷ ns = []"
by (induction ns rule: normal.induct) auto
lemma Ord_omega_sum_aux [simp]: "Ord (omega_sum_aux k ms)"
by (induction rule: omega_sum_aux.induct) auto
lemma Ord_omega_sum: "Ord (omega_sum ms)"
by simp
lemma omega_sum_less_ωω [intro]: "omega_sum ms < ω↑ω"
proof (induction ms)
case (Cons m ms)
have "ω ↑ (length ms) * ord_of_nat m ∈ elts (ω ↑ Suc (length ms))"
using Ord_mem_iff_lt by auto
then have "ω↑(length ms) * ord_of_nat m ∈ elts (ω↑ω)"
using Ord_ord_of_nat oexp_mono_le omega_nonzero ord_of_nat_le_omega by blast
with Cons show ?case
by (auto simp: mult_succ OrdmemD oexp_less indecomposableD indecomposable_ω_power)
qed (auto simp: zero_less_Limit)
lemma omega_sum_aux_less: "omega_sum_aux k ms < ω ↑ k"
proof (induction rule: omega_sum_aux.induct)
case (3 n m ms)
have " ω↑n * ord_of_nat m + ω↑n < ω↑n * ω"
by (metis Ord_ord_of_nat ω_power_succ_gtr mult_succ oexp_succ ord_of_nat.simps(2))
with 3 show ?case
using dual_order.strict_trans by force
qed auto
lemma omega_sum_less: "omega_sum ms < ω ↑ (length ms)"
by (rule omega_sum_aux_less)
lemma omega_sum_ge: "m ≠ 0 ⟹ ω ↑ (length ms) ≤ omega_sum (m#ms)"
apply clarsimp
by (metis Ord_ord_of_nat add_le_cancel_left0 le_mult Nat.neq0_conv ord_of_eq_0_iff vsubsetD)
lemma omega_sum_length_less:
assumes "normal ns" "length ms < length ns"
shows "omega_sum ms < omega_sum ns"
using assms
proof (induction rule: normal.induct)
case (normal_Cons n ns')
have "ω ↑ length ms ≤ ω ↑ length ns'"
using normal_Cons oexp_mono_le by auto
then show ?case
by (metis gr_implies_not_zero less_le_trans normal_Cons.hyps omega_sum_aux_less omega_sum_ge)
qed auto
lemma omega_sum_length_leD:
assumes "omega_sum ms ≤ omega_sum ns" "normal ms"
shows "length ms ≤ length ns"
by (meson assms leD leI omega_sum_length_less)
lemma omega_sum_less_eqlen_iff_cases [simp]:
assumes "length ms = length ns"
shows "omega_sum (m#ms) < omega_sum (n#ns) ⟷ m<n ∨ m=n ∧ omega_sum ms < omega_sum ns"
using omega_sum_less [of ms] omega_sum_less [of ns]
by (metis Kirby.add_less_cancel_left Omega_Omega.Cons Ord_ω Ord_oexp Ord_omega_sum Ord_ord_of_nat assms length_Cons linorder_neqE_nat mult_nat_less_add_less order_less_asym)
lemma omega_sum_less_iff_cases:
assumes "m > 0" "n > 0"
shows "omega_sum (m#ms) < omega_sum (n#ns)
⟷ length ms < length ns
∨ length ms = length ns ∧ m<n
∨ length ms = length ns ∧ m=n ∧ omega_sum ms < omega_sum ns"
by (smt (verit) assms length_Cons less_eq_Suc_le less_le_not_le nat_less_le normal_Cons not_le
omega_sum_length_less omega_sum_less_eqlen_iff_cases)
lemma omega_sum_less_iff:
"((length ms, omega_sum ms), (length ns, omega_sum ns)) ∈ less_than <*lex*> VWF
⟷ (ms,ns) ∈ lenlex less_than"
proof (induction ms arbitrary: ns)
case (Cons m ms)
then show ?case
proof (induction ns)
case (Cons n ns')
show ?case
using Cons.prems Cons_lenlex_iff omega_sum_less_eqlen_iff_cases by fastforce
qed auto
qed auto
lemma eq_omega_sum_less_iff:
assumes "length ms = length ns"
shows "(omega_sum ms, omega_sum ns) ∈ VWF ⟷ (ms,ns) ∈ lenlex less_than"
by (metis assms in_lex_prod less_not_refl less_than_iff omega_sum_less_iff)
lemma eq_omega_sum_eq_iff:
assumes "length ms = length ns"
shows "omega_sum ms = omega_sum ns ⟷ ms=ns"
proof
assume "omega_sum ms = omega_sum ns"
then have "(omega_sum ms, omega_sum ns) ∉ VWF" "(omega_sum ns, omega_sum ms) ∉ VWF"
by auto
then obtain "(ms,ns) ∉ lenlex less_than" "(ns,ms) ∉ lenlex less_than"
using assms eq_omega_sum_less_iff by metis
moreover have "total (lenlex less_than)"
by (simp add: total_lenlex total_less_than)
ultimately show "ms=ns"
by (meson UNIV_I total_on_def)
qed auto
lemma inj_omega_sum: "inj_on omega_sum {l. length l = n}"
unfolding inj_on_def using eq_omega_sum_eq_iff by fastforce
lemma Ex_omega_sum: "γ ∈ elts (ω↑n) ⟹ ∃ns. γ = omega_sum ns ∧ length ns = n"
proof (induction n arbitrary: γ)
case 0
then show ?case
by (rule_tac x="[]" in exI) auto
next
case (Suc n)
then obtain k::nat where k: "γ ∈ elts (ω ↑ n * k)"
and kmin: "⋀k'. k'<k ⟹ γ ∉ elts (ω ↑ n * k')"
by (metis Ord_ord_of_nat elts_mult_ωE oexp_succ ord_of_nat.simps(2))
show ?case
proof (cases k)
case (Suc k')
then obtain δ where δ: "γ = (ω ↑ n * k') + δ"
by (metis lessI mult_succ ord_of_nat.simps(2) k kmin mem_plus_V_E)
then have δin: "δ ∈ elts (ω ↑ n)"
using Suc k mult_succ by auto
then obtain ns where ns: "δ = omega_sum ns" and len: "length ns = n"
using Suc.IH by auto
moreover have "omega_sum ns < ω↑n"
using OrdmemD ns δin by auto
ultimately show ?thesis
by (rule_tac x="k'#ns" in exI) (simp add: δ)
qed (use k in auto)
qed
lemma omega_sum_drop [simp]: "omega_sum (dropWhile (λn. n=0) ns) = omega_sum ns"
by (induction ns) auto
lemma normal_drop [simp]: "normal (dropWhile (λn. n=0) ns)"
by (induction ns) auto
lemma omega_sum_ωω:
assumes "γ ∈ elts (ω↑ω)"
obtains ns where "γ = omega_sum ns" "normal ns"
proof -
obtain ms where "γ = omega_sum ms"
using assms Ex_omega_sum by (auto simp: oexp_Limit elts_ω)
then show thesis
by (metis normal_drop omega_sum_drop that)
qed
definition Cantor_ωω :: "V ⇒ nat list"
where "Cantor_ωω ≡ λx. SOME ns. x = omega_sum ns ∧ normal ns"
lemma
assumes "γ ∈ elts (ω↑ω)"
shows Cantor_ωω: "omega_sum (Cantor_ωω γ) = γ"
and normal_Cantor_ωω: "normal (Cantor_ωω γ)"
by (metis (mono_tags, lifting) Cantor_ωω_def assms omega_sum_ωω someI)+
subsection ‹Larson's set $W(n)$›
definition WW :: "nat list set"
where "WW ≡ {l. strict_sorted l}"
fun into_WW :: "nat ⇒ nat list ⇒ nat list" where
"into_WW k [] = []"
| "into_WW k (n#ns) = (k+n) # into_WW (Suc (k+n)) ns"
fun from_WW :: "nat ⇒ nat list ⇒ nat list" where
"from_WW k [] = []"
| "from_WW k (n#ns) = (n - k) # from_WW (Suc n) ns"
lemma from_into_WW [simp]: "from_WW k (into_WW k ns) = ns"
by (induction ns arbitrary: k) auto
lemma inj_into_WW: "inj (into_WW k)"
by (metis from_into_WW injI)
lemma into_from_WW_aux:
"⟦strict_sorted ns; ∀n∈list.set ns. k ≤ n⟧ ⟹ into_WW k (from_WW k ns) = ns"
by (induction ns arbitrary: k) (auto simp: Suc_leI)
lemma into_from_WW [simp]: "strict_sorted ns ⟹ into_WW 0 (from_WW 0 ns) = ns"
by (simp add: into_from_WW_aux)
lemma into_WW_imp_ge: "y ∈ List.set (into_WW x ns) ⟹ x ≤ y"
by (induction ns arbitrary: x) fastforce+
lemma strict_sorted_into_WW: "strict_sorted (into_WW x ns)"
by (induction ns arbitrary: x) (auto simp: dest: into_WW_imp_ge)
lemma length_into_WW: "length (into_WW x ns) = length ns"
by (induction ns arbitrary: x) auto
lemma WW_eq_range_into: "WW = range (into_WW 0)"
proof -
have "⋀ns. strict_sorted ns ⟹ ns ∈ range (into_WW 0)"
by (metis into_from_WW rangeI)
then show ?thesis by (auto simp: WW_def strict_sorted_into_WW)
qed
lemma into_WW_lenlex_iff: "(into_WW k ms, into_WW k ns) ∈ lenlex less_than ⟷ (ms, ns) ∈ lenlex less_than"
proof (induction ms arbitrary: ns k)
case Nil
then show ?case
by simp (metis length_0_conv length_into_WW)
next
case (Cons m ms)
then show ?case
by (induction ns) (auto simp: Cons_lenlex_iff length_into_WW)
qed
lemma wf_llt [simp]: "wf (lenlex less_than)" and trans_llt [simp]: "trans (lenlex less_than)"
by blast+
lemma total_llt [simp]: "total_on A (lenlex less_than)"
by (meson UNIV_I total_lenlex total_less_than total_on_def)
lemma omega_sum_1_less:
assumes "(ms,ns) ∈ lenlex less_than" shows "omega_sum (1#ms) < omega_sum (1#ns)"
proof -
have "omega_sum (1#ms) < omega_sum (1#ns)" if "length ms < length ns"
using omega_sum_less_iff_cases that zero_less_one by blast
then show ?thesis
using assms by (auto simp: mult_succ simp flip: omega_sum_less_iff)
qed
lemma ordertype_WW_1: "ordertype WW (lenlex less_than) ≤ ordertype UNIV (lenlex less_than)"
by (rule ordertype_mono) auto
lemma ordertype_WW_2: "ordertype UNIV (lenlex less_than) ≤ ω↑ω"
proof (rule ordertype_inc_le_Ord)
show "range (λms. omega_sum (1#ms)) ⊆ elts (ω↑ω)"
by (meson Ord_ω Ord_mem_iff_lt Ord_oexp Ord_omega_sum image_subset_iff omega_sum_less_ωω)
qed (use omega_sum_1_less in auto)
lemma ordertype_WW_3: "ω↑ω ≤ ordertype WW (lenlex less_than)"
proof -
define π where "π ≡ into_WW 0 ∘ Cantor_ωω"
have ωω: "ω↑ω = tp (elts (ω↑ω))"
by simp
also have "… ≤ ordertype WW (lenlex less_than)"
proof (rule ordertype_inc_le)
fix α β
assume α: "α ∈ elts (ω↑ω)" and β: "β ∈ elts (ω↑ω)" and "(α, β) ∈ VWF"
then obtain *: "Ord α" "Ord β" "α<β"
by (metis Ord_in_Ord Ord_ordertype VWF_iff_Ord_less ωω)
then have "length (Cantor_ωω α) ≤ length (Cantor_ωω β)"
using α β by (simp add: Cantor_ωω normal_Cantor_ωω omega_sum_length_leD)
with α β * have "(Cantor_ωω α, Cantor_ωω β) ∈ lenlex less_than"
by (auto simp: Cantor_ωω simp flip: omega_sum_less_iff)
then show "(π α, π β) ∈ lenlex less_than"
by (simp add: π_def into_WW_lenlex_iff)
qed (auto simp: π_def WW_def strict_sorted_into_WW)
finally show "ω↑ω ≤ ordertype WW (lenlex less_than)" .
qed
lemma ordertype_WW: "ordertype WW (lenlex less_than) = ω↑ω"
and ordertype_UNIV_ωω: "ordertype UNIV (lenlex less_than) = ω↑ω"
using ordertype_WW_1 ordertype_WW_2 ordertype_WW_3 by auto
lemma ordertype_ωω:
fixes F :: "nat ⇒ nat list set"
assumes "⋀j::nat. ordertype (F j) (lenlex less_than) = ω↑j"
shows "ordertype (⋃j. F j) (lenlex less_than) = ω↑ω"
proof (rule antisym)
show "ordertype (⋃ (range F)) (lenlex less_than) ≤ ω ↑ ω"
by (metis ordertype_UNIV_ωω ordertype_mono small top_greatest trans_llt wf_llt)
have "⋀n. ω ↑ ord_of_nat n ≤ ordertype (⋃ (range F)) (lenlex less_than)"
by (metis TC_small Union_upper assms ordertype_mono rangeI trans_llt wf_llt)
then show "ω ↑ ω ≤ ordertype (⋃ (range F)) (lenlex less_than)"
by (auto simp: oexp_ω_Limit ZFC_in_HOL.SUP_le_iff elts_ω)
qed
definition WW_seg :: "nat ⇒ nat list set"
where "WW_seg n ≡ {l ∈ WW. length l = n}"
lemma WW_seg_subset_WW: "WW_seg n ⊆ WW"
by (auto simp: WW_seg_def)
lemma WW_eq_UN_WW_seg: "WW = (⋃ n. WW_seg n)"
by (auto simp: WW_seg_def)
lemma ordertype_list_seg: "ordertype {l. length l = n} (lenlex less_than) = ω↑n"
proof -
have "bij_betw omega_sum {l. length l = n} (elts (ω↑n))"
unfolding WW_seg_def bij_betw_def
by (auto simp: inj_omega_sum Ord_mem_iff_lt omega_sum_less dest: Ex_omega_sum)
then show ?thesis
by (force simp: ordertype_eq_iff simp flip: eq_omega_sum_less_iff)
qed
lemma ordertype_WW_seg: "ordertype (WW_seg n) (lenlex less_than) = ω↑n"
(is "ordertype ?W ?R = ω↑n")
proof -
have "ordertype {l. length l = n} ?R = ordertype ?W ?R"
proof (subst ordertype_eq_ordertype)
show "∃f. bij_betw f {l. length l = n} ?W ∧ (∀x∈{l. length l = n}. ∀y∈{l. length l = n}. ((f x, f y) ∈ lenlex less_than) = ((x, y) ∈ lenlex less_than))"
proof (intro exI conjI)
have "inj_on (into_WW 0) {l. length l = n}"
by (metis from_into_WW inj_onI)
then show "bij_betw (into_WW 0) {l. length l = n} ?W"
by (auto simp: bij_betw_def WW_seg_def WW_eq_range_into length_into_WW)
qed (simp add: into_WW_lenlex_iff)
qed auto
then show ?thesis
using ordertype_list_seg by auto
qed
subsection ‹Definitions required for the lemmas›
subsubsection ‹Larson's "$<$"-relation on ordered lists›
instantiation list :: (ord)ord
begin
definition "xs < ys ≡ xs ≠ [] ∧ ys ≠ [] ⟶ last xs < hd ys" for xs ys :: "'a list"
definition "xs ≤ ys ≡ xs < ys ∨ xs = ys" for xs ys :: "'a list"
instance
by standard
end
lemma less_Nil [simp]: "xs < []" "[] < xs"
by (auto simp: less_list_def)
lemma less_sets_imp_list_less:
assumes "list.set xs ≪ list.set ys"
shows "xs < ys"
by (metis assms last_in_set less_list_def less_sets_def list.set_sel(1))
lemma less_sets_imp_sorted_list_of_set:
assumes "A ≪ B" "finite A" "finite B"
shows "list_of A < list_of B"
by (simp add: assms less_sets_imp_list_less)
lemma sorted_list_of_set_imp_less_sets:
assumes "xs < ys" "sorted xs" "sorted ys"
shows "list.set xs ≪ list.set ys"
using assms sorted_hd_le sorted_le_last
by (force simp: less_list_def less_sets_def intro: order.trans)
lemma less_list_iff_less_sets:
assumes "sorted xs" "sorted ys"
shows "xs < ys ⟷ list.set xs ≪ list.set ys"
using assms sorted_hd_le sorted_le_last
by (force simp: less_list_def less_sets_def intro: order.trans)
lemma strict_sorted_append_iff:
"strict_sorted (xs @ ys) ⟷ xs < ys ∧ strict_sorted xs ∧ strict_sorted ys"
by (metis less_list_iff_less_sets less_setsD sorted_wrt_append strict_sorted_imp_less_sets strict_sorted_imp_sorted)
lemma singleton_less_list_iff: "sorted xs ⟹ [n] < xs ⟷ {..n} ∩ list.set xs = {}"
apply (simp add: less_list_def disjoint_iff)
by (metis empty_iff less_le_trans list.set(1) list.set_sel(1) not_le sorted_hd_le)
lemma less_hd_imp_less: "xs < [hd ys] ⟹ xs < ys"
by (simp add: less_list_def)
lemma strict_sorted_concat_I:
assumes "⋀x. x ∈ list.set xs ⟹ strict_sorted x"
"⋀n. Suc n < length xs ⟹ xs!n < xs!Suc n"
"xs ∈ lists (- {[]})"
shows "strict_sorted (concat xs)"
using assms
proof (induction xs)
case (Cons x xs)
then have "x < concat xs"
apply (simp add: less_list_def)
by (metis Compl_iff hd_concat insertI1 length_greater_0_conv length_pos_if_in_set list.sel(1) lists.cases nth_Cons_0)
with Cons show ?case
by (force simp: strict_sorted_append_iff)
qed auto
subsection ‹Nash Williams for lists›
subsubsection ‹Thin sets of lists›
inductive initial_segment :: "'a list ⇒ 'a list ⇒ bool"
where "initial_segment xs (xs@ys)"
definition thin :: "'a list set ⇒ bool"
where "thin A ≡ ¬ (∃x y. x ∈ A ∧ y ∈ A ∧ x ≠ y ∧ initial_segment x y)"
lemma initial_segment_ne:
assumes "initial_segment xs ys" "xs ≠ []"
shows "ys ≠ [] ∧ hd ys = hd xs"
using assms by (auto elim!: initial_segment.cases)
lemma take_initial_segment:
assumes "initial_segment xs ys" "k ≤ length xs"
shows "take k xs = take k ys"
by (metis append_eq_conv_conj assms initial_segment.cases min_def take_take)
lemma initial_segment_length_eq:
assumes "initial_segment xs ys" "length xs = length ys"
shows "xs = ys"
using assms initial_segment.cases by fastforce
lemma initial_segment_Nil [simp]: "initial_segment [] ys"
by (simp add: initial_segment.simps)
lemma initial_segment_Cons [simp]: "initial_segment (x#xs) (y#ys) ⟷ x=y ∧ initial_segment xs ys"
by (metis append_Cons initial_segment.simps list.inject)
lemma init_segment_iff_initial_segment:
assumes "strict_sorted xs" "strict_sorted ys"
shows "init_segment (list.set xs) (list.set ys) ⟷ initial_segment xs ys" (is "?lhs = ?rhs")
proof
assume ?lhs
then obtain S' where S': "list.set ys = list.set xs ∪ S'" "list.set xs ≪ S'"
by (auto simp: init_segment_def)
then have "finite S'"
by (metis List.finite_set finite_Un)
have "ys = xs @ list_of S'"
using S' ‹strict_sorted xs›
proof (induction xs)
case Nil
with ‹strict_sorted ys› show ?case
by auto
next
case (Cons a xs)
with ‹finite S'› have "ys = a # xs @ list_of S'"
by (metis List.finite_set append_Cons assms(2) sorted_list_of_set_Un sorted_list_of_set_set_of)
then show ?case
by (auto simp: Cons)
qed
then show ?rhs
using initial_segment.intros by blast
next
assume ?rhs
then show ?lhs
proof cases
case (1 ys)
with assms show ?thesis
by (simp add: init_segment_Un strict_sorted_imp_less_sets)
qed
qed
theorem Nash_Williams_WW:
fixes h :: "nat list ⇒ nat"
assumes "infinite M" and h: "h ` {l ∈ A. List.set l ⊆ M} ⊆ {..<2}" and "thin A" "A ⊆ WW"
obtains i N where "i < 2" "infinite N" "N ⊆ M" "h ` {l ∈ A. List.set l ⊆ N} ⊆ {i}"
proof -
define AM where "AM ≡ {l ∈ A. List.set l ⊆ M}"
have "thin_set (list.set ` A)"
using ‹thin A› ‹A ⊆ WW› unfolding thin_def thin_set_def WW_def
by (auto simp: subset_iff init_segment_iff_initial_segment)
then have "thin_set (list.set ` AM)"
by (simp add: AM_def image_subset_iff thin_set_def)
then have "Ramsey (list.set ` AM) 2"
using Nash_Williams_2 by metis
moreover have "(h ∘ list_of) ∈ list.set ` AM → {..<2}"
unfolding AM_def
proof clarsimp
fix l
assume "l ∈ A" "list.set l ⊆ M"
then have "strict_sorted l"
using WW_def ‹A ⊆ WW› by blast
then show "h (list_of (list.set l)) < 2"
using h ‹l ∈ A› ‹list.set l ⊆ M› by auto
qed
ultimately obtain N i where N: "N ⊆ M" "infinite N" "i<2"
and "list.set ` AM ∩ Pow N ⊆ (h ∘ list_of) -` {i}"
unfolding Ramsey_eq by (metis ‹infinite M›)
then have N_disjoint: "(h ∘ list_of) -` {1-i} ∩ (list.set ` AM) ∩ Pow N = {}"
unfolding subset_vimage_iff less_2_cases_iff by force
have "h ` {l ∈ A. list.set l ⊆ N} ⊆ {i}"
proof clarify
fix l
assume "l ∈ A" and "list.set l ⊆ N"
then have "h l < 2"
using h ‹N ⊆ M› by force
with ‹i<2› have "h l ≠ Suc 0 - i ⟹ h l = i"
by (auto simp: eval_nat_numeral less_Suc_eq)
moreover have "strict_sorted l"
using ‹A ⊆ WW› ‹l ∈ A› unfolding WW_def by blast
moreover have "h (list_of (list.set l)) = 1 - i ⟶ ¬ (list.set l ⊆ N)"
using N_disjoint ‹N ⊆ M› ‹l ∈ A› by (auto simp: AM_def)
ultimately show "h l = i"
using N ‹N ⊆ M› ‹l ∈ A› ‹list.set l ⊆ N›
by (auto simp: vimage_def set_eq_iff AM_def WW_def subset_iff)
qed
then show thesis
using that ‹i<2› N by auto
qed
subsection ‹Specialised functions on lists›
lemma mem_lists_non_Nil: "xss ∈ lists (- {[]}) ⟷ (∀x ∈ list.set xss. x ≠ [])"
by auto
fun acc_lengths :: "nat ⇒ 'a list list ⇒ nat list"
where "acc_lengths acc [] = []"
| "acc_lengths acc (l#ls) = (acc + length l) # acc_lengths (acc + length l) ls"
lemma length_acc_lengths [simp]: "length (acc_lengths acc ls) = length ls"
by (induction ls arbitrary: acc) auto
lemma acc_lengths_eq_Nil_iff [simp]: "acc_lengths acc ls = [] ⟷ ls = []"
by (metis length_0_conv length_acc_lengths)
lemma set_acc_lengths:
assumes "ls ∈ lists (- {[]})" shows "list.set (acc_lengths acc ls) ⊆ {acc<..}"
using assms by (induction ls rule: acc_lengths.induct) fastforce+
text ‹Useful because @{text acc_lengths.simps} will sometimes be deleted from the simpset.›
lemma hd_acc_lengths [simp]: "hd (acc_lengths acc (l#ls)) = acc + length l"
by simp
lemma last_acc_lengths [simp]:
"ls ≠ [] ⟹ last (acc_lengths acc ls) = acc + sum_list (map length ls)"
by (induction acc ls rule: acc_lengths.induct) auto
lemma nth_acc_lengths [simp]:
"⟦ls ≠ []; k < length ls⟧ ⟹ acc_lengths acc ls ! k = acc + sum_list (map length (take (Suc k) ls))"
by (induction acc ls arbitrary: k rule: acc_lengths.induct) (fastforce simp: less_Suc_eq nth_Cons')+
lemma acc_lengths_plus: "acc_lengths (m+n) as = map ((+)m) (acc_lengths n as)"
by (induction n as arbitrary: m rule: acc_lengths.induct) (auto simp: add.assoc)
lemma acc_lengths_shift: "NO_MATCH 0 acc ⟹ acc_lengths acc as = map ((+)acc) (acc_lengths 0 as)"
by (metis acc_lengths_plus add.comm_neutral)
lemma length_concat_acc_lengths:
"ls ≠ [] ⟹ k + length (concat ls) ∈ list.set (acc_lengths k ls)"
by (metis acc_lengths_eq_Nil_iff last_acc_lengths last_in_set length_concat)
lemma strict_sorted_acc_lengths:
assumes "ls ∈ lists (- {[]})" shows "strict_sorted (acc_lengths acc ls)"
using assms
proof (induction ls rule: acc_lengths.induct)
case (2 acc l ls)
then have "strict_sorted (acc_lengths (acc + length l) ls)"
by auto
then show ?case
using set_acc_lengths "2.prems" by auto
qed auto
lemma acc_lengths_append:
"acc_lengths acc (xs @ ys)
= acc_lengths acc xs @ acc_lengths (acc + sum_list (map length xs)) ys"
by (induction acc xs rule: acc_lengths.induct) (auto simp: add.assoc)
lemma length_concat_ge:
assumes "as ∈ lists (- {[]})"
shows "length (concat as) ≥ length as"
using assms
proof (induction as)
case (Cons a as)
then have "length a ≥ Suc 0" "⋀l. l ∈ list.set as ⟹ length l ≥ Suc 0"
by (auto simp: Suc_leI)
then show ?case
using Cons.IH by force
qed auto
fun interact :: "'a list list ⇒ 'a list list ⇒ 'a list"
where
"interact [] ys = concat ys"
| "interact xs [] = concat xs"
| "interact (x#xs) (y#ys) = x @ y @ interact xs ys"
lemma (in monoid_add) length_interact:
"length (interact xs ys) = sum_list (map length xs) + sum_list (map length ys)"
by (induction rule: interact.induct) (auto simp: length_concat)
lemma length_interact_ge:
assumes "xs ∈ lists (- {[]})" "ys ∈ lists (- {[]})"
shows "length (interact xs ys) ≥ length xs + length ys"
by (metis add_mono assms length_concat length_concat_ge length_interact)
lemma set_interact [simp]:
shows "list.set (interact xs ys) = list.set (concat xs) ∪ list.set (concat ys)"
by (induction rule: interact.induct) auto
lemma interact_eq_Nil_iff [simp]:
assumes "xs ∈ lists (- {[]})" "ys ∈ lists (- {[]})"
shows "interact xs ys = [] ⟷ xs=[] ∧ ys=[]"
using length_interact_ge [OF assms] by fastforce
lemma interact_sing [simp]: "interact [x] ys = x @ concat ys"
by (metis (no_types) concat.simps(2) interact.simps neq_Nil_conv)
lemma hd_interact: "⟦xs ≠ []; hd xs ≠ []⟧ ⟹ hd (interact xs ys) = hd (hd xs)"
by (smt (verit, best) hd_append2 hd_concat interact.elims list.sel(1))
lemma acc_lengths_concat_injective:
assumes "concat as' = concat as" "acc_lengths n as' = acc_lengths n as"
shows "as' = as"
using assms
proof (induction as arbitrary: n as')
case Nil
then show ?case
by (metis acc_lengths_eq_Nil_iff)
next
case (Cons a as)
then obtain a' bs where "as' = a'#bs"
by (metis Suc_length_conv length_acc_lengths)
with Cons show ?case
by simp
qed
lemma acc_lengths_interact_injective:
assumes "interact as' bs' = interact as bs" "acc_lengths a as' = acc_lengths a as" "acc_lengths b bs' = acc_lengths b bs"
shows "as' = as ∧ bs' = bs"
using assms
proof (induction as bs arbitrary: a b as' bs' rule: interact.induct)
case (1 cs) then show ?case
by (metis acc_lengths_concat_injective acc_lengths_eq_Nil_iff interact.simps(1))
next
case (2 c cs)
then show ?case
by (metis acc_lengths_concat_injective acc_lengths_eq_Nil_iff interact.simps(2) list.exhaust)
next
case (3 x xs y ys)
then obtain a' us b' vs where "as' = a'#us" "bs' = b'#vs"
by (metis length_Suc_conv length_acc_lengths)
with 3 show ?case
by auto
qed
lemma strict_sorted_interact_I:
assumes "length ys ≤ length xs" "length xs ≤ Suc (length ys)"
"⋀x. x ∈ list.set xs ⟹ strict_sorted x"
"⋀y. y ∈ list.set ys ⟹ strict_sorted y"
"⋀n. n < length ys ⟹ xs!n < ys!n"
"⋀n. Suc n < length xs ⟹ ys!n < xs!Suc n"
assumes "xs ∈ lists (- {[]})" "ys ∈ lists (- {[]})"
shows "strict_sorted (interact xs ys)"
using assms
proof (induction rule: interact.induct)
case (3 x xs y ys)
then have "x < y"
by force
moreover have "strict_sorted (interact xs ys)"
using 3 by simp (metis Suc_less_eq nth_Cons_Suc)
moreover have "y < interact xs ys"
using 3 apply (simp add: less_list_def)
by (metis hd_interact le_zero_eq length_greater_0_conv list.sel(1) list.set_sel(1) list.size(3) lists.simps mem_lists_non_Nil nth_Cons_0)
ultimately show ?case
using 3 by (simp add: strict_sorted_append_iff less_list_def)
qed auto
subsection ‹Forms and interactions›
subsubsection ‹Forms›
inductive Form_Body :: "[nat, nat, nat list, nat list, nat list] ⇒ bool"
where "Form_Body ka kb xs ys zs"
if "length xs < length ys" "xs = concat (a#as)" "ys = concat (b#bs)"
"a#as ∈ lists (- {[]})" "b#bs ∈ lists (- {[]})"
"length (a#as) = ka" "length (b#bs) = kb"
"c = acc_lengths 0 (a#as)"
"d = acc_lengths 0 (b#bs)"
"zs = concat [c, a, d, b] @ interact as bs"
"strict_sorted zs"
inductive Form :: "[nat, nat list set] ⇒ bool"
where "Form 0 {xs,ys}" if "length xs = length ys" "xs ≠ ys"
| "Form (2*k-1) {xs,ys}" if "Form_Body k k xs ys zs" "k > 0"
| "Form (2*k) {xs,ys}" if "Form_Body (Suc k) k xs ys zs" "k > 0"
inductive_cases Form_0_cases_raw: "Form 0 u"
lemma Form_elim_upair:
assumes "Form l U"
obtains xs ys where "xs ≠ ys" "U = {xs,ys}" "length xs ≤ length ys"
using assms
by (smt (verit, best) Form.simps Form_Body.cases less_or_eq_imp_le nat_neq_iff)
lemma assumes "Form_Body ka kb xs ys zs"
shows Form_Body_WW: "zs ∈ WW"
and Form_Body_nonempty: "length zs > 0"
and Form_Body_length: "length xs < length ys"
using Form_Body.cases [OF assms] by (fastforce simp: WW_def)+
lemma form_cases:
fixes l::nat
obtains (zero) "l = 0" | (nz) ka kb where "l = ka+kb - 1" "0 < kb" "kb ≤ ka" "ka ≤ Suc kb"
proof -
have "l = 0 ∨ (∃ka kb. l = ka+kb - 1 ∧ 0 < kb ∧ kb ≤ ka ∧ ka ≤ Suc kb)"
by presburger
then show thesis
using nz zero by blast
qed
subsubsection ‹Interactions›
lemma interact:
assumes "Form l U" "l>0"
obtains ka kb xs ys zs where "l = ka+kb - 1" "U = {xs,ys}" "Form_Body ka kb xs ys zs" "0 < kb" "kb ≤ ka" "ka ≤ Suc kb"
using assms
unfolding Form.simps
by (smt (verit, best) add_Suc diff_Suc_1 lessI mult_2 nat_less_le order_refl)
definition inter_scheme :: "nat ⇒ nat list set ⇒ nat list"
where "inter_scheme l U ≡
SOME zs. ∃k xs ys. U = {xs,ys} ∧
(l = 2*k-1 ∧ Form_Body k k xs ys zs ∨ l = 2*k ∧ Form_Body (Suc k) k xs ys zs)"
lemma inter_scheme:
assumes "Form l U" "l>0"
obtains ka kb xs ys where "l = ka+kb - 1" "U = {xs,ys}" "Form_Body ka kb xs ys (inter_scheme l U)" "0 < kb" "kb ≤ ka" "ka ≤ Suc kb"
using interact [OF ‹Form l U›]
proof cases
case (2 ka kb xs ys zs)
then have §: "⋀ka kb zs. ¬ Form_Body ka kb ys xs zs"
using Form_Body_length less_asym' by blast
have "Form_Body ka kb xs ys (inter_scheme l U)"
proof (cases "ka = kb")
case True
with 2 have l: "∀k. l ≠ k * 2"
by presburger
have [simp]: "⋀k. kb + kb - Suc 0 = k * 2 - Suc 0 ⟷ k=kb"
by auto
show ?thesis
unfolding inter_scheme_def using 2 l True
by (auto simp: § ‹l > 0› Set.doubleton_eq_iff conj_disj_distribR ex_disj_distrib algebra_simps some_eq_ex)
next
case False
with 2 have l: "∀k. l ≠ k * 2 - Suc 0" and [simp]: "ka = Suc kb"
by presburger+
have [simp]: "⋀k. kb + kb = k * 2 ⟷ k=kb"
by auto
show ?thesis
unfolding inter_scheme_def using 2 l False
by (auto simp: § ‹l > 0› Set.doubleton_eq_iff conj_disj_distribR ex_disj_distrib algebra_simps some_eq_ex)
qed
then show ?thesis
by (simp add: 2 that)
qed (use ‹l > 0› in auto)
lemma inter_scheme_strict_sorted:
assumes "Form l U" "l>0"
shows "strict_sorted (inter_scheme l U)"
using Form_Body.simps assms inter_scheme by fastforce
lemma inter_scheme_simple:
assumes "Form l U" "l>0"
shows "inter_scheme l U ∈ WW ∧ length (inter_scheme l U) > 0"
using inter_scheme [OF assms] by (meson Form_Body_WW Form_Body_nonempty)
subsubsection ‹Injectivity of interactions›
proposition inter_scheme_injective:
assumes "Form l U" "Form l U'" "l > 0" and eq: "inter_scheme l U' = inter_scheme l U"
shows "U' = U"
proof -
obtain ka kb xs ys
where l: "l = ka+kb - 1" and U: "U = {xs,ys}"
and FB: "Form_Body ka kb xs ys (inter_scheme l U)"
and kb: "0 < kb" "kb ≤ ka" "ka ≤ Suc kb"
using assms inter_scheme by blast
then obtain a as b bs c d
where xs: "xs = concat (a#as)" and ys: "ys = concat (b#bs)"
and len: "length (a#as) = ka" "length (b#bs) = kb"
and c: "c = acc_lengths 0 (a#as)"
and d: "d = acc_lengths 0 (b#bs)"
and Ueq: "inter_scheme l U = concat [c, a, d, b] @ interact as bs"
by (auto simp: Form_Body.simps)
obtain ka' kb' xs' ys'
where l': "l = ka'+kb' - 1" and U': "U' = {xs',ys'}"
and FB': "Form_Body ka' kb' xs' ys' (inter_scheme l U')"
and kb': "0 < kb'" "kb' ≤ ka'" "ka' ≤ Suc kb'"
using assms inter_scheme by blast
then obtain a' as' b' bs' c' d'
where xs': "xs' = concat (a'#as')" and ys': "ys' = concat (b'#bs')"
and len': "length (a'#as') = ka'" "length (b'#bs') = kb'"
and c': "c' = acc_lengths 0 (a'#as')"
and d': "d' = acc_lengths 0 (b'#bs')"
and Ueq': "inter_scheme l U' = concat [c', a', d', b'] @ interact as' bs'"
using Form_Body.simps by auto
have [simp]: "ka' = ka ∧ kb' = kb"
using ‹l > 0› l l' kb kb' le_SucE le_antisym mult_2 by linarith
have [simp]: "length c = length c'" "length d = length d'"
using c c' d d' len' len by auto
have c_off: "c' = c" "a' @ d' @ b' @ interact as' bs' = a @ d @ b @ interact as bs"
using eq by (auto simp: Ueq Ueq')
then have len_a: "length a' = length a"
by (metis acc_lengths.simps(2) add.left_neutral c c' nth_Cons_0)
with c_off have §: "a' = a" "d' = d" "b' @ interact as' bs' = b @ interact as bs"
by auto
then have "length (interact as' bs') = length (interact as bs)"
by (metis acc_lengths.simps(2) add_left_cancel append_eq_append_conv d d' list.inject)
with § have "b' = b" "interact as' bs' = interact as bs"
by auto
moreover have "acc_lengths 0 as' = acc_lengths 0 as"
using ‹a' = a› ‹c' = c› by (simp add: c' c acc_lengths_shift)
moreover have "acc_lengths 0 bs' = acc_lengths 0 bs"
using ‹b' = b› ‹d' = d› by (simp add: d' d acc_lengths_shift)
ultimately have "as' = as ∧ bs' = bs"
using acc_lengths_interact_injective by blast
then show ?thesis
by (simp add: ‹a' = a› U U' ‹b' = b› xs xs' ys ys')
qed
lemma strict_sorted_interact_imp_concat:
"strict_sorted (interact as bs) ⟹ strict_sorted (concat as) ∧ strict_sorted (concat bs)"
proof (induction as bs rule: interact.induct)
case (3 x xs y ys)
have "x < concat xs"
using "3.prems"
by (smt (verit, del_insts) Un_iff hd_in_set interact.simps(3) last_in_set less_list_def set_append set_interact sorted_wrt_append)
moreover have "y < concat ys"
using 3 sorted_wrt_append strict_sorted_append_iff by fastforce
ultimately show ?case
using 3 by (auto simp add: strict_sorted_append_iff)
qed auto
lemma strict_sorted_interact_hd:
"⟦strict_sorted (interact cs ds); cs ≠ []; ds ≠ []; hd cs ≠ []; hd ds ≠ []⟧
⟹ hd (hd cs) < hd (hd ds)"
by (metis append_is_Nil_conv hd_append2 hd_in_set interact.simps(3) list.exhaust_sel sorted_wrt_append)
text ‹the lengths of the two lists can differ by one›
proposition interaction_scheme_unique_aux:
assumes "concat as = concat as'" and ys': "concat bs = concat bs'"
and "as ∈ lists (- {[]})" "bs ∈ lists (- {[]})"
and "strict_sorted (interact as bs)"
and "length bs ≤ length as" "length as ≤ Suc (length bs)"
and "as' ∈ lists (- {[]})" "bs' ∈ lists (- {[]})"
and "strict_sorted (interact as' bs')"
and "length bs' ≤ length as'" "length as' ≤ Suc (length bs')"
and "length as = length as'" "length bs = length bs'"
shows "as = as' ∧ bs = bs'"
using assms
proof (induction "length as" arbitrary: as bs as' bs')
case 0 then show ?case
by auto
next
case SUC: (Suc k)
show ?case
proof (cases k)
case 0
with SUC obtain a a' where aa': "as = [a]" "as' = [a']"
by (metis Suc_length_conv length_0_conv)
show ?thesis
proof
show "as = as'"
using aa' ‹concat as = concat as'› by force
with SUC 0 show "bs = bs'"
by (metis Suc_leI append_Nil2 concat.simps impossible_Cons le_antisym length_greater_0_conv list.exhaust)
qed
next
case (Suc k')
then obtain a cs b ds where eq: "as = a#cs" "bs = b#ds"
using SUC
by (metis le0 list.exhaust list.size(3) not_less_eq_eq)
have "length as' ≠ 0"
using SUC by force
then obtain a' cs' b' ds' where eq': "as' = a'#cs'" "bs' = b'#ds'"
by (metis ‹length bs = length bs'› eq(2) length_0_conv list.exhaust)
obtain k: "k = length cs" "k ≤ Suc (length ds)"
using eq SUC by auto
case (Suc k')
obtain [simp]: "b ≠ []" "b' ≠ []" "a ≠ []" "a' ≠ []"
using SUC by (simp add: eq eq')
then have "hd b' = hd b"
using SUC by (metis concat.simps(2) eq'(2) eq(2) hd_append2)
have ss_ab: "strict_sorted (concat as)" "strict_sorted (concat bs)"
using strict_sorted_interact_imp_concat SUC.prems(5) by blast+
have sw_ab: "strict_sorted (a @ b @ interact cs ds)"
by (metis SUC.prems(5) eq interact.simps(3))
then obtain "a < b" "strict_sorted a" "strict_sorted b"
by (metis append_assoc strict_sorted_append_iff)
have b_cs: "strict_sorted (concat (b # cs))"
by (metis append.simps(1) concat.simps(2) interact.simps(3) strict_sorted_interact_imp_concat sw_ab)
then have "b < concat cs"
using strict_sorted_append_iff by auto
have "strict_sorted (a @ concat cs)"
using eq(1) ss_ab(1) by force
have "list.set a = list.set (concat as) ∩ {..< hd b}"
proof -
have "x ∈ list.set a"
if "x < hd b" and "l ∈ list.set cs" and "x ∈ list.set l" for x l
using b_cs sorted_hd_le strict_sorted_imp_sorted that by fastforce
then show ?thesis
using ‹b ≠ []› sw_ab by (force simp: strict_sorted_append_iff sorted_wrt_append eq)
qed
moreover
have ss_ab': "strict_sorted (concat as')" "strict_sorted (concat bs')"
using strict_sorted_interact_imp_concat SUC.prems(10) by blast+
have sw_ab': "strict_sorted (a' @ b' @ interact cs' ds')"
by (metis SUC.prems(10) eq' interact.simps(3))
then obtain "a' < b'" "strict_sorted a'" "strict_sorted b'"
by (metis append_assoc strict_sorted_append_iff)
have b_cs': "strict_sorted (concat (b' # cs'))"
by (metis (no_types) SUC.prems(10) append_Nil eq' interact.simps(3) strict_sorted_append_iff strict_sorted_interact_imp_concat)
then have "b' < concat cs'"
by (simp add: strict_sorted_append_iff)
then have "hd b' ∉ list.set (concat cs')"
by (metis Un_iff ‹b' ≠ []› list.set_sel(1) not_less_iff_gr_or_eq set_interact sorted_wrt_append sw_ab')
have "strict_sorted (a' @ concat cs')"
using eq'(1) ss_ab'(1) by force
then have b_cs': "strict_sorted (b' @ concat cs')"
using ‹b' < concat cs'› eq'(2) ss_ab'(2) strict_sorted_append_iff by auto
have "list.set a' = list.set (concat as') ∩ {..< hd b'}"
proof -
have "x ∈ list.set a'"
if "x < hd b'" and "l ∈ list.set cs'" and "x ∈ list.set l" for x l
using b_cs' sorted_hd_le strict_sorted_imp_sorted that by fastforce
then show ?thesis
using ‹b' ≠ []› sw_ab' by (force simp: strict_sorted_append_iff sorted_wrt_append eq')
qed
ultimately have "a=a'"
by (simp add: SUC.prems(1) ‹hd b' = hd b› ‹strict_sorted a'› ‹strict_sorted a› strict_sorted_equal)
moreover
have ccat_cs_cs': "concat cs = concat cs'"
using SUC.prems(1) ‹a = a'› eq'(1) eq(1) by fastforce
have "b=b'"
proof (cases "ds = [] ∨ ds' = []")
case True
then show ?thesis
using SUC eq'(2) eq(2) by fastforce
next
case False
then have "ds ≠ []" "ds' ≠ []" "sorted (concat ds)" "sorted (concat ds')"
using eq(2) ss_ab(2) eq'(2) ss_ab'(2) strict_sorted_append_iff strict_sorted_imp_sorted by auto
have "strict_sorted b" "strict_sorted b'"
using b_cs b_cs' sorted_wrt_append by auto
moreover
have "cs ≠ []"
using k local.Suc by auto
then obtain "hd cs ≠ []" "hd ds ≠ []"
using SUC.prems(3) SUC.prems(4) eq list.set_sel(1)
by (simp add: ‹ds ≠ []› mem_lists_non_Nil)
then have "concat cs ≠ []"
using ‹cs ≠ []› hd_in_set by auto
have "hd (concat cs) < hd (concat ds)"
using strict_sorted_interact_hd
by (metis ‹cs ≠ []› ‹ds ≠ []› ‹hd cs ≠ []› ‹hd ds ≠ []› hd_concat sorted_wrt_append sw_ab)
have "list.set b = list.set (concat bs) ∩ {..< hd (concat cs)}"
proof -
have 1: "x ∈ list.set b"
if "x < hd (concat cs)" and "l ∈ list.set ds" and "x ∈ list.set l" for x l
using ‹hd (concat cs) < hd (concat ds)› ‹sorted (concat ds)› sorted_hd_le that by fastforce
have 2: "l < hd (concat cs)" if "l ∈ list.set b" for l
by (metis ‹concat cs ≠ []› b_cs concat.simps(2) list.set_sel(1) sorted_wrt_append that)
show ?thesis
using 1 2 by (auto simp: strict_sorted_append_iff sorted_wrt_append eq)
qed
moreover
have "cs' ≠ []"
using k Suc ‹concat cs ≠ []› ccat_cs_cs' by auto
then obtain "hd cs' ≠ []" "hd ds' ≠ []"
using SUC.prems(8,9) ‹ds' ≠ []› eq'(1) eq'(2) list.set_sel(1) by auto
then have "concat cs' ≠ []"
using ‹cs' ≠ []› hd_in_set by auto
have "hd (concat cs') < hd (concat ds')"
using strict_sorted_interact_hd
by (metis ‹cs' ≠ []› ‹ds' ≠ []› ‹hd cs' ≠ []› ‹hd ds' ≠ []› hd_concat sorted_wrt_append sw_ab')
have "list.set b' = list.set (concat bs') ∩ {..< hd (concat cs')}"
proof -
have 1: "x ∈ list.set b'"
if "x < hd (concat cs')" and "l ∈ list.set ds'" and "x ∈ list.set l" for x l
using ‹hd (concat cs') < hd (concat ds')› ‹sorted (concat ds')› sorted_hd_le that by fastforce
have 2: "l < hd (concat cs')" if "l ∈ list.set b'" for l
by (metis ‹concat cs' ≠ []› b_cs' list.set_sel(1) sorted_wrt_append that)
show ?thesis
using 1 2 by (auto simp: strict_sorted_append_iff sorted_wrt_append eq')
qed
ultimately show "b = b'"
by (simp add: SUC.prems(2) ccat_cs_cs' strict_sorted_equal)
qed
moreover
have "cs = cs' ∧ ds = ds'"
proof (rule SUC.hyps)
show "k = length cs"
using eq SUC.hyps(2) by auto[1]
show "concat ds = concat ds'"
using SUC.prems(2) ‹b = b'› eq'(2) eq(2) by auto
show "strict_sorted (interact cs ds)"
using eq SUC.prems(5) strict_sorted_append_iff by auto
show "length ds ≤ length cs" "length cs ≤ Suc (length ds)"
using eq SUC k by auto
show "strict_sorted (interact cs' ds')"
using eq' SUC.prems(10) strict_sorted_append_iff by auto
show "length cs = length cs'"
using SUC eq'(1) k(1) by force
qed (use ccat_cs_cs' eq eq' SUC.prems in auto)
ultimately show ?thesis
by (simp add: ‹a = a'› ‹b = b'› eq eq')
qed
qed
proposition Form_Body_unique:
assumes "Form_Body ka kb xs ys zs" "Form_Body ka kb xs ys zs'" and "kb ≤ ka" "ka ≤ Suc kb"
shows "zs' = zs"
proof -
obtain a as b bs c d
where xs: "xs = concat (a#as)" and ys: "ys = concat (b#bs)"
and ne: "a#as ∈ lists (- {[]})" "b#bs ∈ lists (- {[]})"
and len: "length (a#as) = ka" "length (b#bs) = kb"
and c: "c = acc_lengths 0 (a#as)"
and d: "d = acc_lengths 0 (b#bs)"
and Ueq: "zs = concat [c, a, d, b] @ interact as bs"
and ss_zs: "strict_sorted zs"
using Form_Body.cases [OF assms(1)] by (metis (no_types))
obtain a' as' b' bs' c' d'
where xs': "xs = concat (a'#as')" and ys': "ys = concat (b'#bs')"
and ne': "a'#as' ∈ lists (- {[]})" "b'#bs' ∈ lists (- {[]})"
and len': "length (a'#as') = ka" "length (b'#bs') = kb"
and c': "c' = acc_lengths 0 (a'#as')"
and d': "d' = acc_lengths 0 (b'#bs')"
and Ueq': "zs' = concat [c', a', d', b'] @ interact as' bs'"
and ss_zs': "strict_sorted zs'"
using Form_Body.cases [OF assms(2)] by (metis (no_types))
have [simp]: "length c = length c'" "length d = length d'"
using c c' d d' len' len by auto
note acc_lengths.simps [simp del]
have "a < b"
using ss_zs by (auto simp: Ueq strict_sorted_append_iff less_list_def c d)
have "a' < b'"
using ss_zs' by (auto simp: Ueq' strict_sorted_append_iff less_list_def c' d')
have "a#as = a'#as' ∧ b#bs = b'#bs'"
proof (rule interaction_scheme_unique_aux)
show "strict_sorted (interact (a # as) (b # bs))"
using ss_zs ‹a < b› by (auto simp: Ueq strict_sorted_append_iff less_list_def d)
show "strict_sorted (interact (a' # as') (b' # bs'))"
using ss_zs' ‹a' < b'› by (auto simp: Ueq' strict_sorted_append_iff less_list_def d')
show "length (b # bs) ≤ length (a # as)" "length (b' # bs') ≤ length (a' # as')"
using ‹kb ≤ ka› len len' by auto
show "length (a # as) ≤ Suc (length (b # bs))"
using ‹ka ≤ Suc kb› len by linarith
then show "length (a' # as') ≤ Suc (length (b' # bs'))"
using len len' by fastforce
qed (use len len' xs xs' ys ys' ne ne' in fastforce)+
then show ?thesis
using Ueq Ueq' c c' d d' by blast
qed
lemma Form_Body_imp_inter_scheme:
assumes FB: "Form_Body ka kb xs ys zs" and "0 < kb" "kb ≤ ka" "ka ≤ Suc kb"
shows "zs = inter_scheme ((ka+kb) - Suc 0) {xs,ys}"
proof -
have "length xs < length ys"
by (meson Form_Body_length assms(1))
have [simp]: "a + a = b + b ⟷ a=b" "a + a - Suc 0 = b + b - Suc 0 ⟷ a=b" for a b::nat
by auto
show ?thesis
proof (cases "ka = kb")
case True
show ?thesis
unfolding inter_scheme_def
apply (rule some_equality [symmetric], metis One_nat_def True FB mult_2)
using assms ‹length xs < length ys›
by (auto simp: True mult_2 Set.doubleton_eq_iff Form_Body_unique dest: Form_Body_length, presburger)
next
case False
then have eq: "ka = Suc kb"
using assms by linarith
show ?thesis
unfolding inter_scheme_def
apply (rule some_equality [symmetric], use assms False mult_2 one_is_add eq in fastforce)
using assms ‹length xs < length ys›
by (auto simp: eq mult_2 Set.doubleton_eq_iff Form_Body_unique dest: Form_Body_length, presburger)
qed
qed
subsection ‹For Lemma 3.8 AND PROBABLY 3.7›
definition grab :: "nat set ⇒ nat ⇒ nat set × nat set"
where "grab N n ≡ (N ∩ enumerate N ` {..<n}, N ∩ {enumerate N n..})"
lemma grab_0 [simp]: "grab N 0 = ({}, N)"
by (fastforce simp: grab_def enumerate_0 Least_le)
lemma less_sets_grab:
"infinite N ⟹ fst (grab N n) ≪ snd (grab N n)"
by (auto simp: grab_def less_sets_def intro: enumerate_mono less_le_trans)
lemma finite_grab [iff]: "finite (fst (grab N n))"
by (simp add: grab_def)
lemma card_grab [simp]:
assumes "infinite N" shows "card (fst (grab N n)) = n"
proof -
have "N ∩ enumerate N ` {..<n} = enumerate N ` {..<n}"
using assms by (auto simp: enumerate_in_set)
with assms show ?thesis
by (simp add: card_image grab_def strict_mono_enum strict_mono_imp_inj_on)
qed
lemma fst_grab_subset: "fst (grab N n) ⊆ N"
using grab_def range_enum by fastforce
lemma snd_grab_subset: "snd (grab N n) ⊆ N"
by (auto simp: grab_def)
lemma grab_Un_eq:
assumes "infinite N" shows "fst (grab N n) ∪ snd (grab N n) = N"
proof
show "N ⊆ fst (grab N n) ∪ snd (grab N n)"
unfolding grab_def
using assms enumerate_Ex le_less_linear strict_mono_enum strict_mono_less by fastforce
qed (simp add: grab_def)
lemma finite_grab_iff [simp]: "finite (snd (grab N n)) ⟷ finite N"
by (metis finite_grab grab_Un_eq infinite_Un infinite_super snd_grab_subset)
lemma grab_eqD:
"⟦grab N n = (A,M); infinite N⟧
⟹ A ≪ M ∧ finite A ∧ card A = n ∧ infinite M ∧ A ⊆ N ∧ M ⊆ N"
using card_grab grab_def less_sets_grab finite_grab_iff by auto
lemma less_sets_fst_grab: "A ≪ N ⟹ A ≪ fst (grab N n)"
by (simp add: fst_grab_subset less_sets_weaken2)
text‹Possibly redundant, given @{term grab}›
definition nxt where "nxt ≡ λN. λn::nat. N ∩ {n<..}"
lemma infinite_nxtN: "infinite N ⟹ infinite (nxt N n)"
by (simp add: infinite_nat_greaterThan nxt_def)
lemma nxt_subset: "nxt N n ⊆ N"
unfolding nxt_def by blast
lemma nxt_subset_greaterThan: "m ≤ n ⟹ nxt N n ⊆ {m<..}"
by (auto simp: nxt_def)
lemma nxt_subset_atLeast: "m ≤ n ⟹ nxt N n ⊆ {m..}"
by (auto simp: nxt_def)
lemma enum_nxt_ge: "infinite N ⟹ a ≤ enum (nxt N a) n"
by (simp add: atLeast_le_enum infinite_nxtN nxt_subset_atLeast)
lemma inj_enum_nxt: "infinite N ⟹ inj_on (enum (nxt N a)) A"
by (simp add: infinite_nxtN strict_mono_enum strict_mono_imp_inj_on)
subsection ‹Larson's Lemma 3.11›
text ‹Again from Jean A. Larson,
A short proof of a partition theorem for the ordinal $\omega^\omega$.
\emph{Annals of Mathematical Logic}, 6:129--145, 1973.›
lemma lemma_3_11:
assumes "l > 0"
shows "thin (inter_scheme l ` {U. Form l U})"
using form_cases [of l]
proof cases
case zero
then show ?thesis
using assms by auto
next
case (nz ka kb)
note acc_lengths.simps [simp del]
show ?thesis
unfolding thin_def
proof clarify
fix U U'
assume ne: "inter_scheme l U ≠ inter_scheme l U'" and init: "initial_segment (inter_scheme l U) (inter_scheme l U')"
assume "Form l U"
then obtain kp kq xs ys where "l = kp+kq - 1" "U = {xs,ys}"
and U: "Form_Body kp kq xs ys (inter_scheme l U)" and "0 < kq" "kq ≤ kp" "kp ≤ Suc kq"
using assms inter_scheme by blast
then have "kp = ka ∧ kq = kb"
using nz by linarith
then obtain a as b bs c d
where len: "length (a#as) = ka" "length (b#bs) = kb"
and c: "c = acc_lengths 0 (a#as)"
and d: "d = acc_lengths 0 (b#bs)"
and Ueq: "inter_scheme l U = concat [c, a, d, b] @ interact as bs"
using U by (auto simp: Form_Body.simps)
assume "Form l U'"
then obtain kp' kq' xs' ys' where "l = kp'+kq' - 1" "U' = {xs',ys'}"
and U': "Form_Body kp' kq' xs' ys' (inter_scheme l U')" and "0 < kq'" "kq' ≤ kp'" "kp' ≤ Suc kq'"
using assms inter_scheme by blast
then have "kp' = ka ∧ kq' = kb"
using nz by linarith
then obtain a' as' b' bs' c' d'
where len': "length (a'#as') = ka" "length (b'#bs') = kb"
and c': "c' = acc_lengths 0 (a'#as')"
and d': "d' = acc_lengths 0 (b'#bs')"
and Ueq': "inter_scheme l U' = concat [c', a', d', b'] @ interact as' bs'"
using U' by (auto simp: Form_Body.simps)
have [simp]: "length bs' = length bs" "length as' = length as"
using len len' by auto
have "inter_scheme l U ≠ []" "inter_scheme l U' ≠ []"
using Form_Body_nonempty U U' by auto
define u1 where "u1 ≡ hd (inter_scheme l U)"
have u1_eq': "u1 = hd (inter_scheme l U')"
using ‹inter_scheme l U ≠ []› init u1_def initial_segment_ne by fastforce
have au1: "u1 = length a"
by (simp add: u1_def Ueq c)
have au1': "u1 = length a'"
by (simp add: u1_eq' Ueq' c')
have len_eqk: "length c' = ka" "length d' = kb" "length c' = ka" "length d' = kb"
using c d len c' d' len' by auto
have take: "take (ka + u1 + kb) (c @ a @ d @ l) = c @ a @ d"
"take (ka + u1 + kb) (c' @ a' @ d' @ l) = c' @ a' @ d'" for l
using c d c' d' len by (simp_all flip: au1 au1')
have leU: "ka + u1 + kb ≤ length (inter_scheme l U)"
using c d len by (simp add: au1 Ueq)
then have "take (ka + u1 + kb) (inter_scheme l U) = take (ka + u1 + kb) (inter_scheme l U')"
using take_initial_segment init by blast
then have §: "c @ a @ d = c' @ a' @ d'"
by (metis Ueq Ueq' append.assoc concat.simps(2) take)
have "length (inter_scheme l U) = ka + (c @ a @ d)!(ka-1) + kb + last d"
by (simp add: Ueq c d length_interact nth_append flip: len)
moreover have "length (inter_scheme l U') = ka + (c' @ a' @ d')!(ka-1) + kb + last d'"
by (simp add: Ueq' c' d' length_interact nth_append flip: len')
moreover have "last d = last d'"
using "§" c d d' len'(1) len_eqk(1) by auto
ultimately have "length (inter_scheme l U) = length (inter_scheme l U')"
by (simp add: §)
then show False
using init initial_segment_length_eq ne by blast
qed
qed
subsection ‹Larson's Lemma 3.6›
proposition lemma_3_6:
fixes g :: "nat list set ⇒ nat"
assumes g: "g ∈ [WW]⇗2⇖ → {0,1}"
obtains N j where "infinite N"
and "⋀k u. ⟦k > 0; u ∈ [WW]⇗2⇖; Form k u; [enum N k] < inter_scheme k u; List.set (inter_scheme k u) ⊆ N⟧ ⟹ g u = j k"
proof -
define Φ where "Φ ≡ λm::nat. λM. infinite M ∧ m < Inf M"
define Ψ where "Ψ ≡ λl m n::nat. λM N j. n > m ∧ N ⊆ M ∧ n ∈ M
∧ (∀U. Form l U ∧ U ⊆ WW ∧ [n] < inter_scheme l U ∧ list.set (inter_scheme l U) ⊆ N ⟶ g U = j)"
have *: "∃n N j. Φ n N ∧ Ψ l m n M N j" if "l > 0" "Φ m M" for l m::nat and M :: "nat set"
proof -
define FF where "FF ≡ {U ∈ [WW]⇗2⇖. Form l U}"
define h where "h ≡ λzs. g (inv_into FF (inter_scheme l) zs)"
have "thin (inter_scheme l ` FF)"
using ‹l > 0› lemma_3_11 by (simp add: thin_def FF_def)
moreover
have "inter_scheme l ` FF ⊆ WW"
using inter_scheme_simple ‹0 < l› FF_def by blast
moreover
have "h ` {xs ∈ inter_scheme l ` FF. List.set xs ⊆ M} ⊆ {..<2}"
using g inv_into_into[of concl: "FF" "inter_scheme l"]
by (force simp: h_def FF_def Pi_iff)
ultimately
obtain j N where "j < 2" "infinite N" "N ⊆ M" and hj: "h ` {xs ∈ inter_scheme l ` FF. List.set xs ⊆ N} ⊆ {j}"
using ‹Φ m M› unfolding Φ_def by (blast intro: Nash_Williams_WW [of M])
let ?n = "Inf N"
have "?n > m"
using ‹Φ m M› ‹infinite N› unfolding Φ_def Inf_nat_def infinite_nat_iff_unbounded
by (metis LeastI_ex ‹N ⊆ M› le_less_trans not_less not_less_Least subsetD)
have "g U = j" if "Form l U" "U ⊆ WW" "[?n] < inter_scheme l U" "list.set (inter_scheme l U) ⊆ N - {?n}" for U
proof -
obtain xs ys where xys: "xs ≠ ys" "U = {xs,ys}"
using Form_elim_upair ‹Form l U› by blast
moreover have "inj_on (inter_scheme l) FF"
using ‹0 < l› inj_on_def inter_scheme_injective FF_def by blast
moreover
have "g (inv_into FF (inter_scheme l) (inter_scheme l U)) = j"
using hj that xys subset_Diff_insert by (fastforce simp: h_def FF_def image_iff)
ultimately show ?thesis
using that FF_def by auto
qed
moreover have "?n < Inf (N - {?n})"
by (metis Diff_iff Inf_nat_def Inf_nat_def1 ‹infinite N› finite.emptyI infinite_remove linorder_neqE_nat not_less_Least singletonI)
moreover have "?n ∈ M"
by (metis Inf_nat_def1 ‹N ⊆ M› ‹infinite N› finite.emptyI subsetD)
ultimately have "Φ ?n (N - {?n}) ∧ Ψ l m ?n M (N - {?n}) j"
using ‹Φ m M› ‹infinite N› ‹N ⊆ M› ‹?n > m› by (auto simp: Φ_def Ψ_def)
then show ?thesis
by blast
qed
have base: "Φ 0 {0<..}"
unfolding Φ_def by (metis infinite_Ioi Inf_nat_def1 greaterThan_iff greaterThan_non_empty)
have step: "Ex (λ(n,N,j). Φ n N ∧ Ψ l m n M N j)" if "Φ m M" "l > 0" for m M l
using * [of l m M] that by (auto simp: Φ_def)
define G where "G ≡ λl m M. @(n,N,j). Φ n N ∧ Ψ (Suc l) m n M N j"
have GΦ: "(λ(n,N,j). Φ n N) (G l m M)" and GΨ: "(λ(n,N,j). Ψ (Suc l) m n M N j) (G l m M)"
if "Φ m M" for l m M
using step [OF that, of "Suc l"] by (force simp: G_def dest: some_eq_imp)+
have G_increasing: "(λ(n,N,j). n > m ∧ N ⊆ M ∧ n ∈ M) (G l m M)" if "Φ m M" for l m M
using GΨ [OF that, of l] that by (simp add: Ψ_def split: prod.split_asm)
define H where "H ≡ rec_nat (0,{0<..},0) (λl (m,M,j). G l m M)"
have H_simps: "H 0 = (0,{0<..},0)" "⋀l. H (Suc l) = (case H l of (m,M,j) ⇒ G l m M)"
by (simp_all add: H_def)
have HΦ: "(λ(n,N,j). Φ n N) (H l)" for l
by (induction l) (use base GΦ in ‹auto simp: H_simps split: prod.split_asm›)
define ν where "ν ≡ (λl. case H l of (n,M,j) ⇒ n)"
have H_inc: "ν l ≥ l" for l
proof (induction l)
case (Suc l)
then show ?case
using HΦ [of l] G_increasing [of "ν l"]
apply (clarsimp simp: H_simps ν_def split: prod.split)
by (metis (no_types, lifting) case_prodD leD le_less_trans not_less_eq_eq)
qed auto
let ?N = "range ν"
define j where "j ≡ λl. case H l of (n,M,j) ⇒ j"
have H_increasing_Suc: "(case H k of (n, N, j') ⇒ N) ⊇ (case H (Suc k) of (n, N, j') ⇒ insert n N)" for k
using HΦ [of k]
by (force simp: H_simps split: prod.split dest: G_increasing [where l=k])
have H_increasing_superset: "(case H k of (n, N, j') ⇒ N) ⊇ (case H (n+k) of (n, N, j') ⇒ N)" for k n
proof (induction n)
case (Suc n)
then show ?case
using H_increasing_Suc [of "n+k"] by (auto split: prod.split_asm)
qed auto
then have H_increasing_less: "(case H k of (n, N, j') ⇒ N) ⊇ (case H l of (n, N, j') ⇒ insert n N)"
if "k<l" for k l
by (smt (verit, best) H_increasing_Suc add.commute less_natE order_trans that)
have "ν k < ν (Suc k)" for k
using HΦ [of k] unfolding ν_def
by (auto simp: H_simps split: prod.split dest: G_increasing [where l=k])
then have strict_mono_ν: "strict_mono ν"
by (simp add: strict_mono_Suc_iff)
then have enum_N: "enum ?N = ν"
by (metis enum_works nat_infinite_iff range_strict_mono_ext)
have **: "?N ∩ {n<..} ⊆ N'" if H: "H k = (n, N', j)" for n N' k j
proof clarify
fix l
assume "n < ν l"
then have False if "l ≤ k"
using that strict_monoD [OF strict_mono_ν, of l k ] H by (force simp: ν_def)
then have "k < l" using not_less by blast
then obtain M j where Mj: "H l = (ν l,M,j)"
unfolding ν_def
by (metis (mono_tags, lifting) case_prod_conv old.prod.exhaust)
then show "ν l ∈ N'"
using that H_increasing_less [OF ‹k<l›] Mj by auto
qed
show thesis
proof
show "infinite (?N::nat set)"
using H_inc infinite_nat_iff_unbounded_le by auto
next
fix l U
assume "0 < l" and U: "U ∈ [WW]⇗2⇖"
and interU: "[enum ?N l] < inter_scheme l U" "Form l U"
and sub: "list.set (inter_scheme l U) ⊆ ?N"
obtain k where k: "l = Suc k"
using ‹0 < l› gr0_conv_Suc by blast
have "g U = v" if "H k = (m, M, j0)" and "G k m M = (n, N', v)"
for m M j0 n N' v
proof -
have n: "ν (Suc k) = n"
using that by (simp add: ν_def H_simps)
have "{..enum (range ν) l} ∩ list.set (inter_scheme l U) = {}"
using inter_scheme_strict_sorted ‹0 < l› interU singleton_less_list_iff strict_sorted_iff by blast
then have "list.set (inter_scheme (Suc k) U) ⊆ N'"
using that sub ** [of "Suc k" n N' v] Suc_le_eq not_less_eq_eq
by (fastforce simp: k n enum_N H_simps)
then show ?thesis
using that interU U GΨ [of m M k] HΦ [of k]
by (auto simp: Ψ_def k enum_N H_simps n nsets_def)
qed
with U show "g U = j l"
by (auto simp: k j_def H_simps split: prod.split)
qed
qed
subsection ‹Larson's Lemma 3.7›
subsubsection ‹Preliminaries›
text ‹Analogous to @{thm [source] ordered_nsets_2_eq}, but without type classes›
lemma total_order_nsets_2_eq:
assumes tot: "total_on A r" and irr: "irrefl r"
shows "nsets A 2 = {{x,y} | x y. x ∈ A ∧ y ∈ A ∧ (x,y) ∈ r}"
(is "_ = ?rhs")
proof
show "nsets A 2 ⊆ ?rhs"
using tot
unfolding numeral_nat total_on_def nsets_def
by (fastforce simp: card_Suc_eq Set.doubleton_eq_iff not_less)
show "?rhs ⊆ nsets A 2"
using irr unfolding numeral_nat by (force simp: nsets_def card_Suc_eq irrefl_def)
qed
lemma lenlex_nsets_2_eq: "nsets A 2 = {{x,y} | x y. x ∈ A ∧ y ∈ A ∧ (x,y) ∈ lenlex less_than}"
using total_order_nsets_2_eq by (simp add: total_order_nsets_2_eq irrefl_def)
lemma sum_sorted_list_of_set_map: "finite I ⟹ sum_list (map f (list_of I)) = sum f I"
proof (induction "card I" arbitrary: I)
case (Suc n I)
then have [simp]: "I ≠ {}"
by auto
have "sum_list (map f (list_of (I - {Min I}))) = sum f (I - {Min I})"
using Suc by auto
then show ?case
using Suc.prems sum.remove [of I "Min I" f]
by (simp add: sorted_list_of_set_nonempty Suc)
qed auto
lemma sorted_list_of_set_UN_eq_concat:
assumes I: "strict_mono_sets I f" "finite I" and fin: "⋀i. finite (f i)"
shows "list_of (⋃i ∈ I. f i) = concat (map (list_of ∘ f) (list_of I))"
using I
proof (induction "card I" arbitrary: I)
case (Suc n I)
then have "I ≠ {}" and Iexp: "I = insert (Min I) (I - {Min I})"
using Min_in Suc.hyps(2) Suc.prems(2) by fastforce+
have IH: "list_of (⋃ (f ` (I - {Min I}))) = concat (map (list_of ∘ f) (list_of (I - {Min I})))"
using Suc unfolding strict_mono_sets_def
by (metis DiffE Iexp card_Diff_singleton diff_Suc_1 finite_Diff insertI1)
have "list_of (⋃ (f ` I)) = list_of (⋃ (f ` (insert (Min I) (I - {Min I}))))"
using Iexp by auto
also have "… = list_of (f (Min I) ∪ ⋃ (f ` (I - {Min I})))"
by (metis Union_image_insert)
also have "… = list_of (f (Min I)) @ list_of (⋃ (f ` (I - {Min I})))"
proof (rule sorted_list_of_set_Un)
show "f (Min I) ≪ ⋃ (f ` (I - {Min I}))"
using Suc.prems ‹I ≠ {}› strict_mono_less_sets_Min by blast
show "finite (⋃ (f ` (I - {Min I})))"
by (simp add: ‹finite I› fin)
qed (use fin in auto)
also have "… = list_of (f (Min I)) @ concat (map (list_of ∘ f) (list_of (I - {Min I})))"
using IH by metis
also have "… = concat (map (list_of ∘ f) (list_of I))"
by (simp add: Suc.prems(2) ‹I ≠ {}› sorted_list_of_set_nonempty)
finally show ?case .
qed auto
subsubsection ‹Lemma 3.7 of Jean A. Larson, ibid.›
proposition lemma_3_7:
assumes "infinite N" "l > 0"
obtains M where "M ∈ [WW]⇗m⇖"
"⋀U. U ∈ [M]⇗2⇖ ⟹ Form l U ∧ List.set (inter_scheme l U) ⊆ N"
proof (cases "m < 2")
case True
obtain w where w: "w ∈ WW"
using WW_def strict_sorted_into_WW by auto
define M where "M ≡ if m=0 then {} else {w}"
have M: "M ∈ [WW]⇗m⇖"
using True by (auto simp: M_def nsets_def w)
have [simp]: "[M]⇗2⇖ = {}"
using True by (auto simp: M_def nsets_def w dest: subset_singletonD)
show ?thesis
using M that by fastforce
next
case False
then have "m ≥ 2"
by auto
have nonz: "(enum N ∘ Suc) i > 0" for i
using assms(1) le_enumerate less_le_trans by fastforce
note infinite_nxt_N = infinite_nxtN [OF ‹infinite N›, iff]
note ‹infinite N› [ iff]
have [simp]: "{n<..<Suc n} = {}" "{..<1::nat} = {0}" for n
by auto
note One_nat_def [simp del]
define DF_Suc where "DF_Suc ≡ λk D. enum (nxt N (enum (nxt N (Max D)) (Inf D - 1))) ` {..<Suc k}"
define DF where "DF ≡ λk n. (DF_Suc k ^^ n) ((enum N ∘ Suc) ` {..<Suc k})"
have DF_simps: "DF k 0 = (enum N ∘ Suc) ` {..<Suc k}" "DF k (Suc i) = DF_Suc k (DF k i)" for i k
by (auto simp: DF_def)
have card_DF: "card (DF k i) = Suc k" for i k
proof (induction i)
case 0
have "inj_on (enum N ∘ Suc) {..<Suc k}"
by (simp add: assms(1) strict_mono_def strict_mono_imp_inj_on)
with 0 show ?case
using card_image DF_simps by fastforce
next
case (Suc i)
then show ?case
by (simp add: ‹infinite N› DF_simps DF_Suc_def card_image infinite_nxtN strict_mono_enum strict_mono_imp_inj_on)
qed
have DF_ne: "DF k i ≠ {}" for i k
by (metis card_DF card_lessThan lessThan_empty_iff nat.simps(3))
have finite_DF: "finite (DF k i)" for i k
by (induction i) (auto simp: DF_simps DF_Suc_def)
have DF_Suc: "DF k i ≪ DF k (Suc i)" for i k
unfolding less_sets_def
by (force simp: finite_DF DF_simps DF_Suc_def
intro!: greaterThan_less_enum nxt_subset_greaterThan atLeast_le_enum nxt_subset_atLeast infinite_nxtN [OF ‹infinite N›])
have DF_DF: "DF k i ≪ DF k j" if "i<j" for i j k
by (meson DF_Suc DF_ne UNIV_I less_sets_imp_strict_mono_sets strict_mono_setsD that)
then have sm_DF: "strict_mono_sets UNIV (DF k)" for k
by (simp add: strict_mono_sets_def)
have DF_gt0: "0 < Inf (DF k i)" for i k
proof (cases i)
case 0
then show ?thesis
by (metis DF_ne DF_simps(1) Inf_nat_def1 imageE nonz)
next
case (Suc n)
then show ?thesis
by (metis DF_Suc DF_ne Inf_nat_def1 gr0I gr_implies_not0 less_sets_def)
qed
have DF_N: "DF k i ⊆ N" for i k
proof (induction i)
case 0
then show ?case
using ‹infinite N› range_enum by (auto simp: DF_simps)
next
case (Suc i)
then show ?case
unfolding DF_simps DF_Suc_def image_subset_iff
by (metis IntE ‹infinite N› enumerate_in_set infinite_nxtN nxt_def)
qed
have sm_enum_DF: "strict_mono_on {..k} (enum (DF k i))" for k i
by (metis card_DF enum_works_finite finite_DF lessThan_Suc_atMost)
define AF where "AF ≡ λk i. enum (nxt N (Max (DF k i))) ` {..<Inf (DF k i)}"
have AF_ne: "AF k i ≠ {}" for i k
by (auto simp: AF_def lessThan_empty_iff DF_gt0)
have finite_AF [simp]: "finite (AF k i)" for i k
by (simp add: AF_def)
have card_AF: "card (AF k i) = ⨅ (DF k i)" for k i
by (simp add: AF_def card_image inj_enum_nxt)
have DF_AF: "DF k i ≪ AF k i" for i k
unfolding less_sets_def AF_def
by (simp add: finite_DF greaterThan_less_enum nxt_subset_greaterThan)
have E: "⟦x ≤ y; infinite M⟧ ⟹ enum M x < enum (nxt N (enum M y)) z" for x y z M
by (metis infinite_nxt_N dual_order.eq_iff enumerate_mono greaterThan_less_enum nat_less_le nxt_subset_greaterThan)
have AF_DF_Suc: "AF k i ≪ DF k (Suc i)" for i k
by (auto simp: DF_simps DF_Suc_def less_sets_def AF_def E)
have AF_DF: "AF k p ≪ DF k q" if "p<q" for k p q
by (metis AF_DF_Suc DF_ne Suc_lessI UNIV_I less_sets_trans sm_DF strict_mono_sets_def that)
have AF_Suc: "AF k i ≪ AF k (Suc i)" for i k
using AF_DF_Suc DF_AF DF_ne less_sets_trans by blast
then have sm_AF: "strict_mono_sets UNIV (AF k)" for k
by (simp add: AF_ne less_sets_imp_strict_mono_sets)
define del where "del ≡ λk i j. enum (DF k i) j - enum (DF k i) (j - 1)"
define QF where "QF k ≡ wfrec pair_less (λf (j,i).
if j=0 then AF k i
else let r = (if i=0 then f (j-1,m-1) else f (j,i-1)) in
enum (nxt N (Suc (Max r))) ` {..< del k (if j=k then m - Suc i else i) j})"
for k
note cut_apply [simp]
have finite_QF [simp]: "finite (QF k p)" for p k
using wf_pair_less
proof (induction p rule: wf_induct_rule)
case (less p)
then show ?case
by (simp add: def_wfrec [OF QF_def, of k p] split: prod.split)
qed
have del_gt_0: "⟦j < Suc k; 0 < j⟧ ⟹ 0 < del k i j" for i j k
by (simp add: card_DF del_def finite_DF)
have QF_ne [simp]: "QF k (j,i) ≠ {}" if j: "j < Suc k" for j i k
using wf_pair_less j
proof (induction "(j,i)" rule: wf_induct_rule)
case less
then show ?case
by (auto simp: def_wfrec [OF QF_def, of k "(j,i)"] AF_ne lessThan_empty_iff del_gt_0)
qed
have QF_0 [simp]: "QF k (0,i) = AF k i" for i k
by (simp add: def_wfrec [OF QF_def])
have QF_Suc: "QF k (Suc j,0) = enum (nxt N (Suc (Max (QF k (j, m - 1))))) `
{..< del k (if Suc j = k then m - 1 else 0) (Suc j)}" for j k
apply (simp add: def_wfrec [OF QF_def, of k "(Suc j,0)"] One_nat_def)
apply (simp add: pair_less_def cut_def)
done
have QF_Suc_Suc: "QF k (Suc j, Suc i)
= enum (nxt N (Suc (Max (QF k (Suc j, i))))) ` {..< del k (if Suc j = k then m - Suc(Suc i) else Suc i) (Suc j)}"
for i j k
by (simp add: def_wfrec [OF QF_def, of k "(Suc j,Suc i)"])
have less_QF1: "QF k (j, m - 1) ≪ QF k (Suc j,0)" for j k
by (auto simp: def_wfrec [OF QF_def, of k "(Suc j,0)"] pair_lessI1 enum_nxt_ge
intro!: less_sets_weaken2 [OF less_sets_Suc_Max])
have less_QF2: "QF k (j,i) ≪ QF k (j, Suc i)" for j i k
by (auto simp: def_wfrec [OF QF_def, of k "(j, Suc i)"] pair_lessI2 enum_nxt_ge
intro: less_sets_weaken2 [OF less_sets_Suc_Max] strict_mono_setsD [OF sm_AF])
have less_QF_same: "QF k (j,i') ≪ QF k (j,i)"
if "i' < i" "j ≤ k" for i' i j k
proof (rule strict_mono_setsD [OF less_sets_imp_strict_mono_sets])
show "QF k (j, i) ≪ QF k (j, Suc i)" for i
by (simp add: less_QF2)
show "QF k (j, i) ≠ {}" if "0 < i" for i
using that by (simp add: ‹j ≤ k› le_imp_less_Suc)
qed (use that in auto)
have less_QF_step: "QF k (j-1, i') ≪ QF k (j,i)"
if "0 < j" "j ≤ k" "i' < m" for j i' i k
proof -
have less_QF1': "QF k (j - 1, m-1) ≪ QF k (j,0)" if "j > 0" for j
by (metis less_QF1 that Suc_pred One_nat_def)
have "QF k (j-1, i') ≪ QF k (j,0)"
proof (cases "i' = m - 1")
case True
then show ?thesis
using less_QF1' ‹0 < j› by blast
next
case False
show ?thesis
using False that less_sets_trans [OF less_QF_same less_QF1' QF_ne] by auto
qed
then show ?thesis
by (metis QF_ne less_QF_same less_Suc_eq_le less_sets_trans ‹j ≤ k› zero_less_iff_neq_zero)
qed
have less_QF: "QF k (j',i') ≪ QF k (j,i)"
if j: "j' < j" "j ≤ k" and i: "i' < m" "i < m" for j' j i' i k
using j
proof (induction "j-j'" arbitrary: j)
case (Suc d)
show ?case
proof (cases "j' < j - 1")
case True
then have "QF k (j', i') ≪ QF k (j - 1, i)"
using Suc.hyps Suc.prems(2) by force
then show ?thesis
by (rule less_sets_trans [OF _ less_QF_step QF_ne]) (use Suc i in auto)
next
case False
then have "j' = j - 1"
using ‹j' < j› by linarith
then show ?thesis
using Suc.hyps ‹j ≤ k› less_QF_step i by auto
qed
qed auto
have sm_QF: "strict_mono_sets ({..k} × {..<m}) (QF k)" for k
unfolding strict_mono_sets_def
proof (intro strip)
fix p q
assume p: "p ∈ {..k} × {..<m}" and q: "q ∈ {..k} × {..<m}" and "p < q"
then obtain j' i' j i where §: "p = (j',i')" "q = (j,i)" "i' < m" "i < m" "j' ≤ k" "j ≤ k"
using surj_pair [of p] surj_pair [of q] by blast
with ‹p < q› have "j' < j ∨ j' = j ∧ i' < i"
by auto
then show "QF k p ≪ QF k q"
using § less_QF less_QF_same by presburger
qed
then have sm_QF1: "strict_mono_sets {..<ka} (λj. QF k (j,i))"
if "i<m" "Suc k ≥ ka" "ka ≥ k" for ka k i
proof -
have "{..<ka} ⊆ {..k}"
by (metis lessThan_Suc_atMost lessThan_subset_iff ‹Suc k ≥ ka›)
then show ?thesis
by (simp add: less_QF strict_mono_sets_def subset_iff that)
qed
have disjoint_QF: "i'=i ∧ j'=j" if "¬ disjnt (QF k (j', i')) (QF k (j,i))" "j' ≤ k" "j ≤ k" "i' < m" "i < m" for i' i j' j k
using that strict_mono_sets_imp_disjoint [OF sm_QF]
by (force simp: pairwise_def)
have card_QF: "card (QF k (j,i)) = (if j=0 then ⨅ (DF k i) else del k (if j = k then m - Suc i else i) j)"
for i k j
proof (cases j)
case 0
then show ?thesis
by (simp add: AF_def card_image inj_enum_nxt)
next
case (Suc j')
show ?thesis
by (cases i; simp add: Suc One_nat_def QF_Suc QF_Suc_Suc card_image inj_enum_nxt)
qed
have AF_non_Nil: "list_of (AF k i) ≠ []" for k i
by (simp add: AF_ne)
have QF_non_Nil: "list_of (QF k (j,i)) ≠ []" if "j < Suc k" for i j k
by (simp add: that)
have AF_subset_N: "AF k i ⊆ N" for i k
unfolding AF_def image_subset_iff
using nxt_subset enumerate_in_set infinite_nxtN ‹infinite N› by blast
have QF_subset_N: "QF k (j,i) ⊆ N" for i j k
proof (induction j)
case (Suc j)
show ?case
by (cases i) (use nxt_subset enumerate_in_set in ‹(force simp: QF_Suc QF_Suc_Suc)+›)
qed (use AF_subset_N in auto)
obtain ka k where "k>0" and kka: "k ≤ ka" "ka ≤ Suc k" "l = ((ka+k) - 1)"
by (metis One_nat_def assms(2) diff_add_inverse form_cases le0 le_refl)
then have "ka > 0"
using dual_order.strict_trans1 by blast
have ka_k_or_Suc: "ka = k ∨ ka = Suc k"
using kka by linarith
have lessThan_k: "{..<k} = insert 0 {0<..<k}" if "k>0" for k::nat
using that by auto
then have sorted_list_of_set_k: "list_of {..<k} = 0 # list_of {0<..<k}" if "k>0" for k::nat
using sorted_list_of_set_insert_remove_cons [of concl: 0 "{0<..<k}"] that by simp
define RF where "RF ≡ λj i. if j = k then QF k (j, m - Suc i) else QF k (j,i)"
have RF_subset_N: "RF j i ⊆ N" if "i<m" for i j
using that QF_subset_N by (simp add: RF_def)
have finite_RF [simp]: "finite (RF k p)" for p k
by (simp add: RF_def)
have RF_0: "RF 0 i = AF k i" for i
using RF_def ‹0 < k› by auto
have disjoint_RF: "i'=i ∧ j'=j" if "¬ disjnt (RF j' i') (RF j i)" "j' ≤ k" "j ≤ k" "i' < m" "i < m" for i' i j' j
using disjoint_QF that
by (auto simp: RF_def split: if_split_asm dest: disjoint_QF)
have sum_card_RF [simp]: "(∑j≤n. card (RF j i)) = enum (DF k i) n" if "n ≤ k" "i < m" for i n
using that
proof (induction n)
case 0
then show ?case
using DF_ne [of k i] finite_DF [of k i] ‹k>0›
by (simp add: RF_def AF_def card_image inj_enum_nxt enum_0_eq_Inf_finite)
next
case (Suc n)
then have "enum (DF k i) 0 ≤ enum (DF k i) n ∧ enum (DF k i) n ≤ enum (DF k i) (Suc n)"
using sm_enum_DF [of k i]
by (metis card_DF finite_DF finite_enumerate_mono_iff le_imp_less_Suc less_nat_zero_code linorder_not_le nless_le)
with Suc show ?case
by (auto simp: RF_def card_QF del_def)
qed
have DF_in_N: "enum (DF k i) j ∈ N" if "j ≤ k" for i j
by (metis DF_N card_DF finite_DF finite_enumerate_in_set le_imp_less_Suc subsetD that)
have Inf_DF_N: "⨅(DF k p) ∈ N" for k p
using DF_N DF_ne Inf_nat_def1 by blast
have RF_in_N: "(∑j≤n. card (RF j i)) ∈ N" if "n ≤ k" "i < m" for i n
by (auto simp: DF_in_N that)
have "ka - 1 ≤ k"
using kka(2) by linarith
then have sum_card_RF' [simp]:
"(∑j<ka. card (RF j i)) = enum (DF k i) (ka - 1)" if "i < m" for i
using sum_card_RF [of "ka - 1" i]
by (metis Suc_diff_1 ‹0 < ka› lessThan_Suc_atMost that)
have enum_DF_le_iff [simp]:
"enum (DF k i) j ≤ enum (DF k i') j ⟷ i ≤ i'" (is "?lhs = _")
if "j ≤ k" for i' i j k
proof
show "i ≤ i'" if ?lhs
proof -
have "enum (DF k i) j ∈ DF k i"
by (simp add: card_DF finite_enumerate_in_set finite_DF le_imp_less_Suc ‹j ≤ k›)
moreover have "enum (DF k i') j ∈ DF k i'"
by (simp add: ‹j ≤ k› card_DF finite_enumerate_in_set finite_DF le_imp_less_Suc that)
ultimately have "enum (DF k i') j < enum (DF k i) j" if "i' < i"
using sm_DF [of k] by (meson UNIV_I less_sets_def strict_mono_setsD that)
then show ?thesis
using not_less that by blast
qed
show ?lhs if "i ≤ i'"
by (metis DF_DF ‹j ≤ k› card_DF finite_DF finite_enumerate_in_set le_eq_less_or_eq
less_Suc_eq_le less_sets_def that)
qed
then have enum_DF_eq_iff[simp]:
"enum (DF k i) j = enum (DF k i') j ⟷ i = i'" if "j ≤ k" for i' i j k
by (metis le_antisym order_refl that)
have enum_DF_less_iff [simp]:
"enum (DF k i) j < enum (DF k i') j ⟷ i < i'" if "j ≤ k" for i' i j k
by (meson enum_DF_le_iff not_less that)
have card_AF_sum: "card (AF k i) + (∑j∈{0<..<ka}. card (RF j i)) = enum (DF k i) (ka-1)"
if "i < m" for i
using that ‹k > 0› ‹k ≤ ka› ‹ka ≤ Suc k›
by (simp add: lessThan_k RF_0 flip: sum_card_RF')
have sorted_list_of_set_iff [simp]: "list_of {0<..<k} = [] ⟷ k = 1" if "k>0" for k::nat
using atLeastSucLessThan_greaterThanLessThan that by fastforce
show thesis
proof
have inj: "inj_on (λi. list_of (⋃j<ka. RF j i)) {..<m}"
proof (clarsimp simp: inj_on_def)
fix x y
assume "x < m" "y < m" "list_of (⋃j<ka. RF j x) = list_of (⋃j<ka. RF j y)"
then have eq: "(⋃j<ka. RF j x) = (⋃j<ka. RF j y)"
by (simp add: sorted_list_of_set_inject)
show "x = y"
proof -
obtain n where n: "n ∈ RF 0 x"
using AF_ne QF_0 ‹0 < k› Inf_nat_def1 ‹k ≤ ka› by (force simp: RF_def)
with eq ‹ka > 0› obtain j' where "j' < ka" "n ∈ RF j' y"
by blast
then show ?thesis
using disjoint_QF [of k 0 x j'] n ‹x < m› ‹y < m› ‹ka ≤ Suc k› ‹0 < k›
by (force simp: RF_def disjnt_iff simp del: QF_0 split: if_split_asm)
qed
qed
define M where "M ≡ (λi. list_of (⋃j<ka. RF j i)) ` {..<m}"
have "finite M"
unfolding M_def by blast
moreover have "card M = m"
by (simp add: M_def ‹k ≤ ka› card_image inj)
moreover have "M ⊆ WW"
by (force simp: M_def WW_def)
ultimately show "M ∈ [WW]⇗m⇖"
by (simp add: nsets_def)
have sm_RF: "strict_mono_sets {..<ka} (λj. RF j i)" if "i<m" for i
using sm_QF1 that kka
by (simp add: less_QF RF_def strict_mono_sets_def)
have RF_non_Nil: "list_of (RF j i) ≠ []" if "j < Suc k" for i j
using that by (simp add: RF_def)
have less_RF_same: "RF j i' ≪ RF j i"
if "i' < i" "j < k" for i' i j
using that by (simp add: less_QF_same RF_def)
have less_RF_same_k: "RF k i' ≪ RF k i"
if "i < i'" "i' < m" for i' i
using that by (simp add: less_QF_same RF_def)
show "Form l U ∧ list.set (inter_scheme l U) ⊆ N" if "U ∈ [M]⇗2⇖" for U
proof -
from that obtain x y where "U = {x,y}" "x ∈ M" "y ∈ M" and xy: "(x,y) ∈ lenlex less_than"
by (auto simp: lenlex_nsets_2_eq)
let ?R = "λp. list_of ∘ (λj. RF j p)"
obtain p q where x: "x = list_of (⋃j<ka. RF j p)"
and y: "y = list_of (⋃j<ka. RF j q)" and "p < m" "q < m"
using ‹x ∈ M› ‹y ∈ M› by (auto simp: M_def)
then have pq: "p<q" "length x < length y"
using xy ‹k ≤ ka› ‹ka ≤ Suc k› lexl_not_refl [OF irrefl_less_than]
by (auto simp: lenlex_def sm_RF sorted_list_of_set_UN_lessThan length_concat sum_sorted_list_of_set_map)
have xc: "x = concat (map (?R p) (list_of {..<ka}))"
by (simp add: x sorted_list_of_set_UN_eq_concat ‹k ≤ ka› ‹ka ≤ Suc k› ‹p < m› sm_RF)
have yc: "y = concat (map (?R q) (list_of {..<ka}))"
by (simp add: y sorted_list_of_set_UN_eq_concat ‹k ≤ ka› ‹ka ≤ Suc k› ‹q < m› sm_RF)
have enum_DF_AF: "enum (DF k p) (ka - 1) < hd (list_of (AF k p))" for p
proof (rule less_setsD [OF DF_AF])
show "enum (DF k p) (ka - 1) ∈ DF k p"
using ‹ka ≤ Suc k› card_DF finite_DF by (auto simp: finite_enumerate_in_set)
show "hd (list_of (AF k p)) ∈ AF k p"
using AF_non_Nil finite_AF hd_in_set set_sorted_list_of_set by blast
qed
have less_RF_RF: "RF n p ≪ RF n q" if "n < k" for n
using that ‹p<q› by (simp add: less_RF_same)
have less_RF_Suc: "RF n q ≪ RF (Suc n) q" if "n < k" for n
using ‹q < m› that by (auto simp: RF_def less_QF)
have less_RF_k: "RF k q ≪ RF k p"
using ‹q < m› less_RF_same_k ‹p<q› by blast
have less_RF_k_ka: "RF (k-1) p ≪ RF (ka - 1) q"
using ka_k_or_Suc less_RF_RF
by (metis One_nat_def RF_def ‹0 < k› ‹ka - 1 ≤ k› ‹p < m› diff_Suc_1 diff_Suc_less less_QF_step)
have Inf_DF_eq_enum: "⨅ (DF k i) = enum (DF k i) 0" for k i
by (simp add: Inf_nat_def enumerate_0)
have Inf_DF_less: "⨅ (DF k i') < ⨅ (DF k i)" if "i'<i" for i' i k
by (metis DF_ne enum_0_eq_Inf enum_0_eq_Inf_finite enum_DF_less_iff le0 that)
have AF_Inf_DF_less: "⋀x. x ∈ AF k i ⟹ ⨅ (DF k i') < x" if "i'≤i" for i' i k
using less_setsD [OF DF_AF] DF_ne that
by (metis Inf_DF_less Inf_nat_def1 dual_order.order_iff_strict dual_order.strict_trans)
show ?thesis
proof (cases "k=1")
case True
with kka consider "ka=1" | "ka=2" by linarith
then show ?thesis
proof cases
case 1
define zs where "zs = card (AF 1 p) # list_of (AF 1 p)
@ card (AF 1 q) # list_of (AF 1 q)"
have zs: "Form_Body ka k x y zs"
proof (intro that exI conjI Form_Body.intros)
show "x = concat ([list_of (AF k p)])" "y = concat ([list_of (AF k q)])"
by (simp_all add: x y 1 lessThan_Suc RF_0)
have "AF k p ≪ insert (⨅ (DF k q)) (AF k q)"
by (metis AF_DF DF_ne Inf_nat_def1 RF_0 ‹0 < k› insert_iff less_RF_RF less_sets_def pq(1))
then have "strict_sorted (list_of (AF k p) @ ⨅ (DF k q) # list_of (AF k q))"
by (auto simp: strict_sorted_append_iff intro: less_sets_imp_list_less AF_Inf_DF_less)
moreover have "⋀x. x ∈ AF k q ⟹ ⨅ (DF k p) < x"
by (meson AF_Inf_DF_less less_imp_le_nat ‹p < q›)
moreover have "⋀x. x ∈ AF 1 p ⟹ ⨅ (DF 1 p) < x"
by (meson DF_AF DF_ne Inf_nat_def1 less_setsD)
ultimately show "strict_sorted zs"
using ‹p < q› True Inf_DF_less DF_AF DF_ne
by (auto simp: zs_def less_sets_def card_AF AF_Inf_DF_less)
qed (auto simp: ‹k=1› ‹ka=1› zs_def AF_ne ‹length x < length y›)
have zs_N: "list.set zs ⊆ N"
using AF_subset_N by (auto simp: zs_def card_AF Inf_DF_N ‹k=1›)
show ?thesis
proof
have "l = 1"
using kka ‹k=1› ‹ka=1› by auto
have "Form (2*1-1) {x,y}"
using "1" Form.intros(2) True zs by fastforce
then show "Form l U"
by (simp add: ‹U = {x,y}› ‹l = 1› One_nat_def)
show "list.set (inter_scheme l U) ⊆ N"
using kka zs zs_N ‹k=1› Form_Body_imp_inter_scheme by (fastforce simp: ‹U = {x,y}›)
qed
next
case 2
note True [simp] note 2 [simp]
have [simp]: "{0<..<2} = {1::nat}"
by auto
have enum_DF1_eq: "enum (DF 1 i) 1 = card (AF 1 i) + card (RF 1 i)"
if "i < m" for i
using card_AF_sum that by (simp add: One_nat_def)
have card_RF: "card (RF 1 i) = enum (DF 1 i) 1 - enum (DF 1 i) 0" if "i < m" for i
using that by (auto simp: RF_def card_QF del_def)
have list_of_AF_RF: "list_of (AF 1 q ∪ RF 1 q) = list_of (AF 1 q) @ list_of (RF 1 q)"
by (metis One_nat_def RF_0 True ‹0 < k› finite_RF less_RF_Suc sorted_list_of_set_Un)
define zs where "zs = card (AF 1 p) # (card (AF 1 p) + card (RF 1 p)) # list_of (AF 1 p)
@ (card (AF 1 q) + card (RF 1 q)) # list_of (AF 1 q) @ list_of (RF 1 q) @ list_of (RF 1 p)"
have zs: "Form_Body ka k x y zs"
proof (intro that exI conjI Form_Body.intros)
have "x = list_of (RF 0 p ∪ RF 1 p)"
by (simp add: x eval_nat_numeral lessThan_Suc RF_0 Un_commute One_nat_def)
also have "… = list_of (RF 0 p) @ list_of (RF 1 p)"
using RF_def True ‹p < m› less_QF_step
by (metis QF_0 RF_0 diff_self_eq_0 finite_RF le_refl sorted_list_of_set_Un zero_less_one)
finally show "x = concat ([list_of (AF 1 p),list_of (RF 1 p)])"
by (simp add: RF_0)
have *: "i ∈ AF 1 q ∨ i ∈ RF 1 q ∨ i ∈ RF 1 p ⟹ enum (DF 1 q) 1 < i" for i
using True card_DF finite_enumerate_in_set[OF finite_DF]
by (metis AF_ne DF_AF One_nat_def RF_0 RF_non_Nil finite_RF lessI less_RF_Suc less_RF_k less_setsD
less_sets_trans sorted_list_of_set.sorted_key_list_of_set_eq_Nil_iff)
show "y = concat [list_of (RF 1 q ∪ AF 1 q)]"
by (simp add: y eval_nat_numeral lessThan_Suc RF_0 One_nat_def)
show zs: "zs = concat [[card (AF 1 p), card (AF 1 p) + card (RF 1 p)], list_of (AF 1 p),
[card (AF 1 q) + card (RF 1 q)], list_of (RF 1 q ∪ AF 1 q)] @ interact [list_of (RF 1 p)] []"
using list_of_AF_RF by (simp add: zs_def Un_commute)
show "strict_sorted zs"
proof (simp add: ‹p<m› ‹q<m› ‹p<q› zs_def strict_sorted_append_iff, intro conjI strip)
show "0 < card (RF 1 p)"
using ‹p<m› by (simp add: card_RF card_DF finite_DF)
show G1: "card (AF 1 p) < card (AF 1 q) + card (RF 1 q)"
by (simp add: Inf_DF_less card_AF ‹p<q› trans_less_add1)
show "card (AF 1 p) < x"
if "x ∈ AF 1 p ∪ (AF 1 q ∪ (RF 1 q ∪ RF 1 p))" for x
using that ‹q < m› *
by (metis (no_types) order_refl AF_Inf_DF_less Un_iff G1 card_AF order.strict_trans enum_DF1_eq that)
show G2: "card (AF 1 p) + card (RF 1 p) < card (AF 1 q) + card (RF 1 q)"
using ‹p < q› ‹p < m› ‹q < m› by (metis enum_DF1_eq enum_DF_less_iff le_refl)
show "card (AF 1 q) + card (RF 1 q) < x"
if "x ∈ AF 1 q ∪ (RF 1 q ∪ RF 1 p)" for x
using that ‹q < m› * enum_DF1_eq by force
then show "card (AF 1 p) + card (RF 1 p) < x"
if "x ∈ AF 1 p ∪ (AF 1 q ∪ (RF 1 q ∪ RF 1 p))" for x
using that ‹p < m› finite_enumerate_in_set[OF finite_DF]
by (metis DF_AF G2 Un_iff card_DF dual_order.strict_trans enum_DF1_eq lessI less_setsD)
have "list_of (AF 1 p) < list_of {enum (DF 1 q) 1}"
proof (rule less_sets_imp_sorted_list_of_set)
show "AF 1 p ≪ {enum (DF 1 q) 1}"
by (metis AF_DF card_DF empty_subsetI finite_DF finite_enumerate_in_set insert_subset
less_Suc_eq less_sets_weaken2 ‹p<q›)
qed auto
then show "list_of (AF 1 p) < (card (AF 1 q) + card (RF 1 q)) # list_of (AF 1 q) @ list_of (RF 1 q) @ list_of (RF 1 p)"
using ‹q < m› by (simp add: less_list_def enum_DF1_eq)
have "list_of (AF 1 q) < list_of (RF 1 q)"
by (metis One_nat_def RF_0 True ‹0 < k› finite_RF less_RF_Suc less_sets_imp_sorted_list_of_set)
then show "list_of (AF 1 q) < list_of (RF 1 q) @ list_of (RF 1 p)"
using RF_non_Nil by (auto simp: less_list_def)
show "list_of (RF 1 q) < list_of (RF 1 p)"
using True finite_RF less_RF_k less_sets_imp_sorted_list_of_set by metis
qed
show "[list_of (AF 1 p), list_of (RF 1 p)] ∈ lists (- {[]})"
using RF_non_Nil ‹0 < k› by (auto simp: zs_def AF_ne)
show "[card (AF 1 q) + card (RF 1 q)] = acc_lengths 0 [list_of (RF 1 q ∪ AF 1 q)]"
using list_of_AF_RF by (auto simp: zs_def AF_ne sup_commute)
qed (auto simp: zs_def AF_ne ‹length x < length y›)
have zs_N: "list.set zs ⊆ N"
using ‹p < m› ‹q < m› DF_in_N enum_DF1_eq [symmetric]
by (auto simp: zs_def card_AF AF_subset_N RF_subset_N Inf_DF_N)
show ?thesis
proof
have "Form (2*1) {x,y}"
by (metis "2" Form.simps Suc_1 True zero_less_one zs)
with kka show "Form l U"
by (simp add: ‹U = {x,y}›)
show "list.set (inter_scheme l U) ⊆ N"
using kka zs zs_N ‹k=1› Form_Body_imp_inter_scheme by (fastforce simp: ‹U = {x, y}›)
qed
qed
next
case False
then have "k ≥ 2" "ka ≥ 2"
using kka ‹k>0› by auto
then have k_minus_1 [simp]: "Suc (k - Suc (Suc 0)) = k - Suc 0"
by auto
have [simp]: "Suc (k - 2) = k-1"
using ‹k ≥ 2› by linarith
define PP where "PP ≡ map (?R p) (list_of {0<..<ka})"
define QQ where "QQ ≡ map (?R q) (list_of {0<..<k-1}) @ ([list_of (RF (k-1) q ∪ RF (ka-1) q)])"
let ?INT = "interact PP QQ"
have [simp]: "length PP = ka - 1"
by (simp add: PP_def)
have [simp]: "length QQ = k-1"
using ‹k ≥ 2› by (simp add: QQ_def)
have PP_n: "PP ! n = list_of (RF (Suc n) p)"
if "n < ka-1" for n
using that kka by (auto simp: PP_def nth_sorted_list_of_set_greaterThanLessThan)
have QQ_n: "QQ ! n = (if n < k-2 then list_of (RF (Suc n) q)
else list_of (RF (k-1) q ∪ RF (ka - 1) q))"
if "n < k-1" for n
using that kka by (auto simp: QQ_def nth_append nth_sorted_list_of_set_greaterThanLessThan)
have QQ_n_same: "QQ ! n = list_of (RF (Suc n) q)"
if "n < k-1" "k=ka" for n
using that kka Suc_diff_Suc
by (fastforce simp: One_nat_def QQ_def nth_append nth_sorted_list_of_set_greaterThanLessThan)
have split_nat_interval: "{0<..<n} = insert (n-1) {0<..<n-1}" if "n ≥ 2" for n::nat
using that by auto
have split_list_interval: "list_of{0<..<n} = list_of{0<..<n-1} @ [n-1]" if "n ≥ 2" for n::nat
proof (intro sorted_list_of_set_unique [THEN iffD1] conjI)
have "list_of {0<..<n - 1} < [n - 1]"
by (auto intro: less_sets_imp_list_less)
then show "strict_sorted (list_of {0<..<n - 1} @ [n - 1])"
by (auto simp: strict_sorted_append_iff)
qed (use ‹n ≥ 2› in auto)
have list_of_RF_Un: "list_of (RF (k-1) q ∪ RF k q) = list_of (RF (k-1) q) @ list_of (RF k q)"
by (metis Suc_diff_1 ‹0 < k› finite_RF lessI less_RF_Suc sorted_list_of_set_Un)
have card_AF_sum_QQ: "card (AF k q) + sum_list (map length QQ) = (∑j<ka. card (RF j q))"
proof (cases "ka = Suc k")
case True
have "RF (k-1) q ∩ RF k q = {}"
using less_RF_Suc [of "k-1"] ‹k > 0› by (auto simp: less_sets_def)
then have "card (RF (k-1) q ∪ RF k q) = card (RF (k-1) q) + card (RF k q)"
by (simp add: card_Un_disjoint)
then show ?thesis
using ‹k≥2› ‹q < m›
apply (simp add: QQ_def True flip: RF_0)
apply (simp add: lessThan_k split_nat_interval sum_sorted_list_of_set_map)
done
next
case False
with kka have "ka=k" by linarith
with ‹k≥2› show ?thesis by (simp add: QQ_def lessThan_k split_nat_interval sum_sorted_list_of_set_map flip: RF_0)
qed
define LENS where "LENS ≡ λi. acc_lengths 0 (list_of (AF k i) # map (?R i) (list_of {0<..<ka}))"
have LENS_subset_N: "list.set (LENS i) ⊆ N" if "i < m" for i
proof -
have eq: "(list_of (AF k i) # map (?R i) (list_of {0<..<ka})) = map (?R i) (list_of {..<ka})"
using RF_0 ‹0 < ka› sorted_list_of_set_k by auto
let ?f = "rec_nat [card (AF k i)] (λn r. r @ [(∑j≤Suc n. card (RF j i))])"
have f: "acc_lengths 0 (map (?R i) (list_of {..v})) = ?f v" for v
by (induction v) (auto simp: RF_0 acc_lengths_append sum_sorted_list_of_set_map)
have 3: "list.set (?f v) ⊆ N" if "v ≤ k" for v
using that
proof (induction v)
case 0
have "card (AF k i) ∈ N"
by (metis DF_N DF_ne Inf_nat_def1 card_AF subsetD)
with 0 show ?case by simp
next
case (Suc v)
then have "enum (DF k i) (Suc v) ∈ N"
by (metis DF_N card_DF finite_enumerate_in_set finite_DF in_mono le_imp_less_Suc)
with Suc ‹i < m› show ?case
by (simp del: sum.atMost_Suc)
qed
show ?thesis
unfolding LENS_def
by (metis 3 Suc_pred' ‹0 < ka› ‹ka - 1 ≤ k› eq f lessThan_Suc_atMost)
qed
define LENS_QQ where "LENS_QQ ≡ acc_lengths 0 (list_of (AF k q) # QQ)"
have LENS_QQ_subset: "list.set LENS_QQ ⊆ list.set (LENS q)"
proof (cases "ka = Suc k")
case True
with ‹k ≥ 2› show ?thesis
unfolding QQ_def LENS_QQ_def LENS_def
by (auto simp: list_of_RF_Un split_list_interval acc_lengths_append)
next
case False
then have "ka=k"
using kka by linarith
with ‹k ≥ 2› show ?thesis
by (simp add: QQ_def LENS_QQ_def LENS_def split_list_interval)
qed
have ss_INT: "strict_sorted ?INT"
proof (rule strict_sorted_interact_I)
fix n
assume "n < length QQ"
then have n: "n < k-1"
by simp
have "n = k - 2" if "¬ n < k - 2"
using n that by linarith
moreover have "list_of (RF (Suc (k - 2)) p) < list_of (RF (k-1) q ∪ RF (ka - 1) q)"
by (auto simp: less_sets_imp_sorted_list_of_set less_sets_Un2 less_RF_RF less_RF_k_ka ‹0 < k›)
ultimately show "PP ! n < QQ ! n"
using ‹k ≤ ka› n by (auto simp: PP_n QQ_n less_sets_imp_sorted_list_of_set less_RF_RF)
next
fix n
have V: "⟦Suc n < ka - 1⟧ ⟹ list_of (RF (Suc n) q) < list_of (RF (Suc (Suc n)) p)" for n
by (smt RF_def Suc_leI ‹ka - 1 ≤ k› ‹q < m› diff_Suc_1 finite_RF less_QF_step less_le_trans less_sets_imp_sorted_list_of_set nat_neq_iff zero_less_Suc)
have "RF (k - 1) q ≪ RF k p"
by (metis One_nat_def RF_non_Nil Suc_pred ‹0 < k› finite_RF lessI less_RF_Suc less_RF_k less_sets_trans sorted_list_of_set_eq_Nil_iff)
with kka have "RF (k-1) q ∪ RF (ka - 1) q ≪ RF k p"
by (metis less_RF_k One_nat_def less_sets_Un1 antisym_conv2 diff_Suc_1 le_less_Suc_eq)
then have VI: "list_of (RF (k-1) q ∪ RF (ka - 1) q) < list_of (RF k p)"
by (rule less_sets_imp_sorted_list_of_set) auto
assume "Suc n < length PP"
with ‹ka ≤ Suc k› VI
show "QQ ! n < PP ! Suc n"
apply (clarsimp simp: PP_n QQ_n V)
by (metis One_nat_def Suc_1 Suc_lessI add.right_neutral add_Suc_right diff_Suc_Suc ka_k_or_Suc less_diff_conv)
next
show "PP ∈ lists (- {[]})"
using RF_non_Nil kka
by (clarsimp simp: PP_def) (metis RF_non_Nil less_le_trans)
show "QQ ∈ lists (- {[]})"
using RF_non_Nil kka
by (clarsimp simp: QQ_def) (metis RF_non_Nil Suc_pred ‹0 < k› less_SucI One_nat_def)
qed (use kka PP_def QQ_def in auto)
then have ss_QQ: "strict_sorted (concat QQ)"
using strict_sorted_interact_imp_concat by blast
obtain zs where zs: "Form_Body ka k x y zs" and zs_N: "list.set zs ⊆ N"
proof (intro that exI conjI Form_Body.intros [OF ‹length x < length y›])
show "x = concat (list_of (AF k p) # PP)"
using ‹ka > 0› by (simp add: PP_def RF_0 xc sorted_list_of_set_k)
let ?YR = "(map (list_of ∘ (λj. RF j q)) (list_of {0<..<ka}))"
have "concat ?YR = concat QQ"
proof (rule strict_sorted_equal [OF ss_QQ])
show "strict_sorted (concat ?YR)"
proof (rule strict_sorted_concat_I, simp_all)
fix n
assume 0: "Suc n < ka - Suc 0"
then have "Suc n < k"
by (metis One_nat_def ‹ka - 1 ≤ k› less_le_trans)
then show "list_of (RF (list_of {0<..<ka} ! n) q) < list_of (RF (list_of {0<..<ka} ! Suc n) q)"
by (simp add: Suc_lessD 0 less_RF_Suc less_sets_imp_sorted_list_of_set nth_sorted_list_of_set_greaterThanLessThan)
next
show "?YR ∈ lists (- {[]})"
using RF_non_Nil ‹ka ≤ Suc k› by (auto simp: mem_lists_non_Nil)
qed auto
show "list.set (concat ?YR) = list.set (concat QQ)"
using ka_k_or_Suc
proof
assume "ka = k"
then show "list.set (concat (map (list_of ∘ (λj. RF j q)) (list_of {0<..<ka}))) = list.set (concat QQ)"
using ‹k≥2› by simp (simp add: split_nat_interval QQ_def)
next
assume "ka = Suc k"
then show "list.set (concat (map (list_of ∘ (λj. RF j q)) (list_of {0<..<ka}))) = list.set (concat QQ)"
using ‹k≥2› by simp (auto simp: QQ_def split_nat_interval)
qed
qed
then show "y = concat (list_of (AF k q) # QQ)"
using ‹ka > 0› by (simp add: RF_0 yc sorted_list_of_set_k)
show "list_of (AF k p) # PP ∈ lists (- {[]})" "list_of (AF k q) # QQ ∈ lists (- {[]})"
using RF_non_Nil kka by (auto simp: AF_ne PP_def QQ_def eq_commute [of "[]"])
show "list.set ((LENS p @ list_of (AF k p) @ LENS_QQ @ list_of (AF k q) @ ?INT)) ⊆ N"
using AF_subset_N RF_subset_N LENS_subset_N ‹p < m› ‹q < m› LENS_QQ_subset
by (auto simp: subset_iff PP_def QQ_def)
show "length (list_of (AF k p) # PP) = ka" "length (list_of (AF k q) # QQ) = k"
using ‹0 < ka› ‹0 < k› by auto
show "LENS p = acc_lengths 0 (list_of (AF k p) # PP)"
by (auto simp: LENS_def PP_def)
show "strict_sorted (LENS p @ list_of (AF k p) @ LENS_QQ @ list_of (AF k q) @ ?INT)"
unfolding strict_sorted_append_iff
proof (intro conjI ss_INT)
show "LENS p < list_of (AF k p) @ LENS_QQ @ list_of (AF k q) @ ?INT"
using AF_non_Nil [of k p] ‹k ≤ ka› ‹ka ≤ Suc k› ‹p < m› card_AF_sum enum_DF_AF
by (simp add: enum_DF_AF less_list_def card_AF_sum LENS_def sum_sorted_list_of_set_map
del: acc_lengths.simps)
show "strict_sorted (LENS p)"
unfolding LENS_def
by (rule strict_sorted_acc_lengths) (use RF_non_Nil AF_non_Nil kka in ‹auto simp: in_lists_conv_set›)
show "strict_sorted LENS_QQ"
unfolding LENS_QQ_def QQ_def
by (rule strict_sorted_acc_lengths) (use RF_non_Nil AF_non_Nil kka in ‹auto simp: in_lists_conv_set›)
have last_AF_DF: "last (list_of (AF k p)) < ⨅ (DF k q)"
using AF_DF [OF ‹p < q›, of k] AF_non_Nil [of k p] DF_ne [of k q]
by (metis Inf_nat_def1 finite_AF last_in_set less_sets_def set_sorted_list_of_set)
then show "list_of (AF k p) < LENS_QQ @ list_of (AF k q) @ ?INT"
by (simp add: less_list_def card_AF LENS_QQ_def)
show "LENS_QQ < list_of (AF k q) @ ?INT"
using AF_non_Nil [of k q] ‹q < m› card_AF_sum enum_DF_AF card_AF_sum_QQ
by (auto simp: less_list_def AF_ne hd_append card_AF_sum LENS_QQ_def)
show "list_of (AF k q) < ?INT"
proof -
have "AF k q ≪ RF 1 p"
using ‹0 < k› ‹p < m› ‹q < m› by (simp add: RF_def less_QF flip: QF_0)
then have "last (list_of (AF k q)) < hd (list_of (RF 1 p))"
proof (rule less_setsD)
show "last (list_of (AF k q)) ∈ AF k q"
using AF_non_Nil finite_AF last_in_set set_sorted_list_of_set by blast
show "hd (list_of (RF 1 p)) ∈ RF 1 p"
by (metis One_nat_def RF_non_Nil ‹0 < k› finite_RF hd_in_set not_less_eq set_sorted_list_of_set)
qed
with ‹k > 0› ‹ka ≥ 2› RF_non_Nil show ?thesis
by (simp add: One_nat_def hd_interact less_list_def sorted_list_of_set_greaterThanLessThan PP_def QQ_def)
qed
qed auto
qed (auto simp: LENS_QQ_def)
show ?thesis
proof (cases "ka = k")
case True
then have "l = 2*k-1"
by (simp add: kka(3) mult_2)
then show ?thesis
by (metis One_nat_def Form.intros(2) Form_Body_imp_inter_scheme True ‹0 < k› ‹U = {x, y}› kka zs zs_N)
next
case False
then have "l = 2*k"
using kka by linarith
then show ?thesis
by (metis One_nat_def False Form.intros(3) Form_Body_imp_inter_scheme ‹0 < k› ‹U = {x, y}› antisym kka le_SucE zs zs_N)
qed
qed
qed
qed
qed
subsection ‹Larson's Lemma 3.8›
subsubsection ‹Primitives needed for the inductive construction of @{term b}›
definition IJ where "IJ ≡ λk. Sigma {..k} (λj::nat. {..<j})"
lemma IJ_iff: "u ∈ IJ k ⟷ (∃j i. u = (j,i) ∧ i<j ∧ j≤k)"
by (auto simp: IJ_def)
lemma finite_IJ: "finite (IJ k)"
by (auto simp: IJ_def)
fun prev where
"prev 0 0 = None"
| "prev (Suc 0) 0 = None"
| "prev (Suc j) 0 = Some (j, j - Suc 0)"
| "prev j (Suc i) = Some (j,i)"
lemma prev_eq_None_iff: "prev j i = None ⟷ j ≤ Suc 0 ∧ i = 0"
by (auto simp: le_Suc_eq elim: prev.elims)
lemma prev_pair_less:
"prev j i = Some ji' ⟹ (ji', (j,i)) ∈ pair_less"
by (auto simp: pair_lessI1 elim: prev.elims)
lemma prev_Some_less: "⟦prev j i = Some (j',i'); i ≤ j⟧ ⟹ i' < j'"
by (auto elim: prev.elims)
lemma prev_maximal:
"⟦prev j i = Some (j',i'); (ji'', (j,i)) ∈ pair_less; ji'' ∈ IJ k⟧
⟹ (ji'', (j',i')) ∈ pair_less ∨ ji'' = (j',i')"
by (force simp: IJ_def pair_less_def elim: prev.elims)
lemma pair_less_prev:
assumes "(u, (j,i)) ∈ pair_less" "u ∈ IJ k"
shows "prev j i = Some u ∨ (∃x. (u, x) ∈ pair_less ∧ prev j i = Some x)"
using assms
proof (cases "prev j i")
case None
then show ?thesis
using assms by (force simp: prev_eq_None_iff pair_less_def IJ_def split: prod.split)
next
case (Some a)
then show ?thesis
by (metis assms prev_maximal prod.exhaust_sel)
qed
subsubsection ‹Special primitives for the ordertype proof›
definition USigma :: "'a set set ⇒ ('a set ⇒ 'a set) ⇒ 'a set set"
where "USigma 𝒜 B ≡ ⋃X∈𝒜. ⋃y ∈ B X. {insert y X}"
definition usplit
where "usplit f A ≡ f (A - {Max A}) (Max A)"
lemma USigma_empty [simp]: "USigma {} B = {}"
by (auto simp: USigma_def)
lemma USigma_iff:
assumes "⋀I j. I ∈ ℐ ⟹ I ≪ J I ∧ finite I"
shows "x ∈ USigma ℐ J ⟷ usplit (λI j. I ∈ ℐ ∧ j ∈ J I ∧ x = insert j I) x"
proof -
have [simp]: "⋀I j. ⟦I ∈ ℐ; j ∈ J I⟧ ⟹ Max (insert j I) = j"
by (meson Max_insert2 assms less_imp_le less_sets_def)
show ?thesis
proof -
have §: "j ∉ I" if "I ∈ ℐ" "j ∈ J I" for I j
using that by (metis assms less_irrefl less_sets_def)
have "∃I∈ℐ. ∃j∈J I. x = insert j I"
if "x - {Max x} ∈ ℐ" and "Max x ∈ J (x - {Max x})" "x ≠ {}"
using that by (metis Max_in assms infinite_remove insert_Diff)
then show ?thesis
by (auto simp: USigma_def usplit_def §)
qed
qed
proposition ordertype_append_image_IJ:
assumes lenB [simp]: "⋀i j. i ∈ ℐ ⟹ j ∈ J i ⟹ length (B j) = c"
and AB: "⋀i j. i ∈ ℐ ⟹ j ∈ J i ⟹ A i < B j"
and IJ: "⋀i. i ∈ ℐ ⟹ i ≪ J i ∧ finite i"
and β: "⋀i. i ∈ ℐ ⟹ ordertype (B ` J i) (lenlex less_than) = β"
and A: "inj_on A ℐ"
shows "ordertype (usplit (λi j. A i @ B j) ` USigma ℐ J) (lenlex less_than)
= β * ordertype (A ` ℐ) (lenlex less_than)"
(is "ordertype ?AB ?R = _ * ?α")
proof (cases "ℐ = {}")
case False
have "Ord β"
using β False wf_Ord_ordertype by fastforce
show ?thesis
proof (subst ordertype_eq_iff)
define split where "split ≡ λl::nat list. (take (length l - c) l, (drop (length l - c) l))"
have oB: "ordermap (B ` J i) ?R (B j) ⊏ β" if ‹i ∈ ℐ› ‹j ∈ J i› for i j
using β less_TC_iff that by fastforce
then show "Ord (β * ?α)"
by (intro ‹Ord β› wf_Ord_ordertype Ord_mult; simp)
define f where "f ≡ λu. let (x,y) = split u in let i = inv_into ℐ A x in
β * ordermap (A`ℐ) ?R x + ordermap (B`J i) ?R y"
have inv_into_IA [simp]: "inv_into ℐ A (A i) = i" if "i ∈ ℐ" for i
by (simp add: A that)
show "∃f. bij_betw f ?AB (elts (β * ?α)) ∧ (∀x∈?AB. ∀y∈?AB. (f x < f y) = ((x, y) ∈ ?R))"
unfolding bij_betw_def
proof (intro exI conjI strip)
show "inj_on f ?AB"
proof (clarsimp simp: f_def inj_on_def split_def USigma_iff IJ usplit_def)
fix x y
assume §: "β * ordermap (A ` ℐ) ?R (A (x - {Max x})) + ordermap (B ` J (x - {Max x})) ?R (B (Max x))
= β * ordermap (A ` ℐ) ?R (A (y - {Max y})) + ordermap (B ` J (y - {Max y})) ?R (B (Max y))"
and x: "x - {Max x} ∈ ℐ"
and y: "y - {Max y} ∈ ℐ"
and mx: "Max x ∈ J (x - {Max x})"
and "x = insert (Max x) x"
and my: "Max y ∈ J (y - {Max y})"
have "ordermap (A`ℐ) ?R (A (x - {Max x})) = ordermap (A`ℐ) ?R (A (y - {Max y}))"
and B_eq: "ordermap (B ` J (x - {Max x})) ?R (B (Max x)) = ordermap (B ` J (y - {Max y})) ?R (B (Max y))"
using mult_cancellation_lemma [OF §] oB mx my x y by blast+
then have "A (x - {Max x}) = A (y - {Max y})"
using x y by auto
then have "x - {Max x} = y - {Max y}"
by (metis x y inv_into_IA)
then show "A (x - {Max x}) = A (y - {Max y}) ∧ B (Max x) = B (Max y)"
using B_eq mx my by auto
qed
show "f ` ?AB = elts (β * ?α)"
proof
show "f ` ?AB ⊆ elts (β * ?α)"
using ‹Ord β›
apply (clarsimp simp add: f_def split_def USigma_iff IJ usplit_def)
by (metis TC_small β add_mult_less image_eqI ordermap_in_ordertype trans_llt wf_Ord_ordertype wf_llt)
show "elts (β * ?α) ⊆ f ` ?AB"
proof (clarsimp simp: f_def split_def image_iff USigma_iff IJ usplit_def Bex_def elim!: elts_multE split: prod.split)
fix γ δ
assume δ: "δ ∈ elts β" and γ: "γ ∈ elts ?α"
have "γ ∈ ordermap (A ` ℐ) (lenlex less_than) ` A ` ℐ"
by (meson γ ordermap_surj subset_iff)
then obtain i where "i ∈ ℐ" and yv: "γ = ordermap (A`ℐ) ?R (A i)"
by blast
have "δ ∈ ordermap (B ` J i) (lenlex less_than) ` B ` J i"
by (metis (no_types) β δ ‹i ∈ ℐ› in_mono ordermap_surj)
then obtain j where "j ∈ J i" and xu: "δ = ordermap (B`J i) ?R (B j)"
by blast
then have mji: "Max (insert j i) = j"
by (meson IJ Max_insert2 ‹i ∈ ℐ› less_imp_le less_sets_def)
have [simp]: "i - {j} = i"
using IJ ‹i ∈ ℐ› ‹j ∈ J i› less_setsD by fastforce
show "∃l. (∃K. K - {Max K} ∈ ℐ ∧ Max K ∈ J (K - {Max K}) ∧ K = insert (Max K) K ∧
l = A (K - {Max K}) @ B (Max K)) ∧ β * γ + δ =
β *
ordermap (A ` ℐ) ?R (take (length l - c) l) +
ordermap (B ` J (inv_into ℐ A (take (length l - c) l)))
?R (drop (length l - c) l)"
proof (intro conjI exI)
let ?ji = "insert j i"
show "A i @ B j = A (?ji - {Max ?ji}) @ B (Max ?ji)"
by (auto simp: mji)
qed (use ‹i ∈ ℐ› ‹j ∈ J i› mji xu yv in auto)
qed
qed
next
fix p q
assume "p ∈ ?AB" and "q ∈ ?AB"
then obtain x y where peq: "p = A (x - {Max x}) @ B (Max x)"
and qeq: "q = A (y - {Max y}) @ B (Max y)"
and x: "x - {Max x} ∈ ℐ"
and y: "y - {Max y} ∈ ℐ"
and mx: "Max x ∈ J (x - {Max x})"
and my: "Max y ∈ J (y - {Max y})"
by (auto simp: USigma_iff IJ usplit_def)
let ?mx = "x - {Max x}"
let ?my = "y - {Max y}"
show "(f p < f q) ⟷ ((p, q) ∈ ?R)"
proof
assume "f p < f q"
then
consider "ordermap (A`ℐ) ?R (A (x - {Max x})) < ordermap (A`ℐ) ?R (A (y - {Max y}))"
| "ordermap (A`ℐ) ?R (A (x - {Max x})) = ordermap (A`ℐ) ?R (A (y - {Max y}))"
"ordermap (B`J (x - {Max x})) ?R (B (Max x)) < ordermap (B`J (y - {Max y})) ?R (B (Max y))"
using x y mx my
by (auto dest: mult_cancellation_less simp: f_def split_def peq qeq oB)
then have "(A ?mx @ B (Max x), A ?my @ B (Max y)) ∈ ?R"
proof cases
case 1
then have "(A ?mx, A ?my) ∈ ?R"
using x y by (force simp: Ord_mem_iff_lt intro: converse_ordermap_mono)
then show ?thesis
using x y mx my lenB lenlex_append1 by blast
next
case 2
then have "A ?mx = A ?my"
using ‹?my ∈ ℐ› ‹?mx ∈ ℐ› by auto
then have eq: "?mx = ?my"
by (metis ‹?my ∈ ℐ› ‹?mx ∈ ℐ› inv_into_IA)
then have "(B (Max x), B (Max y)) ∈ ?R"
using mx my 2 by (force simp: Ord_mem_iff_lt intro: converse_ordermap_mono)
with 2 show ?thesis
by (simp add: eq irrefl_less_than)
qed
then show "(p,q) ∈ ?R"
by (simp add: peq qeq f_def split_def sorted_list_of_set_Un AB)
next
assume pqR: "(p,q) ∈ ?R"
then have §: "(A ?mx @ B (Max x), A ?my @ B (Max y)) ∈ ?R"
using peq qeq by blast
then consider "(A ?mx, A ?my) ∈ ?R" | "A ?mx = A ?my ∧ (B (Max x), B (Max y)) ∈ ?R"
proof (cases "(A ?mx, A ?my) ∈ ?R")
case False
have False if "(A ?my, A ?mx) ∈ ?R"
by (metis ‹?my ∈ ℐ› ‹?mx ∈ ℐ› "§" ‹(Max y) ∈ J ?my› ‹(Max x) ∈ J ?mx› lenB lenlex_append1 omega_sum_1_less order.asym that)
then have "A ?mx = A ?my"
by (meson False UNIV_I total_llt total_on_def)
then show ?thesis
using "§" irrefl_less_than that by auto
qed (use that in blast)
then have "β * ordermap (A`ℐ) ?R (A ?mx) + ordermap (B`J ?mx) ?R (B (Max x))
< β * ordermap (A`ℐ) ?R (A ?my) + ordermap (B`J ?my) ?R (B (Max y))"
proof cases
case 1
show ?thesis
proof (rule add_mult_less_add_mult)
show "ordermap (A`ℐ) (lenlex less_than) (A ?mx) < ordermap (A`ℐ) (lenlex less_than) (A ?my)"
by (simp add: "1" ‹?my ∈ ℐ› ‹?mx ∈ ℐ› ordermap_mono_less)
show "Ord (ordertype (A`ℐ) ?R)"
using wf_Ord_ordertype by blast
show "ordermap (B ` J ?mx) ?R (B (Max x)) ∈ elts β"
using Ord_less_TC_mem ‹Ord β› ‹?mx ∈ ℐ› ‹(Max x) ∈ J ?mx› oB by blast
show "ordermap (B ` J ?my) ?R (B (Max y)) ∈ elts β"
using Ord_less_TC_mem ‹Ord β› ‹?my ∈ ℐ› ‹(Max y) ∈ J ?my› oB by blast
qed (use ‹?my ∈ ℐ› ‹?mx ∈ ℐ› ‹Ord β› in auto)
next
case 2
with ‹?mx ∈ ℐ› show ?thesis
using ‹(Max y) ∈ J ?my› ‹(Max x) ∈ J ?mx› ordermap_mono_less
by (metis (no_types, opaque_lifting) Kirby.add_less_cancel_left TC_small image_iff inv_into_IA trans_llt wf_llt y)
qed
then show "f p < f q"
using ‹?my ∈ ℐ› ‹?mx ∈ ℐ› ‹(Max y) ∈ J ?my› ‹(Max x) ∈ J ?mx›
by (auto simp: peq qeq f_def split_def AB)
qed
qed
qed auto
qed auto
subsubsection ‹The final part of 3.8, where two sequences are merged›
inductive merge :: "[nat list list,nat list list,nat list list,nat list list] ⇒ bool"
where NullNull: "merge [] [] [] []"
| Null: "as ≠ [] ⟹ merge as [] [concat as] []"
| App: "⟦as1 ≠ []; bs1 ≠ [];
concat as1 < concat bs1; concat bs1 < concat as2; merge as2 bs2 as bs⟧
⟹ merge (as1@as2) (bs1@bs2) (concat as1 # as) (concat bs1 # bs)"
inductive_simps Null1 [simp]: "merge [] bs us vs"
inductive_simps Null2 [simp]: "merge as [] us vs"
lemma merge_single:
"⟦concat as < concat bs; concat as ≠ []; concat bs ≠ []⟧ ⟹ merge as bs [concat as] [concat bs]"
using merge.App [of as bs "[]" "[]"]
by (fastforce simp: less_list_def)
lemma merge_length1_nonempty:
assumes "merge as bs us vs" "as ∈ lists (- {[]})"
shows "us ∈ lists (- {[]})"
using assms by induction (auto simp: mem_lists_non_Nil)
lemma merge_length2_nonempty:
assumes "merge as bs us vs" "bs ∈ lists (- {[]})"
shows "vs ∈ lists (- {[]})"
using assms by induction (auto simp: mem_lists_non_Nil)
lemma merge_length1_gt_0:
assumes "merge as bs us vs" "as ≠ []"
shows "length us > 0"
using assms by induction auto
lemma merge_length_le:
assumes "merge as bs us vs"
shows "length vs ≤ length us"
using assms by induction auto
lemma merge_length_le_Suc:
assumes "merge as bs us vs"
shows "length us ≤ Suc (length vs)"
using assms by induction auto
lemma merge_length_less2:
assumes "merge as bs us vs"
shows "length vs ≤ length as"
using assms
proof induction
case (App as1 bs1 as2 bs2 as bs)
then show ?case
using length_greater_0_conv [of as1] by (simp, presburger)
qed auto
lemma merge_preserves:
assumes "merge as bs us vs"
shows "concat as = concat us ∧ concat bs = concat vs"
using assms by induction auto
lemma merge_interact:
assumes "merge as bs us vs" "strict_sorted (concat as)" "strict_sorted (concat bs)"
"bs ∈ lists (- {[]})"
shows "strict_sorted (interact us vs)"
using assms
proof induction
case (App as1 bs1 as2 bs2 as bs)
then have bs: "concat bs1 < concat bs" "concat bs1 < concat as"
and nonmt: "concat bs1 ≠ []"
using merge_preserves strict_sorted_append_iff by fastforce+
then have "concat bs1 < interact as bs"
unfolding less_list_def using App bs
by (metis (no_types, lifting) Un_iff concat_append hd_in_set last_in_set merge_preserves set_interact sorted_wrt_append strict_sorted_append_iff)
with App show ?case
by (metis append_in_lists_conv concat_append hd_append2 interact.simps(3) less_list_def strict_sorted_append_iff nonmt)
qed auto
lemma acc_lengths_merge1:
assumes "merge as bs us vs"
shows "list.set (acc_lengths k us) ⊆ list.set (acc_lengths k as)"
using assms
proof (induction arbitrary: k)
case (App as1 bs1 as2 bs2 as bs)
then show ?case
apply (simp add: acc_lengths_append strict_sorted_append_iff length_concat_acc_lengths)
by (simp add: le_supI2 length_concat)
qed (auto simp: length_concat_acc_lengths)
lemma acc_lengths_merge2:
assumes "merge as bs us vs"
shows "list.set (acc_lengths k vs) ⊆ list.set (acc_lengths k bs)"
using assms
proof (induction arbitrary: k)
case (App as1 bs1 as2 bs2 as bs)
then show ?case
apply (simp add: acc_lengths_append strict_sorted_append_iff length_concat_acc_lengths)
by (simp add: le_supI2 length_concat)
qed (auto simp: length_concat_acc_lengths)
lemma length_hd_le_concat:
assumes "as ≠ []" shows "length (hd as) ≤ length (concat as)"
by (metis (no_types) add.commute assms concat.simps(2) le_add2 length_append list.exhaust_sel)
lemma length_hd_merge2:
assumes "merge as bs us vs"
shows "length (hd bs) ≤ length (hd vs)"
using assms by induction (auto simp: length_hd_le_concat)
lemma merge_less_sets_hd:
assumes "merge as bs us vs" "strict_sorted (concat as)" "strict_sorted (concat bs)" "bs ∈ lists (- {[]})"
shows "list.set (hd us) ≪ list.set (concat vs)"
using assms
proof induction
case (App as1 bs1 as2 bs2 as bs)
then have §: "list.set (concat bs1) ≪ list.set (concat bs2)"
by (force simp: dest: strict_sorted_imp_less_sets)
have *: "list.set (concat as1) ≪ list.set (concat bs1)"
using App by (metis concat_append strict_sorted_append_iff strict_sorted_imp_less_sets)
then have "list.set (concat as1) ≪ list.set (concat bs)"
using App § less_sets_trans merge_preserves
by (metis List.set_empty append_in_lists_conv le_zero_eq length_0_conv length_concat_ge)
with * App.hyps show ?case
by (fastforce simp: less_sets_UN1 less_sets_UN2 less_sets_Un2)
qed auto
lemma set_takeWhile:
assumes "strict_sorted (concat as)" "as ∈ lists (- {[]})"
shows "list.set (takeWhile (λx. x < y) as) = {x ∈ list.set as. x < y}"
using assms
proof (induction as)
case (Cons a as)
have "a < y"
if a: "a < concat as" "strict_sorted a" "strict_sorted (concat as)" "x < y" "x ≠ []" "x ∈ list.set as"
for x
proof -
have §: "last x ∈ list.set (concat as)"
using set_concat that by fastforce
have "last a < hd (concat as)"
using Cons.prems that by (auto simp: less_list_def)
also have "… ≤ hd y" if "y ≠ []"
using that a
by (meson § order.strict_trans less_list_def not_le sorted_hd_le strict_sorted_imp_sorted)
finally show ?thesis
by (simp add: less_list_def)
qed
then show ?case
using Cons by (auto simp: strict_sorted_append_iff)
qed auto
proposition merge_exists:
assumes "strict_sorted (concat as)" "strict_sorted (concat bs)"
"as ∈ lists (- {[]})" "bs ∈ lists (- {[]})"
"hd as < hd bs" "as ≠ []" "bs ≠ []"
and disj: "⋀a b. ⟦a ∈ list.set as; b ∈ list.set bs⟧ ⟹ a<b ∨ b<a"
shows "∃us vs. merge as bs us vs"
using assms
proof (induction "length as + length bs" arbitrary: as bs rule: less_induct)
case (less as bs)
obtain as1 as2 bs1 bs2
where A: "as1 ≠ []" "bs1 ≠ []" "concat as1 < concat bs1" "concat bs1 < concat as2"
and B: "as = as1@as2" "bs = bs1@bs2" and C: "bs2 = [] ∨ (as2 ≠ [] ∧ hd as2 < hd bs2)"
proof
define as1 where "as1 ≡ takeWhile (λx. x < hd bs) as"
define as2 where "as2 ≡ dropWhile (λx. x < hd bs) as"
define bs1 where "bs1 ≡ if as2=[] then bs else takeWhile (λx. x < hd as2) bs"
define bs2 where "bs2 ≡ if as2=[] then [] else dropWhile (λx. x < hd as2) bs"
have as1: "as1 = takeWhile (λx. last x < hd (hd bs)) as"
using less.prems by (auto simp: as1_def less_list_def cong: takeWhile_cong)
have as2: "as2 = dropWhile (λx. last x < hd (hd bs)) as"
using less.prems by (auto simp: as2_def less_list_def cong: dropWhile_cong)
have hd_as2: "as2 ≠ [] ⟹ ¬ hd as2 < hd bs"
using as2_def hd_dropWhile by metis
have hd_bs2: "bs2 ≠ [] ⟹ ¬ hd bs2 < hd as2"
using bs2_def hd_dropWhile by metis
show "as1 ≠ []"
by (simp add: as1_def less.prems takeWhile_eq_Nil_iff)
show "bs1 ≠ []"
by (metis as2 bs1_def hd_as2 hd_in_set less.prems(7) less.prems(8) set_dropWhileD takeWhile_eq_Nil_iff)
show "bs2 = [] ∨ (as2 ≠ [] ∧ hd as2 < hd bs2)"
by (metis as2_def bs2_def hd_bs2 less.prems(8) list.set_sel(1) set_dropWhileD)
have AB: "list.set A ≪ list.set B"
if "A ∈ list.set as1" "B ∈ list.set bs" for A B
proof -
have "A ∈ list.set as"
using that by (metis as1 set_takeWhileD)
then have "sorted A"
by (metis concat.simps(2) concat_append less.prems(1) sorted_append split_list_last strict_sorted_imp_sorted)
moreover have "sorted (hd bs)"
by (metis concat.simps(2) hd_Cons_tl less.prems(2) less.prems(7) strict_sorted_append_iff strict_sorted_imp_sorted)
ultimately show ?thesis
using that less.prems
apply (clarsimp simp add: as1_def set_takeWhile less_list_iff_less_sets less_sets_def)
by (metis (full_types) UN_I hd_concat less_le_trans list.set_sel(1) set_concat sorted_hd_le strict_sorted_imp_sorted)
qed
show "as = as1@as2"
by (simp add: as1_def as2_def)
show "bs = bs1@bs2"
by (simp add: bs1_def bs2_def)
have "list.set (concat as1) ≪ list.set (concat bs1)"
using AB set_takeWhileD by (fastforce simp: as1_def bs1_def less_sets_UN1 less_sets_UN2)
then show "concat as1 < concat bs1"
by (rule less_sets_imp_list_less)
have "list.set (concat bs1) ≪ list.set (concat as2)" if "as2 ≠ []"
proof (clarsimp simp add: bs1_def less_sets_UN1 less_sets_UN2 set_takeWhile less.prems)
fix A B
assume "A ∈ list.set as2" "B ∈ list.set bs" "B < hd as2"
with that show "list.set B ≪ list.set A"
using hd_as2 less.prems(1,2)
apply (clarsimp simp add: less_sets_def less_list_def)
apply (auto simp: as2_def)
apply (simp flip: as2_def)
by (smt (verit, ccfv_SIG) UN_I ‹as = as1 @ as2› concat.simps(2) concat_append hd_concat in_set_conv_decomp_first le_less_trans less_le_trans set_concat sorted_append sorted_hd_le sorted_le_last strict_sorted_imp_sorted that)
qed
then show "concat bs1 < concat as2"
by (simp add: bs1_def less_sets_imp_list_less)
qed
obtain cs ds where "merge as2 bs2 cs ds"
proof (cases "as2 = [] ∨ bs2 = []")
case True
then show thesis
using that C NullNull Null by metis
next
have †: "length as2 + length bs2 < length as + length bs"
by (simp add: A B)
case False
moreover have "strict_sorted (concat as2)" "strict_sorted (concat bs2)"
"as2 ∈ lists (- {[]})" "bs2 ∈ lists (- {[]})"
"⋀a b. ⟦a ∈ list.set as2; b ∈ list.set bs2⟧ ⟹ a < b ∨ b < a"
using B less.prems strict_sorted_append_iff by auto
ultimately show ?thesis
using C less.hyps [OF †] False that by force
qed
then obtain cs where "merge (as1 @ as2) (bs1 @ bs2) (concat as1 # cs) (concat bs1 # ds)"
using A merge.App by blast
then show ?case
using B by blast
qed
subsubsection ‹Actual proof of Larson's Lemma 3.8›
proposition lemma_3_8:
assumes "infinite N"
obtains X where "X ⊆ WW" "ordertype X (lenlex less_than) = ω↑ω"
"⋀u. u ∈ [X]⇗2⇖ ⟹
∃l. Form l u ∧ (l > 0 ⟶ [enum N l] < inter_scheme l u ∧ List.set (inter_scheme l u) ⊆ N)"
proof -
let ?LL = "lenlex less_than"
define bf where "bf ≡ λM q. wfrec pair_less (λf (j,i).
let R = (case prev j i of None ⇒ M | Some u ⇒ snd (f u))
in grab R (q j i))"
have bf_rec: "bf M q (j,i) =
(let R = (case prev j i of None ⇒ M | Some u ⇒ snd (bf M q u))
in grab R (q j i))" for M q j i
by (subst (1) bf_def) (simp add: Let_def wfrec bf_def cut_apply prev_pair_less cong: conj_cong split: option.split)
have "infinite (snd (bf M q u)) = infinite M ∧ fst (bf M q u) ⊆ M ∧ snd (bf M q u) ⊆ M" for M q u
using wf_pair_less
proof (induction u rule: wf_induct_rule)
case (less u)
then show ?case
proof (cases u)
case (Pair j i)
with less.IH prev_pair_less show ?thesis
apply (simp add: bf_rec [of M q j i] split: option.split)
using fst_grab_subset snd_grab_subset by blast
qed
qed
then have infinite_bf [simp]: "infinite (snd (bf M q u)) = infinite M"
and bf_subset: "fst (bf M q u) ⊆ M ∧ snd (bf M q u) ⊆ M" for M q u
by auto
have bf_less_sets: "fst (bf M q ij) ≪ snd (bf M q ij)" if "infinite M" for M q ij
using wf_pair_less
proof (induction ij rule: wf_induct_rule)
case (less u)
then show ?case
by (metis bf_rec finite_grab_iff infinite_bf less_sets_grab prod.exhaust_sel that)
qed
have card_fst_bf: "finite (fst (bf M q (j,i))) ∧ card (fst (bf M q (j,i))) = q j i" if "infinite M" for M q j i
by (simp add: that bf_rec [of M q j i] split: option.split)
have bf_cong: "bf M q u = bf M q' u"
if "snd u ≤ fst u" and eq: "⋀y x. ⟦x≤y; y≤fst u⟧ ⟹ q' y x = q y x" for M q q' u
using wf_pair_less that
proof (induction u rule: wf_induct_rule)
case (less u)
show ?case
proof (cases u)
case (Pair j i)
with less.prems show ?thesis
proof (clarsimp simp add: bf_rec [of M _ j i] split: option.split)
fix j' i'
assume *: "prev j i = Some (j',i')"
then have **: "((j', i'), u) ∈ pair_less"
by (simp add: Pair prev_pair_less)
moreover have "i' < j'"
using Pair less.prems by (simp add: prev_Some_less [OF *])
moreover have "⋀x y. ⟦x ≤ y; y ≤ j'⟧ ⟹ q' y x = q y x"
using ** less.prems by (auto simp: pair_less_def Pair)
ultimately show "grab (snd (bf M q (j',i'))) (q j i) = grab (snd (bf M q' (j',i'))) (q j i)"
using less.IH by auto
qed
qed
qed
define ediff where "ediff ≡ λD:: nat ⇒ nat set. λj i. enum (D j) (Suc i) - enum (D j) i"
define F where "F ≡ λl (dl,a0::nat set,b0::nat × nat ⇒ nat set,M).
let (d,Md) = grab (nxt M (enum N (Suc (2 * Suc l)))) (Suc l) in
let (a,Ma) = grab Md (Min d) in
let Gb = bf Ma (ediff (dl(l := d))) in
let dl' = dl(l := d) in
(dl', a, fst ∘ Gb, snd (Gb(l, l-1)))"
define DF where "DF ≡ rec_nat (λi∈{..<0}. {}, {}, λp. {}, N) F"
have DF_simps: "DF 0 = (λi∈{..<0}. {}, {}, λp. {}, N)"
"DF (Suc l) = F l (DF l)" for l
by (auto simp: DF_def)
note cut_apply [simp]
have inf [rule_format]: "∀dl al bl L. DF l = (dl,al,bl,L) ⟶ infinite L" for l
by (induction l) (auto simp: DF_simps F_def Let_def grab_eqD infinite_nxtN assms split: prod.split)
define Ψ where
"Ψ ≡ λ(dl, a, b, M). λl::nat.
dl l ≪ a ∧ card a > 0 ∧
(∀j≤l. card (dl j) = Suc j) ∧ a ≪ ⋃(range b) ∧ range b ⊆ Collect finite ∧
a ⊆ N ∧ ⋃(range b) ⊆ N ∧ infinite M ∧ b(l,l-1) ≪ M ∧ M ⊆ N"
have Ψ_DF: "Ψ (DF (Suc l)) l" for l
proof (induction l)
case 0
show ?case
using assms
apply (clarsimp simp add: bf_rec F_def DF_simps Ψ_def split: prod.split)
apply (drule grab_eqD, blast dest: grab_eqD infinite_nxtN)+
apply (auto simp: less_sets_UN2 less_sets_grab card_fst_bf elim!: less_sets_weaken2)
apply (metis card_1_singleton_iff Min_singleton greaterThan_iff insertI1 le0 nxt_subset_greaterThan subsetD)
using nxt_subset snd_grab_subset bf_subset by blast+
next
case (Suc l)
then show ?case
using assms
unfolding Let_def DF_simps(2)[of "Suc l"] F_def Ψ_def
apply (clarsimp simp add: bf_rec DF_simps split: prod.split)
apply (drule grab_eqD, metis grab_eqD infinite_nxtN)+
apply (safe, simp_all add: less_sets_UN2 less_sets_grab card_fst_bf card_Suc_eq_finite)
apply (meson less_sets_weaken2)
apply (metis Min_in gr0I greaterThan_iff insert_not_empty le_inf_iff less_asym nxt_def subsetD)
apply (meson bf_subset less_sets_weaken2)
apply (meson nxt_subset subset_eq)
apply (meson bf_subset nxt_subset subset_eq)
using bf_rec infinite_bf apply force
using bf_less_sets bf_rec apply force
by (metis bf_rec bf_subset nxt_subset subsetD)
qed
define d where "d ≡ λk. let (dk,ak,bk,M) = DF(Suc k) in dk k"
define a where "a ≡ λk. let (dk,ak,bk,M) = DF(Suc k) in ak"
define b where "b ≡ λk. let (dk,ak,bk,M) = DF(Suc k) in bk"
define M where "M ≡ λk. let (dk,ak,bk,M) = DF k in M"
have infinite_M [simp]: "infinite (M k)" for k
by (auto simp: M_def inf split: prod.split)
have M_Suc_subset: "M (Suc k) ⊆ M k" for k
apply (clarsimp simp add: Let_def M_def F_def DF_simps split: prod.split)
by (metis bf_subset in_mono nxt_subset snd_conv snd_grab_subset)
have Inf_M_Suc_ge: "Inf (M k) ≤ Inf (M (Suc k))" for k
by (simp add: M_Suc_subset cInf_superset_mono infinite_imp_nonempty)
have Inf_M_telescoping: "{Inf (M k)..} ⊆ {Inf (M k')..}" if k': "k'≤k" for k k'
using that Inf_nat_def1 infinite_M unfolding Inf_nat_def atLeast_subset_iff
by (metis M_Suc_subset finite.emptyI le_less_linear lift_Suc_antimono_le not_less_Least subsetD)
have d_eq: "d k = fst (grab (nxt (M k) (enum N (Suc (2 * Suc k)))) (Suc k))" for k
by (simp add: d_def M_def Let_def DF_simps F_def split: prod.split)
then have finite_d [simp]: "finite (d k)" for k
by simp
then have d_ne [simp]: "d k ≠ {}" for k
by (metis card.empty card_grab d_eq infinite_M infinite_nxtN nat.distinct(1))
have a_eq: "∃M. a k = fst (grab M (Min (d k))) ∧ infinite M" for k
apply (simp add: a_def d_def M_def Let_def DF_simps F_def split: prod.split)
by (metis fst_conv grab_eqD infinite_nxtN local.inf)
then have card_a: "card (a k) = Inf (d k)" for k
by (metis cInf_eq_Min card_grab d_ne finite_d)
have d_eq_dl: "d k = dl k" if "(dl,a,b,P) = DF l" "k < l" for k l dl a b P
using that
by (induction l arbitrary: dl a b P) (simp_all add: d_def DF_simps F_def Let_def split: prod.split_asm prod.split)
have card_d [simp]: "card (d k) = Suc k" for k
by (auto simp: d_eq infinite_nxtN)
have d_ne [simp]: "d j ≠ {}" and a_ne [simp]: "a j ≠ {}"
and finite_d [simp]: "finite (d j)" and finite_a [simp]: "finite (a j)" for j
using Ψ_DF [of "j"] by (auto simp: Ψ_def a_def d_def card_gt_0_iff split: prod.split_asm)
have da: "d k ≪ a k" for k
using Ψ_DF [of "k"] by (simp add: Ψ_def a_def d_def split: prod.split_asm)
have ab_same: "a k ≪ ⋃(range(b k))" for k
using Ψ_DF [of "k"] by (simp add: Ψ_def a_def b_def M_def split: prod.split_asm)
have snd_bf_subset: "snd (bf M r (j,i)) ⊆ snd (bf M r (j',i'))"
if ji: "((j',i'), (j,i)) ∈ pair_less" "(j',i') ∈ IJ k"
for M r k j i j' i'
using wf_pair_less ji
proof (induction rule: wf_induct_rule [where a= "(j,i)"])
case (less u)
show ?case
proof (cases u)
case (Pair j i)
then consider "prev j i = Some (j', i')" | x where "((j', i'), x) ∈ pair_less" "prev j i = Some x"
using less.prems pair_less_prev by blast
then show ?thesis
proof cases
case 2 with less.IH show ?thesis
unfolding bf_rec Pair
by (metis in_mono option.simps(5) prev_pair_less snd_grab_subset subsetI that(2))
qed (simp add: Pair bf_rec snd_grab_subset)
qed
qed
have less_bf: "fst (bf M r (j',i')) ≪ fst (bf M r (j,i))"
if ji: "((j',i'), (j,i)) ∈ pair_less" "(j',i') ∈ IJ k" and "infinite M"
for M r k j i j' i'
proof -
consider "prev j i = Some (j', i')" | j'' i'' where "((j', i'), (j'',i'')) ∈ pair_less" "prev j i = Some (j'',i'')"
by (metis pair_less_prev ji prod.exhaust_sel)
then show ?thesis
proof cases
case 1
then show ?thesis
using bf_less_sets bf_rec less_sets_fst_grab ‹infinite M› by force
next
case 2
then have "fst (bf M r (j',i')) ≪ snd (bf M r (j'',i''))"
by (meson bf_less_sets snd_bf_subset less_sets_weaken2 that)
with 2 show ?thesis
using bf_rec bf_subset less_sets_fst_grab ‹infinite M› by auto
qed
qed
have aM: "a k ≪ M (Suc k)" for k
apply (clarsimp simp add: a_def M_def DF_simps F_def Let_def split: prod.split)
by (meson bf_subset grab_eqD infinite_nxtN less_sets_weaken2 local.inf)
then have "a k ≪ a (Suc k)" for k
by (metis IntE card_d card.empty d_eq da fst_grab_subset less_sets_trans less_sets_weaken2 nat.distinct(1) nxt_def subsetI)
then have aa: "a j ≪ a k" if "j<k" for k j
by (meson UNIV_I a_ne less_sets_imp_strict_mono_sets strict_mono_sets_def that)
then have ab: "a k' ≪ b k (j,i)" if "k'≤k" for k k' j i
by (metis a_ne ab_same le_less less_sets_UN2 less_sets_trans rangeI that)
have db: "d j ≪ b k (j,i)" if "j≤k" for k j i
by (meson a_ne ab da less_sets_trans that)
have bMkk: "b k (k,k-1) ≪ M (Suc k)" for k
using Ψ_DF [of k]
by (simp add: Ψ_def b_def d_def M_def split: prod.split_asm)
have b: "∃P ⊆ M k. infinite P ∧ (∀j i. i≤j ⟶ j≤k ⟶ b k (j,i) = fst (bf P (ediff d) (j,i)))" for k
proof (clarsimp simp: b_def DF_simps F_def Let_def split: prod.split)
fix a a' d' dl bb P M' M''
assume gr: "grab M'' (Min d') = (a', M')" "grab (nxt P (enum N (Suc (Suc (Suc (2 * k)))))) (Suc k) = (d', M'')"
and DF: "DF k = (dl, a, bb, P)"
have deq: "d j = (if j = k then d' else dl j)" if "j≤k" for j
proof (cases "j < k")
case True
then show ?thesis by (metis DF d_eq_dl less_not_refl)
next
case False
then show ?thesis
using that DF gr by (auto simp: d_def DF_simps F_def Let_def split: prod.split)
qed
have "M' ⊆ P"
by (metis gr in_mono nxt_subset snd_conv snd_grab_subset subsetI)
also have "P ⊆ M k"
using DF by (simp add: M_def)
finally have "M' ⊆ M k" .
moreover have "infinite M'"
using DF by (metis (mono_tags) finite_grab_iff gr infinite_nxtN local.inf snd_conv)
moreover
have "ediff (dl(k := d')) j i = ediff d j i" if "j≤k" for j i
by (simp add: deq that ediff_def)
then have "bf M' (ediff (dl(k := d'))) (j,i)
= bf M' (ediff d) (j,i)" if "i ≤ j" "j≤k" for j i
using bf_cong that by fastforce
ultimately show "∃P⊆M k. infinite P ∧
(∀j i. i ≤ j ⟶ j ≤ k
⟶ fst (bf M' (ediff (dl(k := d'))) (j,i))
= fst (bf P (ediff d) (j,i)))"
by auto
qed
have card_b: "card (b k (j,i)) = enum (d j) (Suc i) - enum (d j) i" if "j≤k" for k j i
proof (clarsimp simp: b_def DF_simps F_def Let_def split: prod.split)
fix dl
and a a' d':: "nat set"
and bb M M' M''
assume gr: "grab M'' (Min d') = (a', M')" "grab (nxt M (enum N (Suc (Suc (Suc (2 * k)))))) (Suc k) = (d',M'')"
and DF: "DF k = (dl, a, bb, M)"
have "d j = (if j = k then d' else dl j)"
proof (cases "j < k")
case True
then show ?thesis by (metis DF d_eq_dl less_not_refl)
next
case False
then show ?thesis
using that DF gr by (auto simp: d_def DF_simps F_def Let_def split: prod.split)
qed
then show "card (fst (bf M' (ediff (dl(k := d'))) (j,i)))
= enum (d j) (Suc i) - enum (d j) i"
using DF gr card_fst_bf grab_eqD infinite_nxtN local.inf ediff_def by auto
qed
have card_b_pos: "card (b k (j,i)) > 0" if "i < j" "j≤k" for k j i
by (simp add: card_b that finite_enumerate_step)
have b_ne [simp]: "b k (j,i) ≠ {}" if "i < j" "j≤k" for k j i
using card_b_pos [OF that] less_imp_neq by fastforce+
have card_b_finite [simp]: "finite (b k u)" for k u
using Ψ_DF [of k] by (fastforce simp: Ψ_def b_def)
have bM: "b k (j,i) ≪ M (Suc k)" if "i<j" "j≤k" for i j k
proof -
obtain M' where "M' ⊆ M k" "infinite M'"
and bk: "⋀j i. i≤j ⟹ j≤k ⟹ b k (j,i) = fst (bf M' (ediff d) (j,i))"
using b by (metis (no_types, lifting))
show ?thesis
proof (cases "j=k ∧ i = k-1")
case False
show ?thesis
proof (rule less_sets_trans [OF _ bMkk])
show "b k (j,i) ≪ b k (k, k-1)"
using that ‹infinite M'› False
by (force simp: bk pair_less_def IJ_def intro: less_bf)
show "b k (k, k-1) ≠ {}"
using b_ne that by auto
qed
qed (use bMkk in auto)
qed
have b_InfM: "⋃ (range (b k)) ⊆ {⨅(M k)..}" for k
proof (clarsimp simp add: Ψ_def b_def M_def DF_simps F_def Let_def split: prod.split)
fix r dl :: "nat ⇒ nat set"
and a b and d' a' M'' M' P and x j' i' :: nat
assume gr: "grab M'' (Min d') = (a', M')"
"grab (nxt P (enum N (Suc (Suc (Suc (2 * k)))))) (Suc k) = (d', M'')"
and DF: "DF k = (dl, a, b, P)"
and x: "x ∈ fst (bf M' (ediff (dl(k := d'))) (j', i'))"
have "infinite P"
using DF local.inf by blast
then have "M' ⊆ P"
by (meson gr grab_eqD infinite_nxtN nxt_subset order.trans)
with bf_subset show "⨅ P ≤ x"
using Inf_nat_def x le_less_linear not_less_Least by fastforce
qed
have b_Inf_M_Suc: "b k (j,i) ≪ {Inf(M (Suc k))}" if "i<j" "j≤k" for k j i
using bMkk [of k] that
by (metis Inf_nat_def1 bM finite.emptyI infinite_M less_setsD less_sets_singleton2)
have bb_same: "b k (j',i') ≪ b k (j,i)"
if "((j',i'), (j,i)) ∈ pair_less" "(j',i') ∈ IJ k" for k j i j' i'
using that
unfolding b_def DF_simps F_def Let_def
by (auto simp: less_bf grab_eqD infinite_nxtN local.inf split: prod.split)
have bb: "b k' (j',i') ≪ b k (j,i)"
if j: "i' < j'" "j'≤k'" and k: "k'<k" for i i' j j' k' k
proof (rule atLeast_less_sets)
show "b k' (j', i') ≪ {Inf(M (Suc k'))}"
using Suc_lessD b_Inf_M_Suc nat_less_le j by blast
show "b k (j,i) ⊆ {Inf(M (Suc k'))..}"
by (meson Inf_M_telescoping Suc_leI UnionI b_InfM rangeI subset_eq k)
qed
have M_subset_N: "M k ⊆ N" for k
proof (cases k)
case (Suc k')
with Ψ_DF [of k'] show ?thesis
by (auto simp: M_def Let_def Ψ_def split: prod.split)
qed (auto simp: M_def DF_simps)
have a_subset_N: "a k ⊆ N" for k
using Ψ_DF [of k] by (simp add: a_def Ψ_def split: prod.split prod.split_asm)
have d_subset_N: "d k ⊆ N" for k
using M_subset_N [of k] d_eq fst_grab_subset nxt_subset by blast
have b_subset_N: "b k (j,i) ⊆ N" for k j i
using Ψ_DF [of k] by (force simp: b_def Ψ_def)
define 𝒦:: "[nat,nat] ⇒ nat set set"
where "𝒦 ≡ λj0 j. nsets {j0<..} j"
have 𝒦_finite: "finite K" and 𝒦_card: "card K = j" if "K ∈ 𝒦 j0 j" for K j0 j
using that by (auto simp add: 𝒦_def nsets_def)
have 𝒦_enum: "j0 < enum K i" if "K ∈ 𝒦 j0 j" "i < card K" for K j0 j i
using that by (auto simp: 𝒦_def nsets_def finite_enumerate_in_set subset_eq)
have 𝒦_0 [simp]: "𝒦 k 0 = {{}}" for k
by (auto simp: 𝒦_def)
have 𝒦_Suc: "𝒦 j0 (Suc j) = USigma (𝒦 j0 j) (λK. {Max (insert j0 K)<..})" (is "?lhs = ?rhs")
for j j0
proof
show "𝒦 j0 (Suc j) ⊆ USigma (𝒦 j0 j) (λK. {Max (insert j0 K)<..})"
unfolding 𝒦_def nsets_def USigma_def
proof clarsimp
fix K
assume K: "K ⊆ {j0<..}" "finite K" "card K = Suc j"
then have "Max K ∈ K"
by (metis Max_in card_0_eq nat.distinct(1))
then obtain i where "Max (insert j0 (K - {Max K})) < i" "K = insert i (K - {Max K})"
using K
by (simp add: subset_iff) (metis DiffE Max.coboundedI insertCI insert_Diff le_neq_implies_less)
then show "∃L⊆{j0<..}. finite L ∧ card L = j ∧ (∃i∈{Max (insert j0 L)<..}. K = insert i L)"
using K
by (metis ‹Max K ∈ K› card_Diff_singleton_if diff_Suc_1 finite_Diff greaterThan_iff insert_subset)
qed
show "?rhs ⊆ 𝒦 j0 (Suc j)"
by (force simp: 𝒦_def nsets_def USigma_def)
qed
define BB where "BB ≡ λj0 j K. list_of (a j0 ∪ (⋃i<j. b (enum K i) (j0,i)))"
define XX where "XX ≡ λj. BB j j ` 𝒦 j j"
have less_list_of: "BB j i K < list_of (b l (j,i))"
if K: "K ∈ 𝒦 j i" "∀j∈K. j < l" and "i ≤ j" "j ≤ l" for j i K l
unfolding BB_def
proof (rule less_sets_imp_sorted_list_of_set)
have "⋀i. i < card K ⟹ b (enum K i) (j,i) ≪ b l (j, card K)"
using that by (metis 𝒦_card 𝒦_enum 𝒦_finite bb finite_enumerate_in_set nat_less_le less_le_trans)
then show "a j ∪ (⋃i<i. b (enum K i) (j,i)) ≪ b l (j,i)"
using that unfolding 𝒦_def nsets_def
by (auto simp: less_sets_Un1 less_sets_UN1 ab finite_enumerate_in_set subset_eq)
qed auto
have BB_Suc: "BB j0 (Suc j) K = usplit (λL k. BB j0 j L @ list_of (b k (j0, j))) K"
if j: "j ≤ j0" and K: "K ∈ 𝒦 j0 (Suc j)" for j0 j K
proof -
have Kj: "K ⊆ {j0<..}" and [simp]: "finite K" and cardK: "card K = Suc j"
using K by (auto simp: 𝒦_def nsets_def)
have KMK: "K - {Max K} ∈ 𝒦 j0 j"
using that by (simp add: 𝒦_Suc USigma_iff 𝒦_finite less_sets_def usplit_def)
have "j0 < Max K"
by (metis Kj Max_in cardK card_gt_0_iff greaterThan_iff subsetD zero_less_Suc)
have MaxK: "Max K = enum K j"
proof (rule Max_eqI)
fix k
assume "k ∈ K"
with K cardK show "k ≤ enum K j"
by (metis ‹finite K› finite_enumerate_Ex finite_enumerate_mono_iff leI lessI not_less_eq)
qed (auto simp: cardK finite_enumerate_in_set)
have ene: "i<j ⟹ enum (K - {enum K j}) i = enum K i" for i
using finite_enumerate_Diff_singleton [OF ‹finite K›] by (simp add: cardK)
have "BB j0 (Suc j) K = list_of ((a j0 ∪ (⋃x<j. b (enum K x) (j0, x))) ∪ b (enum K j) (j0, j))"
by (simp add: BB_def lessThan_Suc Un_ac)
also have "… = list_of ((a j0 ∪ (⋃i<j. b (enum K i) (j0, i)))) @ list_of (b (enum K j) (j0, j))"
proof (rule sorted_list_of_set_Un)
have "b (enum K i) (j0, i) ≪ b (enum K j) (j0, j)" if "i<j" for i
using K 𝒦_enum bb cardK j le_eq_less_or_eq that by auto
moreover have "a j0 ≪ b (enum K j) (j0, j)"
using MaxK ‹j0 < Max K› ab by auto
ultimately show "a j0 ∪ (⋃x<j. b (enum K x) (j0, x)) ≪ b (enum K j) (j0, j)"
by (simp add: less_sets_Un1 less_sets_UN1)
qed (auto simp: finite_UnI)
also have "… = BB j0 j (K - {Max K}) @ list_of (b (Max K) (j0, j))"
by (simp add: BB_def MaxK ene)
also have "… = usplit (λL k. BB j0 j L @ list_of (b k (j0, j))) K"
by (simp add: usplit_def)
finally show ?thesis .
qed
have enum_d_0: "enum (d j) 0 = Inf (d j)" for j
using enum_0_eq_Inf_finite by auto
have Inf_b_less: "⨅(b k' (j',i')) < ⨅(b k (j,i))"
if j: "i' < j'" "i < j" "j'≤k'" "j≤k" and k: "k'<k" for i i' j j' k' k
using bb [of i' j' k' k j i] that b_ne [of i' j' k'] b_ne [of i j k]
by (simp add: less_sets_def Inf_nat_def1)
have b_ge_k: "⨅ (b k (k, k-1)) ≥ k-1" for k
proof (induction k)
case (Suc k)
show ?case
proof (cases "k=0")
case False
then have "⨅ (b k (k, k - 1)) < ⨅ (b (Suc k) (Suc k, k))"
using Inf_b_less by auto
with Suc show ?thesis
by simp
qed auto
qed auto
have b_ge: "⨅ (b k (j,i)) ≥ k-1" if "k ≥ j" "j > i" for k j i
by (metis Inf_b_less Suc_leI b_ge_k diff_Suc_1 lessI not_less that diff_le_mono)
have hd_b: "hd (list_of (b k (j,i))) = ⨅ (b k (j,i))"
if "i < j" "j ≤ k" for k j i
using that by (simp add: hd_list_of cInf_eq_Min)
have b_disjoint_less: "b (enum K i) (j0, i) ∩ b (enum K i') (j0, i') = {}"
if K: "K ⊆ {j0<..}" "finite K" "card K ≥ j0" "i' < j" "i < i'" "j ≤ j0" for i i' j j0 K
proof (intro bb less_sets_imp_disjnt [unfolded disjnt_def])
show "i < j0"
using that by linarith
then show "j0 ≤ enum K i"
by (meson K finite_enumerate_in_set greaterThan_iff less_imp_le_nat less_le_trans subsetD)
show "enum K i < enum K i'"
using K ‹j ≤ j0› that by auto
qed
have b_disjoint: "b (enum K i) (j0, i) ∩ b (enum K i') (j0, i') = {}"
if K: "K ⊆ {j0<..}" "finite K" "card K ≥ j0" "i < j" "i' < j" "i ≠ i'" "j ≤ j0" for i i' j j0 K
using that b_disjoint_less inf_commute neq_iff by metis
have otω: "ordertype ((λk. list_of (b k (j,i))) ` {Max (insert j K)<..}) ?LL = ω"
(is "?lhs = _")
if K: "K ∈ 𝒦 j i" "j > i" for j i K
proof -
have Sucj: "Suc (Max (insert j K)) ≥ j"
using 𝒦_finite that(1) le_Suc_eq by auto
let ?N = "{Inf(b k (j,i))| k. Max (insert j K) < k}"
have infN: "infinite ?N"
proof (clarsimp simp add: infinite_nat_iff_unbounded_le)
fix m
show "∃n≥m. ∃k. n = ⨅ (b k (j,i)) ∧ Max (insert j K) < k"
using b_ge ‹j > i› Sucj
by (metis (no_types, lifting) diff_Suc_1 le_SucI le_trans less_Suc_eq_le nat_le_linear)
qed
have [simp]: "Max (insert j K) < k ⟷ j < k ∧ (∀a∈K. a < k)" for k
using that by (auto simp: 𝒦_finite)
have "?lhs = ordertype ?N less_than"
proof (intro ordertype_eqI strip)
have "list_of (b k (j,i)) = list_of (b k' (j,i))"
if "j ≤ k" "j ≤ k'" "hd (list_of (b k (j,i))) = hd (list_of (b k' (j,i)))"
for k k'
by (metis Inf_b_less ‹i < j› hd_b nat_less_le not_le that)
moreover have "∃k' j' i'. hd (list_of (b k (j,i))) = ⨅ (b k' (j', i')) ∧ i' < j' ∧ j' ≤ k'"
if "j ≤ k" for k
using that ‹i < j› hd_b less_imp_le_nat by blast
moreover have "∃k'. hd (list_of (b k (j,i))) = ⨅ (b k' (j,i)) ∧ j < k' ∧ (∀a∈K. a < k')"
if "j < k" "∀a∈K. a < k" for k
using that K hd_b less_imp_le_nat by blast
moreover have "⨅ (b k (j,i)) ∈ hd ` (λk. list_of (b k (j,i))) ` {Max (insert j K)<..}"
if "j < k" "∀a∈K. a < k" for k
using that K by (auto simp: hd_b image_iff)
ultimately
show "bij_betw hd ((λk. list_of (b k (j,i))) ` {Max (insert j K)<..}) {⨅ (b k (j,i)) |k. Max (insert j K) < k}"
by (auto simp: bij_betw_def inj_on_def)
next
fix ms ns
assume "ms ∈ (λk. list_of (b k (j,i))) ` {Max (insert j K)<..}"
and "ns ∈ (λk. list_of (b k (j,i))) ` {Max (insert j K)<..}"
with that obtain k k' where
ms: "ms = list_of (b k (j,i))" and ns: "ns = list_of (b k' (j,i))"
and "j < k" "j < k'" and lt_k: "∀a∈K. a < k" and lt_k': "∀a∈K. a < k'"
by (auto simp: 𝒦_finite)
then have len_eq [simp]: "length ns = length ms"
by (simp add: card_b)
have nz: "length ns ≠ 0"
using b_ne ‹i < j› ‹j < k'› ns by auto
show "(hd ms, hd ns) ∈ less_than ⟷ (ms, ns) ∈ ?LL"
proof
assume "(hd ms, hd ns) ∈ less_than"
then show "(ms, ns) ∈ ?LL"
using that nz
by (fastforce simp: lenlex_def 𝒦_finite card_b intro: hd_lex)
next
assume §: "(ms, ns) ∈ ?LL"
then have "(list_of (b k' (j,i)), list_of (b k (j,i))) ∉ ?LL"
using less_asym ms ns omega_sum_1_less by blast
then show "(hd ms, hd ns) ∈ less_than"
using ‹j < k› ‹j < k'› Inf_b_less [of i j i j] ms ns
by (metis Cons_lenlex_iff § len_eq b_ne card_b_finite diff_Suc_1 hd_Cons_tl hd_b length_Cons less_or_eq_imp_le less_than_iff linorder_neqE_nat sorted_list_of_set_eq_Nil_iff that(2))
qed
qed auto
also have "… = ω"
using infN ordertype_nat_ω by blast
finally show ?thesis .
qed
have otωj: "ordertype (BB j0 j ` 𝒦 j0 j) ?LL = ω↑j" if "j ≤ j0" for j j0
using that
proof (induction j)
case 0
then show ?case
by (auto simp: XX_def)
next
case (Suc j)
then have ih: "ordertype (BB j0 j ` 𝒦 j0 j) ?LL = ω ↑ j"
by simp
have "j ≤ j0"
by (simp add: Suc.prems Suc_leD)
have inj_BB: "inj_on (BB j0 j) ([{j0<..}]⇗j⇖)"
proof (clarsimp simp: inj_on_def BB_def nsets_def sorted_list_of_set_Un less_sets_UN2)
fix X Y
assume X: "X ⊆ {j0<..}" and Y: "Y ⊆ {j0<..}"
and "finite X" "finite Y"
and jeq: "j = card X"
and "card Y = card X"
and eq: "list_of (a j0 ∪ (⋃i<card X. b (enum X i) (j0,i)))
= list_of (a j0 ∪ (⋃i<card X. b (enum Y i) (j0,i)))"
have enumX: "⋀n. ⟦n < card X⟧ ⟹ j0 ≤ enum X n"
using X ‹finite X› finite_enumerate_in_set less_imp_le_nat by blast
have enumY: "⋀n. ⟦n < card X⟧ ⟹ j0 ≤ enum Y n"
using subsetD [OF Y]
by (metis ‹card Y = card X› ‹finite Y› finite_enumerate_in_set greaterThan_iff less_imp_le_nat)
have smX: "strict_mono_sets {..<card X} (λi. b (enum X i) (j0, i))"
and smY: "strict_mono_sets {..<card X} (λi. b (enum Y i) (j0, i))"
using Suc.prems ‹card Y = card X› ‹finite X› ‹finite Y› bb enumX enumY jeq
by (auto simp: strict_mono_sets_def)
have len_eq: "length ms = length ns"
if "(ms, ns) ∈ list.set (zip (map (list_of ∘ (λi. b (enum X i) (j0,i))) (list_of {..<n}))
(map (list_of ∘ (λi. b (enum Y i) (j0,i))) (list_of {..<n})))"
"n ≤ card X"
for ms ns n
using that
by (induction n rule: nat.induct) (auto simp: card_b enumX enumY)
have "concat (map (list_of ∘ (λi. b (enum X i) (j0, i))) (list_of {..<card X}))
= concat (map (list_of ∘ (λi. b (enum Y i) (j0, i))) (list_of {..<card X}))"
using eq
by (simp add: sorted_list_of_set_Un less_sets_UN2 sorted_list_of_set_UN_lessThan ab enumX enumY smX smY)
then have map_eq: "map (list_of ∘ (λi. b (enum X i) (j0, i))) (list_of {..<card X})
= map (list_of ∘ (λi. b (enum Y i) (j0, i))) (list_of {..<card X})"
by (rule concat_injective) (auto simp: len_eq split: prod.split)
have "enum X i = enum Y i" if "i < card X" for i
proof -
have "Inf (b (enum X i) (j0,i)) = Inf (b (enum Y i) (j0,i))"
using iffD1 [OF map_eq_conv, OF map_eq] Suc.prems that
by (metis (mono_tags, lifting) card_b_finite comp_apply finite_lessThan lessThan_iff set_sorted_list_of_set)
moreover have "Inf (b (enum X i) (j0,i)) ∈ (b (enum X i) (j0,i))"
"Inf (b (enum Y i) (j0,i)) ∈ (b (enum Y i) (j0,i))" "i < j0"
using Inf_nat_def1 Suc.prems b_ne enumX enumY jeq that by auto
ultimately show ?thesis
by (metis Inf_b_less enumX enumY leI nat_less_le that)
qed
then show "X = Y"
by (simp add: ‹card Y = card X› ‹finite X› ‹finite Y› finite_enum_ext)
qed
have BB_Suc': "BB j0 (Suc j) X = usplit (λL k. BB j0 j L @ list_of (b k (j0, j))) X"
if "X ∈ USigma (𝒦 j0 j) (λK. {Max (insert j0 K)<..})" for X
using that
by (simp add: USigma_iff 𝒦_finite less_sets_def usplit_def 𝒦_Suc BB_Suc ‹j ≤ j0›)
have "ordertype (BB j0 (Suc j) ` 𝒦 j0 (Suc j)) ?LL
= ordertype
(usplit (λL k. BB j0 j L @ list_of (b k (j0, j))) ` USigma (𝒦 j0 j) (λK. {Max (insert j0 K)<..})) ?LL"
by (simp add: BB_Suc' 𝒦_Suc)
also have "… = ω * ordertype (BB j0 j ` 𝒦 j0 j) ?LL"
proof (intro ordertype_append_image_IJ)
fix L k
assume "L ∈ 𝒦 j0 j" and "k ∈ {Max (insert j0 L)<..}"
then have "j0 < k" and L: "⋀a. a ∈ L ⟹ a < k"
by (simp_all add: 𝒦_finite)
then show "BB j0 j L < list_of (b k (j0, j))"
by (simp add: ‹L ∈ 𝒦 j0 j› ‹j ≤ j0› 𝒦_finite less_list_of)
next
show "inj_on (BB j0 j) (𝒦 j0 j)"
by (simp add: 𝒦_def inj_BB)
next
fix L
assume L: "L ∈ 𝒦 j0 j"
then show "L ≪ {Max (insert j0 L)<..} ∧ finite L"
by (simp add: 𝒦_finite less_sets_def)
show "ordertype ((λi. list_of (b i (j0, j))) ` {Max (insert j0 L)<..}) ?LL = ω"
using L Suc.prems Suc_le_lessD otω by blast
qed (auto simp: 𝒦_finite card_b)
also have "… = ω ↑ ord_of_nat (Suc j)"
by (simp add: oexp_mult_commute ih)
finally show ?case .
qed
define seqs where "seqs ≡ λj0 j K. list_of (a j0) # (map (list_of ∘ (λi. b (enum K i) (j0,i))) (list_of {..<j}))"
have length_seqs [simp]: "length (seqs j0 j K) = Suc j" for j0 j K
by (simp add: seqs_def)
have BB_eq_concat_seqs: "BB j0 j K = concat (seqs j0 j K)"
and seqs_ne: "seqs j0 j K ∈ lists (- {[]})"
if K: "K ∈ 𝒦 j0 j" and "j ≤ j0" for K j j0
proof -
have j0: "⋀i. i < card K ⟹ j0 ≤ enum K i" and le_j0: "card K ≤ j0"
using finite_enumerate_in_set that unfolding 𝒦_def nsets_def by fastforce+
show "BB j0 j K = concat (seqs j0 j K)"
using that unfolding BB_def 𝒦_def nsets_def seqs_def
by (fastforce simp: j0 ab bb less_sets_UN2 sorted_list_of_set_Un
strict_mono_sets_def sorted_list_of_set_UN_lessThan)
have "b (enum K i) (j0, i) ≠ {}" if "i < card K" for i
using j0 le_j0 less_le_trans that by simp
moreover have "card K = j"
using K 𝒦_card by blast
ultimately show "seqs j0 j K ∈ lists (- {[]})"
by (clarsimp simp: seqs_def) (metis card_b_finite sorted_list_of_set_eq_Nil_iff)
qed
have BB_decomp: "∃cs. BB j0 j K = concat cs ∧ cs ∈ lists (- {[]})"
if K: "K ∈ 𝒦 j0 j" and "j ≤ j0" for K j j0
using BB_eq_concat_seqs seqs_ne K that(2) by blast
have a_subset_M: "a k ⊆ M k" for k
apply (clarsimp simp: a_def M_def DF_simps F_def Let_def split: prod.split_asm)
by (metis (no_types) fst_conv fst_grab_subset nxt_subset snd_conv snd_grab_subset subsetD)
have ba_Suc: "b k (j,i) ≪ a (Suc k)" if "i < j" "j ≤ k" for i j k
by (meson a_subset_M bM less_sets_weaken2 nat_less_le that)
have ba: "b k (j,i) ≪ a r" if "i < j" "j ≤ k" "k < r" for i j k r
by (metis Suc_lessI a_ne aa ba_Suc less_sets_trans that)
have disjnt_ba: "disjnt (b k (j,i)) (a r)" if "i < j" "j ≤ k" for i j k r
by (meson ab ba disjnt_sym less_sets_imp_disjnt not_le that)
have bb_disjnt: "disjnt (b k (j,i)) (b l (r,q))"
if "q < r" "i < j" "j ≤ k" "r ≤ l" "j < r" for i j q r k l
proof (cases "k=l")
case True
with that show ?thesis
by (force simp: pair_less_def IJ_def intro: bb_same less_sets_imp_disjnt)
next
case False
with that show ?thesis
by (metis bb less_sets_imp_disjnt disjnt_sym nat_neq_iff)
qed
have sum_card_b: "(∑i<j. card (b (enum K i) (j0, i))) = enum (d j0) j - enum (d j0) 0"
if K: "K ⊆ {j0<..}" "finite K" "card K ≥ j0" and "j ≤ j0" for j0 j K
using ‹j ≤ j0›
proof (induction j)
case 0
then show ?case
by auto
next
case (Suc j)
then have "j < card K"
using that(3) by linarith
have dis: "disjnt (b (enum K j) (j0, j)) (⋃i<j. b (enum K i) (j0, i))"
unfolding disjoint_UN_iff
by (meson Suc.prems b_disjoint_less disjnt_def disjnt_sym lessThan_iff less_Suc_eq that)
have j0_less: "j0 < enum K j"
using K ‹j < card K› by (force simp: finite_enumerate_in_set)
have "(∑i<Suc j. card (b (enum K i) (j0, i)))
= card (b (enum K j) (j0, j)) + (∑i<j. card (b (enum K i) (j0, i)))"
by (simp add: lessThan_Suc card_Un_disjnt [OF _ _ dis])
also have "… = card (b (enum K j) (j0, j)) + enum (d j0) j - enum (d j0) 0"
using ‹Suc j ≤ j0› by (simp add: Suc.IH split: nat_diff_split)
also have "… = enum (d j0) (Suc j) - enum (d j0) 0"
using j0_less Suc.prems card_b less_or_eq_imp_le by force
finally show ?case .
qed
have card_UN_b: "card (⋃i<j. b (enum K i) (j0, i)) = enum (d j0) j - enum (d j0) 0"
if K: "K ⊆ {j0<..}" "finite K" "card K ≥ j0" and "j ≤ j0" for j0 j K
using that by (simp add: card_UN_disjoint sum_card_b b_disjoint)
have len_BB: "length (BB j j K) = enum (d j) j"
if K: "K ∈ 𝒦 j j" and "j ≤ j" for j K
proof -
have dis_ab: "⋀i. i < j ⟹ disjnt (a j) (b (enum K i) (j,i))"
using K 𝒦_card 𝒦_enum ab less_sets_imp_disjnt nat_less_le by blast
show ?thesis
using K unfolding BB_def 𝒦_def nsets_def
by (simp add: card_UN_b card_Un_disjnt dis_ab card_a cInf_le_finite finite_enumerate_in_set enum_0_eq_Inf_finite)
qed
have "d k ≪ d (Suc k)" for k
by (metis aM a_ne d_eq da less_sets_fst_grab less_sets_trans less_sets_weaken2 nxt_subset)
then have dd: "d k' ≪ d k" if "k' < k" for k' k
by (meson UNIV_I d_ne less_sets_imp_strict_mono_sets strict_mono_sets_def that)
show thesis
proof
show "(⋃ (range XX)) ⊆ WW"
by (auto simp: XX_def BB_def WW_def)
show "ordertype (⋃ (range XX)) (?LL) = ω ↑ ω"
using otωj by (simp add: XX_def ordertype_ωω)
next
fix U
assume U: "U ∈ [⋃ (range XX)]⇗2⇖"
then obtain x y where Ueq: "U = {x,y}" and len_xy: "length x ≤ length y"
by (auto simp: lenlex_nsets_2_eq lenlex_length)
show "∃l. Form l U ∧ (0 < l ⟶ [enum N l] < inter_scheme l U ∧ list.set (inter_scheme l U) ⊆ N)"
proof (cases "length x = length y")
case True
then show ?thesis
using Form.intros(1) U Ueq by fastforce
next
case False
then have xy: "length x < length y"
using len_xy by auto
obtain j r K L where K: "K ∈ 𝒦 j j" and xeq: "x = BB j j K" and ne: "BB j j K ≠ BB r r L"
and L: "L ∈ 𝒦 r r" and yeq: "y = BB r r L"
using U by (auto simp: Ueq XX_def)
then have "length x = enum (d j) j" "length y = enum (d r) r"
by (auto simp: len_BB)
then have "j < r"
using xy dd
by (metis card_d finite_enumerate_in_set finite_d lessI less_asym less_setsD linorder_neqE_nat)
then have aj_ar: "a j ≪ a r"
using aa by auto
have Ksub: "K ⊆ {j<..}" and "finite K" "card K ≥ j"
using K by (auto simp: 𝒦_def nsets_def)
have Lsub: "L ⊆ {r<..}" and "finite L" "card L ≥ r"
using L by (auto simp: 𝒦_def nsets_def)
have enumK: "enum K i > j" if "i < j" for i
using K 𝒦_card 𝒦_enum that by blast
have enumL: "enum L i > r" if "i < r" for i
using L 𝒦_card 𝒦_enum that by blast
have "list.set (acc_lengths w (seqs j0 j K)) ⊆ (+) w ` d j0"
if K: "K ⊆ {j0<..}" "finite K" "card K ≥ j0" and "j ≤ j0" for j0 j K w
using ‹j ≤ j0›
proof (induction j arbitrary: w)
case 0
then show ?case
by (simp add: seqs_def Inf_nat_def1 card_a)
next
case (Suc j)
let ?db = "⨅ (d j0) + ((∑i<j. card (b (enum K i) (j0,i))) + card (b (enum K j) (j0,j)))"
have "j0 < enum K j"
by (meson Suc.prems Suc_le_lessD finite_enumerate_in_set greaterThan_iff le_trans subsetD K)
then have "enum (d j0) j ≥ ⨅ (d j0)"
using Suc.prems card_d by (simp add: cInf_le_finite finite_enumerate_in_set)
then have "?db = enum (d j0) (Suc j)"
using Suc.prems that
by (simp add: cInf_le_finite finite_enumerate_in_set sum_card_b card_b enum_d_0 ‹j0 < enum K j› less_or_eq_imp_le)
then have "?db ∈ d j0"
using Suc.prems finite_enumerate_in_set by (auto simp: finite_enumerate_in_set)
moreover have "list.set (acc_lengths w (seqs j0 j K)) ⊆ (+) w ` d j0"
by (simp add: Suc Suc_leD)
then have "list.set (acc_lengths (w + ⨅ (d j0))
(map (list_of ∘ (λi. b (enum K i) (j0,i))) (list_of {..<j})))
⊆ (+) w ` d j0"
by (simp add: seqs_def card_a subset_insertI)
ultimately show ?case
by (simp add: seqs_def acc_lengths_append image_iff Inf_nat_def1
sum_sorted_list_of_set_map card_a)
qed
then have acc_lengths_subset_d: "list.set (acc_lengths 0 (seqs j0 j K)) ⊆ d j0"
if K: "K ⊆ {j0<..}" "finite K" "card K ≥ j0" and "j ≤ j0" for j0 j K
by (metis image_add_0 that)
have "strict_sorted x" "strict_sorted y"
by (auto simp: xeq yeq BB_def)
have disjnt_xy: "disjnt (list.set x) (list.set y)"
proof -
have "disjnt (a j) (a r)"
using ‹j < r› aa less_sets_imp_disjnt by blast
moreover have "disjnt (b (enum K i) (j,i)) (a r)" if "i < j" for i
by (simp add: disjnt_ba enumK less_imp_le_nat that)
moreover have "disjnt (a j) (b (enum L q) (r,q))" if "q < r" for q
by (meson disjnt_ba disjnt_sym enumL less_imp_le_nat that)
moreover have "disjnt (b (enum K i) (j,i)) (b (enum L q) (r,q))" if "i < j" "q < r" for i q
by (meson ‹j < r› bb_disjnt enumK enumL less_imp_le that)
ultimately show ?thesis
by (simp add: xeq yeq BB_def)
qed
have "∃us vs. merge (seqs j j K) (seqs r r L) us vs"
proof (rule merge_exists)
show "strict_sorted (concat (seqs j j K))"
using BB_eq_concat_seqs K ‹strict_sorted x› xeq by auto
show "strict_sorted (concat (seqs r r L))"
using BB_eq_concat_seqs L ‹strict_sorted y› yeq by auto
show "seqs j j K ∈ lists (- {[]})" "seqs r r L ∈ lists (- {[]})"
by (auto simp: K L seqs_ne)
show "hd (seqs j j K) < hd (seqs r r L)"
by (simp add: aj_ar less_sets_imp_list_less seqs_def)
show "seqs j j K ≠ []" "seqs r r L ≠ []"
using seqs_def by blast+
have less_bb: "b (enum K i) (j,i) ≪ b (enum L p) (r, p)"
if "¬ b (enum L p) (r, p) ≪ b (enum K i) (j,i)" and "i < j" "p < r"
for i p
by (metis IJ_iff ‹j < r› bb bb_same enumK enumL less_imp_le_nat linorder_neqE_nat pair_lessI1 that)
show "u < v ∨ v < u"
if "u ∈ list.set (seqs j j K)" and "v ∈ list.set (seqs r r L)" for u v
using that enumK enumL unfolding seqs_def
apply (auto simp: seqs_def aj_ar intro!: less_bb less_sets_imp_list_less)
apply (meson ab ba less_imp_le_nat not_le)+
done
qed
then obtain uus vvs where merge: "merge (seqs j j K) (seqs r r L) uus vvs"
by metis
then have "uus ≠ []"
using merge_length1_gt_0 by (auto simp: seqs_def)
then obtain u1 us where us: "u1#us = uus"
by (metis neq_Nil_conv)
define ku where "ku ≡ length (u1#us)"
define ps where "ps ≡ acc_lengths 0 (u1#us)"
have us_ne: "u1#us ∈ lists (- {[]})"
using merge_length1_nonempty seqs_ne us merge us K by auto
have xu_eq: "x = concat (u1#us)"
using BB_eq_concat_seqs K merge merge_preserves us xeq by auto
then have "strict_sorted u1"
using ‹strict_sorted x› strict_sorted_append_iff by auto
have u_sub: "list.set ps ⊆ list.set (acc_lengths 0 (seqs j j K))"
using acc_lengths_merge1 merge ps_def us by blast
have "vvs ≠ []"
using merge BB_eq_concat_seqs L merge_preserves xy yeq by auto
then obtain v1 vs where vs: "v1#vs = vvs"
by (metis neq_Nil_conv)
define kv where "kv ≡ length (v1#vs)"
define qs where "qs ≡ acc_lengths 0 (v1#vs)"
have vs_ne: "v1#vs ∈ lists (- {[]})"
using L merge merge_length2_nonempty seqs_ne vs by auto
have yv_eq: "y = concat (v1#vs)"
using BB_eq_concat_seqs L merge merge_preserves vs yeq by auto
then have "strict_sorted v1"
using ‹strict_sorted y› strict_sorted_append_iff by auto
have v_sub: "list.set qs ⊆ list.set (acc_lengths 0 (seqs r r L))"
using acc_lengths_merge2 merge qs_def vs by blast
have ss_concat_jj: "strict_sorted (concat (seqs j j K))"
using BB_eq_concat_seqs K ‹strict_sorted x› xeq by auto
then obtain k: "0 < kv" "kv ≤ ku" "ku ≤ Suc kv" "kv ≤ Suc j"
using us vs merge_length_le merge_length_le_Suc merge_length_less2 merge
unfolding ku_def kv_def by fastforce
define zs where "zs ≡ concat [ps,u1,qs,v1] @ interact us vs"
have ss: "strict_sorted zs"
proof -
have ssp: "strict_sorted ps"
unfolding ps_def by (meson strict_sorted_acc_lengths us_ne)
have ssq: "strict_sorted qs"
unfolding qs_def by (meson strict_sorted_acc_lengths vs_ne)
have "d j ≪ list.set x"
using da [of j] db [of j] K 𝒦_card 𝒦_enum nat_less_le
by (auto simp: xeq BB_def less_sets_Un2 less_sets_UN2)
then have ac_x: "acc_lengths 0 (seqs j j K) < x"
by (meson Ksub ‹finite K› ‹j ≤ card K› acc_lengths_subset_d le_refl less_sets_imp_list_less less_sets_weaken1)
then have "ps < x"
by (meson Ksub ‹d j ≪ list.set x› ‹finite K› ‹j ≤ card K› acc_lengths_subset_d le_refl less_sets_imp_list_less less_sets_weaken1 u_sub)
then have "ps < u1"
by (metis Nil_is_append_conv concat.simps(2) hd_append2 less_list_def xu_eq)
have "d r ≪ list.set y"
using da [of r] db [of r] L 𝒦_card 𝒦_enum nat_less_le
by (auto simp: yeq BB_def less_sets_Un2 less_sets_UN2)
then have "acc_lengths 0 (seqs r r L) < y"
by (meson Lsub ‹finite L› ‹r ≤ card L› acc_lengths_subset_d le_refl less_sets_imp_list_less less_sets_weaken1)
then have "qs < y"
by (metis L Lsub 𝒦_card ‹d r ≪ list.set y› ‹finite L› acc_lengths_subset_d less_sets_imp_list_less less_sets_weaken1 order_refl v_sub)
then have "qs < v1"
by (metis concat.simps(2) gr_implies_not0 hd_append2 less_list_def list.size(3) xy yv_eq)
have carda_v1: "card (a r) ≤ length v1"
using length_hd_merge2 [OF merge] unfolding vs [symmetric] by (simp add: seqs_def)
have ab_enumK: "⋀i. i < j ⟹ a j ≪ b (enum K i) (j,i)"
by (meson ab enumK le_trans less_imp_le_nat)
have ab_enumL: "⋀q. q < r ⟹ a j ≪ b (enum L q) (r,q)"
by (meson ‹j < r› ab enumL le_trans less_imp_le_nat)
then have ay: "a j ≪ list.set y"
by (auto simp: yeq BB_def less_sets_Un2 less_sets_UN2 aj_ar)
have disjnt_hd_last_K_y: "disjnt {hd l..last l} (list.set y)"
if l: "l ∈ list.set (seqs j j K)" for l
proof (clarsimp simp add: yeq BB_def disjnt_iff Ball_def, intro conjI strip)
fix u
assume u: "u ≤ last l" and "hd l ≤ u"
with l consider "u ≤ last (list_of (a j))" "hd (list_of (a j)) ≤ u"
| i where "i<j" "u ≤ last (list_of (b (enum K i) (j,i)))" "hd (list_of (b (enum K i) (j,i))) ≤ u"
by (force simp: seqs_def)
note l_cases = this
then show "u ∉ a r"
proof cases
case 1
then show ?thesis
by (metis a_ne aj_ar finite_a last_in_set leD less_setsD set_sorted_list_of_set sorted_list_of_set_eq_Nil_iff)
next
case 2
then show ?thesis
by (metis enumK ab ba Inf_nat_def1 b_ne card_b_finite hd_b last_in_set less_asym less_setsD not_le set_sorted_list_of_set sorted_list_of_set_eq_Nil_iff)
qed
fix q
assume "q < r"
show "u ∉ b (enum L q) (r,q)"
using l_cases
proof cases
case 1
then show ?thesis
by (metis ‹q < r› a_ne ab_enumL finite_a last_in_set leD less_setsD set_sorted_list_of_set sorted_list_of_set_eq_Nil_iff)
next
case 2
show ?thesis
proof (cases "enum K i = enum L q")
case True
then show ?thesis
using 2 bb_same [of concl: "enum L q" j i r q] ‹j < r› u
by (metis IJ_iff b_ne card_b_finite enumK last_in_set leD less_imp_le_nat less_setsD pair_lessI1 set_sorted_list_of_set sorted_list_of_set_eq_Nil_iff)
next
case False
with 2 bb enumK enumL show ?thesis
unfolding less_sets_def
by (metis ‹q < r› b_ne card_b_finite last_in_set leD less_imp_le_nat list.set_sel(1) nat_neq_iff set_sorted_list_of_set sorted_list_of_set_eq_Nil_iff)
qed
qed
qed
have u1_y: "list.set u1 ≪ list.set y"
using vs yv_eq L ‹strict_sorted y› merge merge_less_sets_hd merge_preserves seqs_ne ss_concat_jj us by fastforce
have u1_subset_seqs: "list.set u1 ⊆ list.set (concat (seqs j j K))"
using merge_preserves [OF merge] us by auto
have "b k (j,i) ≪ d (Suc k)" if "j≤k" "i<j" for k j i
by (metis bM d_eq less_sets_fst_grab less_sets_weaken2 nxt_subset that)
then have bd: "b k (j,i) ≪ d k'" if "j≤k" "i<j" "k < k'" for k k' j i
by (metis Suc_lessI d_ne dd less_sets_trans that)
have "a k ≪ d (Suc k)" for k
by (metis aM d_eq less_sets_fst_grab less_sets_weaken2 nxt_subset)
then have ad: "a k ≪ d k'" if "k<k'" for k k'
by (metis Suc_lessI d_ne dd less_sets_trans that)
have "u1 < y"
by (simp add: u1_y less_sets_imp_list_less)
have "n < Inf (d r)" if n: "n ∈ list.set u1" for n
proof -
obtain l where l: "l ∈ list.set (seqs j j K)" and n: "n ∈ list.set l"
using n u1_subset_seqs by auto
then consider "l = list_of (a j)" | i where "l = list_of (b (enum K i) (j,i))" "i < j"
by (force simp: seqs_def)
then show ?thesis
proof cases
case 1
then show ?thesis
by (metis Inf_nat_def1 ‹j < r› ad d_ne finite_a less_setsD n set_sorted_list_of_set)
next
case 2
then have "hd (list_of (b (enum K i) (j,i))) = Min (b (enum K i) (j,i))"
by (meson b_ne card_b_finite enumK hd_list_of less_imp_le_nat)
also have "… ≤ n"
using 2 n by (simp add: less_list_def disjnt_iff less_sets_def)
also have f8: "n < hd y"
using less_setsD that u1_y
by (metis gr_implies_not0 list.set_sel(1) list.size(3) xy)
finally have "l < y"
using 2 disjnt_hd_last_K_y [OF l]
by (simp add: disjnt_iff) (metis leI less_imp_le_nat less_list_def list.set_sel(1))
moreover have "last (list_of (b (enum K i) (j,i))) < hd (list_of (a r))"
using ‹l < y› L n by (auto simp: 2yeq BB_eq_concat_seqs seqs_def less_list_def)
then have "enum K i < r"
by (metis "2"(1) a_ne ab card_b_finite empty_iff finite.emptyI finite_a last_in_set leI less_asym less_setsD list.set_sel(1) n set_sorted_list_of_set)
moreover have "j ≤ enum K i"
by (simp add: "2"(2) enumK less_imp_le_nat)
ultimately show ?thesis
using 2 n bd [of j "enum K i" i r] Inf_nat_def1 less_setsD by force
qed
qed
then have "last u1 < Inf (d r)"
using ‹uus ≠ []› us_ne by auto
also have "… ≤ length v1"
using card_a carda_v1 by auto
finally have "last u1 < length v1" .
then have "u1 < qs"
by (simp add: qs_def less_list_def)
have "strict_sorted (interact (u1#us) (v1#vs))"
using L ‹strict_sorted x› ‹strict_sorted y› merge merge_interact merge_preserves seqs_ne us vs xu_eq yv_eq by auto
then have "strict_sorted (interact us vs)" "v1 < interact us vs"
by (auto simp: strict_sorted_append_iff)
moreover have "ps < u1 @ qs @ v1 @ interact us vs"
using ‹ps < u1› us_ne unfolding less_list_def by auto
moreover have "u1 < qs @ v1 @ interact us vs"
by (metis ‹u1 < qs› ‹vvs ≠ []› acc_lengths_eq_Nil_iff hd_append less_list_def qs_def vs)
moreover have "qs < v1 @ interact us vs"
using ‹qs < v1› us_ne ‹last u1 < length v1› vs_ne by (auto simp: less_list_def)
ultimately show ?thesis
by (simp add: zs_def strict_sorted_append_iff ssp ssq ‹strict_sorted u1› ‹strict_sorted v1›)
qed
have ps_subset_d: "list.set ps ⊆ d j"
using K Ksub 𝒦_card ‹finite K› acc_lengths_subset_d u_sub by blast
have ps_less_u1: "ps < u1"
by (metis append.assoc concat.simps(2) ss strict_sorted_append_iff zs_def)
have qs_subset_d: "list.set qs ⊆ d r"
using L Lsub 𝒦_card ‹finite L› acc_lengths_subset_d v_sub by blast
have qs_less_v1: "qs < v1"
by (metis append.assoc concat.simps(2) ss strict_sorted_append_iff zs_def)
have FB: "Form_Body ku kv x y zs"
unfolding Form_Body.simps ku_def kv_def
using ps_def qs_def ss us_ne vs_ne xu_eq xy yv_eq zs_def by blast
then have "zs = (inter_scheme ((ku+kv) - Suc 0) {x,y})"
by (simp add: Form_Body_imp_inter_scheme k)
obtain l where "l ≤ 2 * (Suc j)" and l: "Form l U" and zs_eq_interact: "zs = inter_scheme l {x,y}"
proof
show "ku+kv-1 ≤ 2 * (Suc j)"
using k by auto
show "Form (ku+kv-1) U"
proof (cases "ku=kv")
case True
then show ?thesis
using FB Form.simps Ueq ‹0 < kv› by (auto simp: mult_2)
next
case False
then have "ku = Suc kv"
using k by auto
then show ?thesis
using FB Form.simps Ueq ‹0 < kv› by auto
qed
show "zs = inter_scheme (ku + kv - 1) {x, y}"
using Form_Body_imp_inter_scheme by (simp add: FB k)
qed
then have "enum N l ≤ enum N (Suc (2 * Suc j))"
by (simp add: assms less_imp_le_nat)
also have "… < Min (d j)"
by (smt (verit, best) Min_gr_iff d_eq d_ne finite_d fst_grab_subset greaterThan_iff in_mono le_inf_iff nxt_def)
finally have ls: "{enum N l} ≪ d j"
by simp
have "l > 0"
by (metis l False Form_0_cases_raw Set.doubleton_eq_iff Ueq gr0I)
show ?thesis
unfolding Ueq
proof (intro exI conjI impI)
have zs_subset: "list.set zs ⊆ list.set (acc_lengths 0 (seqs j j K)) ∪ list.set (acc_lengths 0 (seqs r r L)) ∪ list.set x ∪ list.set y"
using u_sub v_sub by (auto simp: zs_def xu_eq yv_eq)
also have "… ⊆ N"
proof (simp, intro conjI)
show "list.set (acc_lengths 0 (seqs j j K)) ⊆ N"
using d_subset_N Ksub ‹finite K› ‹j ≤ card K› acc_lengths_subset_d by blast
show "list.set (acc_lengths 0 (seqs r r L)) ⊆ N"
using d_subset_N Lsub ‹finite L› ‹r ≤ card L› acc_lengths_subset_d by blast
show "list.set x ⊆ N" "list.set y ⊆ N"
by (simp_all add: xeq yeq BB_def a_subset_N UN_least b_subset_N)
qed
finally show "list.set (inter_scheme l {x, y}) ⊆ N"
using zs_eq_interact by blast
have "[enum N l] < ps"
using ps_subset_d ls
by (metis empty_set less_sets_imp_list_less less_sets_weaken2 list.simps(15))
then show "[enum N l] < inter_scheme l {x, y}"
by (simp add: zs_def less_list_def ps_def flip: zs_eq_interact)
qed (use Ueq l in blast)
qed
qed
qed
subsection ‹The main partition theorem for @{term "ω↑ω"}›
definition iso_ll where "iso_ll A B ≡ iso (lenlex less_than ∩ (A×A)) (lenlex less_than ∩ (B×B))"
corollary ordertype_eq_ordertype_iso_ll:
assumes "Field (Restr (lenlex less_than) A) = A" "Field (Restr (lenlex less_than) B) = B"
shows "(ordertype A (lenlex less_than) = ordertype B (lenlex less_than))
⟷ (∃f. iso_ll A B f)"
proof -
have "total_on A (lenlex less_than) ∧ total_on B (lenlex less_than)"
by (meson UNIV_I total_lenlex total_on_def total_on_less_than)
then show ?thesis
by (simp add: assms wf_lenlex lenlex_transI iso_ll_def ordertype_eq_ordertype_iso_Restr)
qed
theorem partition_ωω_aux:
assumes "α ∈ elts ω"
shows "partn_lst (lenlex less_than) WW [ω↑ω,α] 2" (is "partn_lst ?R WW [ω↑ω,α] 2")
proof (cases "α ≤ 1")
case True
then show ?thesis
using strict_sorted_into_WW unfolding WW_def by (auto intro!: partn_lst_triv1[where i=1])
next
case False
obtain m where m: "α = ord_of_nat m"
using assms elts_ω by auto
then have "m>1"
using False by auto
show ?thesis
unfolding partn_lst_def
proof clarsimp
fix f
assume f: "f ∈ [WW]⇗2⇖ → {..<Suc (Suc 0)}"
let ?P0 = "∃X ⊆ WW. ordertype X ?R = ω↑ω ∧ f ` [X]⇗2⇖ ⊆ {0}"
let ?P1 = "∃M ⊆ WW. ordertype M ?R = α ∧ f ` [M]⇗2⇖ ⊆ {1}"
have †: "?P0 ∨ ?P1"
proof (rule disjCI)
assume not1: "¬ ?P1"
have "∃W'. ordertype W' ?R = ω↑n ∧ f ` [W']⇗2⇖ ⊆ {0} ∧ W' ⊆ WW_seg (n*m)" for n::nat
proof -
have fnm: "f ∈ [WW_seg (n*m)]⇗2⇖ → {..<Suc (Suc 0)}"
using f WW_seg_subset_WW [of "n*m"] by (meson in_mono nsets_Pi_contra)
have *: "partn_lst ?R (WW_seg (n*m)) [ω↑n, ord_of_nat m] 2"
using ordertype_WW_seg [of "n*m"]
by (simp add: partn_lst_VWF_imp_partn_lst [OF Theorem_3_2])
show ?thesis
using partn_lst_E [OF * fnm, simplified]
by (metis One_nat_def WW_seg_subset_WW less_2_cases m not1 nth_Cons_0 nth_Cons_Suc numeral_2_eq_2 subset_trans)
qed
then obtain W':: "nat ⇒ nat list set"
where otW': "⋀n. ordertype (W' n) ?R = ω↑n"
and f_W': "⋀n. f ` [W' n]⇗2⇖ ⊆ {0}"
and seg_W': "⋀n. W' n ⊆ WW_seg (n*m)"
by metis
define WW' where "WW' ≡ (⋃n. W' n)"
have "WW' ⊆ WW"
using seg_W' WW_seg_subset_WW by (force simp: WW'_def)
with f have f': "f ∈ [WW']⇗2⇖ → {..<Suc (Suc 0)}"
using nsets_mono by fastforce
have ot': "ordertype WW' ?R = ω↑ω"
proof (rule antisym)
have "ordertype WW' ?R ≤ ordertype WW ?R"
by (simp add: ‹WW' ⊆ WW› lenlex_transI ordertype_mono wf_lenlex)
with ordertype_WW
show "ordertype WW' ?R ≤ ω ↑ ω"
by simp
have "ω ↑ n ≤ ordertype (⋃ (range W')) ?R" for n::nat
using oexp_Limit ordertype_ωω otW' by auto
then show "ω ↑ ω ≤ ordertype WW' ?R"
by (auto simp: elts_ω oexp_Limit ZFC_in_HOL.SUP_le_iff WW'_def)
qed
have FR_WW: "Field (Restr (lenlex less_than) WW) = WW"
by (simp add: Limit_omega_oexp Limit_ordertype_imp_Field_Restr ordertype_WW)
have FR_WW': "Field (Restr (lenlex less_than) WW') = WW'"
by (simp add: Limit_omega_oexp Limit_ordertype_imp_Field_Restr ot')
have FR_W: "Field (Restr (lenlex less_than) (WW_seg n)) = WW_seg n" if "n>0" for n
by (simp add: Limit_omega_oexp ordertype_WW_seg that Limit_ordertype_imp_Field_Restr)
have FR_W': "Field (Restr (lenlex less_than) (W' n)) = W' n" if "n>0" for n
by (simp add: Limit_omega_oexp otW' that Limit_ordertype_imp_Field_Restr)
have "∃h. iso_ll (WW_seg n) (W' n) h" if "n>0" for n
proof (subst ordertype_eq_ordertype_iso_ll [symmetric])
show "ordertype (WW_seg n) (lenlex less_than) = ordertype (W' n) (lenlex less_than)"
by (simp add: ordertype_WW_seg otW')
qed (auto simp: FR_W FR_W' that)
then obtain h_seg where h_seg: "⋀n. n > 0 ⟹ iso_ll (WW_seg n) (W' n) (h_seg n)"
by metis
define h where "h ≡ λl. if l=[] then [] else h_seg (length l) l"
have bij_h_seg: "⋀n. n > 0 ⟹ bij_betw (h_seg n) (WW_seg n) (W' n)"
using h_seg by (simp add: iso_ll_def iso_iff2 FR_W FR_W')
have len_h_seg: "length (h_seg (length l) l) = length l * m"
if "length l > 0" "l ∈ WW" for l
using bij_betwE [OF bij_h_seg] seg_W' that by (simp add: WW_seg_def subset_iff)
have hlen: "length (h x) = length (h y) ⟷ length x = length y" if "x ∈ WW" "y ∈ WW" for x y
using that ‹1 < m› h_def len_h_seg by force
have h: "iso_ll WW WW' h"
unfolding iso_ll_def iso_iff2 FR_WW FR_WW'
proof (intro conjI strip)
have W'_ne: "W' n ≠ {}" for n
using otW' [of n] by auto
then have "[] ∈ WW'"
using seg_W' [of 0] by (auto simp: WW'_def WW_seg_def)
let ?g = "λl. if l=[] then l else inv_into (WW_seg (length l div m)) (h_seg (length l div m)) l"
have h_seg_iff: "⋀n a b. ⟦a ∈ WW_seg n; b ∈ WW_seg n; n>0⟧ ⟹
(a, b) ∈ lenlex less_than ⟷
(h_seg n a, h_seg n b) ∈ lenlex less_than ∧ h_seg n a ∈ W' n ∧ h_seg n b ∈ W' n"
using h_seg by (auto simp: iso_ll_def iso_iff2 FR_W FR_W')
show "bij_betw h WW WW'"
unfolding bij_betw_iff_bijections
proof (intro exI conjI ballI)
fix l
assume "l ∈ WW"
then have l: "l ∈ WW_seg (length l)"
by (simp add: WW_seg_def)
have "h l ∈ W' (length l)"
proof (cases "l=[]")
case True
with seg_W' [of 0] W'_ne show ?thesis
by (auto simp: WW_seg_def h_def)
next
case False
then show ?thesis
using bij_betwE bij_h_seg h_def l by fastforce
qed
show "h l ∈ WW'"
using WW'_def ‹h l ∈ W' (length l)› by blast
show "?g (h l) = l"
proof (cases "l=[]")
case False
then have "length l > 0"
by auto
then have "h_seg (length l) l ≠ []"
using ‹1 < m› ‹l ∈ WW› len_h_seg by fastforce
moreover have "bij_betw (h_seg (length l)) (WW_seg (length l)) (W' (length l))"
using ‹0 < length l› bij_h_seg by presburger
ultimately show ?thesis
using ‹l ∈ WW› bij_betw_inv_into_left h_def l len_h_seg by fastforce
qed (auto simp: h_def)
next
fix l
assume "l ∈ WW'"
then have l: "l ∈ W' (length l div m)"
using WW_seg_def ‹1 < m› seg_W' by (fastforce simp: WW'_def)
show "?g l ∈ WW"
proof (cases "l=[]")
case False
then have "l ∉ W' 0"
using WW_seg_def seg_W' by fastforce
with l have "inv_into (WW_seg (length l div m)) (h_seg (length l div m)) l ∈ WW_seg (length l div m)"
by (metis Nat.neq0_conv bij_betwE bij_betw_inv_into bij_h_seg)
then show ?thesis
using False WW_seg_subset_WW by auto
qed (auto simp: WW_def)
show "h (?g l) = l"
proof (cases "l=[]")
case False
then have "0 < length l div m"
using WW_seg_def l seg_W' by fastforce
then have "inv_into (WW_seg (length l div m)) (h_seg (length l div m)) l ∈ WW_seg (length l div m)"
by (metis bij_betw_imp_surj_on bij_h_seg inv_into_into l)
then show ?thesis
using bij_h_seg [of "length l div m"] WW_seg_def ‹0 < length l div m› bij_betw_inv_into_right l
by (fastforce simp: h_def)
qed (auto simp: h_def)
qed
fix a b
assume "a ∈ WW" "b ∈ WW"
show "(a, b) ∈ Restr (lenlex less_than) WW ⟷ (h a, h b) ∈ Restr (lenlex less_than) WW'"
(is "?lhs = ?rhs")
proof
assume L: ?lhs
then consider "length a < length b" | "length a = length b" "(a, b) ∈ lex less_than"
by (auto simp: lenlex_conv)
then show ?rhs
proof cases
case 1
then have "length (h a) < length (h b)"
using ‹1 < m› ‹a ∈ WW› ‹b ∈ WW› h_def len_h_seg by auto
then have "(h a, h b) ∈ lenlex less_than"
by (auto simp: lenlex_conv)
then show ?thesis
using ‹a ∈ WW› ‹b ∈ WW› ‹bij_betw h WW WW'› bij_betwE by fastforce
next
case 2
then have ab: "a ∈ WW_seg (length a)" "b ∈ WW_seg (length a)"
using ‹a ∈ WW› ‹b ∈ WW› by (auto simp: WW_seg_def)
have "length (h a) = length (h b)"
using 2 ‹a ∈ WW› ‹b ∈ WW› h_def len_h_seg by force
moreover have "(a, b) ∈ lenlex less_than"
using L by blast
then have "(h_seg (length a) a, h_seg (length a) b) ∈ lenlex less_than"
using 2 ab h_seg_iff by blast
ultimately show ?thesis
using 2 ‹a ∈ WW› ‹b ∈ WW› ‹bij_betw h WW WW'› bij_betwE h_def by fastforce
qed
next
assume R: ?rhs
then have R': "(h a, h b) ∈ lenlex less_than"
by blast
then consider "length a < length b"
| "length a = length b" "(h a, h b) ∈ lex less_than"
using ‹a ∈ WW› ‹b ∈ WW› ‹m > 1›
by (auto simp: lenlex_conv h_def len_h_seg split: if_split_asm)
then show ?lhs
proof cases
case 1
then show ?thesis
using omega_sum_less_iff ‹a ∈ WW› ‹b ∈ WW› by auto
next
case 2
then have ab: "a ∈ WW_seg (length a)" "b ∈ WW_seg (length a)"
using ‹a ∈ WW› ‹b ∈ WW› by (auto simp: WW_seg_def)
then have "(a, b) ∈ lenlex less_than"
using bij_betwE [OF bij_h_seg] ‹a ∈ WW› ‹b ∈ WW› R' 2
by (simp add: h_def h_seg_iff split: if_split_asm)
then show ?thesis
using ‹a ∈ WW› ‹b ∈ WW› by blast
qed
qed
qed
let ?fh = "f ∘ image h"
have "bij_betw h WW WW'"
using h unfolding iso_ll_def iso_iff2 by (fastforce simp: FR_WW FR_WW')
moreover have "{..<Suc (Suc 0)} = {0,1}"
by auto
ultimately have fh: "?fh ∈ [WW]⇗2⇖ → {0,1}"
unfolding Pi_iff using bij_betwE f' bij_betw_nsets by (metis PiE comp_apply)
have "f{x,y} = 0" if "x ∈ WW'" "y ∈ WW'" "length x = length y" "x ≠ y" for x y
proof -
obtain p q where "x ∈ W' p" and "y ∈ W' q"
using WW'_def ‹x ∈ WW'› ‹y ∈ WW'› by blast
then obtain n where "{x,y} ∈ [W' n]⇗2⇖"
using seg_W' ‹1 < m› ‹length x = length y› ‹x ≠ y›
by (auto simp: WW'_def WW_seg_def subset_iff)
then show "f{x,y} = 0"
using f_W' by blast
qed
then have fh_eq_0_eqlen: "?fh{x,y} = 0" if "x ∈ WW" "y ∈ WW" "length x = length y" "x≠y" for x y
using ‹bij_betw h WW WW'› that hlen by (simp add: bij_betw_iff_bijections) metis
have m_f_0: "∃x∈[M]⇗2⇖. f x = 0" if "M ⊆ WW" "card M = m" for M
proof -
have "finite M"
using False m that by auto
with not1 [simplified, rule_format, of M] that
have "∃x∈[M]⇗2⇖. f x ≠ Suc 0"
by (simp add: image_subset_iff finite_ordertype_eq_card m)
with that show ?thesis
by (metis PiE f lessThan_iff less_2_cases nsets_mono numeral_2_eq_2 subset_iff)
qed
have m_fh_0: "∃x∈[M]⇗2⇖. ?fh x = 0" if "M ⊆ WW" "card M = m" for M
proof -
have "h ` M ⊆ WW"
using ‹WW' ⊆ WW› ‹bij_betw h WW WW'› bij_betwE that(1) by fastforce
moreover have "card (h ` M) = m"
by (metis ‹bij_betw h WW WW'› bij_betw_def bij_betw_subset card_image that)
ultimately have "∃x ∈ [h ` M]⇗2⇖. f x = 0"
by (metis m_f_0)
then obtain Y where Y: "f (h ` Y) = 0" "Y ⊆ M" and "finite (h ` Y)" "card (h ` Y) = 2"
by (auto simp: nsets_def subset_image_iff)
then have "card Y = 2"
using ‹bij_betw h WW WW'› ‹M ⊆ WW›
by (metis bij_betw_def card_image inj_on_subset)
with Y card.infinite[of Y] show ?thesis
by (auto simp: nsets_def)
qed
obtain N j where "infinite N"
and N: "⋀k u. ⟦k > 0; u ∈ [WW]⇗2⇖; Form k u; [enum N k] < inter_scheme k u; List.set (inter_scheme k u) ⊆ N⟧ ⟹ ?fh u = j k"
using lemma_3_6 [OF fh] by blast
have infN': "infinite (enum N ` {k<..})" for k
by (simp add: ‹infinite N› enum_works finite_image_iff infinite_Ioi strict_mono_imp_inj_on)
have j_0: "j k = 0" if "k>0" for k
proof -
obtain M where M: "M ∈ [WW]⇗m⇖"
and MF: "⋀u. u ∈ [M]⇗2⇖ ⟹ Form k u"
and Mi: "⋀u. u ∈ [M]⇗2⇖ ⟹ List.set (inter_scheme k u) ⊆ enum N ` {k<..}"
using lemma_3_7 [OF infN' ‹k > 0›] by metis
obtain u where u: "u ∈ [M]⇗2⇖" "?fh u = 0"
using m_fh_0 [of M] M [unfolded nsets_def] by force
moreover
have §: "Form k u" "List.set (inter_scheme k u) ⊆ enum N ` {k<..}"
by (simp_all add: MF Mi ‹u ∈ [M]⇗2⇖›)
then have "hd (inter_scheme k u) ∈ enum N ` {k<..}"
using hd_in_set inter_scheme_simple that by blast
then have "[enum N k] < inter_scheme k u"
using strict_mono_enum [OF ‹infinite N›] by (auto simp: less_list_def strict_mono_def)
moreover have "u ∈ [WW]⇗2⇖"
using M u by (auto simp: nsets_def)
moreover have "enum N ` {k<..} ⊆ N"
using ‹infinite N› range_enum by auto
ultimately show ?thesis
using N § that by auto
qed
obtain X where "X ⊆ WW" and otX: "ordertype X (lenlex less_than) = ω↑ω"
and X: "⋀u. u ∈ [X]⇗2⇖ ⟹
∃l. Form l u ∧ (l > 0 ⟶ [enum N l] < inter_scheme l u ∧ List.set (inter_scheme l u) ⊆ N)"
using lemma_3_8 [OF ‹infinite N›] ot' by blast
have 0: "?fh ` [X]⇗2⇖ ⊆ {0}"
proof clarsimp
fix u
assume u: "u ∈ [X]⇗2⇖"
obtain l where "Form l u" and l: "l > 0 ⟶ [enum N l] < inter_scheme l u ∧ List.set (inter_scheme l u) ⊆ N"
using u X by blast
have "?fh u = 0"
proof (cases "l = 0")
case True
then show ?thesis
by (metis Form_0_cases_raw ‹Form l u› ‹X ⊆ WW› doubleton_in_nsets_2 fh_eq_0_eqlen subset_iff u)
next
case False
then obtain "[enum N l] < inter_scheme l u" "List.set (inter_scheme l u) ⊆ N" "j l = 0"
using Nat.neq0_conv j_0 l by blast
with False show ?thesis
using ‹X ⊆ WW› N inter_scheme ‹Form l u› doubleton_in_nsets_2 u by (auto simp: nsets_def)
qed
then show "f (h ` u) = 0"
by auto
qed
show ?P0
proof (intro exI conjI)
show "h ` X ⊆ WW"
using ‹WW' ⊆ WW› ‹X ⊆ WW› ‹bij_betw h WW WW'› bij_betw_imp_surj_on by fastforce
show "ordertype (h ` X) (lenlex less_than) = ω ↑ ω"
proof (subst ordertype_inc_eq)
show "(h x, h y) ∈ lenlex less_than"
if "x ∈ X" "y ∈ X" "(x, y) ∈ lenlex less_than" for x y
using that h ‹X ⊆ WW› by (auto simp: FR_WW FR_WW' iso_iff2 iso_ll_def)
qed (use otX in auto)
show "f ` [h ` X]⇗2⇖ ⊆ {0}"
proof (clarsimp simp: image_subset_iff nsets_def)
fix Y
assume Y: "Y ⊆ h ` X" "finite Y" "card Y = 2"
then have "inv_into WW h ` Y ⊆ X"
by (metis ‹X ⊆ WW› ‹bij_betw h WW WW'› bij_betw_inv_into_LEFT image_mono)
moreover have "finite (inv_into WW h ` Y)"
using ‹finite Y› by blast
moreover have "card (inv_into WW h ` Y) = 2"
using Y by (metis ‹X ⊆ WW› card_image inj_on_inv_into subset_image_iff subset_trans)
ultimately have "f (h ` inv_into WW h ` Y) = 0"
using 0 by (auto simp: image_subset_iff nsets_def)
then show "f Y = 0"
by (metis ‹X ⊆ WW› ‹Y ⊆ h ` X› image_inv_into_cancel image_mono order_trans)
qed
qed
qed
then show "∃i<Suc (Suc 0). ∃H⊆WW. ordertype H ?R = [ω↑ω, α] ! i ∧ f ` [H]⇗2⇖ ⊆ {i}"
by (metis One_nat_def lessI nth_Cons_0 nth_Cons_Suc zero_less_Suc)
qed
qed
text ‹Theorem 3.1 of Jean A. Larson, ibid.›
theorem partition_ωω: "α ∈ elts ω ⟹ partn_lst_VWF (ω↑ω) [ω↑ω,α] 2"
using partn_lst_imp_partn_lst_VWF_eq [OF partition_ωω_aux] ordertype_WW by auto
end