\import Algebra.Field
\import Algebra.Group
\import Algebra.Monoid
\import Algebra.Monoid.Sub
\import Algebra.Ordered
\import Algebra.Pointed
\import Algebra.Ring
\import Algebra.Ring.Local
\import Algebra.Ring.Localization
\import Data.Or
\import Logic
\import Order.LinearOrder
\import Paths
\import Paths.Meta
\import Relation.Equivalence
\open Monoid \hiding (equals)
\open LocRing
\lemma localization-inv {R : CRing} (S : SubMonoid R) (a : SType S) (r : R) (p : S (a.1 * r)) : Inv (inl~ a) (in~ (a.2 * r, a.1 * r, p))
=> Inv.lmake {LocRing S} (in~ (a.2 * r, a.1 * r, p))
(path (~-equiv {SType S} _ _ (
((a.2 * r) * a.1) * ide ==< ide-right >==
(a.2 * r) * a.1 ==< *-comm >==
a.1 * (a.2 * r) ==< inv *-assoc >==
(a.1 * a.2) * r ==< pmap (`* r) *-comm >==
(a.2 * a.1) * r ==< *-assoc >==
a.2 * (a.1 * r) ==< *-comm >==
(a.1 * r) * a.2 ==< inv ide-left >==
ide * ((a.1 * r) * a.2) `qed)))
\where {
\lemma converse (j : Inv (inl~ a)) : TruncP (\Sigma (r : R) (S (a.1 * r)))
=> \let | (in~ b \as i) => j.inv
| p : inl~ a * i = ide => j.inv-right
| (inP (c,cs,q)) => unequals S p
\in inP (b.1 * (ide * c), rewriteEq q (contains_* (contains_* S.contains_ide (contains_* a.3 b.3)) cs))
}
\lemma localization-zro {R : CRing} (S : SubMonoid R) (a : SType S) (s : R) (c : S s) (p : a.1 * s = zro) : inl~ a = zro
=> equals-lem S s c (
(a.1 * ide) * s ==< simplify >==
a.1 * s ==< p >==
zro ==< simplify >==
(zro * a.2) * s `qed)
\lemma localization-nonTrivial {R : CRing} (S : SubMonoid R) (p : Not (S zro)) : 0 /= {LocRing S} 1
=> \case unequals S __ \with {
| inP (c, s, q) => p (transport S (
c ==< simplify >==
(ide * ide) * c ==< inv q >==
(zro * ide) * c ==< simplify >==
zro `qed) s)
}
\lemma localization-isLocal {R : CRing} (S : SubMonoid R) (nt : Not (S zro))
(loc : \Pi (x y : R) -> S y -> (\Sigma (r : R) (S (x * r))) || (\Sigma (r : R) (S ((x + y) * r))))
: LocalCRing { | CRing => LocRing S } \cowith
| zro/=ide => localization-nonTrivial S nt
| locality (in~ x) => \case loc x.1 x.2 x.3 \with {
| byLeft (r,c) => byLeft (localization-inv S x r c)
| byRight (r,c) => byRight (localization-inv S (x.1 * ide + ide * x.2, x.2 * ide, contains_* x.3 S.contains_ide) r (simplify c))
}
\lemma localization-isField {R : CRing} (S : SubMonoid R) (nt : Not (S zro))
(loc : \Pi (x y : R) -> S y -> (\Sigma (r : R) (S (x * r))) || (\Sigma (r : R) (S ((x + y) * r))))
(fp : \Pi (x : R) -> (\Pi (r : R) -> Not (S (x * r))) -> TruncP (\Sigma (s : R) (S s) (x * s = zro)))
: Field { | CRing => LocRing S } \cowith
| LocalCRing => localization-isLocal S nt loc
| #0-tight {in~ x} x-ni => \case fp x.1 (\lam r c[x*r] => x-ni (localization-inv S x r c[x*r])) \with {
| inP (s,c,p) => localization-zro S x s c p
}
\func localization-isDiscreteField {R : CRing} (S : SubMonoid R) (nt : Not (S zro))
(fp : \Pi (x : R) -> (\Sigma (s : R) (S s) (x * s = zro)) || (\Sigma (r : R) (S (x * r))))
: DiscreteField { | CRing => LocRing S } \cowith
| zro/=ide => localization-nonTrivial S nt
| eitherZeroOrInv (in~ x) => \case fp x.1 \with {
| byLeft (s, cs, x*s=0) => byLeft (localization-zro S x s cs x*s=0)
| byRight (r, c[x*r]) => byRight (localization-inv S x r c[x*r])
}
-- | The localization of an ordering commutative ring at the set of positive elements is an ordered field.
\func localization-isOrderedField (R : OrderedCRing) : OrderedField \cowith
| Field => localization-isField (positiveSubset R) zro/>0
(\lam x y y>0 => \case <_+-comparison (negative x) (x + y) (transport isPos simplify y>0) \with {
| byLeft -x>0 => byLeft (negative ide, simplify -x>0)
| byRight x+y>0 => byRight (ide, simplify x+y>0)
})
(\lam x x-ni => inP (ide, ide>zro, ide-right *> <_+-connectedness (\lam x>0 => x-ni ide (simplify x>0)) (\lam -x>0 => x-ni (negative ide) (simplify -x>0))))
| isPos => isPositive
| zro/>0 => zro/>0
| positive_+ {in~ x} {in~ y} x>0 y>0 => positive_+ (positive_* x>0 y.3) (positive_* y>0 x.3)
| ide>zro => ide>zro
| <_+-comparison (in~ x) (in~ y) x+y>0 => ||.map (OrderedRing.positive_*-cancel-left __ y.3) (OrderedRing.positive_*-cancel-left __ x.3) (<_+-comparison _ _ x+y>0)
| <_+-connectedness {in~ x} x/>0 -x/>0 => localization-zro (positiveSubset R) x ide ide>zro (ide-right *> <_+-connectedness x/>0 -x/>0)
| positive_* {in~ x} {in~ y} => positive_* {_} {x.1} {y.1}
| positive=>#0 {in~ x} x>0 => localization-inv (positiveSubset R) x ide (simplify x>0)
| #0=>eitherPosOrNeg {in~ x} => \case localization-inv.converse (positiveSubset R) x __ \with {
| inP (r, x*r>0) => ||.map __.1 __.1 (positive_*-cancel x*r>0)
}
\where {
\func positiveSubset (R : OrderedCRing) : SubMonoid R \cowith
| contains => isPos
| contains_ide => ide>zro
| contains_* => positive_*
\func isPositive {R : OrderedCRing} (x : Type (positiveSubset R)) : \Prop \elim x
| in~ x => isPos x.1
| ~-equiv x y x~y => propExt
(\lam x>0 => OrderedRing.positive_*-cancel-left (transport isPos x~y (positive_* x>0 y.3)) x.3)
(\lam y>0 => OrderedRing.positive_*-cancel-left (transport isPos (inv x~y) (positive_* y>0 x.3)) y.3)
}
-- | The localization of a decidable ordered commutative ring at the set of positive elements is a discrete ordered field.
\func localization-isDiscreteOrderedField (R : OrderedCRing.Dec) : DiscreteOrderedField \cowith
| DiscreteField => localization-isDiscreteField (localization-isOrderedField.positiveSubset R) zro/>0 (\lam x => \case +_trichotomy x \with {
| less x<0 => byRight (negative ide, simplify (R.<0_neg x<0))
| equals x=0 => byLeft (ide, ide>zro, simplify x=0)
| greater x>0 => byRight (ide, simplify (R.>0_pos x>0))
})
| OrderedField => localization-isOrderedField R
\where \open OrderedRing