Theory Fair_Stream
section ‹Fair Streams›
theory Fair_Stream imports "HOL-Library.Stream" begin
definition upt_lists :: ‹nat list stream› where
‹upt_lists ≡ smap (upt 0) (stl nats)›
definition fair_nats :: ‹nat stream› where
‹fair_nats ≡ flat upt_lists›
definition fair :: ‹'a stream ⇒ bool› where
‹fair s ≡ ∀x ∈ sset s. ∀m. ∃n ≥ m. s !! n = x›
lemma upt_lists_snth: ‹x ≤ n ⟹ x ∈ set (upt_lists !! n)›
unfolding upt_lists_def by auto
lemma all_ex_upt_lists: ‹∃n ≥ m. x ∈ set (upt_lists !! n)›
using upt_lists_snth by (meson dual_order.strict_trans1 gt_ex nle_le)
lemma upt_lists_ne: ‹∀xs ∈ sset upt_lists. xs ≠ []›
unfolding upt_lists_def by (simp add: sset_range)
lemma sset_flat_stl: ‹sset (flat (stl s)) ⊆ sset (flat s)›
proof (cases s)
case (SCons x xs)
then show ?thesis
by (cases x) (simp add: stl_sset subsetI, auto)
qed
lemma flat_snth_nth:
assumes ‹x = s !! n ! m› ‹m < length (s !! n)› ‹∀xs ∈ sset s. xs ≠ []›
shows ‹∃n' ≥ n. x = flat s !! n'›
using assms
proof (induct n arbitrary: s)
case 0
then show ?case
using flat_snth by fastforce
next
case (Suc n)
have ‹?case = (∃n' ≥ n. x = flat s !! Suc n')›
by (metis Suc_le_D Suc_le_mono)
also have ‹… = (∃n' ≥ n. x = stl (flat s) !! n')›
by simp
finally have ‹?case = (∃n' ≥ n. x = (tl (shd s) @- flat (stl s)) !! n')›
using Suc.prems flat_unfold by (simp add: shd_sset)
then have ?case if ‹∃n' ≥ n. x = flat (stl s) !! n'›
using that by (metis (no_types, opaque_lifting) add.commute add_diff_cancel_left'
dual_order.trans le_add2 shift_snth_ge)
moreover {
have ‹x = stl s !! n ! m› ‹ m < length (stl s !! n)›
using Suc.prems by simp_all
moreover have ‹∀xs ∈ sset (stl s). xs ≠ []›
using Suc.prems by (cases s) simp_all
ultimately have ‹∃n' ≥ n. x = flat (stl s) !! n'›
using Suc.hyps by blast }
ultimately show ?case .
qed
lemma all_ex_fair_nats: ‹∃n ≥ m. fair_nats !! n = x›
proof -
have ‹∃n ≥ m. x ∈ set (upt_lists !! n)›
using all_ex_upt_lists .
then have ‹∃n ≥ m. ∃k < length (upt_lists !! n). upt_lists !! n ! k = x›
by (simp add: in_set_conv_nth)
then obtain n k where ‹m ≤ n› ‹k < length (upt_lists !! n)› ‹upt_lists !! n ! k = x›
by blast
then obtain n' where ‹n ≤ n'› ‹x = flat upt_lists !! n'›
using flat_snth_nth upt_lists_ne by metis
moreover have ‹m ≤ n'›
using ‹m ≤ n› ‹n ≤ n'› by simp
ultimately show ?thesis
unfolding fair_nats_def by blast
qed
lemma fair_surj:
assumes ‹surj f›
shows ‹fair (smap f fair_nats)›
using assms unfolding fair_def by (metis UNIV_I all_ex_fair_nats imageE snth_smap)
definition fair_stream :: ‹(nat ⇒ 'a) ⇒ 'a stream› where
‹fair_stream f ≡ smap f fair_nats›
theorem fair_stream: ‹surj f ⟹ fair (fair_stream f)›
unfolding fair_stream_def using fair_surj .
theorem UNIV_stream: ‹surj f ⟹ sset (fair_stream f) = UNIV›
unfolding fair_stream_def using all_ex_fair_nats by (metis sset_range stream.set_map surjI)
end