Theory Lazy_List_Limsup
section ‹Limsup of Lazy Lists›
theory Lazy_List_Limsup
imports Coinductive.Coinductive_List
begin
subsection ‹Library›
lemma less_llength_ltake: "i < llength (ltake k Xs) ⟷ i < k ∧ i < llength Xs"
by simp
subsection ‹Infimum›
definition Inf_llist :: ‹'a set llist ⇒ 'a set› where
‹Inf_llist Xs = (⋂i ∈ {i. enat i < llength Xs}. lnth Xs i)›
lemma Inf_llist_subset_lnth: ‹enat i < llength Xs ⟹ Inf_llist Xs ⊆ lnth Xs i›
unfolding Inf_llist_def by fast
lemma Inf_llist_imp_exists_index:
assumes ‹¬ lnull Xs›
shows ‹x ∈ Inf_llist Xs ⟹ ∃i. enat i < llength Xs ∧ x ∈ lnth Xs i›
unfolding Inf_llist_def using assms
by (metis INT_E i0_less llength_eq_0 mem_Collect_eq zero_enat_def)
lemma Inf_llist_imp_all_index: ‹x ∈ Inf_llist Xs ⟹ ∀i. enat i < llength Xs ⟶ x ∈ lnth Xs i›
unfolding Inf_llist_def by blast
lemma all_index_imp_Inf_llist: ‹∀i. enat i < llength Xs ⟶ x ∈ lnth Xs i ⟹ x ∈ Inf_llist Xs›
unfolding Inf_llist_def by auto
lemma Inf_llist_LNil[simp]: ‹Inf_llist LNil = UNIV›
unfolding Inf_llist_def by auto
lemma Inf_llist_LCons[simp]: ‹Inf_llist (LCons X Xs) = X ∩ Inf_llist Xs›
unfolding Inf_llist_def
proof (intro subset_antisym subsetI)
fix x
assume ‹x ∈ (⋂i ∈ {i. enat i < llength (LCons X Xs)}. lnth (LCons X Xs) i)›
then have ‹enat i < llength (LCons X Xs) ⟶ x ∈ lnth (LCons X Xs) i› for i
by blast
then have ‹x ∈ X ∧ (∀i. enat i < llength Xs ⟶ x ∈ lnth Xs i)›
by (metis Suc_ile_eq iless_Suc_eq llength_LCons lnth_0 lnth_Suc_LCons zero_enat_def zero_le)
then show ‹x ∈ X ∩ (⋂i ∈ {i. enat i < llength Xs}. lnth Xs i)›
by blast
next
fix x
assume ‹x ∈ X ∩ ⋂ (lnth Xs ` {i. enat i < llength Xs})›
then have ‹x ∈ X ∧ (∀i. enat i < llength Xs ⟶ x ∈ lnth Xs i)›
by simp
then have ‹∀i. enat i ≤ llength Xs ⟶ x ∈ lnth (LCons X Xs) i›
by (metis Suc_diff_1 Suc_ile_eq lnth_0 lnth_Suc_LCons neq0_conv)
then show ‹x ∈ ⋂ (lnth (LCons X Xs) ` {i. enat i < llength (LCons X Xs)})›
by simp
qed
lemma lhd_subset_Inf_llist: ‹¬ lnull Xs ⟹ Inf_llist Xs ⊆ lhd Xs›
by (cases Xs) simp_all
subsection ‹Infimum up-to›
definition Inf_upto_llist :: ‹'a set llist ⇒ enat ⇒ 'a set› where
‹Inf_upto_llist Xs j = (⋂i ∈ {i. enat i < llength Xs ∧ enat i ≤ j}. lnth Xs i)›
lemma Inf_upto_llist_eq_Inf_llist_ltake: ‹Inf_upto_llist Xs j = Inf_llist (ltake (eSuc j) Xs)›
unfolding Inf_upto_llist_def Inf_llist_def
by (smt (verit, best) Collect_cong Sup.SUP_cong iless_Suc_eq less_llength_ltake lnth_ltake
mem_Collect_eq)
lemma Inf_upto_llist_enat_0[simp]:
‹Inf_upto_llist Xs (enat 0) = (if lnull Xs then UNIV else lhd Xs)›
unfolding Inf_upto_llist_def image_def
by (cases ‹lnull Xs›) (auto simp: lhd_conv_lnth enat_0 enat_0_iff)
lemma Inf_upto_llist_Suc[simp]:
‹Inf_upto_llist Xs (enat (Suc j)) =
Inf_upto_llist Xs (enat j) ∩ (if enat (Suc j) < llength Xs then lnth Xs (Suc j) else UNIV)›
unfolding Inf_upto_llist_def image_def by (auto intro: le_SucI elim: le_SucE)
lemma Inf_upto_llist_infinity[simp]: ‹Inf_upto_llist Xs ∞ = Inf_llist Xs›
unfolding Inf_upto_llist_def Inf_llist_def by simp
lemma Inf_upto_llist_0[simp]: ‹Inf_upto_llist Xs 0 = (if lnull Xs then UNIV else lhd Xs)›
unfolding zero_enat_def by (rule Inf_upto_llist_enat_0)
lemma Inf_upto_llist_eSuc[simp]:
‹Inf_upto_llist Xs (eSuc j) =
(case j of
enat k ⇒ Inf_upto_llist Xs (enat (Suc k))
| ∞ ⇒ Inf_llist Xs)›
by (auto simp: eSuc_enat split: enat.split)
lemma Inf_upto_llist_anti[simp]: ‹j ≤ k ⟹ Inf_upto_llist Xs k ⊆ Inf_upto_llist Xs j›
unfolding Inf_upto_llist_def by auto
lemma Inf_llist_subset_Inf_upto_llist: ‹Inf_llist Xs ⊆ Inf_upto_llist Xs j›
unfolding Inf_llist_def Inf_upto_llist_def by auto
lemma elem_Inf_llist_imp_Inf_upto_llist:
‹x ∈ Inf_llist Xs ⟹ x ∈ Inf_upto_llist Xs (enat j)›
unfolding Inf_llist_def Inf_upto_llist_def by blast
lemma Inf_upto_llist_subset_lnth: ‹j < llength Xs ⟹ Inf_upto_llist Xs j ⊆ lnth Xs j›
unfolding Inf_upto_llist_def by auto
lemma Inf_llist_imp_Inf_upto_llist:
assumes ‹X ⊆ Inf_llist Xs›
shows ‹X ⊆ Inf_upto_llist Xs (enat k)›
using assms elem_Inf_llist_imp_Inf_upto_llist by fast
subsection ‹Limsup›
definition Limsup_llist :: ‹'a set llist ⇒ 'a set› where
‹Limsup_llist Xs =
(⋂i ∈ {i. enat i < llength Xs}. ⋃j ∈ {j. i ≤ j ∧ enat j < llength Xs}. lnth Xs j)›
lemma Limsup_llist_LNil[simp]: ‹Limsup_llist LNil = UNIV›
unfolding Limsup_llist_def by simp
lemma Limsup_llist_LCons:
‹Limsup_llist (LCons X Xs) = (if lnull Xs then X else Limsup_llist Xs)› (is ‹?lhs = ?rhs›)
proof (cases "lnull Xs")
case nnull: False
show ?thesis
proof
{
fix x
assume ‹∀i. enat i ≤ llength Xs ⟶ (∃j ≥ i. enat j ≤ llength Xs ∧ x ∈ lnth (LCons X Xs) j)›
then have ‹∀i. enat i < llength Xs ⟶ (∃j ≥ i. enat j < llength Xs ∧ x ∈ lnth Xs j)›
by (metis Suc_ile_eq Suc_le_D Suc_le_mono lnth_Suc_LCons)
}
then show ‹?lhs ⊆ ?rhs›
by (auto simp: Limsup_llist_def nnull)
{
fix x
assume ‹∀i. enat i < llength Xs ⟶ (∃j ≥ i. enat j < llength Xs ∧ x ∈ lnth Xs j)›
then have ‹∀i. enat i ≤ llength Xs ⟶
(∃j ≥ i. enat j ≤ llength Xs ∧ x ∈ lnth (LCons X Xs) j)›
by (metis Suc_ile_eq Suc_le_D iless_Suc_eq llength_LCons lnth_Suc_LCons nat_le_linear
nnull not_less_eq_eq not_lnull_conv zero_enat_def zero_le)
}
then show "?rhs ⊆ ?lhs"
by (auto simp: Limsup_llist_def nnull)
qed
qed (simp add: Limsup_llist_def enat_0_iff(1))
lemma lfinite_Limsup_llist: ‹lfinite Xs ⟹ Limsup_llist Xs = (if lnull Xs then UNIV else llast Xs)›
proof (induction rule: lfinite_induct)
case (LCons xs)
then obtain y ys where xs: ‹xs = LCons y ys›
by (meson not_lnull_conv)
show ?case
unfolding xs by (simp add: Limsup_llist_LCons LCons.IH[unfolded xs, simplified] llast_LCons)
qed (simp add: Limsup_llist_def)
lemma Limsup_llist_ltl: ‹¬ lnull (ltl Xs) ⟹ Limsup_llist Xs = Limsup_llist (ltl Xs)›
by (metis Limsup_llist_LCons lhd_LCons_ltl lnull_ltlI)
lemma Inf_llist_subset_Limsup_llist: ‹Inf_llist Xs ⊆ Limsup_llist Xs›
unfolding Limsup_llist_def Inf_llist_def by fast
lemma image_Limsup_llist_subset: ‹f ` Limsup_llist Ns ⊆ Limsup_llist (lmap ((`) f) Ns)›
unfolding Limsup_llist_def by fastforce
lemma Limsup_llist_imp_exists_index:
assumes ‹¬ lnull Xs›
shows ‹x ∈ Limsup_llist Xs ⟹ ∃i. enat i < llength Xs ∧ x ∈ lnth Xs i›
unfolding Limsup_llist_def using assms
by simp (metis i0_less llength_eq_0 zero_enat_def)
lemma finite_subset_Limsup_llist_imp_exists_index:
assumes
nnil: ‹¬ lnull Xs› and
fin: ‹finite X› and
in_sup: ‹X ⊆ Limsup_llist Xs›
shows ‹∀i. enat i < llength Xs ⟶ X ⊆ (⋃j ∈ {j. i ≤ j ∧ enat j < llength Xs}. lnth Xs j)›
using assms unfolding Limsup_llist_def by blast
lemma Limsup_llist_lmap_image:
assumes f_inj: ‹inj_on f (Inf_llist (lmap g xs))›
shows ‹Limsup_llist (lmap (λx. f ` g x) xs) = f ` Limsup_llist (lmap g xs)› (is ‹?lhs = ?rhs›)
oops
lemma Limsup_llist_lmap_union:
assumes ‹∀x ∈ lset xs. ∀y ∈ lset xs. g x ∩ h y = {}›
shows ‹Limsup_llist (lmap (λx. g x ∪ h x) xs) =
Limsup_llist (lmap g xs) ∪ Limsup_llist (lmap h xs)› (is ‹?lhs = ?rhs›)
proof (intro equalityI subsetI)
fix x
assume x_in: ‹x ∈ ?lhs›
then have ‹∀i. enat i < llength xs ⟶ (∃j ≥ i. enat j < llength xs ∧
(x ∈ g (lnth xs j) ∨ x ∈ h (lnth xs j)))›
unfolding Limsup_llist_def by auto
then have ‹(∀i'. enat i' < llength xs ⟶ (∃j ≥ i'. enat j < llength xs ∧ x ∈ g (lnth xs j)))
∨ (∀i'. enat i' < llength xs ⟶ (∃j ≥ i'. enat j < llength xs ∧ x ∈ h (lnth xs j)))›
using assms[unfolded disjoint_iff_not_equal] by (metis in_lset_conv_lnth)
then show ‹x ∈ ?rhs›
unfolding Limsup_llist_def by simp
next
fix x
show ‹x ∈ ?rhs ⟹ x ∈ ?lhs›
using assms unfolding Limsup_llist_def by auto
qed
lemma Limsup_set_filter_commute:
assumes ‹¬ lnull Xs›
shows ‹Limsup_llist (lmap (λX. {x ∈ X. p x}) Xs) = {x ∈ Limsup_llist Xs. p x}› (is ‹?lhs = ?rhs›)
proof (intro equalityI subsetI)
fix x
assume ‹x ∈ ?lhs›
then show ‹x ∈ ?rhs›
unfolding Limsup_llist_def
by simp (metis assms i0_less llength_eq_0 zero_enat_def)
qed (simp add: Limsup_llist_def)
subsection ‹Limsup up-to›
definition Limsup_upto_llist :: ‹'a set llist ⇒ enat ⇒ 'a set› where
‹Limsup_upto_llist Xs k =
(⋂i ∈ {i. enat i < llength Xs ∧ enat i ≤ k}.
⋃j ∈ {j. i ≤ j ∧ enat j < llength Xs ∧ enat j ≤ k}. lnth Xs j)›
lemma Limsup_upto_llist_eq_Limsup_llist_ltake:
‹Limsup_upto_llist Xs j = Limsup_llist (ltake (eSuc j) Xs)›
unfolding Limsup_upto_llist_def Limsup_llist_def
by (smt Collect_cong Sup.SUP_cong iless_Suc_eq lnth_ltake less_llength_ltake mem_Collect_eq)
lemma Limsup_upto_llist_enat[simp]:
‹Limsup_upto_llist Xs (enat k) =
(if enat k < llength Xs then lnth Xs k else if lnull Xs then UNIV else llast Xs)›
proof (cases ‹enat k < llength Xs›)
case True
then show ?thesis
unfolding Limsup_upto_llist_def by force
next
case k_ge: False
show ?thesis
proof (cases ‹lnull Xs›)
case nil: True
then show ?thesis
unfolding Limsup_upto_llist_def by simp
next
case nnil: False
then obtain j where
j: ‹eSuc (enat j) = llength Xs›
using k_ge by (metis eSuc_enat_iff enat_ile le_less_linear lhd_LCons_ltl llength_LCons)
have fin: ‹lfinite Xs›
using k_ge not_lfinite_llength by fastforce
have le_k: ‹enat i < llength Xs ∧ i ≤ k ⟷ enat i < llength Xs› for i
using k_ge linear order_le_less_subst2 by fastforce
have ‹Limsup_upto_llist Xs (enat k) = llast Xs›
using j nnil lfinite_Limsup_llist[OF fin] nnil
unfolding Limsup_upto_llist_def Limsup_llist_def using llast_conv_lnth[OF j[symmetric]]
by (simp add: le_k)
then show ?thesis
using k_ge nnil by simp
qed
qed
lemma Limsup_upto_llist_infinity[simp]: ‹Limsup_upto_llist Xs ∞ = Limsup_llist Xs›
unfolding Limsup_upto_llist_def Limsup_llist_def by simp
lemma Limsup_upto_llist_0[simp]:
‹Limsup_upto_llist Xs 0 = (if lnull Xs then UNIV else lhd Xs)›
unfolding Limsup_upto_llist_def image_def
by (simp add: enat_0[symmetric]) (simp add: enat_0 lnth_0_conv_lhd)
lemma Limsup_upto_llist_eSuc[simp]:
‹Limsup_upto_llist Xs (eSuc j) =
(case j of
enat k ⇒ Limsup_upto_llist Xs (enat (Suc k))
| ∞ ⇒ Limsup_llist Xs)›
by (auto simp: eSuc_enat split: enat.split)
lemma Liminf_upto_llist_imp_elem_Limsup_llist:
assumes ‹∃i < llength Xs. ∀j ≥ i. j < llength Xs ⟶ x ∈ Limsup_upto_llist Xs (enat j)›
shows ‹x ∈ Limsup_llist Xs›
using assms by (simp add: Limsup_llist_def Limsup_upto_llist_def)
(metis dual_order.strict_implies_order enat_iless enat_less_imp_le enat_ord_simps(1) not_less)
end