\import Category
\import Equiv (QEquiv, ret)
\import Paths
\import Paths.Meta
\open Precat
\instance ProductPrecat (C D : Precat) : Precat
| Ob => \Sigma C.Ob D.Ob
| Hom X Y => \Sigma (C.Hom X.1 Y.1) (D.Hom X.2 Y.2)
| id X => (id X.1, id X.2)
| o f g => (f.1 ∘ g.1, f.2 ∘ g.2)
| id-left => rewrite (id-left, id-left) idp
| id-right => rewrite (id-right, id-right) idp
| o-assoc => rewrite (o-assoc, o-assoc) idp
\where {
\func iso-first {C D : Precat} {a b : Ob {ProductPrecat C D}}
(iso : Iso {ProductPrecat C D} {a} {b}) : Iso {C} {a.1} {b.1} => \new Iso {
| f => iso.f.1
| hinv => iso.hinv.1
| hinv_f => pmap (\lam x => x.1) iso.hinv_f
| f_hinv => pmap (\lam x => x.1) iso.f_hinv
}
\func iso-second {C D : Precat} {a b : Ob {ProductPrecat C D}}
(iso : Iso {ProductPrecat C D} {a} {b}) : Iso {D} {a.2} {b.2} => \new Iso {
| f => iso.f.2
| hinv => iso.hinv.2
| hinv_f => pmap (\lam x => x.2) iso.hinv_f
| f_hinv => pmap (\lam x => x.2) iso.f_hinv
}
}
\instance ProductCat (C D : Cat) : Cat
| Precat => ProductPrecat C D
| univalence => \new QEquiv {
| ret iso =>
exts (ret {univalence} (ProductPrecat.iso-first iso), ret {univalence} (ProductPrecat.iso-second iso))
| ret_f _ => idp
| f_sec _ => idp
} \where {
}