Skip to content

Commit fb3fd7c

Browse files
committed
feat: add some constructions about RelSeries (append, insert_nth, map, comap) (#3858)
- appending a relation series to another one - insert an element into a relation series to make a longer relation series - map a relation series across a relation preserving function - pullback a lt series across a surjective strictly co-monotonic function. (`f` is strictly co-monotonic if `f x < f y` implies `x < y`)
1 parent 8788d9a commit fb3fd7c

File tree

1 file changed

+154
-2
lines changed

1 file changed

+154
-2
lines changed

Mathlib/Order/RelSeries.lean

Lines changed: 154 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
/-
22
Copyright (c) 2023 Jujian Zhang. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
4-
Authors: Jujian Zhang
4+
Authors: Jujian Zhang, Fangming Li
55
-/
66
import Mathlib.Logic.Equiv.Fin
77
import Mathlib.Data.List.Indexes
88
import Mathlib.Data.Rel
9+
import Mathlib.Tactic.Linarith
10+
import Mathlib.Tactic.Abel
911

1012
/-!
1113
# Series of a relation
@@ -16,6 +18,7 @@ If `r` is a relation on `α` then a relation series of length `n` is a series
1618
-/
1719

1820
variable {α : Type*} (r : Rel α α)
21+
variable {β : Type*} (s : Rel β β)
1922

2023
/--
2124
Let `r` be a relation on `α`, a relation series of `r` of length `n` is a series
@@ -154,6 +157,125 @@ protected noncomputable def withLength [r.InfiniteDimensional] (n : ℕ) : RelSe
154157
lemma nonempty_of_infiniteDimensional [r.InfiniteDimensional] : Nonempty α :=
155158
⟨RelSeries.withLength r 0 0
156159

160+
instance membership : Membership α (RelSeries r) :=
161+
⟨(· ∈ Set.range ·)⟩
162+
163+
theorem mem_def {x : α} {s : RelSeries r} : x ∈ s ↔ x ∈ Set.range s :=
164+
Iff.rfl
165+
166+
/-- Start of a series, i.e. for `a₀ -r→ a₁ -r→ ... -r→ aₙ`, its head is `a₀`.
167+
168+
Since a relation series is assumed to be non-empty, this is well defined. -/
169+
def head (x : RelSeries r) : α := x 0
170+
171+
/-- End of a series, i.e. for `a₀ -r→ a₁ -r→ ... -r→ aₙ`, its last element is `aₙ`.
172+
173+
Since a relation series is assumed to be non-empty, this is well defined. -/
174+
def last (x : RelSeries r) : α := x <| Fin.last _
175+
176+
lemma head_mem (x : RelSeries r) : x.head ∈ x := ⟨_, rfl⟩
177+
178+
lemma last_mem (x : RelSeries r) : x.last ∈ x := ⟨_, rfl⟩
179+
180+
/--
181+
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` and `b₀ -r→ b₁ -r→ ... -r→ bₘ` are two strict series
182+
such that `r aₙ b₀`, then there is a chain of length `n + m + 1` given by
183+
`a₀ -r→ a₁ -r→ ... -r→ aₙ -r→ b₀ -r→ b₁ -r→ ... -r→ bₘ`.
184+
-/
185+
@[simps]
186+
def append (p q : RelSeries r) (connect : r p.last q.head) : RelSeries r where
187+
length := p.length + q.length + 1
188+
toFun := Fin.append p q ∘ Fin.cast (by abel)
189+
step i := by
190+
obtain hi | rfl | hi :=
191+
lt_trichotomy i (Fin.castLE (by linarith) (Fin.last _ : Fin (p.length + 1)))
192+
· convert p.step ⟨i.1, hi⟩ <;> convert Fin.append_left p q _ <;> rfl
193+
· convert connect
194+
· convert Fin.append_left p q _; rfl
195+
· convert Fin.append_right p q _; rfl
196+
· set x := _; set y := _
197+
change r (Fin.append p q x) (Fin.append p q y)
198+
have hx : x = Fin.natAdd _ ⟨i - (p.length + 1), Nat.sub_lt_left_of_lt_add hi <|
199+
i.2.trans <| by linarith!⟩
200+
· ext; dsimp; rw [Nat.add_sub_cancel']; exact hi
201+
have hy : y = Fin.natAdd _ ⟨i - p.length, Nat.sub_lt_left_of_lt_add (le_of_lt hi)
202+
(by exact i.2)⟩
203+
· ext
204+
dsimp
205+
conv_rhs => rw [Nat.add_comm p.length 1, add_assoc,
206+
Nat.add_sub_cancel' <| le_of_lt (show p.length < i.1 from hi), add_comm]
207+
rw [hx, Fin.append_right, hy, Fin.append_right]
208+
convert q.step ⟨i - (p.length + 1), Nat.sub_lt_left_of_lt_add hi <|
209+
by convert i.2 using 1; abel⟩
210+
rw [Fin.succ_mk, Nat.sub_eq_iff_eq_add (le_of_lt hi : p.length ≤ i),
211+
Nat.add_assoc _ 1, add_comm 1, Nat.sub_add_cancel]
212+
exact hi
213+
214+
/--
215+
For two types `α, β` and relation on them `r, s`, if `f : α → β` preserves relation `r`, then an
216+
`r`-series can be pushed out to an `s`-series by
217+
`a₀ -r→ a₁ -r→ ... -r→ aₙ ↦ f a₀ -s→ f a₁ -s→ ... -s→ f aₙ`
218+
-/
219+
@[simps]
220+
def map (p : RelSeries r)
221+
(f : α → β) (hf : ∀ ⦃x y : α⦄, r x y → s (f x) (f y)) : RelSeries s where
222+
length := p.length
223+
toFun := f.comp p
224+
step := (hf <| p.step .)
225+
226+
/--
227+
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` is an `r`-series and `a` is such that
228+
`aᵢ -r→ a -r→ a_ᵢ₊₁`, then
229+
`a₀ -r→ a₁ -r→ ... -r→ a_i -r→ a -r→ aᵢ₊₁ -r→ ... -r→ aₙ`
230+
is another `r`-series
231+
-/
232+
@[simps]
233+
def insertNth (p : RelSeries r) (i : Fin p.length) (a : α)
234+
(prev_connect : r (p (Fin.castSucc i)) a) (connect_next : r a (p i.succ)) : RelSeries r where
235+
toFun := (Fin.castSucc i.succ).insertNth a p
236+
step m := by
237+
set x := _; set y := _; change r x y
238+
obtain hm | hm | hm := lt_trichotomy m.1 i.1
239+
· convert p.step ⟨m, hm.trans i.2
240+
· show Fin.insertNth _ _ _ _ = _
241+
rw [Fin.insertNth_apply_below]
242+
pick_goal 2; exact hm.trans (lt_add_one _)
243+
simp
244+
· show Fin.insertNth _ _ _ _ = _
245+
rw [Fin.insertNth_apply_below]
246+
pick_goal 2; change m.1 + 1 < i.1 + 1; rwa [add_lt_add_iff_right]
247+
simp; rfl
248+
· rw [show x = p m from show Fin.insertNth _ _ _ _ = _ by
249+
rw [Fin.insertNth_apply_below]
250+
pick_goal 2; show m.1 < i.1 + 1; exact hm ▸ lt_add_one _
251+
simp]
252+
convert prev_connect
253+
· ext; exact hm
254+
· change Fin.insertNth _ _ _ _ = _
255+
rw [show m.succ = i.succ.castSucc by ext; change _ + 1 = _ + 1; rw [hm],
256+
Fin.insertNth_apply_same]
257+
· rw [Nat.lt_iff_add_one_le, le_iff_lt_or_eq] at hm
258+
obtain hm | hm := hm
259+
· convert p.step ⟨m.1 - 1, Nat.sub_lt_right_of_lt_add (by linarith) m.2
260+
· change Fin.insertNth _ _ _ _ = _
261+
rw [Fin.insertNth_apply_above (h := hm)]
262+
aesop
263+
· change Fin.insertNth _ _ _ _ = _
264+
rw [Fin.insertNth_apply_above]
265+
swap; exact hm.trans (lt_add_one _)
266+
simp only [Fin.val_succ, Nat.zero_eq, Fin.pred_succ, eq_rec_constant, ge_iff_le,
267+
Fin.succ_mk]
268+
congr
269+
exact Fin.ext <| Eq.symm <| Nat.succ_pred_eq_of_pos (lt_trans (Nat.zero_lt_succ _) hm)
270+
· convert connect_next
271+
· change Fin.insertNth _ _ _ _ = _
272+
rw [show m.castSucc = i.succ.castSucc from Fin.ext hm.symm, Fin.insertNth_apply_same]
273+
· change Fin.insertNth _ _ _ _ = _
274+
rw [Fin.insertNth_apply_above]
275+
swap; change i.1 + 1 < m.1 + 1; rw [hm]; exact lt_add_one _
276+
simp only [Fin.pred_succ, eq_rec_constant]
277+
congr; ext; exact hm.symm
278+
157279
end RelSeries
158280

159281
/-- A type is finite dimensional if its `LTSeries` has bounded length. -/
@@ -166,7 +288,7 @@ abbrev InfiniteDimensionalOrder (γ : Type*) [Preorder γ] :=
166288

167289
section LTSeries
168290

169-
variable (α) [Preorder α]
291+
variable (α) [Preorder α] [Preorder β]
170292
/--
171293
If `α` is a preorder, a LTSeries is a relation series of the less than relation.
172294
-/
@@ -208,6 +330,36 @@ lemma strictMono (x : LTSeries α) : StrictMono x :=
208330
lemma monotone (x : LTSeries α) : Monotone x :=
209331
x.strictMono.monotone
210332

333+
334+
/-- An alternative constructor of `LTSeries` from a strictly monotone function. -/
335+
@[simps]
336+
def mk (length : ℕ) (toFun : Fin (length + 1) → α) (strictMono : StrictMono toFun) :
337+
LTSeries α where
338+
toFun := toFun
339+
step i := strictMono <| lt_add_one i.1
340+
341+
/--
342+
For two preorders `α, β`, if `f : α → β` is strictly monotonic, then a strict chain of `α`
343+
can be pushed out to a strict chain of `β` by
344+
`a₀ < a₁ < ... < aₙ ↦ f a₀ < f a₁ < ... < f aₙ`
345+
-/
346+
@[simps!]
347+
def map (p : LTSeries α) (f : α → β) (hf : StrictMono f) : LTSeries β :=
348+
LTSeries.mk p.length (f.comp p) (hf.comp p.strictMono)
349+
350+
/--
351+
For two preorders `α, β`, if `f : α → β` is surjective and strictly comonotonic, then a
352+
strict series of `β` can be pulled back to a strict chain of `α` by
353+
`b₀ < b₁ < ... < bₙ ↦ f⁻¹ b₀ < f⁻¹ b₁ < ... < f⁻¹ bₙ` where `f⁻¹ bᵢ` is an arbitrary element in the
354+
preimage of `f⁻¹ {bᵢ}`.
355+
-/
356+
@[simps!]
357+
noncomputable def comap (p : LTSeries β) (f : α → β)
358+
(comap : ∀ ⦃x y⦄, f x < f y → x < y)
359+
(surjective : Function.Surjective f) :
360+
LTSeries α := mk p.length (fun i ↦ (surjective (p i)).choose)
361+
(fun i j h ↦ comap (by simpa only [(surjective _).choose_spec] using p.strictMono h))
362+
211363
end LTSeries
212364

213365
end LTSeries

0 commit comments

Comments
 (0)