@@ -3,12 +3,7 @@ Copyright (c) 2025 Robin Carlier. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Robin Carlier
55-/
6- import Mathlib.Tactic.Zify
7- import Mathlib.Data.List.Sort
8- import Mathlib.Tactic.Linarith
9- import Mathlib.Tactic.NormNum.Ineq
10- import Mathlib.Tactic.Ring.Basic
11-
6+ import Mathlib.AlgebraicTopology.SimplexCategory.GeneratorsRelations.EpiMono
127/-! # Normal forms for morphisms in `SimplexCategoryGenRel`.
138
149In this file, we establish that `P_δ` and `P_σ` morphisms in `SimplexCategoryGenRel`
@@ -34,12 +29,13 @@ stones towards proving that the canonical functor
3429* [ Kerodon Tag 04FT ] (https://kerodon.net/tag/04FT)
3530
3631 ## TODOs:
37- - Show that every `P_σ` admits a unique normal form.
3832- Show that every `P_δ` admits a unique normal form.
3933 -/
4034
4135namespace SimplexCategoryGenRel
4236
37+ open CategoryTheory
38+
4339section AdmissibleLists
4440-- Impl. note: We are not bundling admissible lists as a subtype of `List ℕ` so that it remains
4541-- easier to perform inductive constructions and proofs on such lists, and we instead bundle
@@ -155,4 +151,191 @@ theorem simplicialInsert_isAdmissible (L : List ℕ) (hL : IsAdmissible (m + 1)
155151
156152end AdmissibleLists
157153
154+ section NormalFormsP_σ
155+
156+ -- Impl note.: The definition is a bit awkward with the extra parameters, but this
157+ -- is necessary in order to avoid some type theory hell when proving that `orderedInsert`
158+ -- behaves as expected...
159+
160+ /-- Given a sequence `L = [ i 0, ..., i b ]`, `standardσ m L` i is the morphism
161+ `σ (i b) ≫ … ≫ σ (i 0)`. The construction is provided for any list of natural numbers,
162+ but it is intended to behave well only when the list is admissible. -/
163+ def standardσ (L : List ℕ) {m₁ m₂ : ℕ} (h : m₂ + L.length = m₁) : mk m₁ ⟶ mk m₂ :=
164+ match L with
165+ | .nil => eqToHom (by grind)
166+ | .cons a t => standardσ t (by grind) ≫ σ (Fin.ofNat _ a)
167+
168+ @[simp]
169+ lemma standardσ_nil (m : ℕ) : standardσ .nil (by grind) = 𝟙 (mk m) := rfl
170+
171+ @ [simp, reassoc]
172+ lemma standardσ_cons (L : List ℕ) (a : ℕ) {m₁ m₂ : ℕ} (h : m₂ + (a :: L).length = m₁) :
173+ standardσ (L.cons a) h = standardσ L (by grind) ≫ σ (Fin.ofNat _ a) := rfl
174+
175+ @[reassoc]
176+ lemma standardσ_comp_standardσ (L₁ L₂ : List ℕ) {m₁ m₂ m₃ : ℕ}
177+ (h : m₂ + L₁.length = m₁) (h' : m₃ + L₂.length = m₂) :
178+ standardσ L₁ h ≫ standardσ L₂ h' = standardσ (L₂ ++ L₁) (by grind) := by
179+ induction L₂ generalizing L₁ m₁ m₂ m₃ with
180+ | nil =>
181+ obtain rfl : m₃ = m₂ := by grind
182+ simp
183+ | cons a t H =>
184+ dsimp at h' ⊢
185+ obtain rfl : m₂ = (m₃ + t.length) + 1 := by grind
186+ simp [reassoc_of% (H L₁ (m₁ := m₁) (m₂ := m₃ + t.length + 1 ) (m₃ := m₃ + 1 )
187+ (by grind) (by grind))]
188+
189+ variable (m : ℕ) (L : List ℕ)
190+
191+ /-- `simplicialEvalσ` is a lift to ℕ of `(toSimplexCategory.map (standardσ m L _ _)).toOrderHom`.
192+ Rather than defining it as such, we define it inductively for less painful inductive reasoning,
193+ (see `simplicialEvalσ_of_isAdmissible`).
194+ It is expected to produce the correct result only if `L` is admissible, and values for
195+ non-admissible lists should be considered junk values. Similarly, values for out-of-bonds inputs
196+ are junk values. -/
197+ def simplicialEvalσ (L : List ℕ) : ℕ → ℕ :=
198+ fun j ↦ match L with
199+ | [] => j
200+ | a :: L => if a < simplicialEvalσ L j then simplicialEvalσ L j - 1 else simplicialEvalσ L j
201+
202+ lemma simplicialEvalσ_of_lt_mem (j : ℕ) (hj : ∀ k ∈ L, j ≤ k) : simplicialEvalσ L j = j := by
203+ induction L with
204+ | nil => grind [simplicialEvalσ]
205+ | cons _ _ _ =>
206+ simp only [List.mem_cons, forall_eq_or_imp] at hj
207+ grind [simplicialEvalσ]
208+
209+ lemma simplicialEvalσ_monotone (L : List ℕ) : Monotone (simplicialEvalσ L) := by
210+ intro a b hab
211+ induction L generalizing a b with
212+ | nil => exact hab
213+ | cons head tail h_rec => grind [simplicialEvalσ]
214+
215+ variable {m}
216+ /- We prove that `simplicialEvalσ` is indeed a lift of
217+ `(toSimplexCategory.map (standardσ m L _ _)).toOrderHom` when the list is admissible. -/
218+ lemma simplicialEvalσ_of_isAdmissible
219+ (m₁ m₂ : ℕ) (hL : IsAdmissible m₂ L) (hk : m₂ + L.length = m₁)
220+ (j : ℕ) (hj : j < m₁ + 1 ) :
221+ (toSimplexCategory.map <| standardσ L hk).toOrderHom ⟨j, hj⟩ =
222+ simplicialEvalσ L j := by
223+ induction L generalizing m₁ m₂ with
224+ | nil =>
225+ obtain rfl : m₁ = m₂ := by grind
226+ simp [simplicialEvalσ]
227+ | cons a L h_rec =>
228+ simp only [List.length_cons] at hk
229+ subst hk
230+ set a₀ := hL.head
231+ have aux (t : Fin (m₂ + 2 )) :
232+ (a₀.predAbove t : ℕ) = if a < ↑t then (t : ℕ) - 1 else ↑t := by
233+ simp only [Fin.predAbove, a₀]
234+ split_ifs with h₁ h₂ h₂
235+ · rfl
236+ · simp only [Fin.lt_def, Fin.coe_castSucc, IsAdmissible.head_val] at h₁; grind
237+ · simp only [Fin.lt_def, Fin.coe_castSucc, IsAdmissible.head_val, not_lt] at h₁; grind
238+ · rfl
239+ have := h_rec _ _ hL.tail (by grind) hj
240+ have ha₀ : Fin.ofNat (m₂ + 1 ) a = a₀ := by ext; simpa [a₀] using hL.head.prop
241+ simpa only [toSimplexCategory_obj_mk, SimplexCategory.len_mk, standardσ_cons, Functor.map_comp,
242+ toSimplexCategory_map_σ, SimplexCategory.σ, SimplexCategory.mkHom,
243+ SimplexCategory.comp_toOrderHom, SimplexCategory.Hom.toOrderHom_mk, OrderHom.comp_coe,
244+ Function.comp_apply, Fin.predAboveOrderHom_coe, simplicialEvalσ, ha₀, ← this] using aux _
245+
246+ /-- Performing a simplicial insertion in a list is the same as composition on the right by the
247+ corresponding degeneracy operator. -/
248+ lemma standardσ_simplicialInsert (hL : IsAdmissible (m + 1 ) L) (j : ℕ) (hj : j < m + 1 )
249+ (m₁ : ℕ) (hm₁ : m + L.length + 1 = m₁) :
250+ standardσ (m₂ := m) (simplicialInsert j L) (m₁ := m₁)
251+ (by simpa only [simplicialInsert_length, add_assoc]) =
252+ standardσ (m₂ := m + 1 ) L (by grind) ≫ σ (Fin.ofNat _ j) := by
253+ induction L generalizing m j with
254+ | nil => simp [standardσ, simplicialInsert]
255+ | cons a L h_rec =>
256+ simp only [simplicialInsert]
257+ split_ifs
258+ · simp
259+ · have : ∀ (j k : ℕ) (h : j < (k + 1 )), Fin.ofNat (k + 1 ) j = j := by simp -- helps grind below
260+ have : a < m + 2 := by grind -- helps grind below
261+ have : σ (Fin.ofNat (m + 2 ) a) ≫ σ (.ofNat _ j) = σ (.ofNat _ (j + 1 )) ≫ σ (.ofNat _ a) := by
262+ convert σ_comp_σ_nat (n := m) a j (by grind) (by grind) (by grind) <;> grind
263+ simp only [standardσ_cons, Category.assoc, this,
264+ h_rec hL.tail (j + 1 ) (by grind) (by grind)]
265+
266+ attribute [local grind] simplicialInsert_length simplicialInsert_isAdmissible in
267+ /-- Using `standardσ_simplicialInsert`, we can prove that every morphism satisfying `P_σ` is equal
268+ to some `standardσ` for some admissible list of indices. -/
269+ theorem exists_normal_form_P_σ {x y : SimplexCategoryGenRel} (f : x ⟶ y) (hf : P_σ f) :
270+ ∃ L : List ℕ,
271+ ∃ m : ℕ, ∃ b : ℕ,
272+ ∃ h₁ : mk m = y, ∃ h₂ : x = mk (m + b), ∃ h : L.length = b,
273+ IsAdmissible m L ∧ f = standardσ L (by rw [h, h₁.symm, h₂]; rfl) := by
274+ induction hf with
275+ | id n =>
276+ use [], n.len, 0 , rfl, rfl, rfl, IsAdmissible.nil _
277+ rfl
278+ | of f hf =>
279+ cases hf with | @σ m k =>
280+ use [k.val], m, 1 , rfl, rfl, rfl
281+ constructor <;> simp [IsAdmissible, Nat.le_of_lt_add_one k.prop, standardσ]
282+ | @comp_of _ j x' g g' hg hg' h_rec =>
283+ cases hg' with | @σ m k =>
284+ obtain ⟨L₁, m₁, b₁, h₁', rfl, h', hL₁, e₁⟩ := h_rec
285+ obtain rfl : m₁ = m + 1 := congrArg (fun x ↦ x.len) h₁'
286+ use simplicialInsert k.val L₁, m, b₁ + 1 , rfl, by grind, by grind, by grind
287+ subst_vars
288+ have := standardσ (m₁ := m + 1 + L₁.length) [] (by grind) ≫=
289+ (standardσ_simplicialInsert L₁ hL₁ k k.prop _ rfl).symm
290+ simp_all [Fin.ofNat_eq_cast, Fin.cast_val_eq_self, standardσ_comp_standardσ_assoc,
291+ standardσ_comp_standardσ]
292+
293+ section MemIsAdmissible
294+
295+ lemma mem_isAdmissible_of_lt_and_eval_eq_eval_add_one (hL : IsAdmissible m L)
296+ (j : ℕ) (hj₁ : j < m + L.length) (hj₂ : simplicialEvalσ L j = simplicialEvalσ L (j + 1 )) :
297+ j ∈ L := by
298+ induction L generalizing m with
299+ | nil => grind [simplicialEvalσ]
300+ | cons a L h_rec =>
301+ have := h_rec hL.tail (by grind)
302+ suffices ¬j = a → (simplicialEvalσ L j = simplicialEvalσ L (j + 1 )) by grind
303+ intro hja
304+ simp only [simplicialEvalσ] at hj₂
305+ have : simplicialEvalσ L j ≤ simplicialEvalσ L (j + 1 ) :=
306+ simplicialEvalσ_monotone L (by grind)
307+ suffices ¬a < simplicialEvalσ L j → a < simplicialEvalσ L (j + 1 ) →
308+ simplicialEvalσ L j = simplicialEvalσ L (j + 1 ) - 1 →
309+ simplicialEvalσ L j = simplicialEvalσ L (j + 1 ) by grind
310+ intro h₁ h₂ hj₂
311+ simp only [IsAdmissible, List.sorted_cons, List.length_cons] at hL
312+ obtain h | rfl | h := Nat.lt_trichotomy j a
313+ · grind [simplicialEvalσ_monotone, Monotone, simplicialEvalσ_of_lt_mem]
314+ · grind
315+ · have := simplicialEvalσ_of_lt_mem L (a + 1 ) <| fun x h ↦ hL.1 .1 x h
316+ grind [simplicialEvalσ_monotone, Monotone]
317+
318+ lemma lt_and_eval_eq_eval_add_one_of_mem_isAdmissible (hL : IsAdmissible m L) (j : ℕ) (hj : j ∈ L) :
319+ j < m + L.length ∧ simplicialEvalσ L j = simplicialEvalσ L (j + 1 ) := by
320+ induction L generalizing m with
321+ | nil => grind
322+ | cons a L h_rec =>
323+ constructor
324+ · grind [List.mem_iff_getElem, IsAdmissible, List.sorted_cons]
325+ · obtain rfl | h := List.mem_cons.mp hj
326+ · grind [simplicialEvalσ_of_lt_mem, simplicialEvalσ, IsAdmissible, List.sorted_cons]
327+ · have := h_rec hL.tail h
328+ grind [simplicialEvalσ]
329+
330+ /-- We can characterize elements in an admissible list as exactly those for which
331+ `simplicialEvalσ` takes the same value twice in a row. -/
332+ lemma mem_isAdmissible_iff (hL : IsAdmissible m L) (j : ℕ) :
333+ j ∈ L ↔ j < m + L.length ∧ simplicialEvalσ L j = simplicialEvalσ L (j + 1 ) := by
334+ grind [lt_and_eval_eq_eval_add_one_of_mem_isAdmissible,
335+ mem_isAdmissible_of_lt_and_eval_eq_eval_add_one]
336+
337+ end MemIsAdmissible
338+
339+ end NormalFormsP_σ
340+
158341end SimplexCategoryGenRel
0 commit comments