Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
39b9971
start
vihdzp Sep 13, 2025
c314f72
Merge branch 'master' into vi.mk_le_mk
vihdzp Sep 13, 2025
8d9b010
prove thm
vihdzp Sep 13, 2025
853fe7e
apply suggestions
vihdzp Sep 13, 2025
fc170dd
Merge branch 'master' into vi.mk_le_mk
vihdzp Sep 13, 2025
0afbbf5
start
vihdzp Sep 15, 2025
b97c80b
continue
vihdzp Sep 15, 2025
3a3d37c
mostly done
vihdzp Sep 15, 2025
fde9a95
finish!
vihdzp Sep 15, 2025
aa1e91f
one more
vihdzp Sep 15, 2025
8625b36
update doc
vihdzp Sep 15, 2025
a19d426
more
vihdzp Sep 15, 2025
ee13ff1
fix typo
vihdzp Sep 15, 2025
3f0b5af
rename
vihdzp Sep 15, 2025
7461324
let's redo this
vihdzp Sep 16, 2025
e6497af
start
vihdzp Sep 16, 2025
72fa232
Merge branch 'master' into vi.quot
vihdzp Sep 16, 2025
29dc1e7
sure
vihdzp Sep 17, 2025
ae29090
small golfs
vihdzp Sep 17, 2025
4e4ba3f
Merge branch 'vi.quot' into vi.real
vihdzp Sep 17, 2025
347df02
std part
vihdzp Sep 18, 2025
0ee3ad0
weaken hyp
vihdzp Sep 18, 2025
dfe3f1a
Update StandardPart.lean
vihdzp Sep 18, 2025
0c7ce91
Update StandardPart.lean
vihdzp Sep 18, 2025
d0c0f5b
Update StandardPart.lean
vihdzp Sep 19, 2025
c6e1846
Merge branch 'master' into vi.real
vihdzp Sep 26, 2025
68e6a25
condensation namedrop
vihdzp Oct 27, 2025
937c260
Merge branch 'master' into vi.quot
vihdzp Nov 27, 2025
4dafe0a
module
vihdzp Nov 27, 2025
e7a11ab
Merge branch 'vi.quot' into vi.real
vihdzp Nov 27, 2025
d3a41f8
Merge branch 'master' into vi.real
vihdzp Nov 27, 2025
705eb58
Update Mathlib.lean
vihdzp Nov 27, 2025
aa44ee9
Merge branch 'master' into vi.real
vihdzp Nov 27, 2025
4ffc855
Update StandardPart.lean
vihdzp Nov 27, 2025
262a3a4
fix
vihdzp Nov 27, 2025
bc9d72a
Update StandardPart.lean
vihdzp Nov 27, 2025
3699283
module
vihdzp Nov 27, 2025
19d91f7
Update StandardPart.lean
vihdzp Nov 28, 2025
fb215d8
there goes
vihdzp Nov 28, 2025
991c640
Update StandardPart.lean
vihdzp Nov 28, 2025
d51e63b
Merge branch 'master' into vi.real
vihdzp Nov 28, 2025
61787f2
apply suggs
vihdzp Nov 28, 2025
4c7096a
Merge branch 'vi.subring' into vi.real
vihdzp Nov 28, 2025
7e8f4da
Update StandardPart.lean
vihdzp Nov 28, 2025
e09e586
Merge branch 'master' into vi.real
vihdzp Dec 9, 2025
e8eda01
golf
vihdzp Dec 9, 2025
156090f
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Dec 9, 2025
8c91b55
Update StandardPart.lean
vihdzp Dec 12, 2025
c252a5c
Update Mathlib.lean
vihdzp Dec 12, 2025
542f720
start fixes
vihdzp Dec 13, 2025
de14015
Merge branch 'master' into vi.real
vihdzp Dec 13, 2025
6ff3303
apply suggestions
vihdzp Dec 13, 2025
8c584c3
make import private
vihdzp Dec 13, 2025
d644179
golf
vihdzp Dec 13, 2025
8ac5d91
Update StandardPart.lean
vihdzp Dec 13, 2025
81aa665
apply suggestions
vihdzp Dec 14, 2025
6b637cb
Update ValuationSubring.lean
vihdzp Dec 14, 2025
b29ac2b
revert
vihdzp Dec 14, 2025
422995b
change design of Finite
vihdzp Dec 14, 2025
8a4160f
Update Mathlib/Algebra/Order/Ring/Archimedean.lean
vihdzp Dec 15, 2025
703ee27
Update StandardPart.lean
vihdzp Dec 15, 2025
460edfa
Merge branch 'vi.real' of https://github.com/vihdzp/mathlib4 into vi.…
vihdzp Dec 15, 2025
3ed25cf
Sure, that works
vihdzp Dec 15, 2025
5bf87aa
Merge branch 'master' into vi.real
vihdzp Dec 15, 2025
07ccdeb
fixes
vihdzp Dec 15, 2025
3afcbec
Apply suggestions from code review
vihdzp Dec 15, 2025
fdca7fe
Update StandardPart.lean
vihdzp Dec 15, 2025
c5c5469
Merge branch 'vi.real' of https://github.com/vihdzp/mathlib4 into vi.…
vihdzp Dec 15, 2025
fedb1f8
Update Mathlib/Algebra/Order/Ring/StandardPart.lean
vihdzp Dec 15, 2025
1c1a0a9
fix docstring
vihdzp Dec 15, 2025
9a7fb4b
Merge branch 'vi.real' of https://github.com/vihdzp/mathlib4 into vi.…
vihdzp Dec 15, 2025
59726d4
add theorems
vihdzp Dec 16, 2025
d7bf159
trivial fix
vihdzp Dec 16, 2025
51804e3
trivial golfs
vihdzp Dec 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,7 @@ public import Mathlib.Algebra.Order.Ring.Ordering.Defs
public import Mathlib.Algebra.Order.Ring.Pow
public import Mathlib.Algebra.Order.Ring.Prod
public import Mathlib.Algebra.Order.Ring.Rat
public import Mathlib.Algebra.Order.Ring.StandardPart
public import Mathlib.Algebra.Order.Ring.Star
public import Mathlib.Algebra.Order.Ring.Synonym
public import Mathlib.Algebra.Order.Ring.Unbundled.Basic
Expand Down
14 changes: 14 additions & 0 deletions Mathlib/Algebra/Order/Ring/Archimedean.lean
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ theorem mk_map_of_archimedean' [Archimedean S] (f : S →+*o R) {x : S} (h : x
mk (f x) = 0 := by
simpa using mk_map_of_archimedean f.toOrderAddMonoidHom h

