\import Category
\import Category.Limit
\import Category.Subobj
\import Equiv
\import Function.Meta
\import Logic
\import Meta
\import Order.PartialOrder
\import Paths
\import Relation.Equivalence
\func IsRegularSubobj.{o,h} {C : Precat.{o,h}} {obj : C} (s : Subobj obj) : \Prop \elim s
| in~ m => IsRegularMono m.f
| ~-equiv m1 m2 r =>
\have lem {m1 m2 : Mono {C} { | cod => obj }} (m1<=m2 : inso~ m1 <= inso~ m2) (m2<=m1 : inso~ m2 <= inso~ m1) (m1r : IsRegularMono m1.f) : IsRegularMono m2.f => \case \elim m1<=m2, \elim m2<=m1, \elim m1r \with {
| inP m1<=m2, inP m2<=m1, inP e => inP $ Equalizer.mono=>equalizer m2
(pmap (_ ∘) (inv m2<=m1.2) *> inv o-assoc *> pmap (∘ _) e.equal *> o-assoc *> pmap (_ ∘) m2<=m1.2)
\lam h hp => inP (m1<=m2.1 ∘ e.eqMap h hp, inv o-assoc *> pmap (∘ _) m1<=m2.2 *> e.eqBeta)
}
\in propExt (lem (inP (r.1,r.2)) (inP (r.3,r.4))) (lem (inP (r.3,r.4)) (inP (r.1,r.2)))
\lemma regularSubobj-meet.{o,h} {C : FinCompletePrecat.{o,h}} {obj : C} {s1 s2 : Subobj obj} (r1 : IsRegularSubobj s1) (r2 : IsRegularSubobj s2)
: IsRegularSubobj (SubobjectSemilattice.meet s1 s2) \elim s1, s2
| in~ m1, in~ m2 => pullback-isRegularMono r1 r2
\where {
\open PrecatWithBprod
\lemma pullback-isRegularMono {C : CartesianPrecat} {P : Pullback {C}} (fm : IsRegularMono P.f) (gm : IsRegularMono P.g) : IsRegularMono (P.f ∘ pbProj1) \elim fm, gm
| inP (fe : Equalizer) \as fm, inP (ge : Equalizer) \as gm => inP $ Equalizer.mono=>equalizer
(Mono.comp (regularMono_Mono fm) (regularMono_Mono $ regularMono_pullback P gm))
(pair-comp *> pmap2 pair (inv o-assoc *> pmap (∘ _) fe.equal *> o-assoc) (pmap (_ ∘) P.pbCoh *> inv o-assoc *> pmap (∘ _) ge.equal *> o-assoc *> pmap (_ ∘) (inv P.pbCoh)) *> inv pair-comp)
\lam {w} h p =>
\have | (inP (m1,q1)) => IsEquiv.isSurj (fe.isEqualizer w) $ later (h, pmap (∘ h) (inv beta1) *> o-assoc *> pmap (proj1 ∘) p *> inv o-assoc *> pmap (∘ h) beta1)
| (inP (m2,q2)) => IsEquiv.isSurj (ge.isEqualizer w) $ later (h, pmap (∘ h) (inv beta2) *> o-assoc *> pmap (proj2 ∘) p *> inv o-assoc *> pmap (∘ h) beta2)
| p1 => pmap __.1 q1
| p2 => pmap __.1 q2
\in inP (pbMap m1 m2 (p1 *> inv p2), o-assoc *> pmap (_ ∘) P.pbBeta1 *> p1)
}