Local Open Scope morphism_scope.
(** Given two objects a and b, their product a×b is an object such that there are two projections from it to a and b:  # <pre>  π₁        π₂ a <—–——– a×b ———–—> b </pre> # such that for any object z with two projections to a and b, there is a unique arrow h that makes the following diagram commute:  # <pre> π₁        π₂ a <—–——–– a×b –———–—> b ↖         ↑        ↗ \        |       / \       |      / \      |∃!h  / \     |    / \    |   / \   |  / z </pre> # *)
Record Product {C : Category} (c d : C) : Type :=
{
product : C;
Pi_1 : product –≻ c;
Pi_2 : product –≻ d;
Prod_morph_ex : ∀ (p' : Obj) (r1 : p' –≻ c) (r2 : p' –≻ d), p' –≻ product;
Prod_morph_com_1 : ∀ (p' : Obj) (r1 : p' –≻ c) (r2 : p' –≻ d),
(Pi_1 ∘ (Prod_morph_ex p' r1 r2))%morphism = r1;
Prod_morph_com_2 : ∀ (p' : Obj) (r1 : p' –≻ c) (r2 : p' –≻ d),
(Pi_2 ∘ (Prod_morph_ex p' r1 r2))%morphism = r2;
Prod_morph_unique :
∀ (p' : Obj) (r1 : p' –≻ c) (r2 : p' –≻ d) (f g : p' –≻ product),
Pi_1 ∘ f = r1
→ Pi_2 ∘ f = r2
→ Pi_1 ∘ g = r1
→ Pi_2 ∘ g = r2
→ f = g
}.
Arguments Product _ _ _, {_} _ _.
Arguments Pi_1 {_ _ _ _}, {_ _ _} _.
Arguments Pi_2 {_ _ _ _}, {_ _ _} _.
Arguments Prod_morph_ex {_ _ _} _ _ _ _.
Arguments Prod_morph_com_1 {_ _ _} _ _ _ _.
Arguments Prod_morph_com_2 {_ _ _} _ _ _ _.
Arguments Prod_morph_unique {_ _ _} _ _ _ _ _ _ _ _ _ _.
Coercion product : Product >-> Obj.
Notation "a × b" := (Product a b) : object_scope.
Local Open Scope object_scope.

(* Specifications: *)
(** for any pair of objects, their product is unique up to isomorphism. *)
Theorem Product_iso {C : Category} (c d : Obj) (P : c × d) (P' : c × d)
: (P ≃ P')%isomorphism.