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')
}.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')
}.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')
}.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')
}.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')
}.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')
}.

(* Specifications: *)
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').