Skip to content

Commit 7862cbd

Browse files
vihdzpvihdzp
andcommitted
chore(Order/SuccPred/Archimedean): use to_dual (leanprover-community#34882)
Co-authored-by: vihdzp <vi.hdz.p@mgmail.com>
1 parent 570ff68 commit 7862cbd

3 files changed

Lines changed: 48 additions & 94 deletions

File tree

Mathlib/Order/MinMax.lean

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,14 @@ theorem AntitoneOn.map_max (hf : AntitoneOn f s) (ha : a ∈ s) (hb : b ∈ s) :
197197
theorem AntitoneOn.map_min (hf : AntitoneOn f s) (ha : a ∈ s) (hb : b ∈ s) : f (min a b) =
198198
max (f a) (f b) := hf.dual.map_max ha hb
199199

200+
@[to_dual]
200201
theorem Monotone.map_max (hf : Monotone f) : f (max a b) = max (f a) (f b) := by
201202
rcases le_total a b with h | h <;> simp [h, hf h]
202203

203-
theorem Monotone.map_min (hf : Monotone f) : f (min a b) = min (f a) (f b) :=
204-
hf.dual.map_max
205-
204+
@[to_dual]
206205
theorem Antitone.map_max (hf : Antitone f) : f (max a b) = min (f a) (f b) := by
207206
rcases le_total a b with h | h <;> simp [h, hf h]
208207

209-
theorem Antitone.map_min (hf : Antitone f) : f (min a b) = max (f a) (f b) :=
210-
hf.dual.map_max
211-
212208
theorem min_choice (a b : α) : min a b = a ∨ min a b = b := by cases le_total a b <;> simp [*]
213209

214210
theorem max_choice (a b : α) : max a b = a ∨ max a b = b :=

Mathlib/Order/SuccPred/Archimedean.lean

Lines changed: 42 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,46 @@ class IsSuccArchimedean (α : Type*) [Preorder α] [SuccOrder α] : Prop where
3030

3131
/-- A `PredOrder` is pred-archimedean if one can go from any two comparable elements by iterating
3232
`pred` -/
33+
@[to_dual existing]
3334
class IsPredArchimedean (α : Type*) [Preorder α] [PredOrder α] : Prop where
3435
/-- If `a ≤ b` then one can get to `b` from `a` by iterating `pred` -/
3536
exists_pred_iterate_of_le {a b : α} (h : a ≤ b) : ∃ n, pred^[n] b = a
3637

3738
export IsSuccArchimedean (exists_succ_iterate_of_le)
38-
3939
export IsPredArchimedean (exists_pred_iterate_of_le)
4040

41+
attribute [to_dual existing] exists_succ_iterate_of_le
42+
4143
section Preorder
4244

4345
variable [Preorder α]
4446

47+
-- `to_dual` cannot yet reorder arguments of arguments
48+
instance [SuccOrder α] [IsSuccArchimedean α] : IsPredArchimedean αᵒᵈ :=
49+
fun {a b} h => by convert exists_succ_iterate_of_le h.ofDual⟩
50+
51+
@[to_dual existing]
52+
instance [PredOrder α] [IsPredArchimedean α] : IsSuccArchimedean αᵒᵈ :=
53+
fun {a b} h => by convert exists_pred_iterate_of_le h.ofDual⟩
54+
4555
section SuccOrder
4656

4757
variable [SuccOrder α] [IsSuccArchimedean α] {a b : α}
4858

49-
instance : IsPredArchimedean αᵒᵈ :=
50-
fun {a b} h => by convert exists_succ_iterate_of_le h.ofDual⟩
51-
59+
@[to_dual]
5260
theorem LE.le.exists_succ_iterate (h : a ≤ b) : ∃ n, succ^[n] a = b :=
5361
exists_succ_iterate_of_le h
5462

63+
@[to_dual]
5564
theorem exists_succ_iterate_iff_le : (∃ n, succ^[n] a = b) ↔ a ≤ b := by
5665
refine ⟨?_, exists_succ_iterate_of_le⟩
5766
rintro ⟨n, rfl⟩
5867
exact id_le_iterate_of_id_le le_succ n a
5968

69+
-- TODO: rename to `Order.succ_rec`?
6070
/-- Induction principle on a type with a `SuccOrder` for all elements above a given element `m`. -/
61-
@[elab_as_elim]
71+
@[to_dual (attr := elab_as_elim) Pred.rec
72+
/-- Induction principle on a type with a `PredOrder` for all elements below a given element `m`. -/]
6273
theorem Succ.rec {m : α} {P : ∀ n, m ≤ n → Prop} (rfl : P m le_rfl)
6374
(succ : ∀ n (hmn : m ≤ n), P n hmn → P (succ n) (hmn.trans <| le_succ _)) ⦃n : α⦄
6475
(hmn : m ≤ n) : P n hmn := by
@@ -69,11 +80,13 @@ theorem Succ.rec {m : α} {P : ∀ n, m ≤ n → Prop} (rfl : P m le_rfl)
6980
simp_rw [Function.iterate_succ_apply']
7081
exact succ _ (id_le_iterate_of_id_le le_succ n m) (ih _)
7182

83+
@[to_dual Pred.rec_iff]
7284
theorem Succ.rec_iff {p : α → Prop} (hsucc : ∀ a, p a ↔ p (succ a)) {a b : α} (h : a ≤ b) :
7385
p a ↔ p b := by
7486
obtain ⟨n, rfl⟩ := h.exists_succ_iterate
7587
exact Iterate.rec (fun b => p a ↔ p b) Iff.rfl (fun c hc => hc.trans (hsucc _)) n
7688

89+
@[to_dual le_total_of_directed]
7790
lemma le_total_of_codirected {r v₁ v₂ : α} (h₁ : r ≤ v₁) (h₂ : r ≤ v₂) : v₁ ≤ v₂ ∨ v₂ ≤ v₁ := by
7891
obtain ⟨n, rfl⟩ := h₁.exists_succ_iterate
7992
obtain ⟨m, rfl⟩ := h₂.exists_succ_iterate
@@ -89,41 +102,13 @@ lemma le_total_of_codirected {r v₁ v₂ : α} (h₁ : r ≤ v₁) (h₂ : r
89102

90103
end SuccOrder
91104

92-
section PredOrder
93-
94-
variable [PredOrder α] [IsPredArchimedean α] {a b : α}
95-
96-
instance : IsSuccArchimedean αᵒᵈ :=
97-
fun {a b} h => by convert exists_pred_iterate_of_le h.ofDual⟩
98-
99-
theorem LE.le.exists_pred_iterate (h : a ≤ b) : ∃ n, pred^[n] b = a :=
100-
exists_pred_iterate_of_le h
101-
102-
theorem exists_pred_iterate_iff_le : (∃ n, pred^[n] b = a) ↔ a ≤ b :=
103-
exists_succ_iterate_iff_le (α := αᵒᵈ)
104-
105-
/-- Induction principle on a type with a `PredOrder` for all elements below a given element `m`. -/
106-
@[elab_as_elim]
107-
theorem Pred.rec {m : α} {P : ∀ n, n ≤ m → Prop} (rfl : P m le_rfl)
108-
(pred : ∀ n (hnm : n ≤ m), P n hnm → P (pred n) ((pred_le _).trans hnm)) ⦃n : α⦄
109-
(hnm : n ≤ m) : P n hnm :=
110-
Succ.rec (α := αᵒᵈ) (P := P) rfl pred hnm
111-
112-
theorem Pred.rec_iff {p : α → Prop} (hsucc : ∀ a, p a ↔ p (pred a)) {a b : α} (h : a ≤ b) :
113-
p a ↔ p b :=
114-
(Succ.rec_iff (α := αᵒᵈ) hsucc h).symm
115-
116-
lemma le_total_of_directed {r v₁ v₂ : α} (h₁ : v₁ ≤ r) (h₂ : v₂ ≤ r) : v₁ ≤ v₂ ∨ v₂ ≤ v₁ :=
117-
Or.symm (le_total_of_codirected (α := αᵒᵈ) h₁ h₂)
118-
119-
end PredOrder
120-
121105
end Preorder
122106

123107
section PartialOrder
124108

125109
variable [PartialOrder α]
126110

111+
@[to_dual (reorder := h₁ h₂) lt_or_le_of_directed]
127112
lemma lt_or_le_of_codirected [SuccOrder α] [IsSuccArchimedean α] {r v₁ v₂ : α} (h₁ : r ≤ v₁)
128113
(h₂ : r ≤ v₂) : v₁ < v₂ ∨ v₂ ≤ v₁ := by
129114
rw [Classical.or_iff_not_imp_right]
@@ -132,6 +117,7 @@ lemma lt_or_le_of_codirected [SuccOrder α] [IsSuccArchimedean α] {r v₁ v₂
132117
· apply lt_of_le_of_ne h (ne_of_not_le nh).symm
133118
· contradiction
134119

120+
-- `to_dual` cannot yet reorder arguments of arguments
135121
/--
136122
This isn't an instance due to a loop with `LinearOrder`.
137123
-/
@@ -146,18 +132,11 @@ abbrev IsSuccArchimedean.linearOrder [SuccOrder α] [IsSuccArchimedean α]
146132
toDecidableLE := inferInstance
147133
toDecidableLT := inferInstance
148134

149-
lemma lt_or_le_of_directed [PredOrder α] [IsPredArchimedean α] {r v₁ v₂ : α} (h₁ : v₁ ≤ r)
150-
(h₂ : v₂ ≤ r) : v₁ < v₂ ∨ v₂ ≤ v₁ := by
151-
rw [Classical.or_iff_not_imp_right]
152-
intro nh
153-
rcases le_total_of_directed h₁ h₂ with h | h
154-
· apply lt_of_le_of_ne h (ne_of_not_le nh).symm
155-
· contradiction
156-
157135
/--
158136
This isn't an instance due to a loop with `LinearOrder`.
159137
-/
160138
-- See note [reducible non-instances]
139+
@[to_dual existing]
161140
abbrev IsPredArchimedean.linearOrder [PredOrder α] [IsPredArchimedean α]
162141
[DecidableEq α] [DecidableLE α] [DecidableLT α]
163142
[IsDirectedOrder α] : LinearOrder α :=
@@ -173,40 +152,30 @@ variable [LinearOrder α]
173152
section SuccOrder
174153
variable [SuccOrder α]
175154

176-
lemma succ_max (a b : α) : succ (max a b) = max (succ a) (succ b) := succ_mono.map_max
177-
lemma succ_min (a b : α) : succ (min a b) = min (succ a) (succ b) := succ_mono.map_min
155+
@[deprecated (since := "2026-02-05")] alias succ_max := Order.succ_max
156+
@[deprecated (since := "2026-02-05")] alias succ_min := Order.succ_min
157+
158+
@[deprecated (since := "2026-02-05")] alias pred_max := Order.pred_max
159+
@[deprecated (since := "2026-02-05")] alias pred_min := Order.pred_min
178160

179161
variable [IsSuccArchimedean α] {a b : α}
180162

163+
@[to_dual]
181164
theorem exists_succ_iterate_or : (∃ n, succ^[n] a = b) ∨ ∃ n, succ^[n] b = a :=
182165
(le_total a b).imp exists_succ_iterate_of_le exists_succ_iterate_of_le
183166

167+
@[to_dual Pred.rec_linear]
184168
theorem Succ.rec_linear {p : α → Prop} (hsucc : ∀ a, p a ↔ p (succ a)) (a b : α) : p a ↔ p b :=
185169
(le_total a b).elim (Succ.rec_iff hsucc) fun h => (Succ.rec_iff hsucc h).symm
186170

187171
end SuccOrder
188172

189-
section PredOrder
190-
variable [PredOrder α]
191-
192-
lemma pred_max (a b : α) : pred (max a b) = max (pred a) (pred b) := pred_mono.map_max
193-
lemma pred_min (a b : α) : pred (min a b) = min (pred a) (pred b) := pred_mono.map_min
194-
195-
variable [IsPredArchimedean α] {a b : α}
196-
197-
theorem exists_pred_iterate_or : (∃ n, pred^[n] b = a) ∨ ∃ n, pred^[n] a = b :=
198-
(le_total a b).imp exists_pred_iterate_of_le exists_pred_iterate_of_le
199-
200-
theorem Pred.rec_linear {p : α → Prop} (hsucc : ∀ a, p a ↔ p (pred a)) (a b : α) : p a ↔ p b :=
201-
(le_total a b).elim (Pred.rec_iff hsucc) fun h => (Pred.rec_iff hsucc h).symm
202-
203-
end PredOrder
204-
205173
end LinearOrder
206174

207175
section bdd_range
208176
variable [Preorder α] [Nonempty α] [Preorder β] {f : α → β}
209177

178+
@[to_dual]
210179
lemma StrictMono.not_bddAbove_range_of_isSuccArchimedean [NoMaxOrder α] [SuccOrder β]
211180
[IsSuccArchimedean β] (hf : StrictMono f) : ¬ BddAbove (Set.range f) := by
212181
rintro ⟨m, hm⟩
@@ -221,24 +190,22 @@ lemma StrictMono.not_bddAbove_range_of_isSuccArchimedean [NoMaxOrder α] [SuccOr
221190
rintro b _ ⟨a, hba⟩
222191
exact (h a).imp (fun a' ↦ (succ_le_of_lt hba).trans_lt)
223192

224-
lemma StrictMono.not_bddBelow_range_of_isPredArchimedean [NoMinOrder α] [PredOrder β]
225-
[IsPredArchimedean β] (hf : StrictMono f) : ¬ BddBelow (Set.range f) :=
226-
hf.dual.not_bddAbove_range_of_isSuccArchimedean
227-
228-
lemma StrictAnti.not_bddBelow_range_of_isSuccArchimedean [NoMinOrder α] [SuccOrder β]
193+
@[to_dual]
194+
lemma StrictAnti.not_bddAbove_range_of_isSuccArchimedean [NoMinOrder α] [SuccOrder β]
229195
[IsSuccArchimedean β] (hf : StrictAnti f) : ¬ BddAbove (Set.range f) :=
230196
hf.dual_right.not_bddBelow_range_of_isPredArchimedean
231197

232-
lemma StrictAnti.not_bddBelow_range_of_isPredArchimedean [NoMaxOrder α] [PredOrder β]
233-
[IsPredArchimedean β] (hf : StrictAnti f) : ¬ BddBelow (Set.range f) :=
234-
hf.dual_right.not_bddAbove_range_of_isSuccArchimedean
198+
@[deprecated (since := "2026-02-05")]
199+
alias StrictMono.not_bddBelow_range_of_isSuccArchimedean :=
200+
StrictMono.not_bddAbove_range_of_isSuccArchimedean
235201

236202
end bdd_range
237203

238204
section IsWellFounded
239205

240206
variable [PartialOrder α]
241207

208+
-- `to_dual` cannot yet reorder arguments of arguments
242209
instance (priority := 100) WellFoundedLT.toIsPredArchimedean [h : WellFoundedLT α]
243210
[PredOrder α] : IsPredArchimedean α :=
244211
fun {a b} => by
@@ -255,6 +222,7 @@ instance (priority := 100) WellFoundedLT.toIsPredArchimedean [h : WellFoundedLT
255222
refine ⟨k + 1, ?_⟩
256223
rw [iterate_add_apply, iterate_one, hk]⟩
257224

225+
@[to_dual existing]
258226
instance (priority := 100) WellFoundedGT.toIsSuccArchimedean [h : WellFoundedGT α]
259227
[SuccOrder α] : IsSuccArchimedean α :=
260228
let h : IsPredArchimedean αᵒᵈ := by infer_instance
@@ -266,20 +234,13 @@ section OrderBot
266234

267235
variable [Preorder α] [OrderBot α] [SuccOrder α] [IsSuccArchimedean α]
268236

237+
@[to_dual Pred.rec_top]
269238
theorem Succ.rec_bot (p : α → Prop) (hbot : p ⊥) (hsucc : ∀ a, p a → p (succ a)) (a : α) : p a :=
270239
Succ.rec hbot (fun x _ h => hsucc x h) (bot_le : ⊥ ≤ a)
271240

272241
end OrderBot
273242

274-
section OrderTop
275-
276-
variable [Preorder α] [OrderTop α] [PredOrder α] [IsPredArchimedean α]
277-
278-
theorem Pred.rec_top (p : α → Prop) (htop : p ⊤) (hpred : ∀ a, p a → p (pred a)) (a : α) : p a :=
279-
Pred.rec htop (fun x _ h => hpred x h) (le_top : a ≤ ⊤)
280-
281-
end OrderTop
282-
243+
@[to_dual]
283244
lemma SuccOrder.forall_ne_bot_iff
284245
[Nontrivial α] [PartialOrder α] [OrderBot α] [SuccOrder α] [IsSuccArchimedean α]
285246
(P : α → Prop) :
@@ -293,7 +254,8 @@ lemma SuccOrder.forall_ne_bot_iff
293254

294255
section IsLeast
295256

296-
-- TODO: generalize to PartialOrder and `DirectedOn` after https://github.com/leanprover-community/mathlib4/pull/16272
257+
-- TODO: generalize to PartialOrder and `DirectedOn`
258+
@[to_dual]
297259
lemma BddAbove.exists_isGreatest_of_nonempty {X : Type*} [LinearOrder X] [SuccOrder X]
298260
[IsSuccArchimedean X] {S : Set X} (hS : BddAbove S) (hS' : S.Nonempty) :
299261
∃ x, IsGreatest S x := by
@@ -317,18 +279,13 @@ lemma BddAbove.exists_isGreatest_of_nonempty {X : Type*} [LinearOrder X] [SuccOr
317279
· exact ⟨m, hmS, hm⟩
318280
· exact IH hm hn hmS
319281

320-
lemma BddBelow.exists_isLeast_of_nonempty {X : Type*} [LinearOrder X] [PredOrder X]
321-
[IsPredArchimedean X] {S : Set X} (hS : BddBelow S) (hS' : S.Nonempty) :
322-
∃ x, IsLeast S x :=
323-
hS.dual.exists_isGreatest_of_nonempty hS'
324-
325282
end IsLeast
326283

327284
section OrderIso
328285

329286
variable {X Y : Type*} [PartialOrder X] [PartialOrder Y]
330287

331-
set_option backward.isDefEq.respectTransparency false in
288+
-- `to_dual` cannot yet reorder arguments of arguments
332289
/-- `IsSuccArchimedean` transfers across equivalences between `SuccOrder`s. -/
333290
protected lemma IsSuccArchimedean.of_orderIso [SuccOrder X] [IsSuccArchimedean X] [SuccOrder Y]
334291
(f : X ≃o Y) : IsSuccArchimedean Y where
@@ -342,8 +299,8 @@ protected lemma IsSuccArchimedean.of_orderIso [SuccOrder X] [IsSuccArchimedean X
342299
| zero => simp
343300
| succ n IH => simp only [Function.iterate_succ', Function.comp_apply, IH, f.map_succ]
344301

345-
set_option backward.isDefEq.respectTransparency false in
346302
/-- `IsPredArchimedean` transfers across equivalences between `PredOrder`s. -/
303+
@[to_dual existing]
347304
protected lemma IsPredArchimedean.of_orderIso [PredOrder X] [IsPredArchimedean X] [PredOrder Y]
348305
(f : X ≃o Y) : IsPredArchimedean Y where
349306
exists_pred_iterate_of_le {a b} h := by

Mathlib/Order/SuccPred/Basic.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
222222
· rw [succ_le_iff_of_not_isMax fun ha => hb <| ha.mono h]
223223
apply lt_succ_of_le_of_not_isMax h hb
224224

225+
@[to_dual]
225226
theorem succ_mono : Monotone (succ : α → α) := fun _ _ => succ_le_succ
226227

227228
/-- See also `Order.succ_eq_of_covBy`. -/
@@ -421,6 +422,9 @@ section LinearOrder
421422

422423
variable [LinearOrder α] [SuccOrder α] {a b : α}
423424

425+
@[to_dual] lemma succ_max (a b : α) : succ (max a b) = max (succ a) (succ b) := succ_mono.map_max
426+
@[to_dual] lemma succ_min (a b : α) : succ (min a b) = min (succ a) (succ b) := succ_mono.map_min
427+
424428
@[to_dual le_of_pred_lt]
425429
theorem le_of_lt_succ {a b : α} : a < succ b → a ≤ b := fun h ↦ by
426430
by_contra! nh
@@ -620,9 +624,6 @@ theorem pred_covBy_of_not_isMin (h : ¬IsMin a) : pred a ⋖ a :=
620624
theorem pred_lt_of_not_isMin_of_le (ha : ¬IsMin a) : a ≤ b → pred a < b :=
621625
(pred_lt_of_not_isMin ha).trans_le
622626

623-
@[to_dual existing]
624-
theorem pred_mono : Monotone (pred : α → α) := fun _ _ => pred_le_pred
625-
626627
@[deprecated (since := "2025-12-04")]
627628
alias pred_le_pred_of_not_isMin_of_le := pred_mono
628629

0 commit comments

Comments
 (0)