Skip to content

Commit 0b502d5

Browse files
committed
feat: CoeFun for Lex and Colex (#30481)
If `F` is a function type, we should be able to treat `Lex F` as a function type too. This diminishes the visual clutter of going to and from `Lex`. This design was already present for pi types, but wasn't accounted for with neither of `DFinsupp` or `Finsupp`.
1 parent e3a51e4 commit 0b502d5

File tree

4 files changed

+32
-18
lines changed

4 files changed

+32
-18
lines changed

Mathlib/Data/DFinsupp/Lex.lean

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ theorem _root_.Pi.lex_eq_dfinsupp_lex {r : ι → ι → Prop} {s : ∀ i, α i
3636

3737
theorem lex_def {r : ι → ι → Prop} {s : ∀ i, α i → α i → Prop} {a b : Π₀ i, α i} :
3838
DFinsupp.Lex r s a b ↔ ∃ j, (∀ d, r d j → a d = b d) ∧ s j (a j) (b j) :=
39-
Iff.rfl
39+
.rfl
4040

4141
instance [LT ι] [∀ i, LT (α i)] : LT (Lex (Π₀ i, α i)) :=
4242
fun f g ↦ DFinsupp.Lex (· < ·) (fun _ ↦ (· < ·)) (ofLex f) (ofLex g)⟩
4343

44+
theorem lex_lt_iff [LT ι] [∀ i, LT (α i)] {a b : Lex (Π₀ i, α i)} :
45+
a < b ↔ ∃ i, (∀ j, j < i → a j = b j) ∧ a i < b i :=
46+
.rfl
47+
4448
theorem lex_lt_of_lt_of_preorder [∀ i, Preorder (α i)] (r) [IsStrictOrder ι r] {x y : Π₀ i, α i}
4549
(hlt : x < y) : ∃ i, (∀ j, r j i → x j ≤ y j ∧ y j ≤ x j) ∧ x i < y i := by
4650
obtain ⟨hle, j, hlt⟩ := Pi.lt_def.1 hlt
@@ -117,6 +121,7 @@ theorem toLex_monotone : Monotone (@toLex (Π₀ i, α i)) := by
117121
fun j hj ↦ notMem_neLocus.1 fun h ↦ (Finset.min'_le _ _ h).not_gt hj,
118122
(h _).lt_of_ne (mem_neLocus.1 <| Finset.min'_mem _ _)⟩
119123

124+
@[deprecated lex_lt_iff (since := "2025-10-12")]
120125
theorem lt_of_forall_lt_of_lt (a b : Lex (Π₀ i, α i)) (i : ι) :
121126
(∀ j < i, ofLex a j = ofLex b j) → ofLex a i < ofLex b i → a < b :=
122127
fun h1 h2 ↦ ⟨i, h1, h2⟩

Mathlib/Data/Finsupp/Lex.lean

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ theorem _root_.Pi.lex_eq_finsupp_lex {r : α → α → Prop} {s : N → N → P
3636

3737
theorem lex_def {r : α → α → Prop} {s : N → N → Prop} {a b : α →₀ N} :
3838
Finsupp.Lex r s a b ↔ ∃ j, (∀ d, r d j → a d = b d) ∧ s (a j) (b j) :=
39-
Iff.rfl
39+
.rfl
4040

4141
theorem lex_eq_invImage_dfinsupp_lex (r : α → α → Prop) (s : N → N → Prop) :
4242
Finsupp.Lex r s = InvImage (DFinsupp.Lex r fun _ ↦ s) toDFinsupp :=
@@ -46,11 +46,11 @@ instance [LT α] [LT N] : LT (Lex (α →₀ N)) :=
4646
fun f g ↦ Finsupp.Lex (· < ·) (· < ·) (ofLex f) (ofLex g)⟩
4747

4848
theorem lex_lt_iff [LT α] [LT N] {a b : Lex (α →₀ N)} :
49-
a < b ↔ ∃ i, (∀ j, j < i → ofLex a j = ofLex b j) ∧ ofLex a i < ofLex b i :=
50-
Finsupp.lex_def
49+
a < b ↔ ∃ i, (∀ j, j < i → a j = b j) ∧ a i < b i :=
50+
.rfl
5151

5252
theorem lex_lt_iff_of_unique [Preorder α] [LT N] [Unique α] {a b : Lex (α →₀ N)} :
53-
a < b ↔ ofLex a default < ofLex b default := by
53+
a < b ↔ a default < b default := by
5454
simp only [lex_lt_iff, Unique.exists_iff, and_iff_right_iff_imp]
5555
refine fun _ j hj ↦ False.elim (lt_irrefl j ?_)
5656
simpa only [Unique.uniq] using hj
@@ -84,7 +84,7 @@ instance Lex.linearOrder [LinearOrder N] : LinearOrder (Lex (α →₀ N)) where
8484
le := (· ≤ ·)
8585
__ := LinearOrder.lift' (toLex ∘ toDFinsupp ∘ ofLex) finsuppEquivDFinsupp.injective
8686

87-
theorem Lex.single_strictAnti : StrictAnti (fun (a : α) ↦ toLex (single a 1)) := by
87+
theorem Lex.single_strictAnti : StrictAnti fun (a : α) ↦ toLex (single a 1) := by
8888
intro a b h
8989
simp only [LT.lt, Finsupp.lex_def]
9090
simp only [ofLex_toLex, Nat.lt_eq]
@@ -100,20 +100,21 @@ theorem Lex.single_lt_iff {a b : α} : toLex (single b 1) < toLex (single a 1)
100100
theorem Lex.single_le_iff {a b : α} : toLex (single b 1) ≤ toLex (single a 1) ↔ a ≤ b :=
101101
Lex.single_strictAnti.le_iff_ge
102102

103-
theorem Lex.single_antitone : Antitone (fun (a : α) ↦ toLex (single a 1)) :=
103+
theorem Lex.single_antitone : Antitone fun (a : α) ↦ toLex (single a 1) :=
104104
Lex.single_strictAnti.antitone
105105

106106
variable [PartialOrder N]
107107

108108
theorem toLex_monotone : Monotone (@toLex (α →₀ N)) :=
109-
fun a b h ↦ DFinsupp.toLex_monotone (id h : ∀ i, ofLex (toDFinsupp a) i ≤ ofLex (toDFinsupp b) i)
109+
fun a b h ↦ DFinsupp.toLex_monotone (id h : ∀ i, (toDFinsupp a) i ≤ (toDFinsupp b) i)
110110

111+
@[deprecated lex_lt_iff (since := "2025-10-12")]
111112
theorem lt_of_forall_lt_of_lt (a b : Lex (α →₀ N)) (i : α) :
112113
(∀ j < i, ofLex a j = ofLex b j) → ofLex a i < ofLex b i → a < b :=
113114
fun h1 h2 ↦ ⟨i, h1, h2⟩
114115

115116
theorem lex_le_iff_of_unique [Unique α] {a b : Lex (α →₀ N)} :
116-
a ≤ b ↔ ofLex a default ≤ ofLex b default := by
117+
a ≤ b ↔ a default ≤ b default := by
117118
simp only [le_iff_eq_or_lt]
118119
apply or_congr _ lex_lt_iff_of_unique
119120
conv_lhs => rw [← toLex_ofLex a, ← toLex_ofLex b, toLex_inj]
@@ -151,7 +152,7 @@ variable [AddRightStrictMono N]
151152

152153
instance Lex.addRightStrictMono : AddRightStrictMono (Lex (α →₀ N)) :=
153154
fun f _ _ ⟨a, lta, ha⟩ ↦
154-
⟨a, fun j ja ↦ congr_arg (· + ofLex f j) (lta j ja), add_lt_add_right ha _⟩⟩
155+
⟨a, fun j ja ↦ congr_arg (· + f j) (lta j ja), add_lt_add_right ha _⟩⟩
155156

156157
instance Lex.addRightMono : AddRightMono (Lex (α →₀ N)) :=
157158
addRightMono_of_addRightStrictMono _

Mathlib/Order/PiLex.lean

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,6 @@ basic API, just in case -/
4949
/-- The notation `Πₗ i, α i` refers to a pi type equipped with the lexicographic order. -/
5050
notation3 (prettyPrint := false) "Πₗ " (...) ", " r:(scoped p => Lex (∀ i, p i)) => r
5151

52-
@[simp]
53-
theorem toLex_apply (x : ∀ i, β i) (i : ι) : toLex x i = x i :=
54-
rfl
55-
56-
@[simp]
57-
theorem ofLex_apply (x : Lex (∀ i, β i)) (i : ι) : ofLex x i = x i :=
58-
rfl
59-
6052
theorem lex_lt_of_lt_of_preorder [∀ i, Preorder (β i)] {r} (hwf : WellFounded r) {x y : ∀ i, β i}
6153
(hlt : x < y) : ∃ i, (∀ j, r j i → x j ≤ y j ∧ y j ≤ x j) ∧ x i < y i :=
6254
let h' := Pi.lt_def.1 hlt
@@ -90,6 +82,16 @@ instance [LT ι] [∀ a, LT (β a)] : LT (Lex (∀ i, β i)) :=
9082
instance [LT ι] [∀ a, LT (β a)] : LT (Colex (∀ i, β i)) :=
9183
⟨Pi.Lex (· > ·) (· < ·)⟩
9284

85+
-- If `Lex` and `Colex` are ever made into one-field structures, we need a `CoeFun` instance.
86+
-- This will make `x i` syntactically equal to `ofLex x i` for `x : Πₗ i, α i`, thus making
87+
-- the following theorems redundant.
88+
89+
@[simp] theorem toLex_apply (x : ∀ i, β i) (i : ι) : toLex x i = x i := rfl
90+
@[simp] theorem ofLex_apply (x : Lex (∀ i, β i)) (i : ι) : ofLex x i = x i := rfl
91+
92+
@[simp] theorem toColex_apply (x : ∀ i, β i) (i : ι) : toColex x i = x i := rfl
93+
@[simp] theorem ofColex_apply (x : Colex (∀ i, β i)) (i : ι) : ofColex x i = x i := rfl
94+
9395
instance Lex.isStrictOrder [LinearOrder ι] [∀ a, PartialOrder (β a)] :
9496
IsStrictOrder (Lex (∀ i, β i)) (· < ·) where
9597
irrefl := fun a ⟨k, _, hk₂⟩ => lt_irrefl (a k) hk₂

Mathlib/Order/Synonym.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ instance (α : Type*) [DecidableEq α] : DecidableEq (Lex α) :=
177177
instance (α : Type*) [Inhabited α] : Inhabited (Lex α) :=
178178
inferInstanceAs (Inhabited α)
179179

180+
instance {α γ} [H : CoeFun α γ] : CoeFun (Lex α) γ where
181+
coe f := H.coe (ofLex f)
182+
180183
/-- A recursor for `Lex`. Use as `induction x`. -/
181184
@[elab_as_elim, induction_eliminator, cases_eliminator]
182185
protected def Lex.rec {β : Lex α → Sort*} (h : ∀ a, β (toLex a)) : ∀ a, β a := fun a => h (ofLex a)
@@ -233,6 +236,9 @@ instance (α : Type*) [DecidableEq α] : DecidableEq (Colex α) :=
233236
instance (α : Type*) [Inhabited α] : Inhabited (Colex α) :=
234237
inferInstanceAs (Inhabited α)
235238

239+
instance {α γ} [H : CoeFun α γ] : CoeFun (Colex α) γ where
240+
coe f := H.coe (ofColex f)
241+
236242
/-- A recursor for `Colex`. Use as `induction x`. -/
237243
@[elab_as_elim, induction_eliminator, cases_eliminator]
238244
protected def Colex.rec {β : Colex α → Sort*} (h : ∀ a, β (toColex a)) : ∀ a, β a :=

0 commit comments

Comments
 (0)