Skip to content

Commit 4ca1c2e

Browse files
committed
refactor: make LinearOrderedCommMonoidWithZeros cancellative (leanprover-community#31749)
It appears that the only interesting `LinearOrderedCommMonoidWithZero`s are the ones for which every non-zero element is regular. This PR therefore strenghtens `LinearOrderedCommMonoidWithZero`, and similarly for `LinearOrderedAddCommMonoidWithTop`, its additive counterpart. Here are the instances we lose: * `ENNReal`: multiplication by `\top` isn't injective * `ERealᵒᵈ`: multiplication by `\top` isn't injective * `Cardinal`: multiplication by anything but 1 isn't injective * `ArchimedeanClass R` where `R` is a non-strict ordered ring * the pathological counterexample of a `LinearOrderedCommMonoidWithZero` where two positive numbers multiply to zero I believe these are all fine to lose since they had no mathematical motivation (we never use those as targets of valuations). There is an argument to be made that we could keep the existing typeclass as is and instead have the one I'm currently replacing it with under the name `LinearOrderedCancelCommMonoidWithZero`. There are at least two reasons I do not want to do this: 1. We have no evidence that the weaker typeclass is actually useful 2. `LinearOrderedCommMonoidWithZero`, weak or strong version, extends both the algebra and order hierarchy, which is something we want to move away from. Therefore, if anything, we should not be adding more of those typeclasses. This will be used in a later PR to replace `pow_eq_one_iff` with `IsMulTorsionFree.pow_eq_one_iff_left`. [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Should.20linear.20ordered.20comm.20monoids.20with.20zero.20be.20torsion-free)
1 parent 0e883f0 commit 4ca1c2e

File tree

35 files changed

+237
-319
lines changed

35 files changed

+237
-319
lines changed

Counterexamples.lean

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import Counterexamples.Girard
1212
import Counterexamples.HeawoodUnitDistance
1313
import Counterexamples.HomogeneousPrimeNotPrime
1414
import Counterexamples.IrrationalPowerOfIrrational
15-
import Counterexamples.LinearOrderWithPosMulPosEqZero
1615
import Counterexamples.MapFloor
1716
import Counterexamples.MonicNonRegular
1817
import Counterexamples.Motzkin

Counterexamples/LinearOrderWithPosMulPosEqZero.lean

Lines changed: 0 additions & 90 deletions
This file was deleted.

Mathlib/Algebra/Order/AddGroupWithTop.lean

Lines changed: 79 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ public import Mathlib.Algebra.CharZero.Defs
99
public import Mathlib.Algebra.Group.Hom.Defs
1010
public import Mathlib.Algebra.Order.Monoid.Canonical.Defs
1111
public import Mathlib.Algebra.Order.Monoid.WithTop
12+
public import Mathlib.Algebra.Regular.Basic
1213

14+
import Mathlib.Tactic.ByContra
1315
import Mathlib.Tactic.TermCongr
1416

1517
/-!
@@ -37,16 +39,22 @@ class LinearOrderedAddCommMonoidWithTop (α : Type*) extends
3739
AddCommMonoid α, LinearOrder α, IsOrderedAddMonoid α, OrderTop α where
3840
/-- In a `LinearOrderedAddCommMonoidWithTop`, the `⊤` element is invariant under addition. -/
3941
protected top_add' : ∀ x : α, ⊤ + x = ⊤
42+
protected isAddLeftRegular_of_ne_top ⦃x : α⦄ : x ≠ ⊤ → IsAddLeftRegular x
4043

4144
/-- A linearly ordered commutative group with an additively absorbing `⊤` element.
4245
Instances should include number systems with an infinite element adjoined. -/
43-
class LinearOrderedAddCommGroupWithTop (α : Type*) extends LinearOrderedAddCommMonoidWithTop α,
44-
SubNegMonoid α, Nontrivial α where
46+
-- We do not extend `LinearOrderedAddCommMonoidWithTop` as that would bring in the unnecessary
47+
-- `isAddLeftRegular_of_ne_top` field.
48+
class LinearOrderedAddCommGroupWithTop (α : Type*)
49+
extends AddCommMonoid α, LinearOrder α, IsOrderedAddMonoid α, OrderTop α, SubNegMonoid α,
50+
Nontrivial α where
51+
/-- In a `LinearOrderedAddCommMonoidWithTop`, the `⊤` element is invariant under addition. -/
52+
protected top_add' (x : α) : ⊤ + x = ⊤
4553
neg_top : -(⊤ : α) = ⊤
4654
add_neg_cancel_of_ne_top ⦃x : α⦄ : x ≠ ⊤ → x + -x = 0
4755

4856
section LinearOrderedAddCommMonoidWithTop
49-
variable [LinearOrderedAddCommMonoidWithTop α]
57+
variable [LinearOrderedAddCommMonoidWithTop α] {a b c : α}
5058

5159
@[simp]
5260
theorem top_add (a : α) : ⊤ + a = ⊤ :=
@@ -56,13 +64,52 @@ theorem top_add (a : α) : ⊤ + a = ⊤ :=
5664
theorem add_top (a : α) : a + ⊤ = ⊤ :=
5765
Trans.trans (add_comm _ _) (top_add _)
5866

67+
@[simp] lemma IsAddRegular.of_ne_top (ha : a ≠ ⊤) : IsAddRegular a := by
68+
simpa using LinearOrderedAddCommMonoidWithTop.isAddLeftRegular_of_ne_top ha
69+
70+
lemma add_left_injective_of_ne_top (b : α) (h : b ≠ ⊤) : Function.Injective (fun x ↦ x + b) :=
71+
(IsAddRegular.of_ne_top h).2
72+
73+
lemma add_right_injective_of_ne_top (b : α) (h : b ≠ ⊤) : Function.Injective (fun x ↦ b + x) :=
74+
(IsAddRegular.of_ne_top h).1
75+
76+
@[simp]
77+
lemma add_left_inj_of_ne_top (h : a ≠ ⊤) : b + a = c + a ↔ b = c :=
78+
(add_left_injective_of_ne_top _ h).eq_iff
79+
80+
@[simp]
81+
lemma add_right_inj_of_ne_top (h : a ≠ ⊤) : a + b = a + c ↔ b = c :=
82+
(add_right_injective_of_ne_top _ h).eq_iff
83+
84+
lemma add_left_strictMono_of_ne_top (h : b ≠ ⊤) : StrictMono (fun x ↦ x + b) :=
85+
add_left_mono.strictMono_of_injective <| add_left_injective_of_ne_top _ h
86+
87+
lemma add_right_strictMono_of_ne_top (h : b ≠ ⊤) : StrictMono (fun x ↦ b + x) :=
88+
add_right_mono.strictMono_of_injective <| add_right_injective_of_ne_top _ h
89+
90+
@[simp]
91+
lemma add_le_add_iff_left_of_ne_top (h : a ≠ ⊤) : b + a ≤ c + a ↔ b ≤ c :=
92+
(add_left_strictMono_of_ne_top h).le_iff_le
93+
94+
@[simp]
95+
lemma add_le_add_iff_right_of_ne_top (h : a ≠ ⊤) : a + b ≤ a + c ↔ b ≤ c :=
96+
(add_right_strictMono_of_ne_top h).le_iff_le
97+
98+
@[simp]
99+
lemma add_lt_add_iff_left_of_ne_top (h : a ≠ ⊤) : b + a < c + a ↔ b < c :=
100+
(add_left_strictMono_of_ne_top h).lt_iff_lt
101+
102+
@[simp]
103+
lemma add_lt_add_iff_right_of_ne_top (h : a ≠ ⊤) : a + b < a + c ↔ b < c :=
104+
(add_right_strictMono_of_ne_top h).lt_iff_lt
105+
59106
end LinearOrderedAddCommMonoidWithTop
60107

61108
namespace LinearOrderedAddCommGroupWithTop
62109

63-
variable [LinearOrderedAddCommGroupWithTop α] {a b : α}
110+
variable [LinearOrderedAddCommGroupWithTop α] {a b c : α}
64111

65-
attribute [simp] LinearOrderedAddCommGroupWithTop.neg_top
112+
attribute [simp] neg_top
66113

67114
@[deprecated (since := "2025-12-14")] protected alias add_neg_cancel := add_neg_cancel_of_ne_top
68115

@@ -87,29 +134,19 @@ lemma neg_add_cancel_right_of_ne_top (hb : b ≠ ⊤) (a : α) : a + -b + b = a
87134
intro h
88135
obtain ⟨a, ha⟩ := exists_ne (0 : α)
89136
rw [← zero_add a] at ha
90-
simp [top_add, -zero_add, ← h] at ha
137+
simp [LinearOrderedAddCommGroupWithTop.top_add', -zero_add, ← h] at ha
91138

92139
@[simp] lemma zero_ne_top : 0 ≠ (⊤ : α) := top_ne_zero.symm
93140

94141
@[simp] lemma top_pos : (0 : α) < ⊤ := lt_top_iff_ne_top.2 top_ne_zero.symm
95142

96-
@[simp]
97-
lemma add_neg_cancel_iff_ne_top : a + -a = 0 ↔ a ≠ ⊤ where
98-
mp := by contrapose; simp +contextual
99-
mpr h := add_neg_cancel_of_ne_top h
100-
101-
@[simp]
102-
lemma sub_self_eq_zero_iff_ne_top : a - a = 0 ↔ a ≠ ⊤ := by
103-
rw [sub_eq_add_neg, add_neg_cancel_iff_ne_top]
104-
105-
alias ⟨_, sub_self_eq_zero_of_ne_top⟩ := sub_self_eq_zero_iff_ne_top
106-
107143
@[simp] lemma isAddUnit_iff : IsAddUnit a ↔ a ≠ ⊤ where
108-
mp := by rintro ⟨⟨b, c, hbc, -⟩, rfl⟩ rfl; simp [top_add] at hbc
144+
mp := by rintro ⟨⟨b, c, hbc, -⟩, rfl⟩ rfl; simp [LinearOrderedAddCommGroupWithTop.top_add'] at hbc
109145
mpr ha := .of_add_eq_zero (-a) <| by simp [ha, add_neg_cancel_of_ne_top]
110146

111147
instance : LinearOrderedAddCommMonoidWithTop α where
112-
top_add' := top_add
148+
top_add' := LinearOrderedAddCommGroupWithTop.top_add'
149+
isAddLeftRegular_of_ne_top _a ha := (isAddUnit_iff.2 ha).isAddRegular.1
113150

114151
lemma add_ne_top : a + b ≠ ⊤ ↔ a ≠ ⊤ ∧ b ≠ ⊤ := by simp [← isAddUnit_iff]
115152

@@ -140,92 +177,67 @@ instance (priority := 100) toSubtractionMonoid : SubtractionMonoid α where
140177
have ha : a ≠ ⊤ := by rintro rfl; simp at h
141178
exact left_neg_eq_right_neg (a := a) (by simp [neg_add_cancel_of_ne_top, *]) h
142179

143-
lemma add_left_injective_of_ne_top (b : α) (h : b ≠ ⊤) : Function.Injective fun x ↦ x + b :=
144-
fun x y hxy ↦ by simpa [h] using congr($hxy - b)
145-
146180
@[deprecated (since := "2025-12-27")]
147181
alias injective_add_left_of_ne_top := add_left_injective_of_ne_top
148182

149-
lemma add_right_injective_of_ne_top (b : α) (h : b ≠ ⊤) : Function.Injective fun x ↦ b + x := by
150-
simpa [add_comm] using add_left_injective_of_ne_top b h
151-
152183
@[deprecated (since := "2025-12-27")]
153184
alias injective_add_right_of_ne_top := add_right_injective_of_ne_top
154185

155-
@[simp]
156-
lemma add_left_inj_of_ne_top {a b c : α} (h : a ≠ ⊤) : b + a = c + a ↔ b = c :=
157-
(add_left_injective_of_ne_top _ h).eq_iff
158-
159-
@[simp]
160-
lemma add_right_inj_of_ne_top {a b c : α} (h : a ≠ ⊤) : a + b = a + c ↔ b = c :=
161-
(add_right_injective_of_ne_top _ h).eq_iff
162-
163-
lemma sub_left_injective_of_ne_top (b : α) (h : b ≠ ⊤) : Function.Injective fun x ↦ x - b := by
186+
lemma sub_left_injective_of_ne_top (h : b ≠ ⊤) : Function.Injective fun x ↦ x - b := by
164187
simpa [sub_eq_add_neg] using add_left_injective_of_ne_top (-b) (by simpa)
165188

166-
lemma sub_right_injective_of_ne_top (b : α) (h : b ≠ ⊤) : Function.Injective fun x ↦ b - x := by
189+
lemma sub_right_injective_of_ne_top (h : b ≠ ⊤) : Function.Injective fun x ↦ b - x := by
167190
simpa [sub_eq_add_neg] using (add_right_injective_of_ne_top b h).comp neg_injective
168191

169192
@[simp]
170-
lemma sub_left_inj_of_ne_top {a b c : α} (h : a ≠ ⊤) : b - a = c - a ↔ b = c :=
171-
(sub_left_injective_of_ne_top _ h).eq_iff
193+
lemma sub_left_inj_of_ne_top (h : a ≠ ⊤) : b - a = c - a ↔ b = c :=
194+
(sub_left_injective_of_ne_top h).eq_iff
172195

173196
@[simp]
174-
lemma sub_right_inj_of_ne_top {a b c : α} (h : a ≠ ⊤) : a - b = a - c ↔ b = c :=
175-
(sub_right_injective_of_ne_top _ h).eq_iff
176-
177-
lemma add_left_strictMono_of_ne_top (b : α) (h : b ≠ ⊤) : StrictMono fun x ↦ x + b :=
178-
(Monotone.add_const monotone_id _).strictMono_of_injective (add_left_injective_of_ne_top _ h)
197+
lemma sub_right_inj_of_ne_top (h : a ≠ ⊤) : a - b = a - c ↔ b = c :=
198+
(sub_right_injective_of_ne_top h).eq_iff
179199

180200
@[deprecated (since := "2025-12-27")]
181201
alias strictMono_add_left_of_ne_top := add_left_strictMono_of_ne_top
182202

183-
lemma add_right_strictMono_of_ne_top (b : α) (h : b ≠ ⊤) : StrictMono fun x ↦ b + x := by
184-
simpa [add_comm] using add_left_strictMono_of_ne_top b h
185-
186203
@[deprecated (since := "2025-12-27")]
187204
alias strictMono_add_right_of_ne_top := add_right_strictMono_of_ne_top
188205

189-
@[simp]
190-
lemma add_le_add_iff_left_of_ne_top {a b c : α} (h : a ≠ ⊤) : b + a ≤ c + a ↔ b ≤ c :=
191-
(add_left_strictMono_of_ne_top _ h).le_iff_le
206+
lemma sub_left_strictMono_of_ne_top (h : b ≠ ⊤) : StrictMono fun x ↦ x - b := by
207+
simpa [sub_eq_add_neg] using add_left_strictMono_of_ne_top (b := -b) (by simpa)
192208

193209
@[simp]
194-
lemma add_le_add_iff_right_of_ne_top {a b c : α} (h : a ≠ ⊤) : a + b ≤ a + c ↔ b ≤ c :=
195-
(add_right_strictMono_of_ne_top _ h).le_iff_le
210+
lemma sub_le_sub_iff_left_of_ne_top (h : a ≠ ⊤) : b - a ≤ c - a ↔ b ≤ c :=
211+
(sub_left_strictMono_of_ne_top h).le_iff_le
196212

197213
@[simp]
198-
lemma add_lt_add_iff_left_of_ne_top {a b c : α} (h : a ≠ ⊤) : b + a < c + a ↔ b < c :=
199-
(add_left_strictMono_of_ne_top _ h).lt_iff_lt
214+
lemma sub_lt_sub_iff_left_of_ne_top (h : a ≠ ⊤) : b - a < c - a ↔ b < c :=
215+
(sub_left_strictMono_of_ne_top h).lt_iff_lt
200216

201217
@[simp]
202-
lemma add_lt_add_iff_right_of_ne_top {a b c : α} (h : a ≠ ⊤) : a + b < a + c ↔ b < c :=
203-
(add_right_strictMono_of_ne_top _ h).lt_iff_lt
204-
205-
lemma sub_left_strictMono_of_ne_top (b : α) (h : b ≠ ⊤) : StrictMono fun x ↦ x - b := by
206-
simpa [sub_eq_add_neg] using add_left_strictMono_of_ne_top (-b) (by simpa)
218+
lemma add_neg_cancel_iff_ne_top : a + -a = 0 ↔ a ≠ ⊤ where
219+
mp := by contrapose; simp +contextual
220+
mpr h := add_neg_cancel_of_ne_top h
207221

208222
@[simp]
209-
lemma sub_le_sub_iff_left_of_ne_top {a b c : α} (h : a ≠ ⊤) : b - a ≤ c - a ↔ b ≤ c :=
210-
(sub_left_strictMono_of_ne_top _ h).le_iff_le
223+
lemma sub_self_eq_zero_iff_ne_top : a - a = 0 a ≠ ⊤ := by
224+
rw [sub_eq_add_neg, add_neg_cancel_iff_ne_top]
211225

212-
@[simp]
213-
lemma sub_lt_sub_iff_left_of_ne_top {a b c : α} (h : a ≠ ⊤) : b - a < c - a ↔ b < c :=
214-
(sub_left_strictMono_of_ne_top _ h).lt_iff_lt
226+
alias ⟨_, sub_self_eq_zero_of_ne_top⟩ := sub_self_eq_zero_iff_ne_top
215227

216-
lemma sub_pos (a b : α) : 0 < a - b ↔ b < a ∨ b = ⊤ := by
228+
lemma sub_pos : 0 < a - b ↔ b < a ∨ b = ⊤ := by
217229
obtain rfl | hb := eq_or_ne b ⊤
218230
· simp
219-
· rw [← sub_self_eq_zero_of_ne_top hb]
220-
simp [hb]
231+
· simp [← sub_self_eq_zero_of_ne_top hb, hb]
221232

222233
end LinearOrderedAddCommGroupWithTop
223234

224235
namespace WithTop
225236

226-
instance linearOrderedAddCommMonoidWithTop [AddCommMonoid α] [LinearOrder α]
237+
instance linearOrderedAddCommMonoidWithTop [AddCancelCommMonoid α] [LinearOrder α]
227238
[IsOrderedAddMonoid α] : LinearOrderedAddCommMonoidWithTop (WithTop α) where
228239
top_add' := WithTop.top_add
240+
isAddLeftRegular_of_ne_top _a ha _b _c := WithTop.add_left_cancel ha
229241

230242
namespace LinearOrderedAddCommGroup
231243
variable [AddCommGroup G] {x y : WithTop G}
@@ -254,6 +266,7 @@ instance instSub : Sub (WithTop G) where
254266
cases x <;> cases y <;> simp [← coe_sub]
255267

256268
instance [LinearOrder G] [IsOrderedAddMonoid G] : LinearOrderedAddCommGroupWithTop (WithTop G) where
269+
__ := WithTop.linearOrderedAddCommMonoidWithTop
257270
sub_eq_add_neg a b := by cases a <;> cases b <;> simp [← coe_sub, ← coe_neg, sub_eq_add_neg]
258271
neg_top := WithTop.map_top _
259272
zsmul := zsmulRec

Mathlib/Algebra/Order/Field/Canonical.lean

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ abbrev CanonicallyOrderedAdd.toLinearOrderedCommGroupWithZero :
2323
LinearOrderedCommGroupWithZero α where
2424
bot := 0
2525
bot_le := zero_le
26-
zero_le_one := zero_le_one
27-
mul_le_mul_left _ _ h _ := by grw [h]
26+
zero_le := zero_le
27+
mul_lt_mul_of_pos_left _a ha _b _c hbc :=
28+
have : PosMulStrictMono α := PosMulReflectLT.toPosMulStrictMono _
29+
mul_lt_mul_of_pos_left hbc ha
2830

2931
variable [IsStrictOrderedRing α] [Sub α] [OrderedSub α]
3032

0 commit comments

Comments
 (0)