theorem mk_le_mk_add_of_archimedean [Archimedean S] (f : S →+*o R) (x : R) (y : S) :
mk x ≤ mk (f y) + mk x := by
obtain rfl | hy := eq_or_ne y 0
· simp
· rw [mk_map_of_archimedean' f hy, zero_add]

theorem mk_le_add_mk_of_archimedean [Archimedean S] (f : S →+*o R) (x : R) (y : S) :
mk x ≤ mk x + mk (f y) := by
rw [add_comm]
exact mk_le_mk_add_of_archimedean f x y

theorem mk_map_nonneg_of_archimedean [Archimedean S] (f : S →+*o R) (y : S) : 0 ≤ mk (f y) := by
simpa using mk_le_mk_add_of_archimedean f 1 y

@[simp]
theorem mk_intCast {n : ℤ} (h : n ≠ 0) : mk (n : S) = 0 := by
obtain _ | _ := subsingleton_or_nontrivial S
Expand Down
359 changes: 359 additions & 0 deletions Mathlib/Algebra/Order/Ring/StandardPart.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
/-
Copyright (c) 2025 Violeta Hernández Palacios. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Violeta Hernández Palacios
-/
module

public import Mathlib.Algebra.Order.Ring.Archimedean
public import Mathlib.Algebra.Ring.Subring.Order
public import Mathlib.Data.Real.Archimedean
public import Mathlib.Order.Quotient
public import Mathlib.RingTheory.Valuation.ValuationSubring

import Mathlib.Data.Real.CompleteField

/-!
# Standard part function

Given a finite element in a non-archimedean field, the standard part function rounds it to the
unique closest real number. That is, it chops off any infinitesimals.

Let `K` be a linearly ordered field. The subset of finite elements (i.e. those bounded by a natural
number) is a `ValuationSubring`, which means we can construct its residue field
`FiniteResidueField`, roughly corresponding to the finite elements quotiented by infinitesimals.
This field inherits a `LinearOrder` instance, which makes it into an Archimedean linearly ordered
field, meaning we can uniquely embed it in the reals.

Given a finite element of the field, the `ArchimedeanClass.stdPart` function returns the real number
corresponding to this unique embedding. This function generalizes, among other things, the standard
part function on `Hyperreal`.

## TODO

Redefine `Hyperreal.st` in terms of `ArchimedeanClass.stdPart`.

## References

* https://en.wikipedia.org/wiki/Standard_part_function
-/

@[expose] public section

namespace ArchimedeanClass
variable
{K : Type*} [LinearOrder K] [Field K] [IsOrderedRing K] {x y : K}
{R : Type*} [LinearOrder R] [CommRing R] [IsOrderedRing R] [Archimedean R]

/-! ### Finite residue field -/

variable (K) in
/-- The valuation subring of elements in non-negative Archimedean classes, i.e. elements bounded by
some natural number. -/
noncomputable def FiniteElement : Type _ :=
(addValuation K).toValuation.valuationSubring

namespace FiniteElement

instance : CommRing (FiniteElement K) := by
unfold FiniteElement; infer_instance

instance : IsDomain (FiniteElement K) := by
unfold FiniteElement; infer_instance

instance : ValuationRing (FiniteElement K) := by
unfold FiniteElement; infer_instance

instance : LinearOrder (FiniteElement K) := by
unfold FiniteElement; infer_instance

instance : IsStrictOrderedRing (FiniteElement K) := by
unfold FiniteElement; infer_instance

@[simp] theorem val_zero : (0 : FiniteElement K).1 = 0 := rfl
@[simp] theorem val_one : (1 : FiniteElement K).1 = 1 := rfl
@[simp] theorem val_add (x y : FiniteElement K) : (x + y).1 = x.1 + y.1 := rfl
@[simp] theorem val_sub (x y : FiniteElement K) : (x - y).1 = x.1 - y.1 := rfl
@[simp] theorem val_mul (x y : FiniteElement K) : (x * y).1 = x.1 * y.1 := rfl

@[ext] theorem ext {x y : FiniteElement K} (h : x.1 = y.1) : x = y := Subtype.ext h

/-- The constructor for `FiniteElement`. -/
protected def mk (x : K) (h : 0 ≤ mk x) : FiniteElement K := ⟨x, h⟩

@[simp] theorem mk_zero (h : 0 ≤ mk (0 : K)) : FiniteElement.mk 0 h = 0 := rfl
@[simp] theorem mk_one (h : 0 ≤ mk (1 : K)) : FiniteElement.mk 1 h = 1 := rfl
@[simp] theorem mk_natCast {n : ℕ} (h : 0 ≤ mk (n : K)) : FiniteElement.mk (n : K) h = n := rfl
@[simp] theorem mk_intCast {n : ℤ} (h : 0 ≤ mk (n : K)) : FiniteElement.mk (n : K) h = n := rfl

@[simp]
theorem mk_neg {x : K} (h : 0 ≤ mk x) :
-FiniteElement.mk x h = FiniteElement.mk (-x) (by rwa [mk_neg]) :=
rfl

theorem not_isUnit_iff_mk_pos {x : FiniteElement K} : ¬ IsUnit x ↔ 0 < mk x.1 :=
Valuation.Integer.not_isUnit_iff_valuation_lt_one

theorem isUnit_iff_mk_eq_zero {x : FiniteElement K} : IsUnit x ↔ mk x.1 = 0 := by
rw [← not_iff_not, not_isUnit_iff_mk_pos, lt_iff_not_ge, x.2.ge_iff_eq']

end FiniteElement

variable (K) in
/-- The residue field of `FiniteElement`. This quotient inherits an order from `K`,
which makes it into a linearly ordered Archimedean field. -/
def FiniteResidueField : Type _ :=
IsLocalRing.ResidueField (FiniteElement K)

namespace FiniteResidueField

noncomputable instance : Field (FiniteResidueField K) :=
inferInstanceAs (Field (IsLocalRing.ResidueField _))

private theorem ordConnected_preimage_mk' : ∀ x, Set.OrdConnected <| Quotient.mk
(Submodule.quotientRel (IsLocalRing.maximalIdeal (FiniteElement K))) ⁻¹' {x} := by
refine fun x ↦ ⟨?_⟩
rintro x rfl y hy z ⟨hxz, hzy⟩
have := hxz.trans hzy
rw [Set.mem_preimage, Set.mem_singleton_iff, Quotient.eq, Submodule.quotientRel_def,
IsLocalRing.mem_maximalIdeal, mem_nonunits_iff, FiniteElement.not_isUnit_iff_mk_pos] at hy ⊢
apply hy.trans_le (mk_antitoneOn _ _ _) <;> simpa

noncomputable instance : LinearOrder (FiniteResidueField K) :=
@Quotient.instLinearOrder _ _ _ ordConnected_preimage_mk' (Classical.decRel _)

/-- The quotient map from finite elements on the field to the associated residue field. -/
def mk : FiniteElement K →+*o FiniteResidueField K where
monotone' _ _ h := Quotient.mk_monotone h
__ := IsLocalRing.residue (FiniteElement K)

@[induction_eliminator]
theorem ind {motive : FiniteResidueField K → Prop} (mk : ∀ x, motive (mk x)) : ∀ x, motive x :=
Quotient.ind mk

instance ordConnected_preimage_mk :
∀ x, Set.OrdConnected (mk ⁻¹' ({x} : Set (FiniteResidueField K))) :=
ordConnected_preimage_mk'

theorem mk_eq_mk {x y : FiniteElement K} : mk x = mk y ↔ 0 < ArchimedeanClass.mk (x.1 - y.1) := by
apply Quotient.eq.trans
rw [Submodule.quotientRel_def, IsLocalRing.mem_maximalIdeal, mem_nonunits_iff,
FiniteElement.not_isUnit_iff_mk_pos, AddSubgroupClass.coe_sub]

theorem mk_eq_zero {x : FiniteElement K} : mk x = 0 ↔ 0 < ArchimedeanClass.mk x.1 := by
apply mk_eq_mk.trans
simp

theorem mk_ne_zero {x : FiniteElement K} : mk x ≠ 0 ↔ ArchimedeanClass.mk x.1 = 0 := by
rw [ne_eq, mk_eq_zero, not_lt, x.2.ge_iff_eq']

theorem mk_le_mk {x y : FiniteElement K} : mk x ≤ mk y ↔ x ≤ y ∨ mk x = mk y := by
refine (Quotient.mk_le_mk (H := ordConnected_preimage_mk')).trans ?_
rw [← Quotient.eq_iff_equiv]
rfl

theorem mk_lt_mk {x y : FiniteElement K} : mk x < mk y ↔ x < y ∧ mk x ≠ mk y := by
refine (Quotient.mk_lt_mk (H := ordConnected_preimage_mk')).trans ?_
rw [← Quotient.eq_iff_equiv]
rfl

theorem lt_of_mk_lt_mk {x y : FiniteElement K} (h : mk x < mk y) : x < y :=
(mk_lt_mk.1 h).1

private theorem mul_le_mul_of_nonneg_left' {x y z : FiniteResidueField K} (h : x ≤ y) (hz : 0 ≤ z) :
z * x ≤ z * y := by
induction x with | mk x
induction y with | mk y
induction z with | mk z
rw [← map_mul, ← map_mul]
rw [← map_zero mk] at hz
rw [mk_le_mk] at h hz ⊢
grind [mul_le_mul_of_nonneg_left]

instance : IsOrderedRing (FiniteResidueField K) where
zero_le_one := mk.monotone' zero_le_one
add_le_add_left x y h z := by
induction x with | mk x
induction y with | mk y
induction z with | mk z
obtain h | h := mk_le_mk.1 h
· exact mk.monotone' <| add_le_add_left h _
· rw [h]
mul_le_mul_of_nonneg_left _ hx _ _ h := mul_le_mul_of_nonneg_left' h hx
mul_le_mul_of_nonneg_right x hx y z h := by
simp_rw [mul_comm _ x]
exact mul_le_mul_of_nonneg_left' h hx

instance : Archimedean (FiniteResidueField K) where
arch x y hy := by
induction x with | mk x
induction y with | mk y
obtain hx | hx := le_or_gt (mk x) 0
· use 0
rwa [zero_nsmul]
· obtain ⟨n, hn⟩ := ((mk_ne_zero.1 hy.ne').trans (mk_ne_zero.1 hx.ne').symm).le
refine ⟨n, mk.monotone' ?_⟩
change x.1 ≤ n • y.1
convert ← hn
· exact abs_of_pos <| lt_of_mk_lt_mk hx
· exact abs_of_pos <| lt_of_mk_lt_mk hy

/-- An embedding from an Archimedean field into `K` induces an embedding into
`FiniteResidueField K`. -/
def ofArchimedean (f : R →+*o K) : R →+*o FiniteResidueField K where
toFun r := mk <| .mk _ (mk_map_nonneg_of_archimedean f r)
map_zero' := by simp
map_one' := by simp
map_add' x y := by
simp_rw [map_add]
exact mk.map_add
(.mk _ (mk_map_nonneg_of_archimedean f x)) (.mk _ (mk_map_nonneg_of_archimedean f y))
map_mul' x y := by
simp_rw [map_mul]
exact mk.map_mul
(.mk _ (mk_map_nonneg_of_archimedean f x)) (.mk _ (mk_map_nonneg_of_archimedean f y))
monotone' x y h := mk.monotone' <| f.monotone' h

theorem ofArchimedean_apply (f : R →+*o K) (r : R) :
ofArchimedean f r = mk (.mk _ (mk_map_nonneg_of_archimedean f r)) :=
rfl

theorem ofArchimedean_injective (f : R →+*o K) : Function.Injective (ofArchimedean f) := by
rw [injective_iff_map_eq_zero]
intro r hr
contrapose! hr
rw [ofArchimedean_apply, mk_ne_zero]
exact mk_map_of_archimedean' f hr

@[simp]
theorem ofArchimedean_inj (f : R →+*o K) {x y : R} :
ofArchimedean f x = ofArchimedean f y ↔ x = y :=
(ofArchimedean_injective f).eq_iff

end FiniteResidueField

/-! ### Standard part -/

/-- The standard part of a `FiniteElement` is the unique real number with an infinitesimal
difference.
Comment on lines +237 to +238
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add that as a lemma characterizing this def?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had that on a follow-up PR, but I can move it here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added this theorem, along with some prerequisite lemmas.


For any infinite inputs, this function outputs a junk value of 0. -/
@[no_expose]
noncomputable def stdPart (x : K) : ℝ :=
if h : 0 ≤ mk x then
OrderRingHom.comp default FiniteResidueField.mk (.mk x h) else 0

theorem stdPart_of_mk_ne_zero (h : mk x ≠ 0) : stdPart x = 0 := by
obtain h | h := h.lt_or_gt
· exact dif_neg h.not_ge
· rw [stdPart, dif_pos h.le, OrderRingHom.comp_apply, FiniteResidueField.mk_eq_zero.2 h,
map_zero]

theorem stdPart_of_mk_nonneg (f : FiniteResidueField K →+*o ℝ) (h : 0 ≤ mk x) :
stdPart x = f (.mk <| .mk x h) := by
rw [stdPart, dif_pos h, OrderRingHom.comp_apply]
congr
exact Subsingleton.allEq _ _

@[simp]
theorem stdPart_zero : stdPart (0 : K) = 0 := by
rw [stdPart, dif_pos] <;> simp

@[simp]
theorem stdPart_one : stdPart (1 : K) = 1 := by
rw [stdPart, dif_pos] <;> simp

@[simp]
theorem stdPart_neg (x : K) : stdPart (-x) = -stdPart x := by
simp_rw [stdPart, ArchimedeanClass.mk_neg]
split_ifs
· rw [← FiniteElement.mk_neg, map_neg]
· simp

@[simp]
theorem stdPart_inv (x : K) : stdPart x⁻¹ = (stdPart x)⁻¹ := by
obtain hx | hx := eq_or_ne (mk x) 0
· unfold stdPart
have hx' : 0 ≤ mk x⁻¹ := by simp_all
rw [dif_pos hx.ge, dif_pos hx']
· apply eq_inv_of_mul_eq_one_left
suffices FiniteElement.mk x⁻¹ hx' * .mk x hx.ge = 1 by
rw [← map_mul, this, map_one]
ext
apply inv_mul_cancel₀
aesop
· rw [stdPart_of_mk_ne_zero hx, stdPart_of_mk_ne_zero, inv_zero]
rwa [mk_inv, neg_ne_zero]

theorem stdPart_add (hx : 0 ≤ mk x) (hy : 0 ≤ mk y) :
stdPart (x + y) = stdPart x + stdPart y := by
unfold stdPart
rw [dif_pos hx, dif_pos hy, dif_pos]
exact map_add _ (FiniteElement.mk x hx) (.mk y hy)

theorem stdPart_sub (hx : 0 ≤ mk x) (hy : 0 ≤ mk y) :
stdPart (x - y) = stdPart x - stdPart y := by
rw [sub_eq_add_neg, sub_eq_add_neg, stdPart_add hx, stdPart_neg]
rwa [mk_neg]

theorem stdPart_mul {x y : K} (hx : 0 ≤ mk x) (hy : 0 ≤ mk y) :
stdPart (x * y) = stdPart x * stdPart y := by
unfold stdPart
rw [dif_pos hx, dif_pos hy, dif_pos]
exact map_mul _ (FiniteElement.mk x hx) (.mk y hy)

theorem stdPart_div (hx : 0 ≤ mk x) (hy : 0 ≤ -mk y) :
stdPart (x / y) = stdPart x / stdPart y := by
rw [div_eq_mul_inv, div_eq_mul_inv, stdPart_mul hx, stdPart_inv]
rwa [mk_inv]

@[simp]
theorem stdPart_intCast (n : ℤ) : stdPart (n : K) = n := by
obtain rfl | hn := eq_or_ne n 0
· simp
· rw [stdPart, dif_pos]
· rw [FiniteElement.mk_intCast]
simp
· rw [mk_intCast hn]

@[simp]
theorem stdPart_natCast (n : ℕ) : stdPart (n : K) = n :=
mod_cast stdPart_intCast n

@[simp]
theorem stdPart_ofNat (n : ℕ) [n.AtLeastTwo] : stdPart (ofNat(n) : K) = n :=
stdPart_natCast n

@[simp]
theorem stdPart_ratCast (q : ℚ) : stdPart (q : K) = q := by
cases q with | div n d hd
simp_rw [Rat.cast_div, Rat.cast_intCast, Rat.cast_natCast]
obtain rfl | hn := eq_or_ne n 0
· simp
· rw [stdPart_div]
· simp
· rw [mk_intCast hn]
· rw [mk_natCast hd, neg_zero]

@[simp]
theorem stdPart_real (f : ℝ →+*o K) (r : ℝ) : stdPart (f r) = r := by
rw [stdPart, dif_pos]
exact r.ringHom_apply <| OrderRingHom.comp _ (FiniteResidueField.ofArchimedean f)

theorem ofArchimedean_stdPart (f : ℝ →+*o K) (hx : 0 ≤ mk x) :
FiniteResidueField.ofArchimedean f (stdPart x) = .mk (.mk x hx) := by
rw [stdPart, dif_pos hx, ← OrderRingHom.comp_apply, ← OrderRingHom.comp_assoc,
OrderRingHom.comp_apply, OrderRingHom.apply_eq_self]

/-- The standard part of `x` is the unique real `r` such that `x - r` is infinitesimal. -/
theorem mk_sub_pos_iff (f : ℝ →+*o K) {r : ℝ} (hx : 0 ≤ mk x) :
0 < mk (x - f r) ↔ stdPart x = r := by
refine (FiniteResidueField.mk_eq_zero
(x := .mk x hx - .mk _ (mk_map_nonneg_of_archimedean f r))).symm.trans ?_
rw [map_sub, ← FiniteResidueField.ofArchimedean_apply, ← ofArchimedean_stdPart f hx,
sub_eq_zero, FiniteResidueField.ofArchimedean_inj f]

theorem mk_sub_stdPart_pos (f : ℝ →+*o K) (hx : 0 ≤ mk x) : 0 < mk (x - f (stdPart x)) :=
(mk_sub_pos_iff f hx).2 rfl

end ArchimedeanClass
2 changes: 1 addition & 1 deletion Mathlib/Order/Quotient.lean
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ theorem mk_le_mk {x y : α} : Quotient.mk s x ≤ Quotient.mk s y ↔ x ≤ y
exact fun h ↦ ((H _).out h₁.symm rfl ⟨h₂, h.le⟩).symm
· exact .inr (_root_.trans h₁ h₂)

instance [DecidableRel (· ≈ · : α → α → Prop)] : LinearOrder (Quotient s) where
instance instLinearOrder [DecidableRel (· ≈ · : α → α → Prop)] : LinearOrder (Quotient s) where
le_antisymm x y h₁ h₂ := by
induction x using Quotient.inductionOn with | h x
induction y using Quotient.inductionOn with | h y
Expand Down
Loading