Theory Energy_Order
section ‹Vectors of (extended) Naturals as Energies›
theory Energy_Order
imports Main List_Lemmas "HOL-Library.Extended_Nat" Well_Quasi_Orders.Well_Quasi_Orders
begin
text ‹
We consider vectors with entries in the extended naturals as energies and fix a dimension later.
In this theory we introduce the component-wise order on energies (represented as lists of enats)
as well as a minimum and supremum.
›
type_synonym energy = "enat list"
definition energy_leq:: "energy ⇒ energy ⇒ bool" (infix "e≤" 80) where
"energy_leq e e' = ((length e = length e')
∧ (∀i < length e. (e ! i) ≤ (e' ! i)))"
abbreviation energy_l:: "energy ⇒ energy ⇒ bool" (infix "e<" 80) where
"energy_l e e' ≡ e e≤ e' ∧ e ≠ e'"
text‹We now establish that ‹energy_leg› is a partial order.›
interpretation energy_leq: ordering "energy_leq" "energy_l"
proof
fix e e' e''
show "e e≤ e" using energy_leq_def by simp
show "e e≤ e' ⟹ e' e≤ e'' ⟹ e e≤ e''" using energy_leq_def by fastforce
show "e e< e' = e e< e'" by simp
show "e e≤ e' ⟹ e' e≤ e ⟹ e = e'" using energy_leq_def
by (metis (no_types, lifting) nth_equalityI order_antisym_conv)
qed
text‹
We now show that it is well-founded when considering a fixed dimension ‹n›.
For the proof we define the subsequence of a given sequence of energies such that the last entry is
increasing but never equals ‹∞›.›
fun subsequence_index::"(nat ⇒ energy) ⇒ nat ⇒ nat" where
"subsequence_index f 0 = (SOME x. (last (f x) ≠ ∞))" |
"subsequence_index f (Suc n) = (SOME x. (last (f x) ≠ ∞
∧ (subsequence_index f n) < x
∧ (last (f (subsequence_index f n)) ≤ last (f x))))"
lemma energy_leq_wqo:
shows "wqo_on energy_leq {e::energy. length e = n}"
proof
show "transp_on {e. length e = n} (e≤)"
by (metis energy_leq.trans transp_onI)
show "almost_full_on (e≤) {e::energy. length e = n}"
proof(induct n)
case 0
then show ?case
by (smt (verit, del_insts) almost_full_onI energy_leq.refl good_def length_0_conv mem_Collect_eq zero_less_Suc)
next
case (Suc n)
hence allF: "∀f ∈ SEQ {e::energy. length e = n}. (∃i j. i < j ∧ (f i) e≤ (f j))"
unfolding almost_full_on_def good_def by simp
have "{e::energy. length e = Suc n} = {e@[x]|e x::enat. e ∈ {e::energy. length e = n}}"
using length_Suc_conv_rev by auto
show ?case
proof
fix f
show "∀i. f i ∈ {e::energy. length e = Suc n} ⟹ good (e≤) f"
proof-
assume "∀i. f i ∈ {e::energy. length e = Suc n}"
show "good (e≤) f" unfolding good_def proof-
show "∃i j. i < j ∧ f i e≤ f j"
proof(cases "finite {i::nat. (f i) ! n = ∞}")
case True
define upbound where "upbound = Sup {(f i) ! n| i::nat. (f i) ! n ≠ ∞}"
then show ?thesis
proof(cases "upbound = ∞")
case True
have exist: "⋀i. (f i) ! n ≠ ∞ ⟹ ∃j. i < j ∧ (f j) ! n ≠ ∞ ∧ (f i) ! n ≤ (f j) ! n"
proof-
fix i
assume "(f i) ! n ≠ ∞"
have "¬(∃j. i < j ∧ (f j) ! n ≠ ∞ ∧(f i) ! n ≤ (f j) ! n) ⟹ False"
proof-
assume "¬(∃j. i < j ∧ (f j) ! n ≠ ∞ ∧ (f i) ! n ≤ (f j) ! n)"
hence A: "⋀j. i < j ⟹ (f j) ! n = ∞ ∨ (f i) ! n > (f j) ! n" by auto
define max_value where "max_value = Max {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}"
have "⋀k. (f k) ! n ≠ ∞ ⟹(f k) ! n ≤ max_value"
proof-
fix k
assume not_inf: "(f k) ! n ≠ ∞"
show "(f k) ! n ≤ max_value"
proof(cases "k ≤ i")
case True
hence "(f k) ! n ∈ {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}" using not_inf by auto
then show ?thesis using Max_ge ‹(f k) ! n ∈ {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}› max_value_def by auto
next
case False
hence "(f k) ! n < (f i) ! n" using A not_inf
by (meson leI)
have "(f i) ! n ∈ {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}" using ‹(f i) ! n ≠ ∞› by auto
hence "(f i) ! n ≤ max_value" using Max_ge max_value_def by auto
then show ?thesis using ‹(f k) ! n < (f i) ! n› by auto
qed
qed
hence "upbound = max_value" using upbound_def
by (smt (verit) Sup_least True antisym enat_ord_code(3) mem_Collect_eq)
have " (f i)! n ∈ {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}" using ‹(f i) ! n ≠ ∞› by auto
hence notempty: "{(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞} ≠ {}" by auto
have "finite {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}" by simp
hence "max_value ∈ {(f k) ! n| k. k ≤ i ∧ (f k) ! n ≠ ∞}" unfolding max_value_def using Max_in notempty by blast
hence "max_value ≠ ∞" using max_value_def by auto
hence "upbound ≠ ∞" using ‹upbound = max_value› by simp
thus "False" using True by simp
qed
thus "∃j. i < j ∧ (f j) ! n ≠ ∞ ∧(f i) ! n ≤ (f j) ! n"
by blast
qed
define f' where "f' ≡ λi. butlast (f (subsequence_index f i))"
have "f' ∈ SEQ {e::energy. length e = n}"
proof
show "∀i. f' i ∈ {e. length e = n}"
proof
fix i
have "(f (subsequence_index f i)) ∈ {e. length e = Suc n}" using ‹∀i. f i ∈ {e::energy. length e = Suc n}›
by simp
thus "f' i ∈ {e. length e = n}"
using f'_def by auto
qed
qed
hence "(∃i j. i < j ∧ (f' i) e≤ (f' j))"
using allF by simp
from this obtain i j where ij: "i < j ∧ (f' i) e≤ (f' j)" by auto
hence le: "butlast (f (subsequence_index f i)) e≤ butlast (f (subsequence_index f j))" using f'_def by simp
have last: "⋀x. last (f x) = (f x) ! n" using last_len
using ‹∀i. f i ∈ {e. length e = Suc n}› by auto
have "{x. (last (f x) ≠ ∞)} ≠ {}"
proof
assume "{x. last (f x) ≠ ∞} = {}"
hence "⋀x. last (f x) = ∞" by auto
hence "⋀x. (f x) ! n = ∞" using ‹⋀x. last (f x) = (f x) ! n› by auto
thus "False" using ‹finite {i::nat. (f i) ! n = ∞}› by simp
qed
hence subsequence_index_0: "(last (f (subsequence_index f 0)) ≠ ∞)"
using subsequence_index.simps(1)
by (metis (mono_tags, lifting) Collect_empty_eq some_eq_imp)
have subsequence_index_Suc: "⋀m. (last (f (subsequence_index f (Suc m))) ≠ ∞ ∧ (subsequence_index f m) < (subsequence_index f (Suc m)) ∧ (last (f (subsequence_index f m)) ≤ last (f (subsequence_index f (Suc m)))))"
proof-
fix m
have some: "subsequence_index f (Suc m) = (SOME x. last (f x) ≠ ∞ ∧ subsequence_index f m < x ∧ last (f (subsequence_index f m)) ≤ last (f x))" using subsequence_index.simps(2) by auto
show "(last (f (subsequence_index f (Suc m))) ≠ ∞ ∧ (subsequence_index f m) < (subsequence_index f (Suc m)) ∧ (last (f (subsequence_index f m)) ≤ last (f (subsequence_index f (Suc m)))))"
proof(induct m)
case 0
have "{x. last (f x) ≠ ∞ ∧ subsequence_index f 0 < x ∧ last (f (subsequence_index f 0)) ≤ last (f x)} ≠ {}"
unfolding last using subsequence_index_0 exist
by (simp add: last)
then show ?case using some some_eq_ex
by (smt (z3) empty_Collect_eq subsequence_index.simps(2))
next
case (Suc m)
hence "{x. last (f x) ≠ ∞ ∧ subsequence_index f (Suc m) < x ∧ last (f (subsequence_index f (Suc m))) ≤ last (f x)} ≠ {}"
unfolding last using exist by simp
then show ?case using some some_eq_ex
by (smt (z3) empty_Collect_eq subsequence_index.simps(2))
qed
qed
hence "⋀i j. i < j ⟹ subsequence_index f i < subsequence_index f j"
by (simp add: lift_Suc_mono_less)
hence "subsequence_index f i < subsequence_index f j" using ‹i < j ∧ (f' i) e≤ (f' j)› by simp
have "⋀i j. i < j ⟹ last (f (subsequence_index f i)) ≤ last (f (subsequence_index f j))"
proof-
fix i j
show "i < j ⟹ last (f (subsequence_index f i)) ≤ last (f (subsequence_index f j))"
proof-
assume "i < j"
show "last (f (subsequence_index f i)) ≤ last (f (subsequence_index f j))" using ‹i < j›
proof(induct "j-i" arbitrary: i j)
case 0
then show ?case by simp
next
case (Suc x)
then show ?case
proof(cases "x = 0")
case True
hence "j = Suc i" using Suc
by (simp add: Nat.lessE Suc_pred diff_diff_cancel)
then show ?thesis using subsequence_index_Suc by simp
next
case False
hence "∃x'. x = Suc x'"
by (simp add: not0_implies_Suc)
then show ?thesis using Suc subsequence_index_Suc
by (smt (verit, ccfv_SIG) Suc_leD diff_Suc_Suc diff_diff_cancel diff_le_self dual_order.strict_trans2 not_less_eq_eq verit_comp_simplify1(3) zero_less_diff)
qed
qed
qed
qed
hence "(f (subsequence_index f i))!n ≤ (f (subsequence_index f j))!n" using ‹i < j ∧ (f' i) e≤ (f' j)› last by simp
have "(f (subsequence_index f i)) e≤ (f (subsequence_index f j))" unfolding energy_leq_def
proof
show "length (f (subsequence_index f i)) = length (f (subsequence_index f j))" using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
show "∀ia<length (f (subsequence_index f i)). f (subsequence_index f i) ! ia ≤ f (subsequence_index f j) ! ia "
proof
fix ia
show "ia < length (f (subsequence_index f i)) ⟶ f (subsequence_index f i) ! ia ≤ f (subsequence_index f j) ! ia"
proof
assume "ia < length (f (subsequence_index f i))"
hence "ia < Suc n" using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
show "f (subsequence_index f i) ! ia ≤ f (subsequence_index f j) ! ia "
proof(cases "ia < n")
case True
hence "f (subsequence_index f i) ! ia = (butlast (f (subsequence_index f i))) ! ia" using nth_butlast ‹ia < length (f (subsequence_index f i))› ‹∀i. f i ∈ {e::energy. length e = Suc n}›
by (metis (mono_tags, lifting) SEQ_iff ‹f' ∈ SEQ {e. length e = n}› f'_def mem_Collect_eq)
also have "... ≤ (butlast (f (subsequence_index f j))) ! ia" using le unfolding energy_leq_def using True ‹f' ∈ SEQ {e. length e = n}› f'_def by simp
also have "... = f (subsequence_index f j) ! ia" using True nth_butlast ‹ia < length (f (subsequence_index f i))› ‹∀i. f i ∈ {e::energy. length e = Suc n}›
by (metis (mono_tags, lifting) SEQ_iff ‹f' ∈ SEQ {e. length e = n}› f'_def mem_Collect_eq)
finally show ?thesis .
next
case False
hence "ia = n" using ‹ia < Suc n› by simp
then show ?thesis using ‹(f (subsequence_index f i))!n ≤ (f (subsequence_index f j))!n› by simp
qed
qed
qed
qed
then show ?thesis using ‹subsequence_index f i < subsequence_index f j› by auto
next
case False
hence "∃upbound_nat. upbound = enat upbound_nat" by simp
from this obtain upbound_nat where "upbound = enat upbound_nat" by auto
have "¬(∃x. infinite {i::nat. (f i) ! n = x}) ⟹ False "
proof-
assume "¬(∃x. infinite {i::nat. (f i) ! n = x})"
hence allfinite: "⋀x. x ≤ upbound ⟹ finite {i::nat. (f i) ! n = x}" by auto
have "⋀k. k ≠ ∞ ⟹ finite {n::enat. n ≤ k}"
by (metis finite_enat_bounded mem_Collect_eq not_enat_eq)
hence "finite ({x. x ≤ upbound} ∪ {∞}) " using False by simp
hence "finite {{i::nat. (f i) ! n = x}| x. x ≤ upbound ∨ x = ∞}" by simp
hence union_finite: "finite (⋃ {{i::nat. (f i) ! n = x}| x. x ≤ upbound ∨ x = ∞})" using finite_Union allfinite True by auto
have "{i::nat. True} = (⋃ {{i::nat. (f i) ! n = x}| x. x ≤ upbound ∨ x = ∞})"
proof
show "{i. True} ⊆ ⋃ {{i. f i ! n = x} |x. x ≤ upbound ∨ x = ∞}"
proof
fix x
show "x ∈ {i. True} ⟹ x ∈ ⋃ {{i. f i ! n = x} |x. x ≤ upbound ∨ x = ∞}"
proof-
assume "x ∈ {i. True}"
hence "x ∈ {i. f i ! n = f x ! n}" by simp
show "x ∈ ⋃ {{i. f i ! n = x} |x. x ≤ upbound ∨ x = ∞}"
proof(cases "f x ! n = ∞")
case True
thus "x ∈ ⋃ {{i. f i ! n = x} |x. x ≤ upbound ∨ x = ∞}" using ‹x ∈ {i. f i ! n = f x ! n}›
by auto
next
case False
hence "f x ! n ≤ upbound" using upbound_def
by (metis (mono_tags, lifting) Sup_upper mem_Collect_eq)
thus "x ∈ ⋃ {{i. f i ! n = x} |x. x ≤ upbound ∨ x = ∞}" using ‹x ∈ {i. f i ! n = f x ! n}›
by auto
qed
qed
qed
show "⋃ {{i. f i ! n = x} |x. x ≤ upbound ∨ x = ∞} ⊆ {i. True}" by simp
qed
thus "False" using union_finite by simp
qed
hence "∃x. infinite {i::nat. (f i) ! n = x}" by auto
from this obtain x where inf_x: "infinite {i::nat. (f i) ! n = x}" by auto
define f' where "f' ≡ λi. butlast (f (enumerate {i::nat. (f i) ! n = x} i))"
have "∀i. f' i ∈ {e. length e = n}"
proof
fix i
have "f (enumerate {i::nat. (f i) ! n = x} i) ∈ {e. length e = Suc n}" using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
hence "length (f (enumerate {i::nat. (f i) ! n = x} i)) = Suc n" by simp
hence "length (butlast (f (enumerate {i::nat. (f i) ! n = x} i))) = n" using length_butlast
by simp
hence "butlast (f (enumerate {i::nat. (f i) ! n = x} i)) ∈ {e. length e = n}" by simp
thus "f' i ∈ {e. length e = n}" using f'_def by simp
qed
hence "f' ∈ SEQ {e::energy. length e = n}"
unfolding SEQ_def by simp
hence "(∃i j. i < j ∧ (f' i) e≤ (f' j))"
using allF by simp
from this obtain i j where ij: "i < j ∧ (f' i) e≤ (f' j)" by auto
hence le: "(enumerate {i::nat. (f i) ! n = x} i) < (enumerate {i::nat. (f i) ! n = x} j)"
using enumerate_mono inf_x by simp
have "(f (enumerate {i::nat. (f i) ! n = x} i)) e≤ (f (enumerate {i::nat. (f i) ! n = x} j))"
unfolding energy_leq_def
proof
show " length (f (wellorder_class.enumerate {i. f i ! n = x} i)) =
length (f (wellorder_class.enumerate {i. f i ! n = x} j))"
using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
show "∀ia<length (f (wellorder_class.enumerate {i. f i ! n = x} i)).
f (wellorder_class.enumerate {i. f i ! n = x} i) ! ia
≤ f (wellorder_class.enumerate {i. f i ! n = x} j) ! ia "
proof
fix ia
show "ia < length (f (wellorder_class.enumerate {i. f i ! n = x} i)) ⟶
f (wellorder_class.enumerate {i. f i ! n = x} i) ! ia
≤ f (wellorder_class.enumerate {i. f i ! n = x} j) ! ia"
proof
assume "ia < length (f (wellorder_class.enumerate {i. f i ! n = x} i))"
hence "ia < Suc n" using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
show "f (wellorder_class.enumerate {i. f i ! n = x} i) ! ia
≤ f (wellorder_class.enumerate {i. f i ! n = x} j) ! ia"
proof(cases "ia < n")
case True
hence "f (wellorder_class.enumerate {i. f i ! n = x} i) ! ia = (f' i) ! ia" using f'_def
by (smt (verit) SEQ_iff ‹f' ∈ SEQ {e. length e = n}› mem_Collect_eq nth_butlast)
also have "... ≤ (f' j) ! ia" using ij energy_leq_def True ‹f' ∈ SEQ {e. length e = n}›
by simp
also have "... = f (wellorder_class.enumerate {i. f i ! n = x} j) ! ia" using f'_def True
by (smt (verit) SEQ_iff ‹f' ∈ SEQ {e. length e = n}› mem_Collect_eq nth_butlast)
finally show ?thesis .
next
case False
hence "ia = n" using ‹ia < Suc n› by simp
hence "f (wellorder_class.enumerate {i. f i ! n = x} i) ! ia = x"
using enumerate_in_set ‹infinite {i::nat. (f i) ! n = x}›
by auto
hence "f (wellorder_class.enumerate {i. f i ! n = x} i) ! ia = f (wellorder_class.enumerate {i. f i ! n = x} j) ! ia"
using enumerate_in_set ‹infinite {i::nat. (f i) ! n = x}› ‹ia = n›
by force
then show ?thesis by simp
qed
qed
qed
qed
then show ?thesis using le by auto
qed
next
case False
define f' where "f' ≡ λi. butlast (f (enumerate {i::nat. (f i) ! n = ∞} i))"
have "∀i. f' i ∈ {e. length e = n}"
proof
fix i
have "f (enumerate {i::nat. (f i) ! n = ∞} i) ∈ {e. length e = Suc n}" using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
hence "length (f (enumerate {i::nat. (f i) ! n = ∞} i)) = Suc n" by simp
hence "length (butlast (f (enumerate {i::nat. (f i) ! n = ∞} i))) = n" using length_butlast
by simp
hence "butlast (f (enumerate {i::nat. (f i) ! n = ∞} i)) ∈ {e. length e = n}" by simp
thus "f' i ∈ {e. length e = n}" using f'_def by simp
qed
hence "f' ∈ SEQ {e::energy. length e = n}"
unfolding SEQ_def by simp
hence "(∃i j. i < j ∧ (f' i) e≤ (f' j))"
using allF by simp
from this obtain i j where ij: "i < j ∧ (f' i) e≤ (f' j)" by auto
hence le: "(enumerate {i::nat. (f i) ! n = ∞} i) < (enumerate {i::nat. (f i) ! n = ∞} j)"
using enumerate_mono False by simp
have "(f (enumerate {i::nat. (f i) ! n = ∞} i)) e≤ (f (enumerate {i::nat. (f i) ! n = ∞} j))"
unfolding energy_leq_def
proof
show " length (f (wellorder_class.enumerate {i. f i ! n = ∞} i)) =
length (f (wellorder_class.enumerate {i. f i ! n = ∞} j))"
using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
show "∀ia<length (f (wellorder_class.enumerate {i. f i ! n = ∞} i)).
f (wellorder_class.enumerate {i. f i ! n = ∞} i) ! ia
≤ f (wellorder_class.enumerate {i. f i ! n = ∞} j) ! ia "
proof
fix ia
show "ia < length (f (wellorder_class.enumerate {i. f i ! n = ∞} i)) ⟶
f (wellorder_class.enumerate {i. f i ! n = ∞} i) ! ia
≤ f (wellorder_class.enumerate {i. f i ! n = ∞} j) ! ia"
proof
assume "ia < length (f (wellorder_class.enumerate {i. f i ! n = ∞} i))"
hence "ia < Suc n" using ‹∀i. f i ∈ {e::energy. length e = Suc n}› by simp
show "f (wellorder_class.enumerate {i. f i ! n = ∞} i) ! ia
≤ f (wellorder_class.enumerate {i. f i ! n = ∞} j) ! ia"
proof(cases "ia < n")
case True
hence "f (wellorder_class.enumerate {i. f i ! n = ∞} i) ! ia = (f' i) ! ia" using f'_def
by (smt (verit) SEQ_iff ‹f' ∈ SEQ {e. length e = n}› mem_Collect_eq nth_butlast)
also have "... ≤ (f' j) ! ia" using ij energy_leq_def True ‹f' ∈ SEQ {e. length e = n}›
by simp
also have "... = f (wellorder_class.enumerate {i. f i ! n = ∞} j) ! ia" using f'_def True
by (smt (verit) SEQ_iff ‹f' ∈ SEQ {e. length e = n}› mem_Collect_eq nth_butlast)
finally show ?thesis .
next
case False
hence "ia = n" using ‹ia < Suc n› by simp
hence "f (wellorder_class.enumerate {i. f i ! n = ∞} i) ! ia = ∞"
using enumerate_in_set ‹infinite {i::nat. (f i) ! n = ∞}›
by auto
hence "f (wellorder_class.enumerate {i. f i ! n = ∞} i) ! ia = f (wellorder_class.enumerate {i. f i ! n = ∞} j) ! ia"
using enumerate_in_set ‹infinite {i::nat. (f i) ! n = ∞}› ‹ia = n›
by force
then show ?thesis by simp
qed
qed
qed
qed
thus "∃i j. i < j ∧ (f i) e≤ (f j)"using le by auto
qed
qed
qed
qed
qed
qed
text‹\subsection*{Minimum}›
definition energy_Min:: "energy set ⇒ energy set" where
"energy_Min A = {e∈A . ∀e'∈A. e≠e' ⟶ ¬ (e' e≤ e)}"
text‹We now observe that the minimum of a non-empty set is not empty. Further, each element $a \in A$ has a lower bound in ‹energy_Min› $A$.›
lemma energy_Min_not_empty:
assumes "A ≠ {}" and "⋀e. e∈ A ⟹length e = n"
shows "energy_Min A ≠ {}"
using assms proof(induction n arbitrary: A)
case 0
hence "{[]} = A" using assms by auto
hence "[] ∈ energy_Min A" using energy_Min_def by auto
then show ?case by auto
next
case (Suc n)
have "{butlast a |a. a ∈ A} ≠ {}" using Suc(2) by simp
have "⋀a. a ∈ {butlast a |a. a ∈ A} ⟹ length a = n" using Suc(3) by auto
hence "energy_Min {butlast a |a. a ∈ A} ≠ {}" using ‹{butlast a |a. a ∈ A} ≠ {}› Suc(1)
by meson
hence "∃x. x∈ energy_Min {butlast a |a. a ∈ A}" by auto
from this obtain x where "x∈ energy_Min {butlast a |a. a ∈ A}" by auto
hence "x∈ {butlast a |a. a ∈ A}" using energy_Min_def by auto
hence "∃a. a∈ A ∧ x = butlast a" by auto
from this obtain a where "a∈ A ∧ x = butlast a" by auto
have "last a ∈ {x. (butlast a)@[x] ∈ A} "
by (metis Suc.prems(2) Zero_neq_Suc ‹a ∈ A ∧ x = butlast a› append_butlast_last_id list.size(3) mem_Collect_eq)
hence "{x. (butlast a)@[x] ∈ A} ≠ {}" by auto
have "∃B. finite B ∧ B⊆ {x. (butlast a)@[x] ∈ A} ∧ Inf {x. (butlast a)@[x] ∈ A} = Min B"
proof(cases "Inf {x. butlast a @ [x] ∈ A} = ∞")
case True
hence "∞ ∈ {x. (butlast a)@[x] ∈ A}" using ‹{x. (butlast a)@[x] ∈ A} ≠ {}›
by (metis ‹last a ∈ {x. butlast a @ [x] ∈ A}› wellorder_InfI)
hence "finite {∞} ∧ {∞} ⊆{x. (butlast a)@[x] ∈ A} ∧Inf {x. (butlast a)@[x] ∈ A} = Min {∞}"
by (simp add: True)
then show ?thesis by blast
next
case False
hence "∃m. (enat m) ∈ {x. butlast a @ [x] ∈ A}"
by (metis Inf_top_conv(2) Succ_def ‹a ∈ A ∧ x = butlast a› not_infinity_eq top_enat_def)
from this obtain m where "(enat m) ∈ {x. butlast a @ [x] ∈ A}" by auto
hence finite: "finite {x. (butlast a)@[x] ∈ A ∧ x≤ enat m}"
by (metis (no_types, lifting) finite_enat_bounded mem_Collect_eq)
have subset: "{x. (butlast a)@[x] ∈ A ∧ x≤ enat m} ⊆ {x. (butlast a)@[x] ∈ A}" by (simp add: Collect_mono)
have "Inf {x. (butlast a)@[x] ∈ A} = Inf {x. (butlast a)@[x] ∈ A ∧ x≤ enat m}" using ‹(enat m) ∈ {x. butlast a @ [x] ∈ A}›
by (smt (verit) Inf_lower mem_Collect_eq nle_le wellorder_InfI)
hence "Inf {x. (butlast a)@[x] ∈ A} = Min {x. (butlast a)@[x] ∈ A ∧ x≤ enat m}" using ‹(enat m) ∈ {x. butlast a @ [x] ∈ A}›
using finite
by (smt (verit, best) False Inf_enat_def Min_Inf)
hence "finite {x. (butlast a)@[x] ∈ A ∧ x≤ enat m} ∧ {x. (butlast a)@[x] ∈ A ∧ x≤ enat m} ⊆ {x. (butlast a)@[x] ∈ A} ∧ Inf {x. (butlast a)@[x] ∈ A} = Min {x. (butlast a)@[x] ∈ A ∧ x≤ enat m}"
using finite subset by simp
then show ?thesis by blast
qed
from this obtain B where B: "finite B ∧ B⊆ {x. (butlast a)@[x] ∈ A} ∧ Inf {x. (butlast a)@[x] ∈ A} = Min B" by auto
hence "((butlast a)@[Min B])∈ A"
by (metis ‹last a ∈ {x. butlast a @ [x] ∈ A}› mem_Collect_eq wellorder_InfI)
have "∀b ∈ A. ((butlast a)@[Min B])≠b ⟶ ¬ (energy_leq b ((butlast a)@[Min B]))"
proof
fix b
assume "b∈ A"
have "energy_leq b (butlast a @ [Min B]) ⟹ butlast a @ [Min B] = b"
proof-
assume "energy_leq b (butlast a @ [Min B])"
have "energy_leq (butlast b) (butlast a)"
unfolding energy_leq_def proof
show "length (butlast b) = length (butlast a)"
using ‹⋀a. a ∈ {butlast a |a. a ∈ A} ⟹ length a = n› ‹a ∈ A ∧ x = butlast a› ‹b ∈ A› mem_Collect_eq by blast
show "∀i<length (butlast b). butlast b ! i ≤ butlast a ! i"
proof
fix i
show "i < length (butlast b) ⟶ butlast b ! i ≤ butlast a ! i "
proof
assume " i < length (butlast b)"
hence "i <length b"
by (simp add: Suc.prems(2) ‹b ∈ A›)
hence B: "b ! i ≤ (butlast a @ [Min B]) !i" using ‹energy_leq b (butlast a @ [Min B])› energy_leq_def by auto
have "butlast b ! i = b! i" using ‹i < length (butlast b)› nth_butlast by auto
have "butlast a ! i = (butlast a @ [Min B]) !i "
by (metis ‹i < length (butlast b)› ‹length (butlast b) = length (butlast a)› butlast_snoc nth_butlast)
thus "butlast b ! i ≤ butlast a ! i " using B ‹butlast b ! i = b! i› by auto
qed
qed
qed
hence "butlast b = butlast a" using ‹x∈ energy_Min {butlast a |a. a ∈ A}› ‹a∈ A ∧ x = butlast a› energy_Min_def ‹b∈ A› by auto
hence "(butlast a)@[last b] ∈ A" using Suc(3)
by (metis ‹b ∈ A› append_butlast_last_id list.size(3) nat.discI)
hence "Min B ≤ last b"
by (metis (no_types, lifting) B Inf_lower mem_Collect_eq)
have "last b ≤ Min B" using ‹energy_leq b (butlast a @ [Min B])› energy_leq_def
by (metis (no_types, lifting) ‹butlast b = butlast a› append_butlast_last_id butlast.simps(1) dual_order.refl impossible_Cons length_Cons length_append_singleton lessI nth_append_length)
hence "last b = Min B" using ‹Min B ≤ last b› by simp
thus "butlast a @ [Min B] = b" using ‹butlast b = butlast a› Suc(3)
by (metis Zero_not_Suc ‹b ∈ A› append_butlast_last_id list.size(3))
qed
thus "butlast a @ [Min B] ≠ b ⟶ ¬ energy_leq b (butlast a @ [Min B])"
by auto
qed
hence "((butlast a)@[Min B]) ∈ energy_Min A" using energy_Min_def ‹((butlast a)@[Min B])∈ A›
by simp
thus ?case by auto
qed
lemma energy_Min_contains_smaller:
assumes "a ∈ A"
shows "∃b ∈ energy_Min A. b e≤ a"
proof-
define set where "set ≡ {e. e ∈ A ∧ e e≤ a}"
hence "a ∈ set"
by (simp add: assms(1) energy_leq.refl)
hence "set ≠ {}" by auto
have "⋀s. s∈ set ⟹length s = length a" using energy_leq_def set_def
by simp
hence "energy_Min set ≠ {}" using ‹set ≠ {}› energy_Min_not_empty by simp
hence "∃b. b ∈ energy_Min set" by auto
from this obtain b where "b ∈ energy_Min set" by auto
hence "⋀b'. b'∈ A ⟹ b' ≠ b ⟹ ¬ (b' e≤ b)"
proof-
fix b'
assume "b' ∈ A"
assume "b' ≠ b"
show "¬ (b' e≤ b)"
proof
assume "(b' e≤ b)"
hence "b' e≤ a" using ‹b ∈ energy_Min set› energy_Min_def
by (simp add: energy_leq.trans local.set_def)
hence "b' ∈ set" using ‹b' ∈ A› set_def by simp
thus "False" using ‹b ∈ energy_Min set› energy_Min_def ‹b' e≤ b› ‹b' ≠ b› by auto
qed
qed
hence "b∈ energy_Min A" using energy_Min_def
using ‹b ∈ energy_Min set› local.set_def by auto
thus ?thesis using ‹b ∈ energy_Min set› energy_Min_def set_def by auto
qed
text‹We now establish how the minimum relates to subsets.›
lemma energy_Min_subset:
assumes "A ⊆ B"
shows "A ∩ (energy_Min B) ⊆ energy_Min A" and
"energy_Min B ⊆ A ⟹ energy_Min B = energy_Min A"
proof-
show "A ∩ energy_Min B ⊆ energy_Min A"
proof
fix e
assume "e ∈ A ∩ energy_Min B"
hence "∃a ∈ energy_Min A. a e≤ e" using assms energy_Min_contains_smaller by blast
from this obtain a where "a ∈ energy_Min A" and " a e≤ e" by auto
hence "a = e" using ‹e ∈ A ∩ energy_Min B› unfolding energy_Min_def
using assms by auto
thus "e ∈ energy_Min A" using ‹a ∈ energy_Min A› by simp
qed
assume "energy_Min B ⊆ A"
hence "energy_Min B ⊆ energy_Min A" using ‹A ∩ energy_Min B ⊆ energy_Min A› by auto
have "energy_Min A ⊆ energy_Min B"
proof
fix a
assume "a ∈ energy_Min A"
hence "a ∈ B" unfolding energy_Min_def using assms by blast
hence "∃b ∈ energy_Min B. b e≤ a" using assms energy_Min_contains_smaller by blast
from this obtain b where "b ∈ energy_Min B" and "b e≤ a" by auto
hence "a = b" using ‹energy_Min B ⊆ A› energy_Min_def
using ‹a ∈ energy_Min A› by auto
thus "a ∈ energy_Min B"
using ‹b ∈ energy_Min B› by simp
qed
thus "energy_Min B = energy_Min A" using ‹energy_Min B ⊆ energy_Min A› by simp
qed
text‹We now show that by well-foundedness the minimum is a finite set. For the proof we first generalise ‹enumerate›.›
fun enumerate_arbitrary :: "'a set ⇒ nat ⇒ 'a" where
"enumerate_arbitrary A 0 = (SOME a. a ∈ A)" |
"enumerate_arbitrary A (Suc n)
= enumerate_arbitrary (A - {enumerate_arbitrary A 0}) n"
lemma enumerate_arbitrary_in:
shows "infinite A ⟹ enumerate_arbitrary A i ∈ A"
proof(induct i arbitrary: A)
case 0
then show ?case using enumerate_arbitrary.simps finite.simps some_in_eq by auto
next
case (Suc i)
hence "infinite (A - {enumerate_arbitrary A 0})" using infinite_remove by simp
hence "Energy_Order.enumerate_arbitrary (A - {enumerate_arbitrary A 0}) i ∈ (A - {enumerate_arbitrary A 0})" using Suc.hyps by blast
hence "enumerate_arbitrary A (Suc i) ∈ (A - {enumerate_arbitrary A 0})" using enumerate_arbitrary.simps by simp
then show ?case by auto
qed
lemma enumerate_arbitrary_neq:
shows "infinite A ⟹ i < j
⟹ enumerate_arbitrary A i ≠ enumerate_arbitrary A j"
proof(induct i arbitrary: j A)
case 0
then show ?case using enumerate_arbitrary.simps
by (metis Diff_empty Diff_iff enumerate_arbitrary_in finite_Diff_insert gr0_implies_Suc insert_iff)
next
case (Suc i)
hence "∃j'. j = Suc j'"
by (simp add: not0_implies_Suc)
from this obtain j' where "j = Suc j'" by auto
hence "i < j'" using Suc by simp
from Suc have "infinite (A - {enumerate_arbitrary A 0})" using infinite_remove by simp
hence "enumerate_arbitrary (A - {enumerate_arbitrary A 0}) i ≠ enumerate_arbitrary (A - {enumerate_arbitrary A 0}) j'" using Suc ‹i < j'›
by force
then show ?case using enumerate_arbitrary.simps
by (simp add: ‹j = Suc j'›)
qed
lemma energy_Min_finite:
assumes "⋀e. e∈ A ⟹ length e = n"
shows "finite (energy_Min A)"
proof-
have "wqo_on energy_leq (energy_Min A)" using energy_leq_wqo assms
by (smt (verit, del_insts) Collect_mono_iff energy_Min_def wqo_on_subset)
hence wqoMin: "(∀f ∈ SEQ (energy_Min A). (∃i j. i < j ∧ energy_leq (f i) (f j)))" unfolding wqo_on_def almost_full_on_def good_def by simp
have "¬ finite (energy_Min A) ⟹ False"
proof-
assume "¬ finite (energy_Min A)"
hence "infinite (energy_Min A)"
by simp
define f where "f ≡ enumerate_arbitrary (energy_Min A)"
have fneq: "⋀i j. f i ∈ energy_Min A ∧ (j ≠ i ⟶ f j ≠ f i)"
proof
fix i j
show "f i ∈ energy_Min A" unfolding f_def using enumerate_arbitrary_in ‹infinite (energy_Min A)› by auto
show "j ≠ i ⟶ f j ≠ f i" proof
assume "j ≠ i"
show "f j ≠ f i" proof(cases "j < i")
case True
then show ?thesis unfolding f_def using enumerate_arbitrary_neq ‹infinite (energy_Min A)› by auto
next
case False
hence "i < j" using ‹j ≠ i› by auto
then show ?thesis unfolding f_def using enumerate_arbitrary_neq ‹infinite (energy_Min A)›
by metis
qed
qed
qed
hence "∃i j. i < j ∧ energy_leq (f i) (f j)" using wqoMin SEQ_def by simp
thus "False" using energy_Min_def fneq by force
qed
thus ?thesis by auto
qed
text‹\subsection*{Supremum}›
definition energy_sup :: "nat ⇒ energy set ⇒ energy" where
"energy_sup n A = map (λi. Sup {(e!i)|e. e ∈ A}) [0..<n]"
text‹We now show that we indeed defined a supremum, i.e.\ a least upper bound, when considering a fixed dimension ‹n›.›
lemma energy_sup_is_sup:
shows energy_sup_in: "⋀a. a ∈ A ⟹ length a = n ⟹ a e≤ (energy_sup n A)" and
energy_sup_leq: "⋀s. (⋀a. a∈ A ⟹a e≤ s) ⟹ length s = n
⟹ (energy_sup n A) e≤ s"
proof-
fix a
assume A1: "a ∈ A" and A2: "length a = n"
show "a e≤ (energy_sup n A)"
unfolding energy_leq_def energy_sup_def
proof
show "length a = length (map (λi. Sup {(v!i)|v. v ∈ A}) [0..<n])" using A2
by simp
show "∀i<length a. a ! i ≤ map (λi. Sup {(v!i)|v. v ∈ A}) [0..<n] ! i "
proof
fix i
show "i < length a ⟶ a ! i ≤ map (λi. Sup {(v!i)|v. v ∈ A}) [0..<n] ! i "
proof
assume "i < length a"
thus "a ! i ≤ map (λi. Sup {(v!i)|v. v ∈ A}) [0..<n] ! i " using A1 A2
by (smt (verit, del_insts) Sup_upper diff_add_inverse length_upt mem_Collect_eq minus_nat.diff_0 nth_map nth_upt)
qed
qed
qed
next
fix x
assume A1: "⋀a. a∈ A ⟹a e≤ x" and A2: "length x = n"
show "(energy_sup n A) e≤ x"
unfolding energy_leq_def
proof
show L: "length (energy_sup n A) = length x" using A2 energy_sup_def by simp
show "∀i<length (energy_sup n A). energy_sup n A ! i ≤ x ! i "
proof
fix i
show "i < length (energy_sup n A) ⟶ energy_sup n A ! i ≤ x ! i "
proof
assume "i < length (energy_sup n A)"
hence "i < length [0..<n]" using L A2 by simp
from A1 have "⋀a. a∈{v ! i |v. v ∈ A} ⟹ a ≤ x ! i"
proof-
fix a
assume "a∈{v ! i |v. v ∈ A} "
hence "∃v∈A. a = v ! i" by auto
from this obtain v where "v∈ A" and "a=v !i" by auto
thus " a ≤ x ! i" using A1 energy_leq_def L ‹i < length (energy_sup n A)› by simp
qed
have "(energy_sup n A) ! i = (map (λi. Sup {(v!i)|v. v ∈ A}) [0..<n] ! i) " using energy_sup_def by auto
also have "... = (λi. Sup {(v!i)|v. v ∈ A}) ([0..<n] ! i)" using nth_map ‹i < length [0..<n]›
by auto
also have "... = Sup {v ! i |v. v ∈ A}"
using ‹i < length [0..<n]› by auto
also have "...≤ (x ! i) " using ‹⋀a. a∈{v ! i |v. v ∈ A} ⟹ a ≤ x ! i›
by (meson Sup_least)
finally show "energy_sup n A ! i ≤ x ! i " .
qed
qed
qed
qed
text‹We now observe a version of monotonicity. Afterwards we show that the supremum of the empty set is the zero-vector.›
lemma energy_sup_leq_energy_sup:
assumes "A ≠ {}" and "⋀a. a∈ A ⟹ ∃b∈ B. energy_leq a b" and
"⋀a. a∈ A ⟹ length a = n"
shows "energy_leq (energy_sup n A) (energy_sup n B)"
proof-
have len: "length (energy_sup n B) = n" using energy_sup_def by simp
have "⋀a. a∈ A ⟹ energy_leq a (energy_sup n B)"
proof-
fix a
assume "a∈ A"
hence "∃b∈ B. energy_leq a b" using assms by simp
from this obtain b where "b ∈ B" and "energy_leq a b" by auto
hence "energy_leq b (energy_sup n B)" using energy_sup_in energy_leq_def
by (simp add: ‹a ∈ A› assms(3))
thus "energy_leq a (energy_sup n B)" using ‹energy_leq a b› energy_leq.trans by blast
qed
thus ?thesis using len energy_sup_leq by blast
qed
lemma empty_Sup_is_zero:
assumes "i < n"
shows "(energy_sup n {}) ! i = 0"
proof-
have "(energy_sup n {}) ! i = (map (λi. Sup {(v!i)|v. v ∈ {}}) [0..<n]) ! i"
using energy_sup_def by auto
also have "... = (λi. Sup {(v!i)|v. v ∈ {}}) ([0..<n] ! i)" using nth_map assms by simp
finally show "(energy_sup n {}) ! i = 0"
by (simp add: bot_enat_def)
qed
end