Theory HoTT_Equivalence
theory HoTT_Equivalence
imports HoTT_Identity
begin
section ‹Contractibility and fibers›
definition contractible :: "expr ⇒ expr" where
"contractible A ≡
sigma_type A
(λcenter. pi_type A
(λx. identity_type A center x))"
lemma contractible_form:
assumes A: "A ∷⇩h universe i"
shows "contractible A ∷⇩h universe i"
unfolding contractible_def
proof (rule sigma_form[OF A])
fix center
assume center: "center ∷⇩h A"
show "pi_type A (λx. identity_type A center x) ∷⇩h universe i"
proof (rule pi_form[OF A])
fix x
assume x: "x ∷⇩h A"
show "identity_type A center x ∷⇩h universe i"
by (rule identity_form[OF A center x])
qed
qed
definition fiber ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr"
where
"fiber A B f b ≡
sigma_type A (λa. identity_type B (app f a) b)"
lemma fiber_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and b: "b ∷⇩h B"
shows "fiber A B f b ∷⇩h universe i"
unfolding fiber_def
proof (rule sigma_form[OF A])
fix a
assume a: "a ∷⇩h A"
have fa: "app f a ∷⇩h B" by (rule arrow_elim[OF f a])
show "identity_type B (app f a) b ∷⇩h universe i"
by (rule identity_form[OF B fa b])
qed
definition contractible_map ::
"expr ⇒ expr ⇒ expr ⇒ expr"
where
"contractible_map A B f ≡
pi_type B (λb. contractible (fiber A B f b))"
lemma contractible_map_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
shows "contractible_map A B f ∷⇩h universe i"
unfolding contractible_map_def
proof (rule pi_form[OF B])
fix b
assume b: "b ∷⇩h B"
have fib: "fiber A B f b ∷⇩h universe i"
by (rule fiber_form[OF A B f b])
show "contractible (fiber A B f b) ∷⇩h universe i"
by (rule contractible_form[OF fib])
qed
section ‹Bi-invertible maps and equivalences›
definition left_inverse ::
"expr ⇒ expr ⇒ expr ⇒ expr"
where
"left_inverse A B f ≡
sigma_type (arrow B A)
(λg. homotopy A (λ_. A)
(compose A B A g f) (identity_function A))"
definition right_inverse ::
"expr ⇒ expr ⇒ expr ⇒ expr"
where
"right_inverse A B f ≡
sigma_type (arrow B A)
(λg. homotopy B (λ_. B)
(compose B A B f g) (identity_function B))"
definition biinvertible ::
"expr ⇒ expr ⇒ expr ⇒ expr"
where
"biinvertible A B f ≡
product (left_inverse A B f) (right_inverse A B f)"
definition equivalence :: "expr ⇒ expr ⇒ expr" where
"equivalence A B ≡
sigma_type (arrow A B) (λf. biinvertible A B f)"
lemma nondependent_homotopy_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and g: "g ∷⇩h arrow A B"
shows "homotopy A (λ_. B) f g ∷⇩h universe i"
proof (rule homotopy_form[OF A])
fix x
assume "x ∷⇩h A"
show "B ∷⇩h universe i" by (rule B)
next
show "f ∷⇩h pi_type A (λ_. B)"
using f unfolding arrow_def .
next
show "g ∷⇩h pi_type A (λ_. B)"
using g unfolding arrow_def .
qed
lemma nondependent_homotopy_refl_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
shows "homotopy_refl A (λ_. B) f ∷⇩h
homotopy A (λ_. B) f f"
proof (rule homotopy_refl_type[OF A])
fix x
assume "x ∷⇩h A"
show "B ∷⇩h universe i" by (rule B)
next
show "f ∷⇩h pi_type A (λ_. B)"
using f unfolding arrow_def .
qed
lemma left_inverse_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
shows "left_inverse A B f ∷⇩h universe i"
unfolding left_inverse_def
proof (rule sigma_form)
show "arrow B A ∷⇩h universe i"
by (rule arrow_form[OF B A])
next
fix g
assume g: "g ∷⇩h arrow B A"
have gf: "compose A B A g f ∷⇩h arrow A A"
by (rule compose_type[OF A f g])
have id: "identity_function A ∷⇩h arrow A A"
by (rule identity_function_type[OF A])
show "homotopy A (λ_. A) (compose A B A g f)
(identity_function A) ∷⇩h universe i"
by (rule nondependent_homotopy_form[OF A A gf id])
qed
lemma right_inverse_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
shows "right_inverse A B f ∷⇩h universe i"
unfolding right_inverse_def
proof (rule sigma_form)
show "arrow B A ∷⇩h universe i"
by (rule arrow_form[OF B A])
next
fix g
assume g: "g ∷⇩h arrow B A"
have fg: "compose B A B f g ∷⇩h arrow B B"
by (rule compose_type[OF B g f])
have id: "identity_function B ∷⇩h arrow B B"
by (rule identity_function_type[OF B])
show "homotopy B (λ_. B) (compose B A B f g)
(identity_function B) ∷⇩h universe i"
by (rule nondependent_homotopy_form[OF B B fg id])
qed
lemma biinvertible_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
shows "biinvertible A B f ∷⇩h universe i"
unfolding biinvertible_def
by (rule product_form[OF left_inverse_form[OF A B f]
right_inverse_form[OF A B f]])
lemma equivalence_form:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
shows "equivalence A B ∷⇩h universe i"
unfolding equivalence_def
proof (rule sigma_form)
show "arrow A B ∷⇩h universe i"
by (rule arrow_form[OF A B])
next
fix f
assume f: "f ∷⇩h arrow A B"
show "biinvertible A B f ∷⇩h universe i"
by (rule biinvertible_form[OF A B f])
qed
lemma equivalence_intro:
assumes f: "f ∷⇩h arrow A B"
and w: "w ∷⇩h biinvertible A B f"
shows "pair f w ∷⇩h equivalence A B"
unfolding equivalence_def
proof (rule sigma_intro)
show "f ∷⇩h arrow A B" by (rule f)
next
show "w ∷⇩h biinvertible A B f" by (rule w)
qed
section ‹The identity equivalence›
lemma compose_identity_self [simp]:
"compose A A A (identity_function A) (identity_function A) ≡
identity_function A"
unfolding compose_def identity_function_def by simp
definition identity_biinvertible :: "expr ⇒ expr" where
"identity_biinvertible A ≡
pair
(pair (identity_function A)
(homotopy_refl A (λ_. A) (identity_function A)))
(pair (identity_function A)
(homotopy_refl A (λ_. A) (identity_function A)))"
lemma identity_biinvertible_type:
assumes A: "A ∷⇩h universe i"
shows "identity_biinvertible A ∷⇩h
biinvertible A A (identity_function A)"
proof -
have id: "identity_function A ∷⇩h arrow A A"
by (rule identity_function_type[OF A])
have H: "homotopy_refl A (λ_. A) (identity_function A)
∷⇩h homotopy A (λ_. A)
(identity_function A) (identity_function A)"
by (rule nondependent_homotopy_refl_type[OF A A id])
have Hcomp: "homotopy_refl A (λ_. A) (identity_function A)
∷⇩h homotopy A (λ_. A)
(compose A A A (identity_function A) (identity_function A))
(identity_function A)"
using H by simp
have left: "pair (identity_function A)
(homotopy_refl A (λ_. A) (identity_function A))
∷⇩h left_inverse A A (identity_function A)"
unfolding left_inverse_def
proof (rule sigma_intro)
show "identity_function A ∷⇩h arrow A A" by (rule id)
next
show "homotopy_refl A (λ_. A) (identity_function A) ∷⇩h
homotopy A (λ_. A)
(compose A A A (identity_function A) (identity_function A))
(identity_function A)"
by (rule Hcomp)
qed
have right: "pair (identity_function A)
(homotopy_refl A (λ_. A) (identity_function A))
∷⇩h right_inverse A A (identity_function A)"
unfolding right_inverse_def
proof (rule sigma_intro)
show "identity_function A ∷⇩h arrow A A" by (rule id)
next
show "homotopy_refl A (λ_. A) (identity_function A) ∷⇩h
homotopy A (λ_. A)
(compose A A A (identity_function A) (identity_function A))
(identity_function A)"
by (rule Hcomp)
qed
show "identity_biinvertible A ∷⇩h
biinvertible A A (identity_function A)"
unfolding identity_biinvertible_def biinvertible_def
by (rule product_intro[OF left right])
qed
definition identity_equivalence :: "expr ⇒ expr" where
"identity_equivalence A ≡
pair (identity_function A) (identity_biinvertible A)"
theorem identity_equivalence_type:
assumes A: "A ∷⇩h universe i"
shows "identity_equivalence A ∷⇩h equivalence A A"
unfolding identity_equivalence_def equivalence_def
proof (rule sigma_intro)
show "identity_function A ∷⇩h arrow A A"
by (rule identity_function_type[OF A])
next
show "identity_biinvertible A ∷⇩h
biinvertible A A (identity_function A)"
by (rule identity_biinvertible_type[OF A])
qed
section ‹Composition of equivalences›
definition left_inverse_function ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr"
where
"left_inverse_function A B f w ≡ first (first w)"
definition left_inverse_homotopy ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr"
where
"left_inverse_homotopy A B f w ≡ second (first w)"
definition right_inverse_function ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr"
where
"right_inverse_function A B f w ≡ first (second w)"
definition right_inverse_homotopy ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr"
where
"right_inverse_homotopy A B f w ≡ second (second w)"
lemma left_inverse_component_type:
assumes w: "w ∷⇩h biinvertible A B f"
shows "first w ∷⇩h left_inverse A B f"
using w unfolding biinvertible_def by (rule product_first)
lemma right_inverse_component_type:
assumes w: "w ∷⇩h biinvertible A B f"
shows "second w ∷⇩h right_inverse A B f"
using w unfolding biinvertible_def by (rule product_second)
lemma left_inverse_function_type:
assumes w: "w ∷⇩h biinvertible A B f"
shows "left_inverse_function A B f w ∷⇩h arrow B A"
proof -
have L: "first w ∷⇩h left_inverse A B f"
by (rule left_inverse_component_type[OF w])
show "left_inverse_function A B f w ∷⇩h arrow B A"
unfolding left_inverse_function_def
using L unfolding left_inverse_def by (rule sigma_first)
qed
lemma left_inverse_homotopy_type:
assumes w: "w ∷⇩h biinvertible A B f"
shows "left_inverse_homotopy A B f w ∷⇩h
homotopy A (λ_. A)
(compose A B A (left_inverse_function A B f w) f)
(identity_function A)"
proof -
have L: "first w ∷⇩h left_inverse A B f"
by (rule left_inverse_component_type[OF w])
show "left_inverse_homotopy A B f w ∷⇩h
homotopy A (λ_. A)
(compose A B A (left_inverse_function A B f w) f)
(identity_function A)"
unfolding left_inverse_homotopy_def left_inverse_function_def
using L unfolding left_inverse_def by (rule sigma_second)
qed
lemma right_inverse_function_type:
assumes w: "w ∷⇩h biinvertible A B f"
shows "right_inverse_function A B f w ∷⇩h arrow B A"
proof -
have R: "second w ∷⇩h right_inverse A B f"
by (rule right_inverse_component_type[OF w])
show "right_inverse_function A B f w ∷⇩h arrow B A"
unfolding right_inverse_function_def
using R unfolding right_inverse_def by (rule sigma_first)
qed
lemma right_inverse_homotopy_type:
assumes w: "w ∷⇩h biinvertible A B f"
shows "right_inverse_homotopy A B f w ∷⇩h
homotopy B (λ_. B)
(compose B A B f (right_inverse_function A B f w))
(identity_function B)"
proof -
have R: "second w ∷⇩h right_inverse A B f"
by (rule right_inverse_component_type[OF w])
show "right_inverse_homotopy A B f w ∷⇩h
homotopy B (λ_. B)
(compose B A B f (right_inverse_function A B f w))
(identity_function B)"
unfolding right_inverse_homotopy_def right_inverse_function_def
using R unfolding right_inverse_def by (rule sigma_second)
qed
definition composite_left_inverse_function ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"composite_left_inverse_function A B C f g wf wg ≡
compose C B A
(left_inverse_function A B f wf)
(left_inverse_function B C g wg)"
lemma composite_left_inverse_function_type:
assumes C: "C ∷⇩h universe i"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "composite_left_inverse_function A B C f g wf wg
∷⇩h arrow C A"
unfolding composite_left_inverse_function_def
by (rule compose_type[OF C
left_inverse_function_type[OF wg]
left_inverse_function_type[OF wf]])
definition composite_left_homotopy ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"composite_left_homotopy A B C f g wf wg ≡
lambda A (λx.
path_concat A
(app (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x))))
(app (left_inverse_function A B f wf) (app f x))
x
(ap B A (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x)))
(app f x)
(app (left_inverse_homotopy B C g wg) (app f x)))
(app (left_inverse_homotopy A B f wf) x))"
lemma composite_left_homotopy_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and C: "C ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and g: "g ∷⇩h arrow B C"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "composite_left_homotopy A B C f g wf wg ∷⇩h
homotopy A (λ_. A)
(compose A C A
(composite_left_inverse_function A B C f g wf wg)
(compose A B C g f))
(identity_function A)"
unfolding composite_left_homotopy_def homotopy_def
composite_left_inverse_function_def
proof (rule pi_intro[OF A])
fix x
assume x: "x ∷⇩h A"
have fx: "app f x ∷⇩h B"
by (rule arrow_elim[OF f x])
have gfx: "app g (app f x) ∷⇩h C"
by (rule arrow_elim[OF g fx])
have lf: "left_inverse_function A B f wf ∷⇩h arrow B A"
by (rule left_inverse_function_type[OF wf])
have lg: "left_inverse_function B C g wg ∷⇩h arrow C B"
by (rule left_inverse_function_type[OF wg])
have lg_gfx: "app (left_inverse_function B C g wg) (app g (app f x))
∷⇩h B"
by (rule arrow_elim[OF lg gfx])
have lf_lg_gfx: "app (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x)))
∷⇩h A"
by (rule arrow_elim[OF lf lg_gfx])
have lf_fx: "app (left_inverse_function A B f wf) (app f x)
∷⇩h A"
by (rule arrow_elim[OF lf fx])
have Lg: "left_inverse_homotopy B C g wg ∷⇩h
homotopy B (λ_. B)
(compose B C B (left_inverse_function B C g wg) g)
(identity_function B)"
by (rule left_inverse_homotopy_type[OF wg])
have Lg_pi: "left_inverse_homotopy B C g wg ∷⇩h
pi_type B
(λu. identity_type B
(app (compose B C B (left_inverse_function B C g wg) g) u)
(app (identity_function B) u))"
using Lg unfolding homotopy_def .
have Lg_x_raw: "app (left_inverse_homotopy B C g wg) (app f x)
∷⇩h identity_type B
(app (compose B C B (left_inverse_function B C g wg) g) (app f x))
(app (identity_function B) (app f x))"
by (rule pi_elim[OF Lg_pi fx])
have Lg_x: "app (left_inverse_homotopy B C g wg) (app f x)
∷⇩h identity_type B
(app (left_inverse_function B C g wg) (app g (app f x)))
(app f x)"
using Lg_x_raw by simp
have step_one: "ap B A (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x)))
(app f x)
(app (left_inverse_homotopy B C g wg) (app f x))
∷⇩h identity_type A
(app (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x))))
(app (left_inverse_function A B f wf) (app f x))"
by (rule ap_type[OF B A lf lg_gfx fx Lg_x])
have Lf: "left_inverse_homotopy A B f wf ∷⇩h
homotopy A (λ_. A)
(compose A B A (left_inverse_function A B f wf) f)
(identity_function A)"
by (rule left_inverse_homotopy_type[OF wf])
have Lf_pi: "left_inverse_homotopy A B f wf ∷⇩h
pi_type A
(λu. identity_type A
(app (compose A B A (left_inverse_function A B f wf) f) u)
(app (identity_function A) u))"
using Lf unfolding homotopy_def .
have Lf_x_raw: "app (left_inverse_homotopy A B f wf) x
∷⇩h identity_type A
(app (compose A B A (left_inverse_function A B f wf) f) x)
(app (identity_function A) x)"
by (rule pi_elim[OF Lf_pi x])
have Lf_x: "app (left_inverse_homotopy A B f wf) x
∷⇩h identity_type A
(app (left_inverse_function A B f wf) (app f x)) x"
using Lf_x_raw by simp
have composed: "path_concat A
(app (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x))))
(app (left_inverse_function A B f wf) (app f x))
x
(ap B A (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x)))
(app f x)
(app (left_inverse_homotopy B C g wg) (app f x)))
(app (left_inverse_homotopy A B f wf) x)
∷⇩h identity_type A
(app (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x)))) x"
by (rule path_concat_type[OF A lf_lg_gfx lf_fx x step_one Lf_x])
show "path_concat A
(app (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x))))
(app (left_inverse_function A B f wf) (app f x)) x
(ap B A (left_inverse_function A B f wf)
(app (left_inverse_function B C g wg) (app g (app f x)))
(app f x)
(app (left_inverse_homotopy B C g wg) (app f x)))
(app (left_inverse_homotopy A B f wf) x)
∷⇩h identity_type A
(app
(compose A C A
(compose C B A
(left_inverse_function A B f wf)
(left_inverse_function B C g wg))
(compose A B C g f)) x)
(app (identity_function A) x)"
using composed by simp
qed
definition composite_left_inverse ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"composite_left_inverse A B C f g wf wg ≡
pair
(composite_left_inverse_function A B C f g wf wg)
(composite_left_homotopy A B C f g wf wg)"
lemma composite_left_inverse_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and C: "C ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and g: "g ∷⇩h arrow B C"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "composite_left_inverse A B C f g wf wg ∷⇩h
left_inverse A C (compose A B C g f)"
unfolding composite_left_inverse_def left_inverse_def
proof (rule sigma_intro)
show "composite_left_inverse_function A B C f g wf wg ∷⇩h
arrow C A"
by (rule composite_left_inverse_function_type[OF C wf wg])
next
show "composite_left_homotopy A B C f g wf wg ∷⇩h
homotopy A (λ_. A)
(compose A C A
(composite_left_inverse_function A B C f g wf wg)
(compose A B C g f))
(identity_function A)"
by (rule composite_left_homotopy_type[OF A B C f g wf wg])
qed
definition composite_right_inverse_function ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"composite_right_inverse_function A B C f g wf wg ≡
compose C B A
(right_inverse_function A B f wf)
(right_inverse_function B C g wg)"
lemma composite_right_inverse_function_type:
assumes C: "C ∷⇩h universe i"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "composite_right_inverse_function A B C f g wf wg
∷⇩h arrow C A"
unfolding composite_right_inverse_function_def
by (rule compose_type[OF C
right_inverse_function_type[OF wg]
right_inverse_function_type[OF wf]])
definition composite_right_homotopy ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"composite_right_homotopy A B C f g wf wg ≡
lambda C (λz.
path_concat C
(app g (app f
(app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z))))
(app g (app (right_inverse_function B C g wg) z))
z
(ap B C g
(app f
(app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_function B C g wg) z)
(app (right_inverse_homotopy A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_homotopy B C g wg) z))"
lemma composite_right_homotopy_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and C: "C ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and g: "g ∷⇩h arrow B C"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "composite_right_homotopy A B C f g wf wg ∷⇩h
homotopy C (λ_. C)
(compose C A C (compose A B C g f)
(composite_right_inverse_function A B C f g wf wg))
(identity_function C)"
unfolding composite_right_homotopy_def homotopy_def
composite_right_inverse_function_def
proof (rule pi_intro[OF C])
fix z
assume z: "z ∷⇩h C"
have rf: "right_inverse_function A B f wf ∷⇩h arrow B A"
by (rule right_inverse_function_type[OF wf])
have rg: "right_inverse_function B C g wg ∷⇩h arrow C B"
by (rule right_inverse_function_type[OF wg])
have rgz: "app (right_inverse_function B C g wg) z ∷⇩h B"
by (rule arrow_elim[OF rg z])
have rf_rgz: "app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z) ∷⇩h A"
by (rule arrow_elim[OF rf rgz])
have f_rf_rgz: "app f
(app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)) ∷⇩h B"
by (rule arrow_elim[OF f rf_rgz])
have g_f_rf_rgz: "app g (app f
(app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z))) ∷⇩h C"
by (rule arrow_elim[OF g f_rf_rgz])
have g_rgz: "app g (app (right_inverse_function B C g wg) z)
∷⇩h C"
by (rule arrow_elim[OF g rgz])
have Rf: "right_inverse_homotopy A B f wf ∷⇩h
homotopy B (λ_. B)
(compose B A B f (right_inverse_function A B f wf))
(identity_function B)"
by (rule right_inverse_homotopy_type[OF wf])
have Rf_pi: "right_inverse_homotopy A B f wf ∷⇩h
pi_type B
(λu. identity_type B
(app (compose B A B f (right_inverse_function A B f wf)) u)
(app (identity_function B) u))"
using Rf unfolding homotopy_def .
have Rf_z_raw: "app (right_inverse_homotopy A B f wf)
(app (right_inverse_function B C g wg) z)
∷⇩h identity_type B
(app (compose B A B f (right_inverse_function A B f wf))
(app (right_inverse_function B C g wg) z))
(app (identity_function B)
(app (right_inverse_function B C g wg) z))"
by (rule pi_elim[OF Rf_pi rgz])
have Rf_z: "app (right_inverse_homotopy A B f wf)
(app (right_inverse_function B C g wg) z)
∷⇩h identity_type B
(app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_function B C g wg) z)"
using Rf_z_raw by simp
have step_one: "ap B C g
(app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_function B C g wg) z)
(app (right_inverse_homotopy A B f wf)
(app (right_inverse_function B C g wg) z))
∷⇩h identity_type C
(app g (app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z))))
(app g (app (right_inverse_function B C g wg) z))"
by (rule ap_type[OF B C g f_rf_rgz rgz Rf_z])
have Rg: "right_inverse_homotopy B C g wg ∷⇩h
homotopy C (λ_. C)
(compose C B C g (right_inverse_function B C g wg))
(identity_function C)"
by (rule right_inverse_homotopy_type[OF wg])
have Rg_pi: "right_inverse_homotopy B C g wg ∷⇩h
pi_type C
(λu. identity_type C
(app (compose C B C g (right_inverse_function B C g wg)) u)
(app (identity_function C) u))"
using Rg unfolding homotopy_def .
have Rg_z_raw: "app (right_inverse_homotopy B C g wg) z
∷⇩h identity_type C
(app (compose C B C g (right_inverse_function B C g wg)) z)
(app (identity_function C) z)"
by (rule pi_elim[OF Rg_pi z])
have Rg_z: "app (right_inverse_homotopy B C g wg) z
∷⇩h identity_type C
(app g (app (right_inverse_function B C g wg) z)) z"
using Rg_z_raw by simp
have composed: "path_concat C
(app g (app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z))))
(app g (app (right_inverse_function B C g wg) z)) z
(ap B C g
(app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_function B C g wg) z)
(app (right_inverse_homotopy A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_homotopy B C g wg) z)
∷⇩h identity_type C
(app g (app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)))) z"
by (rule path_concat_type[OF C g_f_rf_rgz g_rgz z step_one Rg_z])
show "path_concat C
(app g (app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z))))
(app g (app (right_inverse_function B C g wg) z)) z
(ap B C g
(app f (app (right_inverse_function A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_function B C g wg) z)
(app (right_inverse_homotopy A B f wf)
(app (right_inverse_function B C g wg) z)))
(app (right_inverse_homotopy B C g wg) z)
∷⇩h identity_type C
(app
(compose C A C (compose A B C g f)
(compose C B A
(right_inverse_function A B f wf)
(right_inverse_function B C g wg))) z)
(app (identity_function C) z)"
using composed by simp
qed
definition composite_right_inverse ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"composite_right_inverse A B C f g wf wg ≡
pair
(composite_right_inverse_function A B C f g wf wg)
(composite_right_homotopy A B C f g wf wg)"
lemma composite_right_inverse_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and C: "C ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and g: "g ∷⇩h arrow B C"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "composite_right_inverse A B C f g wf wg ∷⇩h
right_inverse A C (compose A B C g f)"
unfolding composite_right_inverse_def right_inverse_def
proof (rule sigma_intro)
show "composite_right_inverse_function A B C f g wf wg ∷⇩h
arrow C A"
by (rule composite_right_inverse_function_type[OF C wf wg])
next
show "composite_right_homotopy A B C f g wf wg ∷⇩h
homotopy C (λ_. C)
(compose C A C (compose A B C g f)
(composite_right_inverse_function A B C f g wf wg))
(identity_function C)"
by (rule composite_right_homotopy_type[OF A B C f g wf wg])
qed
definition compose_biinvertible ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒
expr ⇒ expr ⇒ expr"
where
"compose_biinvertible A B C f g wf wg ≡
pair
(composite_left_inverse A B C f g wf wg)
(composite_right_inverse A B C f g wf wg)"
lemma compose_biinvertible_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and C: "C ∷⇩h universe i"
and f: "f ∷⇩h arrow A B"
and g: "g ∷⇩h arrow B C"
and wf: "wf ∷⇩h biinvertible A B f"
and wg: "wg ∷⇩h biinvertible B C g"
shows "compose_biinvertible A B C f g wf wg ∷⇩h
biinvertible A C (compose A B C g f)"
unfolding compose_biinvertible_def biinvertible_def
by (rule product_intro[OF
composite_left_inverse_type[OF A B C f g wf wg]
composite_right_inverse_type[OF A B C f g wf wg]])
definition compose_equivalence ::
"expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr ⇒ expr"
where
"compose_equivalence A B C e d ≡
pair
(compose A B C (first d) (first e))
(compose_biinvertible A B C
(first e) (first d) (second e) (second d))"
theorem compose_equivalence_type:
assumes A: "A ∷⇩h universe i"
and B: "B ∷⇩h universe i"
and C: "C ∷⇩h universe i"
and e: "e ∷⇩h equivalence A B"
and d: "d ∷⇩h equivalence B C"
shows "compose_equivalence A B C e d ∷⇩h equivalence A C"
proof -
have ef: "first e ∷⇩h arrow A B"
using e unfolding equivalence_def by (rule sigma_first)
have ew: "second e ∷⇩h biinvertible A B (first e)"
using e unfolding equivalence_def by (rule sigma_second)
have df: "first d ∷⇩h arrow B C"
using d unfolding equivalence_def by (rule sigma_first)
have dw: "second d ∷⇩h biinvertible B C (first d)"
using d unfolding equivalence_def by (rule sigma_second)
have composite: "compose A B C (first d) (first e)
∷⇩h arrow A C"
by (rule compose_type[OF A ef df])
have witness: "compose_biinvertible A B C
(first e) (first d) (second e) (second d)
∷⇩h biinvertible A C
(compose A B C (first d) (first e))"
by (rule compose_biinvertible_type[OF A B C ef df ew dw])
show "compose_equivalence A B C e d ∷⇩h equivalence A C"
unfolding compose_equivalence_def equivalence_def
by (intro sigma_intro composite witness)
qed
end