1
1
/-
2
2
Copyright (c) 2023 Jujian Zhang. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
- Authors: Jujian Zhang
4
+ Authors: Jujian Zhang, Fangming Li
5
5
-/
6
6
import Mathlib.Logic.Equiv.Fin
7
7
import Mathlib.Data.List.Indexes
8
8
import Mathlib.Data.Rel
9
+ import Mathlib.Tactic.Linarith
10
+ import Mathlib.Tactic.Abel
9
11
10
12
/-!
11
13
# Series of a relation
@@ -16,6 +18,7 @@ If `r` is a relation on `α` then a relation series of length `n` is a series
16
18
-/
17
19
18
20
variable {α : Type *} (r : Rel α α)
21
+ variable {β : Type *} (s : Rel β β)
19
22
20
23
/--
21
24
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
154
157
lemma nonempty_of_infiniteDimensional [r.InfiniteDimensional] : Nonempty α :=
155
158
⟨RelSeries.withLength r 0 0 ⟩
156
159
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
+
157
279
end RelSeries
158
280
159
281
/-- A type is finite dimensional if its `LTSeries` has bounded length. -/
@@ -166,7 +288,7 @@ abbrev InfiniteDimensionalOrder (γ : Type*) [Preorder γ] :=
166
288
167
289
section LTSeries
168
290
169
- variable (α) [Preorder α]
291
+ variable (α) [Preorder α] [Preorder β]
170
292
/--
171
293
If `α` is a preorder, a LTSeries is a relation series of the less than relation.
172
294
-/
@@ -208,6 +330,36 @@ lemma strictMono (x : LTSeries α) : StrictMono x :=
208
330
lemma monotone (x : LTSeries α) : Monotone x :=
209
331
x.strictMono.monotone
210
332
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
+
211
363
end LTSeries
212
364
213
365
end LTSeries
0 commit comments