Theory FAE_Sequence
theory FAE_Sequence
imports "HOL-Library.Confluent_Quotient"
begin
type_synonym 'a seq = "nat ⇒ 'a"
abbreviation finite_range :: "('a ⇒ 'b) ⇒ bool" where "finite_range f ≡ finite (range f)"
lemma finite_range_pair:
assumes 1: "finite_range (λx. fst (f x))" and 2: "finite_range (λx. snd (f x))"
shows "finite_range f"
proof -
have "range f ⊆ range (λx. fst (f x)) × range (λx. snd (f x))"
by(auto 4 3 intro: rev_image_eqI dest: sym)
then show ?thesis by(rule finite_subset)(use assms in simp)
qed
definition seq_at :: "'a seq ⇒ 'a ⇒ nat set" where "seq_at f x = f -` {x}"
typedef 'a fseq = "{f :: 'a seq. finite_range f}" morphisms ap_fseq Abs_fseq
by(rule exI[where x="λ_. undefined"]) simp
setup_lifting type_definition_fseq
lift_bnf 'a fseq [wits: "λx. (λ_ :: nat. x)"]
subgoal by(metis finite_imageI fun.set_map mem_Collect_eq)
subgoal by(auto intro: finite_range_pair)
subgoal by auto
subgoal by auto
done
lemma ap_map_fseq [simp]: "ap_fseq (map_fseq f x) = f ∘ ap_fseq x"
by transfer simp
lift_definition fseq_eq :: "'a fseq ⇒ 'a fseq ⇒ bool" is "λf g. finite {n. f n ≠ g n}" .
lemma fseq_eq_unfold: "fseq_eq f g ⟷ finite {n. ap_fseq f n ≠ ap_fseq g n}"
by transfer simp
lemma reflp_fseq_eq [simp]: "reflp fseq_eq"
by(rule reflpI)(simp add: fseq_eq_unfold)
lemma symp_fseq_eq [simp]: "symp fseq_eq"
by(rule sympI)(simp add: fseq_eq_unfold eq_commute)
lemma transp_fseq_eq [simp]: "transp fseq_eq"
apply(rule transpI)
subgoal for f g h unfolding fseq_eq_unfold
by(rule finite_subset[where B="{n. ap_fseq f n ≠ ap_fseq g n} ∪ {n. ap_fseq g n ≠ ap_fseq h n}"]) auto
done
lemma equivp_fseq_eq [simp]: "equivp fseq_eq"
by(simp add: equivp_reflp_symp_transp)
functor map_fseq
by(simp_all add: fseq.map_id0 fseq.map_comp fun_eq_iff)
quotient_type 'a fae_seq = "'a fseq" / fseq_eq by simp
lemma map_fseq_eq: "fseq_eq f g ⟹ fseq_eq (map_fseq h f) (map_fseq h g)"
unfolding fseq_eq_unfold by(auto elim!: finite_subset[rotated])
lemma finite_set_fseq [simp]: "finite (set_fseq x)"
by transfer
interpretation wide_intersection_fseq: wide_intersection_finite fseq_eq map_fseq set_fseq
by unfold_locales(simp_all add: map_fseq_eq fseq.map_id[unfolded id_def] fseq.set_map cong: fseq.map_cong)
lemma fseq_subdistributivity:
assumes "A OO B ≠ bot"
shows "rel_fseq A OO fseq_eq OO rel_fseq B ≤ fseq_eq OO rel_fseq (A OO B) OO fseq_eq"
proof(rule predicate2I; elim relcomppE; transfer fixing: A B)
fix f and g g' :: "'c seq" and h
assume fg: "rel_fun(=) A f g" and gg': "finite {n. g n ≠ g' n}" and g'h: "rel_fun (=) B g' h"
and f: "finite_range f" and g: "finite_range g" and g': "finite_range g'" and h: "finite_range h"
from assms obtain a c b where ac: "A a c" and cb: "B c b" by(auto simp add: fun_eq_iff)
let ?X = "{n. g n ≠ g' n}"
let ?f = "λn. if n ∈ ?X then a else f n"
let ?h = "λn. if n ∈ ?X then b else h n"
have "range ?f ⊆ insert a (range f)" by auto
then have "finite_range ?f" by(rule finite_subset)(simp add: f)
moreover have "range ?h ⊆ insert b (range h)" by auto
then have "finite_range ?h" by(rule finite_subset)(simp add: h)
moreover have "{n. f n ≠ ?f n} ⊆ ?X" by auto
then have "finite {n. f n ≠ ?f n}" by(rule finite_subset)(simp add: gg')
moreover have "{n. ?h n ≠ h n} ⊆ ?X" by auto
then have "finite {n. ?h n ≠ h n}" by(rule finite_subset)(simp add: gg')
moreover have "rel_fun (=) (A OO B) ?f ?h" using fg g'h ac cb by(auto simp add: rel_fun_def)
ultimately
show "∃ya∈{f. finite_range f}. finite {n. f n ≠ ya n} ∧ (∃yb∈{f. finite_range f}. rel_fun (=) (A OO B) ya yb ∧ finite {n. yb n ≠ h n})"
unfolding mem_Collect_eq Bex_def by blast
qed
lift_bnf 'a fae_seq
subgoal by(rule fseq_subdistributivity)
subgoal by(rule wide_intersection_fseq.wide_intersection)
done
lift_definition fseq_at :: "'a fseq ⇒ 'a ⇒ nat set" is seq_at .
lemma fae_vimage_singleton: "finite (f -` {x}) ⟷ finite (g -` {x})" if "finite {n. f n ≠ g n}"
proof
assume *: "finite (g -` {x})"
have "f -` {x} ⊆ g -` {x} ∪ {n. f n ≠ g n}" by auto
thus "finite (f -` {x})" by(rule finite_subset)(use that * in auto)
next
assume *: "finite (f -` {x})"
have "g -` {x} ⊆ f -` {x} ∪ {n. f n ≠ g n}" by auto
thus "finite (g -` {x})" by(rule finite_subset)(use that * in auto)
qed
lift_definition set_fae_seq_alt :: "'a fae_seq ⇒ 'a set" is "λf. {a. infinite (fseq_at f a)}"
by(transfer)(clarsimp simp add: set_eq_iff seq_at_def fae_vimage_singleton)
lemma fseq_at_infinite_Inr:
"⟦infinite (fseq_at f x); fseq_eq (map_fseq Inr f) g⟧ ⟹ ∃x'∈set_fseq g. x ∈ Basic_BNFs.setr x'"
apply transfer
apply (auto simp add: seq_at_def vimage_def)
apply (smt (verit, ccfv_SIG) finite_subset mem_Collect_eq setr.simps subsetI)
done
lemma fseq_at_Inr_infinite:
assumes "⋀g. fseq_eq (map_fseq Inr f) g ⟶ (∃x'∈set_fseq g. x ∈ Basic_BNFs.setr x')"
shows "infinite (fseq_at f x)"
proof
assume fin: "finite (fseq_at f x)"
let ?g = "map_fseq (λy. if x = y then Inl undefined else Inr y) f"
have "fseq_eq (map_fseq Inr f) ?g" using fin
by transfer(simp add: seq_at_def vimage_def eq_commute)
with assms[of "?g"] show False by(auto simp add: fseq.set_map)
qed
lemma set_fae_seq_eq_alt: "set_fae_seq f = set_fae_seq_alt f"
by transfer(use fseq_at_Inr_infinite in ‹force simp add: fseq_at_infinite_Inr›)
end