Theory Quotient_TLList
section ‹Setup for Isabelle's quotient package for terminated lazy lists›
theory Quotient_TLList imports
TLList
"HOL-Library.Quotient_Product"
"HOL-Library.Quotient_Sum"
"HOL-Library.Quotient_Set"
begin
subsection ‹Rules for the Quotient package›
lemma tmap_id_id [id_simps]:
"tmap id id = id"
by(simp add: fun_eq_iff tllist.map_id)
declare tllist_all2_eq[id_simps]
lemma case_sum_preserve [quot_preserve]:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
and q3: "Quotient3 R3 Abs3 Rep3"
shows "((Abs1 ---> Rep2) ---> (Abs3 ---> Rep2) ---> map_sum Rep1 Rep3 ---> Abs2) case_sum = case_sum"
using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] Quotient3_abs_rep[OF q3]
by(simp add: fun_eq_iff split: sum.split)
lemma case_sum_preserve2 [quot_preserve]:
assumes q: "Quotient3 R Abs Rep"
shows "((id ---> Rep) ---> (id ---> Rep) ---> id ---> Abs) case_sum = case_sum"
using Quotient3_abs_rep[OF q]
by(auto intro!: ext split: sum.split)
lemma case_prod_preserve [quot_preserve]:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
and q3: "Quotient3 R3 Abs3 Rep3"
shows "((Abs1 ---> Abs2 ---> Rep3) ---> map_prod Rep1 Rep2 ---> Abs3) case_prod = case_prod"
using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] Quotient3_abs_rep[OF q3]
by(simp add: fun_eq_iff split: prod.split)
lemma case_prod_preserve2 [quot_preserve]:
assumes q: "Quotient3 R Abs Rep"
shows "((id ---> id ---> Rep) ---> id ---> Abs) case_prod = case_prod"
using Quotient3_abs_rep[OF q]
by(auto intro!: ext)
lemma id_preserve [quot_preserve]:
assumes "Quotient3 R Abs Rep"
shows "(Rep ---> Abs) id = id"
using Quotient3_abs_rep[OF assms]
by(auto intro: ext)
functor tmap: tmap
by(simp_all add: fun_eq_iff tmap_id_id tllist.map_comp)
lemma reflp_tllist_all2:
assumes R: "reflp R" and Q: "reflp Q"
shows "reflp (tllist_all2 R Q)"
proof(rule reflpI)
fix xs
show "tllist_all2 R Q xs xs"
apply(coinduction arbitrary: xs)
using assms by(auto elim: reflpE)
qed
lemma symp_tllist_all2: "⟦ symp R; symp S ⟧ ⟹ symp (tllist_all2 R S)"
by (rule sympI)(auto 4 3 simp add: tllist_all2_conv_all_tnth elim: sympE dest: lfinite_llength_enat not_lfinite_llength)
lemma transp_tllist_all2: "⟦ transp R; transp S ⟧ ⟹ transp (tllist_all2 R S)"
by (rule transpI) (rule tllist_all2_trans)
lemma tllist_equivp [quot_equiv]:
"⟦ equivp R; equivp S ⟧ ⟹ equivp (tllist_all2 R S)"
by (simp add: equivp_reflp_symp_transp reflp_tllist_all2 symp_tllist_all2 transp_tllist_all2)
declare tllist_all2_eq [simp, id_simps]
lemma tmap_preserve [quot_preserve]:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
and q3: "Quotient3 R3 Abs3 Rep3"
and q4: "Quotient3 R4 Abs4 Rep4"
shows "((Abs1 ---> Rep2) ---> (Abs3 ---> Rep4) ---> tmap Rep1 Rep3 ---> tmap Abs2 Abs4) tmap = tmap"
and "((Abs1 ---> id) ---> (Abs2 ---> id) ---> tmap Rep1 Rep2 ---> id) tmap = tmap"
using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] Quotient3_abs_rep[OF q3] Quotient3_abs_rep[OF q4]
by(simp_all add: fun_eq_iff tllist.map_comp o_def)
lemmas tmap_respect [quot_respect] = tmap_transfer2
lemma Quotient3_tmap_Abs_Rep:
"⟦Quotient3 R1 Abs1 Rep1; Quotient3 R2 Abs2 Rep2⟧
⟹ tmap Abs1 Abs2 (tmap Rep1 Rep2 ts) = ts"
by(drule abs_o_rep)+(simp add: tllist.map_comp tmap_id_id)
lemma Quotient3_tllist_all2_tmap_tmapI:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
shows "tllist_all2 R1 R2 (tmap Rep1 Rep2 ts) (tmap Rep1 Rep2 ts)"
by(coinduction arbitrary: ts)(auto simp add: Quotient3_rep_reflp[OF q1] Quotient3_rep_reflp[OF q2])
lemma tllist_all2_rel:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
shows "tllist_all2 R1 R2 r s ⟷ (tllist_all2 R1 R2 r r ∧ tllist_all2 R1 R2 s s ∧ tmap Abs1 Abs2 r = tmap Abs1 Abs2 s)"
(is "?lhs ⟷ ?rhs")
proof(intro iffI conjI)
assume "?lhs"
thus "tllist_all2 R1 R2 r r"
apply -
apply(rule tllist_all2_reflI)
apply(clarsimp simp add: in_tset_conv_tnth)
apply(metis tllist_all2_tnthD Quotient3_rel [OF q1])
apply(metis tllist_all2_tfinite1_terminalD Quotient3_rel [OF q2])
done
from ‹?lhs› show "tllist_all2 R1 R2 s s"
apply -
apply(rule tllist_all2_reflI)
apply(clarsimp simp add: in_tset_conv_tnth)
apply(metis tllist_all2_tnthD2 Quotient3_rel [OF q1])
apply(metis tllist_all2_tfinite2_terminalD Quotient3_rel [OF q2])
done
from ‹?lhs› show "tmap Abs1 Abs2 r = tmap Abs1 Abs2 s"
unfolding tmap_eq_tmap_conv_tllist_all2
by(rule tllist_all2_mono)(metis Quotient3_rel[OF q1] Quotient3_rel[OF q2])+
next
assume "?rhs"
thus "?lhs"
unfolding tmap_eq_tmap_conv_tllist_all2
apply(clarsimp simp add: tllist_all2_conv_all_tnth)
apply(subst Quotient3_rel[OF q1, symmetric])
apply(subst Quotient3_rel[OF q2, symmetric])
apply(auto 4 3 dest: lfinite_llength_enat not_lfinite_llength)
done
qed
lemma tllist_quotient [quot_thm]:
"⟦ Quotient3 R1 Abs1 Rep1; Quotient3 R2 Abs2 Rep2 ⟧
⟹ Quotient3 (tllist_all2 R1 R2) (tmap Abs1 Abs2) (tmap Rep1 Rep2)"
by(blast intro: Quotient3I dest: Quotient3_tmap_Abs_Rep Quotient3_tllist_all2_tmap_tmapI tllist_all2_rel)
declare [[mapQ3 tllist = (tllist_all2, tllist_quotient)]]
lemma TCons_preserve [quot_preserve]:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
shows "(Rep1 ---> (tmap Rep1 Rep2) ---> (tmap Abs1 Abs2)) TCons = TCons"
using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2]
by(simp add: fun_eq_iff tllist.map_comp o_def tmap_id_id[unfolded id_def])
lemmas TCons_respect [quot_respect] = TCons_transfer2
lemma TNil_preserve [quot_preserve]:
assumes "Quotient3 R2 Abs2 Rep2"
shows "(Rep2 ---> tmap Abs1 Abs2) TNil = TNil"
using Quotient3_abs_rep[OF assms]
by(simp add: fun_eq_iff)
lemmas TNil_respect [quot_respect] = TNil_transfer2
lemmas tllist_all2_respect [quot_respect] = tllist_all2_transfer
lemma tllist_all2_prs:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
shows "tllist_all2 ((Abs1 ---> Abs1 ---> id) P) ((Abs2 ---> Abs2 ---> id) Q)
(tmap Rep1 Rep2 ts) (tmap Rep1 Rep2 ts')
⟷ tllist_all2 P Q ts ts'"
(is "?lhs ⟷ ?rhs")
proof
assume ?lhs
thus ?rhs
proof(coinduct)
case (tllist_all2 ts ts')
thus ?case using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2]
by(cases ts)(case_tac [!] ts', auto simp add: tllist_all2_TNil1 tllist_all2_TCons1)
qed
next
assume ?rhs
thus ?lhs
apply(coinduction arbitrary: ts ts')
using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2]
by(auto dest: tllist_all2_is_TNilD intro: tllist_all2_tfinite1_terminalD tllist_all2_thdD tllist_all2_ttlI)
qed
lemma tllist_all2_preserve [quot_preserve]:
assumes "Quotient3 R1 Abs1 Rep1"
and "Quotient3 R2 Abs2 Rep2"
shows "((Abs1 ---> Abs1 ---> id) ---> (Abs2 ---> Abs2 ---> id) --->
tmap Rep1 Rep2 ---> tmap Rep1 Rep2 ---> id) tllist_all2 = tllist_all2"
by(simp add: fun_eq_iff tllist_all2_prs[OF assms])
lemma tllist_all2_preserve2 [quot_preserve]:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
shows "(tllist_all2 ((Rep1 ---> Rep1 ---> id) R1) ((Rep2 ---> Rep2 ---> id) R2)) = (=)"
by (simp add: fun_eq_iff map_fun_def comp_def Quotient3_rel_rep[OF q1] Quotient3_rel_rep[OF q2]
tllist_all2_eq)
lemma corec_tllist_preserve [quot_preserve]:
assumes q1: "Quotient3 R1 Abs1 Rep1"
and q2: "Quotient3 R2 Abs2 Rep2"
and q3: "Quotient3 R3 Abs3 Rep3"
shows "((Abs1 ---> id) ---> (Abs1 ---> Rep2) ---> (Abs1 ---> Rep3) ---> (Abs1 ---> id) ---> (Abs1 ---> tmap Rep3 Rep2) ---> (Abs1 ---> Rep1) ---> Rep1 ---> tmap Abs3 Abs2) corec_tllist = corec_tllist"
(is "?lhs = ?rhs")
proof(intro ext)
fix IS_TNIL TNIL THD endORmore TTL_end TTL_more b
show "?lhs IS_TNIL TNIL THD endORmore TTL_end TTL_more b = ?rhs IS_TNIL TNIL THD endORmore TTL_end TTL_more b"
by(coinduction arbitrary: b rule: tllist.coinduct_strong)(auto simp add: Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] Quotient3_abs_rep[OF q3] Quotient3_tmap_Abs_Rep[OF q3 q2])
qed
end