Theory Pushout_Scaffold
theory Pushout_Scaffold
imports Equivalence_Quotients
begin
section ‹Pushout-style quotients of disjoint sums›
text ‹
The pushout of two maps is first presented here as a quotient of the disjoint
sum by the obvious glue relation. This algebraic infrastructure is independent of
any topology; the topological quotient is added later, once the point-set
infrastructure is in place.
›
inductive pushout_rel ::
"('c => 'a) => ('c => 'b) => ('a + 'b) => ('a + 'b) => bool"
for f :: "'c => 'a" and g :: "'c => 'b"
where
refl [intro!, simp]: "pushout_rel f g x x"
| sym: "pushout_rel f g x y ==> pushout_rel f g y x"
| trans: "pushout_rel f g x y ==> pushout_rel f g y z ==> pushout_rel f g x z"
| glue [intro]: "pushout_rel f g (Inl (f c)) (Inr (g c))"
interpretation pushout_equiv: equivalence_relation "pushout_rel f g"
proof
show "pushout_rel f g x x" for x
by (rule pushout_rel.refl)
next
show "pushout_rel f g x y ==> pushout_rel f g y x" for x y
by (rule pushout_rel.sym)
next
show "pushout_rel f g x y ==> pushout_rel f g y z ==> pushout_rel f g x z" for x y z
by (rule pushout_rel.trans)
qed
definition pushout_class ::
"('c => 'a) => ('c => 'b) => ('a + 'b) => ('a + 'b) set"
where
"pushout_class f g x = equiv_class (pushout_rel f g) x"
definition pushout_space ::
"('c => 'a) => ('c => 'b) => ('a + 'b) set set"
where
"pushout_space f g = quotient_space (pushout_rel f g)"
definition pushout_inl ::
"('c => 'a) => ('c => 'b) => 'a => ('a + 'b) set"
where
"pushout_inl f g a = pushout_class f g (Inl a)"
definition pushout_inr ::
"('c => 'a) => ('c => 'b) => 'b => ('a + 'b) set"
where
"pushout_inr f g b = pushout_class f g (Inr b)"
lemma pushout_class_eq_iff:
"pushout_class f g x = pushout_class f g y ⟷ pushout_rel f g x y"
unfolding pushout_class_def
by (rule pushout_equiv.equiv_class_eq_iff)
lemma pushout_inl_in_space [intro]:
"pushout_inl f g a ∈ pushout_space f g"
unfolding pushout_inl_def pushout_space_def pushout_class_def quotient_space_def
by blast
lemma pushout_inr_in_space [intro]:
"pushout_inr f g b ∈ pushout_space f g"
unfolding pushout_inr_def pushout_space_def pushout_class_def quotient_space_def
by blast
lemma pushout_glue:
"pushout_inl f g (f c) = pushout_inr f g (g c)"
by (simp add: pushout_class_eq_iff pushout_inl_def pushout_inr_def pushout_rel.glue)
definition pushout_case_compatible ::
"('c => 'a) => ('c => 'b) => ('a => 'd) => ('b => 'd) => bool"
where
"pushout_case_compatible f g left right ⟷ (∀c. left (f c) = right (g c))"
lemma pushout_rel_case_cong:
assumes compat: "pushout_case_compatible f g left right"
and rel: "pushout_rel f g x y"
shows "case_sum left right x = case_sum left right y"
using rel
proof (induction rule: pushout_rel.induct)
case (refl x)
then show ?case by simp
next
case (sym x y)
then show ?case by simp
next
case (trans x y z)
then show ?case by simp
next
case (glue c)
then show ?case
using compat unfolding pushout_case_compatible_def by simp
qed
definition pushout_rec ::
"('c => 'a) => ('c => 'b) => ('a => 'd) => ('b => 'd) => ('a + 'b) set => 'd"
where
"pushout_rec f g left right X =
(THE z. ∃x. X = pushout_class f g x ∧ z = case_sum left right x)"
lemma pushout_rec_well_defined:
assumes compat: "pushout_case_compatible f g left right"
and X_in: "X ∈ pushout_space f g"
shows "∃! z. ∃x. X = pushout_class f g x ∧ z = case_sum left right x"
proof -
from X_in obtain rep where X_rep: "X = pushout_class f g rep"
unfolding pushout_space_def quotient_space_def pushout_class_def by blast
show ?thesis
proof (rule ex1I[of _ "case_sum left right rep"])
show "∃x. X = pushout_class f g x ∧ case_sum left right rep = case_sum left right x"
by (rule exI[where x = rep], simp add: X_rep)
next
fix z
assume hz: "∃x. X = pushout_class f g x ∧ z = case_sum left right x"
from hz obtain x where
x: "X = pushout_class f g x" "z = case_sum left right x"
by blast
have "pushout_rel f g x rep"
using X_rep x(1) by (simp add: pushout_class_eq_iff)
then have rel_rep_x: "pushout_rel f g rep x"
by (rule pushout_rel.sym)
from compat rel_rep_x have "case_sum left right rep = case_sum left right x"
by (rule pushout_rel_case_cong)
with x show "z = case_sum left right rep"
by simp
qed
qed
lemma pushout_rec_inl:
assumes compat: "pushout_case_compatible f g left right"
shows "pushout_rec f g left right (pushout_inl f g a) = left a"
proof -
have uniq:
"∃! z. ∃x. pushout_inl f g a = pushout_class f g x ∧ z = case_sum left right x"
using pushout_rec_well_defined[OF compat pushout_inl_in_space[of f g a]] .
have witness:
"∃x. pushout_inl f g a = pushout_class f g x ∧ left a = case_sum left right x"
unfolding pushout_inl_def by (intro exI[of _ "Inl a"]) simp
show ?thesis
unfolding pushout_rec_def
by (rule the1_equality[OF uniq witness])
qed
lemma pushout_rec_inr:
assumes compat: "pushout_case_compatible f g left right"
shows "pushout_rec f g left right (pushout_inr f g b) = right b"
proof -
have uniq:
"∃! z. ∃x. pushout_inr f g b = pushout_class f g x ∧ z = case_sum left right x"
using pushout_rec_well_defined[OF compat pushout_inr_in_space[of f g b]] .
have witness:
"∃x. pushout_inr f g b = pushout_class f g x ∧ right b = case_sum left right x"
unfolding pushout_inr_def by (intro exI[of _ "Inr b"]) simp
show ?thesis
unfolding pushout_rec_def
by (rule the1_equality[OF uniq witness])
qed
end