2015-02-26 18:19:54 +00:00
|
|
|
/-
|
|
|
|
Copyright (c) 2015 Floris van Doorn. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
Authors: Floris van Doorn
|
|
|
|
-/
|
2015-03-19 14:48:15 +00:00
|
|
|
import types.trunc types.pi arity
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
open eq is_trunc pi equiv equiv.ops
|
2014-12-22 01:18:38 +00:00
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
namespace category
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-04-25 03:04:24 +00:00
|
|
|
/-
|
|
|
|
Just as in Coq-HoTT we add two redundant fields to precategories: assoc' and id_id.
|
|
|
|
The first is to make (Cᵒᵖ)ᵒᵖ = C definitionally when C is a constructor.
|
|
|
|
The second is to ensure that the functor from the terminal category 1 ⇒ Cᵒᵖ is
|
|
|
|
opposite to the functor 1 ⇒ C.
|
|
|
|
-/
|
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
structure precategory [class] (ob : Type) : Type :=
|
2015-04-25 03:04:24 +00:00
|
|
|
mk' ::
|
2015-02-26 18:19:54 +00:00
|
|
|
(hom : ob → ob → Type)
|
|
|
|
(comp : Π⦃a b c : ob⦄, hom b c → hom a b → hom a c)
|
|
|
|
(ID : Π (a : ob), hom a a)
|
2015-04-25 03:04:24 +00:00
|
|
|
(assoc : Π ⦃a b c d : ob⦄ (h : hom c d) (g : hom b c) (f : hom a b),
|
2015-02-26 18:19:54 +00:00
|
|
|
comp h (comp g f) = comp (comp h g) f)
|
2015-04-25 03:04:24 +00:00
|
|
|
(assoc' : Π ⦃a b c d : ob⦄ (h : hom c d) (g : hom b c) (f : hom a b),
|
|
|
|
comp (comp h g) f = comp h (comp g f))
|
2015-02-26 18:19:54 +00:00
|
|
|
(id_left : Π ⦃a b : ob⦄ (f : hom a b), comp !ID f = f)
|
|
|
|
(id_right : Π ⦃a b : ob⦄ (f : hom a b), comp f !ID = f)
|
2015-04-25 03:04:24 +00:00
|
|
|
(id_id : Π (a : ob), comp !ID !ID = ID a)
|
|
|
|
(is_hset_hom : Π(a b : ob), is_hset (hom a b))
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-10-02 23:54:27 +00:00
|
|
|
-- attribute precategory [multiple-instances] --this is not used anywhere
|
2015-04-25 03:04:24 +00:00
|
|
|
attribute precategory.is_hset_hom [instance]
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-10-01 19:52:28 +00:00
|
|
|
infixr ∘ := precategory.comp
|
2015-02-26 18:19:54 +00:00
|
|
|
-- input ⟶ using \--> (this is a different arrow than \-> (→))
|
2015-10-09 20:21:03 +00:00
|
|
|
infixl [parsing_only] ` ⟶ `:25 := precategory.hom
|
2015-02-24 00:54:16 +00:00
|
|
|
namespace hom
|
2015-10-22 22:41:55 +00:00
|
|
|
infixl ` ⟶ `:60 := precategory.hom -- if you open this namespace, hom a b is printed as a ⟶ b
|
2015-02-24 00:54:16 +00:00
|
|
|
end hom
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-09-02 23:41:19 +00:00
|
|
|
abbreviation hom [unfold 2] := @precategory.hom
|
|
|
|
abbreviation comp [unfold 2] := @precategory.comp
|
|
|
|
abbreviation ID [unfold 2] := @precategory.ID
|
|
|
|
abbreviation assoc [unfold 2] := @precategory.assoc
|
|
|
|
abbreviation assoc' [unfold 2] := @precategory.assoc'
|
|
|
|
abbreviation id_left [unfold 2] := @precategory.id_left
|
|
|
|
abbreviation id_right [unfold 2] := @precategory.id_right
|
|
|
|
abbreviation id_id [unfold 2] := @precategory.id_id
|
|
|
|
abbreviation is_hset_hom [unfold 2] := @precategory.is_hset_hom
|
2015-04-25 03:04:24 +00:00
|
|
|
|
2015-10-23 05:12:34 +00:00
|
|
|
definition is_hprop_hom_eq {ob : Type} [C : precategory ob] {x y : ob} (f g : x ⟶ y)
|
|
|
|
: is_hprop (f = g) :=
|
|
|
|
_
|
|
|
|
|
2015-04-25 03:04:24 +00:00
|
|
|
-- the constructor you want to use in practice
|
2015-05-18 22:08:19 +00:00
|
|
|
protected definition precategory.mk [constructor] {ob : Type} (hom : ob → ob → Type)
|
2015-04-25 03:04:24 +00:00
|
|
|
[hset : Π (a b : ob), is_hset (hom a b)]
|
|
|
|
(comp : Π ⦃a b c : ob⦄, hom b c → hom a b → hom a c) (ID : Π (a : ob), hom a a)
|
|
|
|
(ass : Π ⦃a b c d : ob⦄ (h : hom c d) (g : hom b c) (f : hom a b),
|
|
|
|
comp h (comp g f) = comp (comp h g) f)
|
|
|
|
(idl : Π ⦃a b : ob⦄ (f : hom a b), comp (ID b) f = f)
|
|
|
|
(idr : Π ⦃a b : ob⦄ (f : hom a b), comp f (ID a) = f) : precategory ob :=
|
|
|
|
precategory.mk' hom comp ID ass (λa b c d h g f, !ass⁻¹) idl idr (λa, !idl) hset
|
2015-02-26 18:19:54 +00:00
|
|
|
|
|
|
|
section basic_lemmas
|
2015-02-27 05:45:21 +00:00
|
|
|
variables {ob : Type} [C : precategory ob]
|
|
|
|
variables {a b c d : ob} {h : c ⟶ d} {g : hom b c} {f f' : hom a b} {i : a ⟶ a}
|
|
|
|
include C
|
2015-02-26 18:19:54 +00:00
|
|
|
|
2015-09-25 19:02:14 +00:00
|
|
|
definition id [reducible] [unfold 2] := ID a
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-03-13 22:27:29 +00:00
|
|
|
definition id_leftright (f : hom a b) : id ∘ f ∘ id = f := !id_left ⬝ !id_right
|
|
|
|
definition comp_id_eq_id_comp (f : hom a b) : f ∘ id = id ∘ f := !id_right ⬝ !id_left⁻¹
|
2015-09-24 02:44:36 +00:00
|
|
|
definition id_comp_eq_comp_id (f : hom a b) : id ∘ f = f ∘ id := !id_left ⬝ !id_right⁻¹
|
2015-03-13 14:32:48 +00:00
|
|
|
|
2015-02-27 05:45:21 +00:00
|
|
|
definition left_id_unique (H : Π{b} {f : hom b a}, i ∘ f = f) : i = id :=
|
2015-03-13 00:25:31 +00:00
|
|
|
calc i = i ∘ id : by rewrite id_right
|
|
|
|
... = id : by rewrite H
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-02-27 05:45:21 +00:00
|
|
|
definition right_id_unique (H : Π{b} {f : hom a b}, f ∘ i = f) : i = id :=
|
2015-03-13 00:25:31 +00:00
|
|
|
calc i = id ∘ i : by rewrite id_left
|
|
|
|
... = id : by rewrite H
|
2015-02-27 05:45:21 +00:00
|
|
|
|
2015-09-02 23:41:19 +00:00
|
|
|
definition homset [reducible] [constructor] (x y : ob) : hset :=
|
2015-02-27 05:45:21 +00:00
|
|
|
hset.mk (hom x y) _
|
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
end basic_lemmas
|
2015-04-22 02:55:59 +00:00
|
|
|
section squares
|
2015-02-27 05:45:21 +00:00
|
|
|
parameters {ob : Type} [C : precategory ob]
|
2015-10-01 19:52:28 +00:00
|
|
|
local infixl ` ⟶ `:25 := @precategory.hom ob C
|
|
|
|
local infixr ∘ := @precategory.comp ob C _ _ _
|
2015-02-27 05:45:21 +00:00
|
|
|
definition compose_squares {xa xb xc ya yb yc : ob}
|
|
|
|
{xg : xb ⟶ xc} {xf : xa ⟶ xb} {yg : yb ⟶ yc} {yf : ya ⟶ yb}
|
|
|
|
{wa : xa ⟶ ya} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
|
|
|
|
(xyab : wb ∘ xf = yf ∘ wa) (xybc : wc ∘ xg = yg ∘ wb)
|
|
|
|
: wc ∘ (xg ∘ xf) = (yg ∘ yf) ∘ wa :=
|
|
|
|
calc
|
2015-03-13 00:25:31 +00:00
|
|
|
wc ∘ (xg ∘ xf) = (wc ∘ xg) ∘ xf : by rewrite assoc
|
|
|
|
... = (yg ∘ wb) ∘ xf : by rewrite xybc
|
|
|
|
... = yg ∘ (wb ∘ xf) : by rewrite assoc
|
|
|
|
... = yg ∘ (yf ∘ wa) : by rewrite xyab
|
|
|
|
... = (yg ∘ yf) ∘ wa : by rewrite assoc
|
2015-02-27 05:45:21 +00:00
|
|
|
|
|
|
|
definition compose_squares_2x2 {xa xb xc ya yb yc za zb zc : ob}
|
|
|
|
{xg : xb ⟶ xc} {xf : xa ⟶ xb} {yg : yb ⟶ yc} {yf : ya ⟶ yb} {zg : zb ⟶ zc} {zf : za ⟶ zb}
|
|
|
|
{va : ya ⟶ za} {vb : yb ⟶ zb} {vc : yc ⟶ zc} {wa : xa ⟶ ya} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
|
|
|
|
(xyab : wb ∘ xf = yf ∘ wa) (xybc : wc ∘ xg = yg ∘ wb)
|
|
|
|
(yzab : vb ∘ yf = zf ∘ va) (yzbc : vc ∘ yg = zg ∘ vb)
|
|
|
|
: (vc ∘ wc) ∘ (xg ∘ xf) = (zg ∘ zf) ∘ (va ∘ wa) :=
|
|
|
|
calc
|
2015-03-13 00:25:31 +00:00
|
|
|
(vc ∘ wc) ∘ (xg ∘ xf) = vc ∘ (wc ∘ (xg ∘ xf)) : by rewrite (assoc vc wc _)
|
|
|
|
... = vc ∘ ((yg ∘ yf) ∘ wa) : by rewrite (compose_squares xyab xybc)
|
|
|
|
... = (vc ∘ (yg ∘ yf)) ∘ wa : by rewrite assoc
|
|
|
|
... = ((zg ∘ zf) ∘ va) ∘ wa : by rewrite (compose_squares yzab yzbc)
|
|
|
|
... = (zg ∘ zf) ∘ (va ∘ wa) : by rewrite assoc
|
2015-02-27 05:45:21 +00:00
|
|
|
|
|
|
|
definition square_precompose {xa xb xc yb yc : ob}
|
|
|
|
{xg : xb ⟶ xc} {yg : yb ⟶ yc} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
|
|
|
|
(H : wc ∘ xg = yg ∘ wb) (xf : xa ⟶ xb) : wc ∘ xg ∘ xf = yg ∘ wb ∘ xf :=
|
|
|
|
calc
|
2015-03-13 00:25:31 +00:00
|
|
|
wc ∘ xg ∘ xf = (wc ∘ xg) ∘ xf : by rewrite assoc
|
|
|
|
... = (yg ∘ wb) ∘ xf : by rewrite H
|
|
|
|
... = yg ∘ wb ∘ xf : by rewrite assoc
|
2015-02-27 05:45:21 +00:00
|
|
|
|
|
|
|
definition square_postcompose {xb xc yb yc yd : ob}
|
|
|
|
{xg : xb ⟶ xc} {yg : yb ⟶ yc} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
|
|
|
|
(H : wc ∘ xg = yg ∘ wb) (yh : yc ⟶ yd) : (yh ∘ wc) ∘ xg = (yh ∘ yg) ∘ wb :=
|
|
|
|
calc
|
2015-03-13 00:25:31 +00:00
|
|
|
(yh ∘ wc) ∘ xg = yh ∘ wc ∘ xg : by rewrite assoc
|
|
|
|
... = yh ∘ yg ∘ wb : by rewrite H
|
|
|
|
... = (yh ∘ yg) ∘ wb : by rewrite assoc
|
2015-02-27 05:45:21 +00:00
|
|
|
|
|
|
|
definition square_prepostcompose {xa xb xc yb yc yd : ob}
|
|
|
|
{xg : xb ⟶ xc} {yg : yb ⟶ yc} {wb : xb ⟶ yb} {wc : xc ⟶ yc}
|
|
|
|
(H : wc ∘ xg = yg ∘ wb) (yh : yc ⟶ yd) (xf : xa ⟶ xb)
|
|
|
|
: (yh ∘ wc) ∘ (xg ∘ xf) = (yh ∘ yg) ∘ (wb ∘ xf) :=
|
|
|
|
square_precompose (square_postcompose H yh) xf
|
|
|
|
end squares
|
2015-02-24 00:54:16 +00:00
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
structure Precategory : Type :=
|
|
|
|
(carrier : Type)
|
|
|
|
(struct : precategory carrier)
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-05-18 22:08:19 +00:00
|
|
|
definition precategory.Mk [reducible] [constructor] {ob} (C) : Precategory := Precategory.mk ob C
|
|
|
|
definition precategory.MK [reducible] [constructor] (a b c d e f g h) : Precategory :=
|
2015-09-24 02:44:36 +00:00
|
|
|
Precategory.mk a (@precategory.mk a b c d e f g h)
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
abbreviation carrier [unfold 1] := @Precategory.carrier
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
attribute Precategory.carrier [coercion]
|
|
|
|
attribute Precategory.struct [instance] [priority 10000] [coercion]
|
|
|
|
-- definition precategory.carrier [coercion] [reducible] := Precategory.carrier
|
|
|
|
-- definition precategory.struct [instance] [coercion] [reducible] := Precategory.struct
|
2015-10-01 19:52:28 +00:00
|
|
|
notation g ` ∘[`:60 C:0 `] `:0 f:60 :=
|
2015-04-13 19:30:59 +00:00
|
|
|
@comp (Precategory.carrier C) (Precategory.struct C) _ _ _ g f
|
2015-02-21 00:30:32 +00:00
|
|
|
-- TODO: make this left associative
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
definition Precategory.eta (C : Precategory) : Precategory.mk C C = C :=
|
|
|
|
Precategory.rec (λob c, idp) C
|
2014-12-12 04:14:53 +00:00
|
|
|
|
2015-03-16 16:01:36 +00:00
|
|
|
/-Characterization of paths between precategories-/
|
2015-10-22 22:41:55 +00:00
|
|
|
-- introduction tule for paths between precategories
|
2015-03-16 16:01:36 +00:00
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
definition precategory_eq {ob : Type}
|
|
|
|
{C D : precategory ob}
|
|
|
|
(p : Π{a b}, @hom ob C a b = @hom ob D a b)
|
|
|
|
(q : Πa b c g f, cast p (@comp ob C a b c g f) = @comp ob D a b c (cast p g) (cast p f))
|
|
|
|
: C = D :=
|
2015-03-16 16:01:36 +00:00
|
|
|
begin
|
2015-10-22 22:41:55 +00:00
|
|
|
induction C with hom1 comp1 ID1 a b il ir, induction D with hom2 comp2 ID2 a' b' il' ir',
|
|
|
|
esimp at *,
|
|
|
|
revert q, eapply homotopy2.rec_on @p, esimp, clear p, intro p q, induction p,
|
|
|
|
esimp at *,
|
|
|
|
assert H : comp1 = comp2,
|
|
|
|
{ apply eq_of_homotopy3, intros, apply eq_of_homotopy2, intros, apply q},
|
|
|
|
induction H,
|
|
|
|
assert K : ID1 = ID2,
|
|
|
|
{ apply eq_of_homotopy, intro a, exact !ir'⁻¹ ⬝ !il},
|
|
|
|
induction K,
|
|
|
|
apply ap0111111 (precategory.mk' hom1 comp1 ID1): apply is_hprop.elim
|
2015-03-16 16:01:36 +00:00
|
|
|
end
|
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
|
|
|
|
definition precategory_eq_of_equiv {ob : Type}
|
|
|
|
{C D : precategory ob}
|
|
|
|
(p : Π⦃a b⦄, @hom ob C a b ≃ @hom ob D a b)
|
|
|
|
(q : Π{a b c} g f, p (@comp ob C a b c g f) = @comp ob D a b c (p g) (p f))
|
|
|
|
: C = D :=
|
2015-03-16 16:01:36 +00:00
|
|
|
begin
|
2015-10-22 22:41:55 +00:00
|
|
|
fapply precategory_eq,
|
|
|
|
{ intro a b, exact ua !@p},
|
|
|
|
{ intros, refine !cast_ua ⬝ !q ⬝ _, apply ap011 !@comp !cast_ua⁻¹ !cast_ua⁻¹},
|
2015-03-16 16:01:36 +00:00
|
|
|
end
|
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
/- if we need to prove properties about precategory_eq, it might be easier with the following proof:
|
2015-03-16 22:50:42 +00:00
|
|
|
begin
|
2015-10-22 22:41:55 +00:00
|
|
|
induction C with hom1 comp1 ID1, induction D with hom2 comp2 ID2, esimp at *,
|
|
|
|
assert H : Σ(s : hom1 = hom2), (λa b, equiv_of_eq (apd100 s a b)) = p,
|
|
|
|
{ fconstructor,
|
|
|
|
{ apply eq_of_homotopy2, intros, apply ua, apply p},
|
|
|
|
{ apply eq_of_homotopy2, intros, rewrite [to_right_inv !eq_equiv_homotopy2, equiv_of_eq_ua]}},
|
|
|
|
induction H with H1 H2, induction H1, esimp at H2,
|
|
|
|
assert K : (λa b, equiv.refl) = p,
|
|
|
|
{ refine _ ⬝ H2, apply eq_of_homotopy2, intros, exact !equiv_of_eq_refl⁻¹},
|
|
|
|
induction K, clear H2,
|
|
|
|
esimp at *,
|
|
|
|
assert H : comp1 = comp2,
|
|
|
|
{ apply eq_of_homotopy3, intros, apply eq_of_homotopy2, intros, apply q},
|
|
|
|
assert K : ID1 = ID2,
|
|
|
|
{ apply eq_of_homotopy, intros, apply r},
|
|
|
|
induction H, induction K,
|
|
|
|
apply ap0111111 (precategory.mk' hom1 comp1 ID1): apply is_hprop.elim
|
2015-03-16 22:50:42 +00:00
|
|
|
end
|
2015-10-22 22:41:55 +00:00
|
|
|
-/
|
2015-03-16 22:50:42 +00:00
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
definition Precategory_eq {C D : Precategory}
|
2015-03-16 22:50:42 +00:00
|
|
|
(p : carrier C = carrier D)
|
2015-10-22 22:41:55 +00:00
|
|
|
(q : Π{a b : C}, a ⟶ b = cast p a ⟶ cast p b)
|
|
|
|
(r : Π{a b c : C} (g : b ⟶ c) (f : a ⟶ b), cast q (g ∘ f) = cast q g ∘ cast q f)
|
|
|
|
: C = D :=
|
|
|
|
begin
|
|
|
|
induction C with X C, induction D with Y D, esimp at *, induction p,
|
|
|
|
esimp at *,
|
|
|
|
apply ap (Precategory.mk X),
|
|
|
|
apply precategory_eq @q @r
|
|
|
|
end
|
|
|
|
|
|
|
|
definition Precategory_eq_of_equiv {C D : Precategory}
|
|
|
|
(p : carrier C ≃ carrier D)
|
|
|
|
(q : Π⦃a b : C⦄, a ⟶ b ≃ p a ⟶ p b)
|
|
|
|
(r : Π{a b c : C} (g : b ⟶ c) (f : a ⟶ b), q (g ∘ f) = q g ∘ q f)
|
|
|
|
: C = D :=
|
2015-03-16 22:50:42 +00:00
|
|
|
begin
|
2015-10-22 22:41:55 +00:00
|
|
|
induction C with X C, induction D with Y D, esimp at *,
|
|
|
|
revert q r, eapply equiv.rec_on_ua p, clear p, intro p, induction p, esimp,
|
|
|
|
intros,
|
|
|
|
apply ap (Precategory.mk X),
|
|
|
|
apply precategory_eq_of_equiv @q @r
|
2015-03-16 22:50:42 +00:00
|
|
|
end
|
|
|
|
|
2015-10-22 22:41:55 +00:00
|
|
|
-- elimination rules for paths between precategories.
|
|
|
|
-- The first elimination rule is "ap carrier"
|
|
|
|
|
|
|
|
definition Precategory_eq_hom [unfold 3] {C D : Precategory} (p : C = D) (a b : C)
|
|
|
|
: hom a b = hom (cast (ap carrier p) a) (cast (ap carrier p) b) :=
|
|
|
|
by induction p; reflexivity
|
|
|
|
--(ap10 (ap10 (apd (λx, @hom (carrier x) (Precategory.struct x)) p⁻¹ᵖ) a) b)⁻¹ᵖ ⬝ _
|
|
|
|
|
|
|
|
|
|
|
|
-- beta/eta rules
|
|
|
|
definition ap_Precategory_eq' {C D : Precategory}
|
|
|
|
(p : carrier C = carrier D)
|
|
|
|
(q : Π{a b : C}, a ⟶ b = cast p a ⟶ cast p b)
|
|
|
|
(r : Π{a b c : C} (g : b ⟶ c) (f : a ⟶ b), cast q (g ∘ f) = cast q g ∘ cast q f)
|
|
|
|
(s : Πa, cast q (ID a) = ID (cast p a)) : ap carrier (Precategory_eq p @q @r) = p :=
|
|
|
|
begin
|
|
|
|
induction C with X C, induction D with Y D, esimp at *, induction p,
|
|
|
|
rewrite [↑Precategory_eq, -ap_compose,↑function.compose,ap_constant]
|
|
|
|
end
|
|
|
|
|
2015-10-23 05:12:34 +00:00
|
|
|
/-
|
2015-10-22 22:41:55 +00:00
|
|
|
theorem Precategory_eq'_eta {C D : Precategory} (p : C = D) :
|
|
|
|
Precategory_eq
|
|
|
|
(ap carrier p)
|
|
|
|
(Precategory_eq_hom p)
|
|
|
|
(by induction p; intros; reflexivity) = p :=
|
|
|
|
begin
|
|
|
|
induction p, induction C with X C, unfold Precategory_eq,
|
|
|
|
induction C, unfold precategory_eq, exact sorry
|
|
|
|
end
|
2015-10-23 05:12:34 +00:00
|
|
|
-/
|
2015-10-22 22:41:55 +00:00
|
|
|
|
|
|
|
/-
|
|
|
|
theorem Precategory_eq2 {C D : Precategory} (p q : C = D)
|
|
|
|
(r : ap carrier p = ap carrier q)
|
|
|
|
(s : Precategory_eq_hom p =[r] Precategory_eq_hom q)
|
|
|
|
: p = q :=
|
|
|
|
begin
|
|
|
|
|
|
|
|
end
|
|
|
|
-/
|
|
|
|
|
2015-02-26 18:19:54 +00:00
|
|
|
end category
|