\import Algebra.Group
\import Algebra.Ring
\import Algebra.Semiring
\import Category
\import Category.Limit
\import Equiv (QEquiv)
\import Equiv.Univalence (QEquiv-to-=)
\import Function.Meta
\import Paths
\import Paths.Meta
\class PreAdditivePrecat \extends Precat{
| AbHom {X Y : Ob} : AbGroup(Hom X Y)
| l-bilinear {X Y Z : Ob}{g h : Hom X Y}{f : Hom Y Z} : (g AbHom.+ h) >> f = g >> f AbHom.+ h >> f
| r-bilinear {X Y Z : Ob}{g h : Hom Y Z}{f : Hom X Y} : f >> (g AbHom.+ h) = f >> g AbHom.+ f >> h
}
\func Ring=OneObjectPreAdd : PreAdditivePrecat (\Sigma) = Ring => QEquiv-to-= \new QEquiv {
| f => PreAdditiveCategory-OneObject
| ret => Ring_toCat
| ret_f _ => idp
| f_sec _ => exts (idp, idp, \lam _ _ => idp, \lam _ _ => idp, \lam _ => idp, idp, \lam n => natCoefCoincide)
}
\where {
\func natCoefCoincide {b : Ring}{n : Nat} : natCoef {PreAdditiveCategory-OneObject (Ring_toCat b)} n = b.natCoef n \elim n
| 0 => rewrite b.natCoefZero idp
| suc n => rewrite (b.natCoefSuc, inv $ natCoefCoincide {b} {n} ) idp
{- | PreAdditiveCategory with one object is a ring -}
\func PreAdditiveCategory-OneObject (X : PreAdditivePrecat (\Sigma)) : Ring (X.Hom () ()) \cowith
| AbGroup => X.AbHom {()}{()}
| ide => X.id ()
| * => X.∘
| ide-left => X.id-left
| ide-right => X.id-right
| *-assoc => X.o-assoc
| ldistr => X.l-bilinear
| rdistr => X.r-bilinear
\func Ring_toCat (R : Ring) : PreAdditivePrecat (\Sigma) \cowith
| Hom () () => R
| id () => R.ide
| o => R.*
| id-left => R.ide-left
| id-right => R.ide-right
| o-assoc => R.*-assoc
| AbHom => R
| l-bilinear => R.ldistr
| r-bilinear => R.rdistr
}
\class AdditivePrecat \extends PreAdditivePrecat, CartesianPrecat