Skip to content

Commit 337d737

Browse files
committed
chore(Order/Basic): use @[to_dual] for Preorder/PartialOrder (#31852)
This PR tags some part of `Mathlib.Order.Basic` with `@[to_dual]`. This PR adds a lot of new declarations in cases where there used to not be a dual declaration (and even a new simp lemma `ne_iff_gt_iff_ge`). The sections for pure `LE`/`LT`, and `LinearOrder` in this file are left to be tagged for future PRs.
1 parent 7df6728 commit 337d737

File tree

1 file changed

+67
-91
lines changed

1 file changed

+67
-91
lines changed

Mathlib/Order/Basic.lean

Lines changed: 67 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ provide many aliases to dot notation-less lemmas. For example, `le_trans` is ali
5353
## TODO
5454
5555
- expand module docs
56-
- automatic construction of dual definitions / theorems
5756
5857
## Tags
5958
@@ -123,76 +122,71 @@ section Preorder
123122

124123
variable [Preorder α] {a b c d : α}
125124

125+
@[to_dual self (reorder := a b)]
126126
theorem not_lt_iff_not_le_or_ge : ¬a < b ↔ ¬a ≤ b ∨ b ≤ a := by
127127
rw [lt_iff_le_not_ge, Classical.not_and_iff_not_or_not, Classical.not_not]
128128

129129
-- Unnecessary brackets are here for readability
130+
@[to_dual self (reorder := a b)]
130131
lemma not_lt_iff_le_imp_ge : ¬ a < b ↔ (a ≤ b → b ≤ a) := by
131132
simp [not_lt_iff_not_le_or_ge, or_iff_not_imp_left]
132133

133134
@[deprecated (since := "2025-05-11")] alias not_lt_iff_le_imp_le := not_lt_iff_le_imp_ge
134135

135-
@[simp] lemma lt_self_iff_false (x : α) : x < x ↔ False := ⟨lt_irrefl x, False.elim⟩
136-
137-
alias le_trans' := ge_trans
138-
alias lt_trans' := gt_trans
139-
alias LE.le.trans := le_trans
140-
alias LE.le.trans' := le_trans'
141-
alias LT.lt.trans := lt_trans
142-
alias LT.lt.trans' := lt_trans'
143-
alias LE.le.trans_lt := lt_of_le_of_lt
144-
alias LE.le.trans_lt' := lt_of_le_of_lt'
145-
alias LT.lt.trans_le := lt_of_lt_of_le
146-
alias LT.lt.trans_le' := lt_of_lt_of_le'
147-
alias LE.le.lt_of_not_ge := lt_of_le_not_ge
148-
alias LT.lt.le := le_of_lt
149-
alias LT.lt.ne := ne_of_lt
150-
alias Eq.le := le_of_eq
151-
alias Eq.ge := ge_of_eq
152-
alias LT.lt.asymm := lt_asymm
153-
alias LT.lt.not_gt := lt_asymm
136+
@[simp, to_dual self]
137+
lemma lt_self_iff_false (x : α) : x < x ↔ False := ⟨lt_irrefl x, False.elim⟩
154138

155-
@[deprecated (since := "2025-05-11")] alias LE.le.lt_of_not_le := LE.le.lt_of_not_ge
156-
@[deprecated (since := "2025-06-07")] alias LT.lt.not_lt := LT.lt.not_gt
139+
@[to_dual ge_trans'] alias le_trans' := ge_trans
140+
@[to_dual gt_trans'] alias lt_trans' := gt_trans
141+
@[to_dual trans'] alias LE.le.trans := le_trans
142+
@[to_dual trans'] alias LT.lt.trans := lt_trans
143+
@[to_dual trans_lt'] alias LE.le.trans_lt := lt_of_le_of_lt
144+
@[to_dual trans_le'] alias LT.lt.trans_le := lt_of_lt_of_le
157145

158-
theorem ne_of_not_le (h : ¬a ≤ b) : a ≠ b := fun hab ↦ h (le_of_eq hab)
146+
@[to_dual self (reorder := a b)] alias LE.le.lt_of_not_ge := lt_of_le_not_ge
147+
@[to_dual self (reorder := a b)] alias LT.lt.le := le_of_lt
148+
@[to_dual self (reorder := a b)] alias LT.lt.asymm := lt_asymm
149+
@[to_dual self (reorder := a b)] alias LT.lt.not_gt := lt_asymm
159150

160-
protected lemma Eq.not_lt (hab : a = b) : ¬a < b := fun h' ↦ h'.ne hab
161-
protected lemma Eq.not_gt (hab : a = b) : ¬b < a := hab.symm.not_lt
151+
@[to_dual ne'] alias LT.lt.ne := ne_of_lt
152+
@[to_dual ge] alias Eq.le := le_of_eq
162153

163-
@[simp] lemma le_of_subsingleton [Subsingleton α] : a ≤ b := (Subsingleton.elim a b).le
154+
@[to_dual self] protected lemma LT.lt.false : a < a → False := lt_irrefl a
164155

165-
-- Making this a @[simp] lemma causes confluence problems downstream.
166-
@[nontriviality]
167-
lemma not_lt_of_subsingleton [Subsingleton α] : ¬a < b := (Subsingleton.elim a b).not_lt
156+
@[to_dual not_gt] protected lemma Eq.not_lt (hab : a = b) : ¬a < b := fun h' ↦ h'.ne hab
168157

169-
namespace LT.lt
158+
@[deprecated (since := "2025-05-11")] alias LE.le.lt_of_not_le := LE.le.lt_of_not_ge
159+
@[deprecated (since := "2025-06-07")] alias LT.lt.not_lt := LT.lt.not_gt
170160

171-
protected theorem false : a < a → False := lt_irrefl a
161+
@[to_dual ne_of_not_ge]
162+
theorem ne_of_not_le (h : ¬a ≤ b) : a ≠ b := fun hab ↦ h (le_of_eq hab)
172163

173-
theorem ne' (h : a < b) : b ≠ a := h.ne.symm
164+
@[simp, to_dual self (reorder := a b)]
165+
lemma le_of_subsingleton [Subsingleton α] : a ≤ b := (Subsingleton.elim a b).le
174166

175-
end LT.lt
167+
-- Making this a @[simp] lemma causes confluence problems downstream.
168+
@[nontriviality, to_dual self (reorder := a b)]
169+
lemma not_lt_of_subsingleton [Subsingleton α] : ¬a < b := (Subsingleton.elim a b).not_lt
176170

171+
@[to_dual le_of_forall_ge]
177172
theorem le_of_forall_le (H : ∀ c, c ≤ a → c ≤ b) : a ≤ b := H _ le_rfl
178-
theorem le_of_forall_ge (H : ∀ c, a ≤ c → b ≤ c) : b ≤ a := H _ le_rfl
179173

174+
@[to_dual forall_ge_iff_le]
180175
theorem forall_le_iff_le : (∀ ⦃c⦄, c ≤ a → c ≤ b) ↔ a ≤ b :=
181176
⟨le_of_forall_le, fun h _ hca ↦ le_trans hca h⟩
182177

183-
theorem forall_ge_iff_le : (∀ ⦃c⦄, a ≤ c → b ≤ c) ↔ b ≤ a :=
184-
⟨le_of_forall_ge, fun h _ hca ↦ le_trans h hca⟩
185-
186178
@[deprecated (since := "2025-07-27")] alias forall_le_iff_ge := forall_ge_iff_le
187179

188180
/-- monotonicity of `≤` with respect to `→` -/
189-
@[gcongr] theorem le_imp_le_of_le_of_le (h₁ : c ≤ a) (h₂ : b ≤ d) : a ≤ b → c ≤ d :=
181+
@[gcongr, to_dual self (reorder := a b, c d, h₁ h₂)]
182+
theorem le_imp_le_of_le_of_le (h₁ : c ≤ a) (h₂ : b ≤ d) : a ≤ b → c ≤ d :=
190183
fun hab ↦ (h₁.trans hab).trans h₂
191184

192185
@[deprecated (since := "2025-07-31")] alias le_implies_le_of_le_of_le := le_imp_le_of_le_of_le
193186

194187
/-- monotonicity of `<` with respect to `→` -/
195-
@[gcongr] theorem lt_imp_lt_of_le_of_le (h₁ : c ≤ a) (h₂ : b ≤ d) : a < b → c < d :=
188+
@[gcongr, to_dual self (reorder := a b, c d, h₁ h₂)]
189+
theorem lt_imp_lt_of_le_of_le (h₁ : c ≤ a) (h₂ : b ≤ d) : a < b → c < d :=
196190
fun hab ↦ (h₁.trans_lt hab).trans_le h₂
197191

198192
namespace Mathlib.Tactic.GCongr
@@ -211,63 +205,45 @@ section PartialOrder
211205

212206
variable [PartialOrder α] {a b : α}
213207

208+
@[to_dual lt_of_le'] -- TODO: should be called `gt_of_ge`
214209
theorem Ne.lt_of_le : a ≠ b → a ≤ b → a < b :=
215210
flip lt_of_le_of_ne
216211

217-
theorem Ne.lt_of_le' : b ≠ a → a ≤ b → a < b :=
218-
flip lt_of_le_of_ne'
219-
220-
alias LE.le.antisymm := le_antisymm
221-
alias LE.le.antisymm' := ge_antisymm
222-
alias LE.le.lt_of_ne := lt_of_le_of_ne
223-
alias LE.le.lt_of_ne' := lt_of_le_of_ne'
224-
225-
-- Unnecessary brackets are here for readability
226-
lemma le_imp_eq_iff_le_imp_ge' : (a ≤ b → b = a) ↔ (a ≤ b → b ≤ a) where
227-
mp h hab := (h hab).le
228-
mpr h hab := (h hab).antisymm hab
229-
230-
@[deprecated (since := "2025-05-11")] alias le_imp_eq_iff_le_imp_le := le_imp_eq_iff_le_imp_ge'
231-
232-
-- Unnecessary brackets are here for readability
233-
lemma le_imp_eq_iff_le_imp_ge : (a ≤ b → a = b) ↔ (a ≤ b → b ≤ a) where
234-
mp h hab := (h hab).ge
235-
mpr h hab := hab.antisymm (h hab)
236-
237-
@[deprecated (since := "2025-05-11")] alias ge_imp_eq_iff_le_imp_le := le_imp_eq_iff_le_imp_ge
238-
239212
namespace LE.le
240213

241-
theorem lt_iff_ne (h : a ≤ b) : a < b ↔ a ≠ b :=
242-
fun h ↦ h.ne, h.lt_of_ne⟩
243-
244-
theorem lt_iff_ne' (h : a ≤ b) : a < b ↔ b ≠ a :=
245-
fun h ↦ h.ne.symm, h.lt_of_ne'⟩
214+
@[to_dual antisymm'] alias antisymm := le_antisymm
215+
@[to_dual lt_of_ne'] alias lt_of_ne := lt_of_le_of_ne
246216

247-
theorem not_lt_iff_eq (h : a ≤ b) : ¬a < b ↔ a = b :=
248-
h.lt_iff_ne.not_left
217+
@[to_dual lt_iff_ne']
218+
theorem lt_iff_ne (h : a ≤ b) : a < b ↔ a ≠ b := ⟨ne_of_lt, h.lt_of_ne⟩
249219

250-
theorem not_lt_iff_eq' (h : a ≤ b) : ¬a < b ↔ b = a :=
251-
h.lt_iff_ne'.not_left
220+
@[to_dual not_lt_iff_eq']
221+
theorem not_lt_iff_eq (h : a ≤ b) : ¬a < b ↔ a = b := h.lt_iff_ne.not_left
252222

253-
theorem ge_iff_eq (h : a ≤ b) : b ≤ a ↔ a = b :=
254-
⟨h.antisymm, Eq.ge⟩
255-
256-
theorem ge_iff_eq' (h : a ≤ b) : b ≤ a ↔ b = a :=
257-
fun h' ↦ h'.antisymm h, Eq.le⟩
223+
@[to_dual ge_iff_eq']
224+
theorem ge_iff_eq (h : a ≤ b) : b ≤ a ↔ a = b := ⟨h.antisymm, Eq.ge⟩
258225

259226
@[deprecated (since := "2025-06-08")] alias gt_iff_ne := lt_iff_ne'
260227
@[deprecated (since := "2025-06-08")] alias le_iff_eq := ge_iff_eq'
261228
@[deprecated (since := "2025-06-08")] alias not_gt_iff_eq := not_lt_iff_eq'
262229

263230
end LE.le
264231

232+
-- Unnecessary brackets are here for readability
233+
@[to_dual le_imp_eq_iff_le_imp_ge']
234+
lemma le_imp_eq_iff_le_imp_ge : (a ≤ b → a = b) ↔ (a ≤ b → b ≤ a) where
235+
mp h hab := (h hab).ge
236+
mpr h hab := hab.antisymm (h hab)
237+
265238
-- See Note [decidable namespace]
239+
@[to_dual le_iff_eq_or_lt']
266240
protected theorem Decidable.le_iff_eq_or_lt [DecidableLE α] : a ≤ b ↔ a = b ∨ a < b :=
267241
Decidable.le_iff_lt_or_eq.trans or_comm
268242

243+
@[to_dual le_iff_eq_or_lt']
269244
theorem le_iff_eq_or_lt : a ≤ b ↔ a = b ∨ a < b := le_iff_lt_or_eq.trans or_comm
270245

246+
@[to_dual lt_iff_le_and_ne']
271247
theorem lt_iff_le_and_ne : a < b ↔ a ≤ b ∧ a ≠ b :=
272248
fun h ↦ ⟨le_of_lt h, ne_of_lt h⟩, fun ⟨h1, h2⟩ ↦ h1.lt_of_ne h2⟩
273249

@@ -277,62 +253,62 @@ lemma eq_iff_not_lt_of_le (hab : a ≤ b) : a = b ↔ ¬ a < b := hab.not_lt_iff
277253
@[deprecated (since := "2025-06-08")] alias LE.le.eq_iff_not_lt := eq_iff_not_lt_of_le
278254

279255
-- See Note [decidable namespace]
256+
@[to_dual eq_iff_ge_not_gt]
280257
protected theorem Decidable.eq_iff_le_not_lt [DecidableLE α] : a = b ↔ a ≤ b ∧ ¬a < b :=
281258
fun h ↦ ⟨h.le, h ▸ lt_irrefl _⟩, fun ⟨h₁, h₂⟩ ↦
282259
h₁.antisymm <| Decidable.byContradiction fun h₃ ↦ h₂ (h₁.lt_of_not_ge h₃)⟩
283260

261+
@[to_dual eq_iff_ge_not_gt]
284262
theorem eq_iff_le_not_lt : a = b ↔ a ≤ b ∧ ¬a < b := open scoped Classical in
285263
Decidable.eq_iff_le_not_lt
286264

287265
-- See Note [decidable namespace]
266+
@[to_dual eq_or_lt_of_le']
288267
protected theorem Decidable.eq_or_lt_of_le [DecidableLE α] (h : a ≤ b) : a = b ∨ a < b :=
289268
(Decidable.lt_or_eq_of_le h).symm
290269

270+
@[to_dual eq_or_lt_of_le']
291271
theorem eq_or_lt_of_le (h : a ≤ b) : a = b ∨ a < b := (lt_or_eq_of_le h).symm
292-
theorem eq_or_lt_of_le' (h : a ≤ b) : b = a ∨ a < b := (eq_or_lt_of_le h).imp Eq.symm id
293272

294-
alias LE.le.lt_or_eq_dec := Decidable.lt_or_eq_of_le
295-
alias LE.le.eq_or_lt_dec := Decidable.eq_or_lt_of_le
296-
alias LE.le.lt_or_eq := lt_or_eq_of_le
297-
alias LE.le.eq_or_lt := eq_or_lt_of_le
298-
alias LE.le.eq_or_lt' := eq_or_lt_of_le'
299-
alias LE.le.lt_or_eq' := lt_or_eq_of_le'
273+
@[to_dual lt_or_eq_dec'] alias LE.le.lt_or_eq_dec := Decidable.lt_or_eq_of_le
274+
@[to_dual eq_or_lt_dec'] alias LE.le.eq_or_lt_dec := Decidable.eq_or_lt_of_le
275+
@[to_dual lt_or_eq'] alias LE.le.lt_or_eq := lt_or_eq_of_le
276+
@[to_dual eq_or_lt'] alias LE.le.eq_or_lt := eq_or_lt_of_le
300277

301278
@[deprecated (since := "2025-06-08")] alias eq_or_gt_of_le := eq_or_lt_of_le'
302279
@[deprecated (since := "2025-06-08")] alias gt_or_eq_of_le := lt_or_eq_of_le'
303280
@[deprecated (since := "2025-06-08")] alias LE.le.eq_or_gt := LE.le.eq_or_lt'
304281
@[deprecated (since := "2025-06-08")] alias LE.le.gt_or_eq := LE.le.lt_or_eq'
305282

283+
@[to_dual eq_of_le_of_not_lt']
306284
theorem eq_of_le_of_not_lt (h₁ : a ≤ b) (h₂ : ¬a < b) : a = b := h₁.eq_or_lt.resolve_right h₂
307-
theorem eq_of_le_of_not_lt' (h₁ : a ≤ b) (h₂ : ¬a < b) : b = a := (eq_of_le_of_not_lt h₁ h₂).symm
308285

309-
alias LE.le.eq_of_not_lt := eq_of_le_of_not_lt
310-
alias LE.le.eq_of_not_lt' := eq_of_le_of_not_lt'
286+
@[to_dual eq_of_not_lt'] alias LE.le.eq_of_not_lt := eq_of_le_of_not_lt
311287

312288
@[deprecated (since := "2025-06-08")] alias eq_of_ge_of_not_gt := eq_of_le_of_not_lt'
313289
@[deprecated (since := "2025-06-08")] alias LE.le.eq_of_not_gt := LE.le.eq_of_not_lt'
314290

291+
@[to_dual ge_iff_gt]
315292
theorem Ne.le_iff_lt (h : a ≠ b) : a ≤ b ↔ a < b := ⟨fun h' ↦ lt_of_le_of_ne h' h, fun h ↦ h.le⟩
316293

294+
@[to_dual not_ge_or_not_le]
317295
theorem Ne.not_le_or_not_ge (h : a ≠ b) : ¬a ≤ b ∨ ¬b ≤ a := not_and_or.1 <| le_antisymm_iff.not.1 h
318296

319297
@[deprecated (since := "2025-06-07")] alias Ne.not_le_or_not_le := Ne.not_le_or_not_ge
320298

321299
-- See Note [decidable namespace]
300+
@[to_dual ne_iff_gt_iff_ge]
322301
protected theorem Decidable.ne_iff_lt_iff_le [DecidableEq α] : (a ≠ b ↔ a < b) ↔ a ≤ b :=
323302
fun h ↦ Decidable.byCases le_of_eq (le_of_lt ∘ h.mp), fun h ↦ ⟨lt_of_le_of_ne h, ne_of_lt⟩⟩
324303

325-
@[simp]
326-
theorem ne_iff_lt_iff_le : (a ≠ b ↔ a < b) ↔ a ≤ b :=
327-
haveI := Classical.dec
304+
@[to_dual (attr := simp) ne_iff_gt_iff_ge]
305+
theorem ne_iff_lt_iff_le : (a ≠ b ↔ a < b) ↔ a ≤ b := open scoped Classical in
328306
Decidable.ne_iff_lt_iff_le
329307

308+
@[to_dual eq_of_forall_ge_iff]
330309
lemma eq_of_forall_le_iff (H : ∀ c, c ≤ a ↔ c ≤ b) : a = b :=
331310
((H _).1 le_rfl).antisymm ((H _).2 le_rfl)
332311

333-
lemma eq_of_forall_ge_iff (H : ∀ c, a ≤ c ↔ b ≤ c) : a = b :=
334-
((H _).2 le_rfl).antisymm ((H _).1 le_rfl)
335-
336312
/-- To prove commutativity of a binary operation `○`, we only to check `a ○ b ≤ b ○ a` for all `a`,
337313
`b`. -/
338314
lemma commutative_of_le {f : β → β → α} (comm : ∀ a b, f a b ≤ f b a) : ∀ a b, f a b = f b a :=

0 commit comments

Comments
 (0)