Section CartesianClosedCat.
Variable A: Type.
Variable arrow: A -> A -> Prop.
Variable iso: A -> A -> Prop.
Class CCC (prod expo: A -> A -> A): Prop := mkCCC {
comm: forall x y, iso (prod x y) (prod y x);
assoc: forall x y z, iso (prod (prod x y) z) (prod x (prod y z));
adjoint: forall x y z, arrow (prod x y) z <-> arrow x (expo y z);
prod_UMP: forall x x' y y', arrow x x' -> arrow y y' -> arrow (prod x y) (prod x' y')
}.
(* This is an example of useful property. *)
Hypothesis transitivity: forall x y z, arrow x y -> arrow y z -> arrow x z.
Hypothesis identity: forall x, arrow x x.

Lemma expo_UMP: forall prod expo `{CCC prod expo},
forall x x' y y', arrow x' x -> arrow y y' -> arrow (expo x y) (expo x' y').