From 9a6e23ba386a24a1c37064fc395c03a9adaa2f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 26 Jan 2025 18:40:45 +0100 Subject: [PATCH 01/81] feat(AlgebraicTopology/SimplicialSet): degenerate simplices --- Mathlib.lean | 1 + .../SimplicialSet/Degenerate.lean | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean diff --git a/Mathlib.lean b/Mathlib.lean index e5041a5fd5c1bb..c8b75bc285c880 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1118,6 +1118,7 @@ import Mathlib.AlgebraicTopology.SimplicialObject.Split import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.SimplicialSet.Boundary import Mathlib.AlgebraicTopology.SimplicialSet.Coskeletal +import Mathlib.AlgebraicTopology.SimplicialSet.Degenerate import Mathlib.AlgebraicTopology.SimplicialSet.HomotopyCat import Mathlib.AlgebraicTopology.SimplicialSet.Horn import Mathlib.AlgebraicTopology.SimplicialSet.KanComplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean new file mode 100644 index 00000000000000..f365244caebb6b --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -0,0 +1,124 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ + +import Mathlib.AlgebraicTopology.SimplicialSet.Basic + +/-! +# Degenerate simplices + +Given a simplicial set `X` and `n : ℕ`, we define the sets `X.degenerate n` +and `X.nonDegenerate n` of degenerate or non-degenerate simplices of dimension `n`. + +## TODO (@joelriou) + +* `SSet.exists_nonDegenerate` shows that any `n`-simplex can be written +as `X.map f.op y` for some epimorphism `f : [n] ⟶ [m]` and some +non-degenerate simplex `y`. Show that `f` and `y` are unique. + +-/ + +universe u + +open CategoryTheory Simplicial Limits Opposite + +namespace SSet + +variable (X : SSet.{u}) + +/-- A `n`-simplex of a simplicial `X` is degenerate if it is in the range +of `X.map f.op` for some morphism `f : [n] ⟶ [m]` with `m < n`. -/ +def degenerate (n : ℕ) : Set (X _[n]) := + setOf (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ([n] : SimplexCategory) ⟶ [m]), + x ∈ Set.range (X.map f.op)) + +/-- The set of `n`-dimensional non-degenerate simplices in a simplicial +set `X` is the complement of `X.degenerate n`. -/ +def nonDegenerate (n : ℕ) : Set (X _[n]) := (X.degenerate n)ᶜ + +@[simp] +lemma degenerate_zero : X.degenerate 0 = ⊥ := by + ext x + simp only [Set.bot_eq_empty, Set.mem_empty_iff_false, iff_false] + rintro ⟨m, hm, _⟩ + simp at hm + +@[simp] +lemma nondegenerate_zero : X.nonDegenerate 0 = ⊤ := by + simp [nonDegenerate] + +variable {n : ℕ} + +lemma mem_nonDegenerate_iff_not_mem_degenerate (x : X _[n]) : + x ∈ X.nonDegenerate n ↔ x ∉ X.degenerate n := Iff.rfl + +lemma mem_degenerate_iff_not_mem_nonDegenerate (x : X _[n]) : + x ∈ X.degenerate n ↔ x ∉ X.nonDegenerate n := by + simp [nonDegenerate] + +lemma σ_mem_degenerate (i : Fin (n + 1)) (x : X _[n]) : + X.σ i x ∈ X.degenerate (n + 1) := + ⟨n, by omega, SimplexCategory.σ i, Set.mem_range_self x⟩ + +lemma mem_degenerate_iff (x : X _[n]) : + x ∈ X.degenerate n ↔ ∃ (m : ℕ) (_ : m < n) + (f : ([n] : SimplexCategory) ⟶ [m]) (_ : Epi f), + x ∈ Set.range (X.map f.op) := by + constructor + · rintro ⟨m, hm, f, y, hy⟩ + rw [← image.fac f, op_comp] at hy + have : _ ≤ m := SimplexCategory.len_le_of_mono (f := image.ι f) inferInstance + exact ⟨(image f).len, by omega, factorThruImage f, inferInstance, by aesop⟩ + · rintro ⟨m, hm, f, hf, hx⟩ + exact ⟨m, hm, f, hx⟩ + +lemma degenerate_eq_iUnion_range_σ : + X.degenerate (n + 1) = ⋃ (i : Fin (n + 1)), Set.range (X.σ i) := by + ext x + constructor + · intro hx + rw [mem_degenerate_iff] at hx + obtain ⟨m, hm, f, hf, y, rfl⟩ := hx + obtain ⟨i, θ, rfl⟩ := SimplexCategory.eq_σ_comp_of_not_injective f (fun hf ↦ by + have := SimplexCategory.le_of_mono (f := f) (by + rwa [SimplexCategory.mono_iff_injective]) + omega) + aesop + · intro hx + simp only [Set.mem_iUnion, Set.mem_range] at hx + obtain ⟨i, y, rfl⟩ := hx + apply σ_mem_degenerate + +lemma exists_nonDegenerate (x : X _[n]) : + ∃ (m : ℕ) (f : ([n] : SimplexCategory) ⟶ [m]) (_ : Epi f) + (y : X.nonDegenerate m), x = X.map f.op y := by + induction n with + | zero => + exact ⟨0, 𝟙 _, inferInstance, ⟨x, by simp⟩, by simp⟩ + | succ n hn => + by_cases hx : x ∈ X.nonDegenerate (n + 1) + · exact ⟨n + 1, 𝟙 _, inferInstance, ⟨x, hx⟩, by simp⟩ + · simp only [← mem_degenerate_iff_not_mem_nonDegenerate, + degenerate_eq_iUnion_range_σ, Set.mem_iUnion, Set.mem_range] at hx + obtain ⟨i, y, rfl⟩ := hx + obtain ⟨m, f, hf, z, rfl⟩ := hn y + exact ⟨_, SimplexCategory.σ i ≫ f, inferInstance, z, by simp; rfl⟩ + +lemma isIso_of_nonDegenerate (x : X.nonDegenerate n) + {m : SimplexCategory} (f : ([n] : SimplexCategory) ⟶ m) [Epi f] + (y : X.obj (op m)) (hy : X.map f.op y = x) : + IsIso f := by + obtain ⟨x, hx⟩ := x + induction' m using SimplexCategory.rec with m + rw [mem_nonDegenerate_iff_not_mem_degenerate] at hx + by_contra! + refine hx ⟨_ ,?_, f, y, hy⟩ + by_contra! + obtain rfl : m = n := + le_antisymm (SimplexCategory.len_le_of_epi (f := f) inferInstance) this + obtain rfl := SimplexCategory.eq_id_of_epi f + exact this inferInstance + +end SSet From e782e896fa286c26f7678f46bcc9ebbdb114ba99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Sun, 26 Jan 2025 20:49:15 +0100 Subject: [PATCH 02/81] Update Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean --- Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index f365244caebb6b..2332c7db1ed10e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -3,7 +3,6 @@ Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ - import Mathlib.AlgebraicTopology.SimplicialSet.Basic /-! From 666f6ea8486c1251f07c9f326ee0902b553af841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 26 Jan 2025 20:56:43 +0100 Subject: [PATCH 03/81] feat(AlgebraicTopology/SimplicialSet/Degenerate): uniqueness of a decomposition --- .../AlgebraicTopology/SimplexCategory.lean | 3 + .../SimplicialSet/Degenerate.lean | 131 +++++++++++++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory.lean b/Mathlib/AlgebraicTopology/SimplexCategory.lean index ba34f389c2b8c7..cd97849afdfdd2 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory.lean @@ -147,6 +147,9 @@ theorem Hom.ext {a b : SimplexCategory} (f g : a ⟶ b) : f.toOrderHom = g.toOrderHom → f = g := Hom.ext' _ _ +lemma congr_toOrderHom_apply {a b : SimplexCategory} {f g : a ⟶ b} (h : f = g) + (x : Fin (a.len + 1)) : f.toOrderHom x = g.toOrderHom x := by rw [h] + /-- The constant morphism from [0]. -/ def const (x y : SimplexCategory) (i : Fin (y.len + 1)) : x ⟶ y := Hom.mk <| ⟨fun _ => i, by tauto⟩ diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index f365244caebb6b..30ad2dc120a91d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -3,7 +3,6 @@ Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ - import Mathlib.AlgebraicTopology.SimplicialSet.Basic /-! @@ -12,11 +11,10 @@ import Mathlib.AlgebraicTopology.SimplicialSet.Basic Given a simplicial set `X` and `n : ℕ`, we define the sets `X.degenerate n` and `X.nonDegenerate n` of degenerate or non-degenerate simplices of dimension `n`. -## TODO (@joelriou) - -* `SSet.exists_nonDegenerate` shows that any `n`-simplex can be written -as `X.map f.op y` for some epimorphism `f : [n] ⟶ [m]` and some -non-degenerate simplex `y`. Show that `f` and `y` are unique. +Any simplex `x : X _[n]` can be written in a unique way as `X.map f.op y` +for an epimorphism `f : [n] ⟶ [m]` and a non-degenerate `m`-simplex `y` +(see lemmas `exists_nonDegenerate`, `unique_nonDegenerate₁`, `unique_nonDegenerate₂` +and `unique_nonDegenerate₃`). -/ @@ -121,4 +119,125 @@ lemma isIso_of_nonDegenerate (x : X.nonDegenerate n) obtain rfl := SimplexCategory.eq_id_of_epi f exact this inferInstance +namespace unique_nonDegenerate + +/-! +Auxiliary definitions and lemmas for the lemmas +`unique_nonDegenerate₁`, `unique_nonDegenerate₂` and +`unique_nonDegenerate₃` which assert the uniqueness of the +decomposition obtained in the lemma `exists_nonDegenerate`. +-/ + +section + +variable {X} {x : X _[n]} + {m₁ m₂ : ℕ} {f₁ : ([n] : SimplexCategory) ⟶ [m₁]} (hf₁ : SplitEpi f₁) + (y₁ : X.nonDegenerate m₁) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ([n] : SimplexCategory) ⟶ [m₂]) + (y₂ : X _[m₂]) (hy₂ : x = X.map f₂.op y₂) + +/-- The composition of a section of `f₁` and `f₂`. It is proven below that it +is the identity, see `g_eq_id`. -/ +def g := hf₁.section_ ≫ f₂ + +variable {f₂ y₁ y₂} + +include hf₁ hy₁ hy₂ + +lemma map_g_op_y₂ : X.map (g hf₁ f₂).op y₂ = y₁ := by + dsimp [g] + rw [FunctorToTypes.map_comp_apply, ← hy₂, hy₁, ← FunctorToTypes.map_comp_apply, ← op_comp, + SplitEpi.id, op_id, FunctorToTypes.map_id_apply] + +lemma isIso_factorThruImage_g : + IsIso (factorThruImage (g hf₁ f₂)) := by + have := map_g_op_y₂ hf₁ hy₁ hy₂ + rw [← image.fac (g hf₁ f₂), op_comp, FunctorToTypes.map_comp_apply] at this + exact X.isIso_of_nonDegenerate y₁ (factorThruImage (g hf₁ f₂)) _ this + +lemma mono_g : Mono (g hf₁ f₂) := by + have := isIso_factorThruImage_g hf₁ hy₁ hy₂ + rw [← image.fac (g hf₁ f₂)] + infer_instance + +lemma le : m₁ ≤ m₂ := by + have := isIso_factorThruImage_g hf₁ hy₁ hy₂ + exact SimplexCategory.len_le_of_mono + (f := factorThruImage (g hf₁ f₂) ≫ image.ι _) inferInstance + +end + +section + +variable {X} {x : X _[n]} {m : ℕ} {f₁ : ([n] : SimplexCategory) ⟶ [m]} + {y₁ : X.nonDegenerate m} (hy₁ : x = X.map f₁.op y₁) + {f₂ : ([n] : SimplexCategory) ⟶ [m]} {y₂ : X _[m]} (hy₂ : x = X.map f₂.op y₂) + +include hy₁ hy₂ + +lemma g_eq_id (hf₁ : SplitEpi f₁) : g hf₁ f₂ = 𝟙 _ := by + have := mono_g hf₁ hy₁ hy₂ + apply SimplexCategory.eq_id_of_mono + +end + +end unique_nonDegenerate + +section + +open unique_nonDegenerate + +/-! +The following lemmas `unique_nonDegenerate₁`, `unique_nonDegenerate₂` and +`unique_nonDegenerate₃` assert the uniqueness of the decomposition +obtained in the lemma `exists_nonDegenerate`. +-/ + +lemma unique_nonDegenerate₁ (x : X _[n]) + {m₁ m₂ : ℕ} (f₁ : ([n] : SimplexCategory) ⟶ [m₁]) [Epi f₁] + (y₁ : X.nonDegenerate m₁) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ([n] : SimplexCategory) ⟶ [m₂]) [Epi f₂] + (y₂ : X.nonDegenerate m₂) (hy₂ : x = X.map f₂.op y₂) : m₁ = m₂ := by + obtain ⟨⟨hf₁⟩⟩ := isSplitEpi_of_epi f₁ + obtain ⟨⟨hf₂⟩⟩ := isSplitEpi_of_epi f₂ + exact le_antisymm (le hf₁ hy₁ hy₂) (le hf₂ hy₂ hy₁) + +lemma unique_nonDegenerate₂ (x : X _[n]) + {m : ℕ} (f₁ : ([n] : SimplexCategory) ⟶ [m]) [Epi f₁] + (y₁ : X.nonDegenerate m) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ([n] : SimplexCategory) ⟶ [m]) + (y₂ : X.nonDegenerate m) (hy₂ : x = X.map f₂.op y₂) : y₁ = y₂ := by + obtain ⟨⟨hf₁⟩⟩ := isSplitEpi_of_epi f₁ + ext + simpa [g_eq_id hy₁ hy₂ hf₁] using (map_g_op_y₂ hf₁ hy₁ hy₂).symm + +lemma unique_nonDegenerate₃ (x : X _[n]) + {m : ℕ} (f₁ : ([n] : SimplexCategory) ⟶ [m]) [Epi f₁] + (y₁ : X.nonDegenerate m) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ([n] : SimplexCategory) ⟶ [m]) + (y₂ : X.nonDegenerate m) (hy₂ : x = X.map f₂.op y₂) : f₁ = f₂ := by + ext x : 3 + suffices ∃ (hf₁ : SplitEpi f₁), hf₁.section_.toOrderHom (f₁.toOrderHom x) = x by + obtain ⟨hf₁, hf₁'⟩ := this + dsimp at hf₁' + simpa [g, hf₁'] using (SimplexCategory.congr_toOrderHom_apply (g_eq_id hy₁ hy₂ hf₁) + (f₁.toOrderHom x)).symm + obtain ⟨⟨hf⟩⟩ := isSplitEpi_of_epi f₁ + let α (y : Fin (m + 1)) : Fin (n + 1) := + if y = f₁.toOrderHom x then x else hf.section_.toOrderHom y + have hα₁ (y : Fin (m + 1)) : f₁.toOrderHom (α y) = y := by + dsimp [α] + split_ifs with hy + · rw [hy] + · apply SimplexCategory.congr_toOrderHom_apply hf.id + have hα₂ : Monotone α := by + rintro y₁ y₂ h + by_contra! h' + suffices y₂ ≤ y₁ by simp [show y₁ = y₂ by omega] at h' + simpa only [hα₁, hα₁] using f₁.toOrderHom.monotone h'.le + exact ⟨{ section_ := SimplexCategory.Hom.mk ⟨α, hα₂⟩, id := by ext : 3; apply hα₁ }, + by simp [α]⟩ + +end + end SSet From be3325926e5524e8877de1c3a34ee829c6a5bd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:00:56 +0100 Subject: [PATCH 04/81] Update Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean Co-authored-by: Nick Ward <102917377+gio256@users.noreply.github.com> --- Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index 2332c7db1ed10e..1041bc64513986 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -27,7 +27,7 @@ namespace SSet variable (X : SSet.{u}) -/-- A `n`-simplex of a simplicial `X` is degenerate if it is in the range +/-- An `n`-simplex of a simplicial set `X` is degenerate if it is in the range of `X.map f.op` for some morphism `f : [n] ⟶ [m]` with `m < n`. -/ def degenerate (n : ℕ) : Set (X _[n]) := setOf (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ([n] : SimplexCategory) ⟶ [m]), From 9908fbb92b196e9eb55edbfebcf430f155c51bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 8 Feb 2025 00:21:20 +0100 Subject: [PATCH 05/81] fix notations --- Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index 1041bc64513986..2a8337bc741a90 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -30,7 +30,7 @@ variable (X : SSet.{u}) /-- An `n`-simplex of a simplicial set `X` is degenerate if it is in the range of `X.map f.op` for some morphism `f : [n] ⟶ [m]` with `m < n`. -/ def degenerate (n : ℕ) : Set (X _[n]) := - setOf (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ([n] : SimplexCategory) ⟶ [m]), + setOf (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ⦋n⦌ ⟶ ⦋m⦌), x ∈ Set.range (X.map f.op)) /-- The set of `n`-dimensional non-degenerate simplices in a simplicial @@ -62,8 +62,7 @@ lemma σ_mem_degenerate (i : Fin (n + 1)) (x : X _[n]) : ⟨n, by omega, SimplexCategory.σ i, Set.mem_range_self x⟩ lemma mem_degenerate_iff (x : X _[n]) : - x ∈ X.degenerate n ↔ ∃ (m : ℕ) (_ : m < n) - (f : ([n] : SimplexCategory) ⟶ [m]) (_ : Epi f), + x ∈ X.degenerate n ↔ ∃ (m : ℕ) (_ : m < n) (f : ⦋n⦌ ⟶ ⦋m⦌) (_ : Epi f), x ∈ Set.range (X.map f.op) := by constructor · rintro ⟨m, hm, f, y, hy⟩ @@ -91,7 +90,7 @@ lemma degenerate_eq_iUnion_range_σ : apply σ_mem_degenerate lemma exists_nonDegenerate (x : X _[n]) : - ∃ (m : ℕ) (f : ([n] : SimplexCategory) ⟶ [m]) (_ : Epi f) + ∃ (m : ℕ) (f : ⦋n⦌ ⟶ ⦋m⦌) (_ : Epi f) (y : X.nonDegenerate m), x = X.map f.op y := by induction n with | zero => @@ -106,7 +105,7 @@ lemma exists_nonDegenerate (x : X _[n]) : exact ⟨_, SimplexCategory.σ i ≫ f, inferInstance, z, by simp; rfl⟩ lemma isIso_of_nonDegenerate (x : X.nonDegenerate n) - {m : SimplexCategory} (f : ([n] : SimplexCategory) ⟶ m) [Epi f] + {m : SimplexCategory} (f : ⦋n⦌ ⟶ m) [Epi f] (y : X.obj (op m)) (hy : X.map f.op y = x) : IsIso f := by obtain ⟨x, hx⟩ := x From a022357fa23c8872a63e684e43031d3abcc5e08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 14 Feb 2025 10:56:04 +0100 Subject: [PATCH 06/81] fix --- .../SimplicialSet/Degenerate.lean | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index 2a8337bc741a90..f8c8f92697267e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -14,7 +14,7 @@ and `X.nonDegenerate n` of degenerate or non-degenerate simplices of dimension ` ## TODO (@joelriou) * `SSet.exists_nonDegenerate` shows that any `n`-simplex can be written -as `X.map f.op y` for some epimorphism `f : [n] ⟶ [m]` and some +as `X.map f.op y` for some epimorphism `f : ⦋n⦌ ⟶ ⦋m⦌` and some non-degenerate simplex `y`. Show that `f` and `y` are unique. -/ @@ -29,13 +29,13 @@ variable (X : SSet.{u}) /-- An `n`-simplex of a simplicial set `X` is degenerate if it is in the range of `X.map f.op` for some morphism `f : [n] ⟶ [m]` with `m < n`. -/ -def degenerate (n : ℕ) : Set (X _[n]) := +def degenerate (n : ℕ) : Set (X _⦋n⦌) := setOf (fun x ↦ ∃ (m : ℕ) (_ : m < n) (f : ⦋n⦌ ⟶ ⦋m⦌), x ∈ Set.range (X.map f.op)) /-- The set of `n`-dimensional non-degenerate simplices in a simplicial set `X` is the complement of `X.degenerate n`. -/ -def nonDegenerate (n : ℕ) : Set (X _[n]) := (X.degenerate n)ᶜ +def nonDegenerate (n : ℕ) : Set (X _⦋n⦌) := (X.degenerate n)ᶜ @[simp] lemma degenerate_zero : X.degenerate 0 = ⊥ := by @@ -50,18 +50,18 @@ lemma nondegenerate_zero : X.nonDegenerate 0 = ⊤ := by variable {n : ℕ} -lemma mem_nonDegenerate_iff_not_mem_degenerate (x : X _[n]) : +lemma mem_nonDegenerate_iff_not_mem_degenerate (x : X _⦋n⦌) : x ∈ X.nonDegenerate n ↔ x ∉ X.degenerate n := Iff.rfl -lemma mem_degenerate_iff_not_mem_nonDegenerate (x : X _[n]) : +lemma mem_degenerate_iff_not_mem_nonDegenerate (x : X _⦋n⦌) : x ∈ X.degenerate n ↔ x ∉ X.nonDegenerate n := by simp [nonDegenerate] -lemma σ_mem_degenerate (i : Fin (n + 1)) (x : X _[n]) : +lemma σ_mem_degenerate (i : Fin (n + 1)) (x : X _⦋n⦌) : X.σ i x ∈ X.degenerate (n + 1) := ⟨n, by omega, SimplexCategory.σ i, Set.mem_range_self x⟩ -lemma mem_degenerate_iff (x : X _[n]) : +lemma mem_degenerate_iff (x : X _⦋n⦌) : x ∈ X.degenerate n ↔ ∃ (m : ℕ) (_ : m < n) (f : ⦋n⦌ ⟶ ⦋m⦌) (_ : Epi f), x ∈ Set.range (X.map f.op) := by constructor @@ -89,7 +89,7 @@ lemma degenerate_eq_iUnion_range_σ : obtain ⟨i, y, rfl⟩ := hx apply σ_mem_degenerate -lemma exists_nonDegenerate (x : X _[n]) : +lemma exists_nonDegenerate (x : X _⦋n⦌) : ∃ (m : ℕ) (f : ⦋n⦌ ⟶ ⦋m⦌) (_ : Epi f) (y : X.nonDegenerate m), x = X.map f.op y := by induction n with From 03fe2d776f8948552aa6986d91f5e88b3bc9992c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 18 Apr 2025 22:57:52 +0200 Subject: [PATCH 07/81] whitespace --- .../SimplicialSet/Degenerate.lean | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index bf4920b34a5063..2ae98e0a53b1a6 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -132,8 +132,7 @@ section variable {X} {x : X _⦋n⦌} {m₁ m₂ : ℕ} {f₁ : ⦋n⦌ ⟶ ⦋m₁⦌} (hf₁ : SplitEpi f₁) (y₁ : X.nonDegenerate m₁) (hy₁ : x = X.map f₁.op y₁) - (f₂ : ⦋n⦌ ⟶ ⦋m₂⦌) - (y₂ : X _⦋m₂⦌) (hy₂ : x = X.map f₂.op y₂) + (f₂ : ⦋n⦌ ⟶ ⦋m₂⦌) (y₂ : X _⦋m₂⦌) (hy₂ : x = X.map f₂.op y₂) /-- The composition of a section of `f₁` and `f₂`. It is proven below that it is the identity, see `g_eq_id`. -/ @@ -186,29 +185,26 @@ The following lemmas `unique_nonDegenerate₁`, `unique_nonDegenerate₂` and obtained in the lemma `exists_nonDegenerate`. -/ -lemma unique_nonDegenerate₁ (x : X _⦋n⦌) - {m₁ m₂ : ℕ} (f₁ : ⦋n⦌ ⟶ ⦋m₁⦌) [Epi f₁] - (y₁ : X.nonDegenerate m₁) (hy₁ : x = X.map f₁.op y₁) - (f₂ : ⦋n⦌ ⟶ ⦋m₂⦌) [Epi f₂] - (y₂ : X.nonDegenerate m₂) (hy₂ : x = X.map f₂.op y₂) : m₁ = m₂ := by +lemma unique_nonDegenerate₁ (x : X _⦋n⦌) {m₁ m₂ : ℕ} + (f₁ : ⦋n⦌ ⟶ ⦋m₁⦌) [Epi f₁] (y₁ : X.nonDegenerate m₁) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ⦋n⦌ ⟶ ⦋m₂⦌) [Epi f₂] (y₂ : X.nonDegenerate m₂) (hy₂ : x = X.map f₂.op y₂) : + m₁ = m₂ := by obtain ⟨⟨hf₁⟩⟩ := isSplitEpi_of_epi f₁ obtain ⟨⟨hf₂⟩⟩ := isSplitEpi_of_epi f₂ exact le_antisymm (le hf₁ hy₁ hy₂) (le hf₂ hy₂ hy₁) -lemma unique_nonDegenerate₂ (x : X _⦋n⦌) - {m : ℕ} (f₁ : ⦋n⦌ ⟶ ⦋m⦌) [Epi f₁] - (y₁ : X.nonDegenerate m) (hy₁ : x = X.map f₁.op y₁) - (f₂ : ⦋n⦌ ⟶ ⦋m⦌) - (y₂ : X.nonDegenerate m) (hy₂ : x = X.map f₂.op y₂) : y₁ = y₂ := by +lemma unique_nonDegenerate₂ (x : X _⦋n⦌) {m : ℕ} + (f₁ : ⦋n⦌ ⟶ ⦋m⦌) [Epi f₁] (y₁ : X.nonDegenerate m) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ⦋n⦌ ⟶ ⦋m⦌) (y₂ : X.nonDegenerate m) (hy₂ : x = X.map f₂.op y₂) : + y₁ = y₂ := by obtain ⟨⟨hf₁⟩⟩ := isSplitEpi_of_epi f₁ ext simpa [g_eq_id hy₁ hy₂ hf₁] using (map_g_op_y₂ hf₁ hy₁ hy₂).symm -lemma unique_nonDegenerate₃ (x : X _⦋n⦌) - {m : ℕ} (f₁ : ⦋n⦌ ⟶ ⦋m⦌) [Epi f₁] - (y₁ : X.nonDegenerate m) (hy₁ : x = X.map f₁.op y₁) - (f₂ : ⦋n⦌ ⟶ ⦋m⦌) - (y₂ : X.nonDegenerate m) (hy₂ : x = X.map f₂.op y₂) : f₁ = f₂ := by +lemma unique_nonDegenerate₃ (x : X _⦋n⦌) {m : ℕ} + (f₁ : ⦋n⦌ ⟶ ⦋m⦌) [Epi f₁] (y₁ : X.nonDegenerate m) (hy₁ : x = X.map f₁.op y₁) + (f₂ : ⦋n⦌ ⟶ ⦋m⦌) (y₂ : X.nonDegenerate m) (hy₂ : x = X.map f₂.op y₂) : + f₁ = f₂ := by ext x : 3 suffices ∃ (hf₁ : SplitEpi f₁), hf₁.section_.toOrderHom (f₁.toOrderHom x) = x by obtain ⟨hf₁, hf₁'⟩ := this From c62c07961bf808bfc32cefe527bfda96c09a6ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 5 Aug 2025 14:56:37 +0530 Subject: [PATCH 08/81] chore(AlgebraicTopology/SimplexCategory): cleaning up lemmas about epi/mono --- .../SimplexCategory/Basic.lean | 104 +++++++++++++----- 1 file changed, 79 insertions(+), 25 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 4137740aa04a71..3f3087e06b24b5 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -612,25 +612,25 @@ theorem epi_iff_surjective {n m : SimplexCategory} {f : n ⟶ m} : NonemptyFinLinOrd.epi_iff_surjective, NonemptyFinLinOrd.coe_of, ConcreteCategory.hom_ofHom] /-- A monomorphism in `SimplexCategory` must increase lengths -/ -theorem len_le_of_mono {x y : SimplexCategory} {f : x ⟶ y} : Mono f → x.len ≤ y.len := by - intro hyp_f_mono - have f_inj : Function.Injective f.toOrderHom.toFun := mono_iff_injective.1 hyp_f_mono - simpa using Fintype.card_le_of_injective f.toOrderHom.toFun f_inj +theorem len_le_of_mono {x y : SimplexCategory} (f : x ⟶ y) [Mono f] : x.len ≤ y.len := by + simpa using Fintype.card_le_of_injective f.toOrderHom.toFun + (by dsimp; rwa [← mono_iff_injective]) -theorem le_of_mono {n m : ℕ} {f : ⦋n⦌ ⟶ ⦋m⦌} : CategoryTheory.Mono f → n ≤ m := - len_le_of_mono +theorem le_of_mono {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [Mono f] : n ≤ m := + len_le_of_mono f /-- An epimorphism in `SimplexCategory` must decrease lengths -/ -theorem len_le_of_epi {x y : SimplexCategory} {f : x ⟶ y} : Epi f → y.len ≤ x.len := by - intro hyp_f_epi - have f_surj : Function.Surjective f.toOrderHom.toFun := epi_iff_surjective.1 hyp_f_epi - simpa using Fintype.card_le_of_surjective f.toOrderHom.toFun f_surj +theorem len_le_of_epi {x y : SimplexCategory} (f : x ⟶ y) [Epi f] : y.len ≤ x.len := by + simpa using Fintype.card_le_of_surjective f.toOrderHom.toFun + (by dsimp; rwa [← epi_iff_surjective]) -theorem le_of_epi {n m : ℕ} {f : ⦋n⦌ ⟶ ⦋m⦌} : Epi f → m ≤ n := len_le_of_epi +theorem le_of_epi {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [Epi f] : m ≤ n := len_le_of_epi f -instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by - rw [mono_iff_injective] - exact Fin.succAbove_right_injective +lemma len_eq_of_isIso {x y : SimplexCategory} (f : x ⟶ y) [IsIso f] : x.len = y.len := + le_antisymm (len_le_of_mono f) (len_le_of_epi f) + +lemma eq_of_isIso {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [IsIso f] : n = m := + len_eq_of_isIso f instance {n : ℕ} {i : Fin (n + 1)} : Epi (σ i) := by rw [epi_iff_surjective] @@ -679,6 +679,29 @@ theorem isIso_of_bijective {x y : SimplexCategory} {f : x ⟶ y} haveI : IsIso ((forget SimplexCategory).map f) := (isIso_iff_bijective _).mpr hf isIso_of_reflects_iso f (forget SimplexCategory) +lemma isIso_iff_of_mono {n m : SimplexCategory} (f : n ⟶ m) [Mono f] : + IsIso f ↔ n.len = m.len := by + refine ⟨fun _ ↦ le_antisymm (SimplexCategory.len_le_of_mono f) + (SimplexCategory.len_le_of_epi f), fun h ↦ ?_⟩ + obtain rfl : n = m := by aesop + have h := mono_iff_injective.1 (inferInstanceAs (Mono f)) + exact isIso_of_bijective ⟨h, by rwa [← Finite.injective_iff_surjective]⟩ +instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by + rw [mono_iff_injective] + exact Fin.succAbove_right_injective + +lemma isIso_iff_of_epi {n m : SimplexCategory} (f : n ⟶ m) [Epi f] : + IsIso f ↔ n.len = m.len := by + refine ⟨fun _ ↦ le_antisymm (SimplexCategory.len_le_of_mono f) + (SimplexCategory.len_le_of_epi f), fun h ↦ ?_⟩ + obtain rfl : n = m := by aesop + have h := epi_iff_surjective.1 (inferInstanceAs (Epi f)) + exact isIso_of_bijective ⟨by rwa [Finite.injective_iff_surjective], h⟩ + +instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by + rw [mono_iff_injective] + exact Fin.succAbove_right_injective + /-- An isomorphism in `SimplexCategory` induces an `OrderIso`. -/ @[simp] def orderIsoOfIso {x y : SimplexCategory} (e : x ≅ y) : Fin (x.len + 1) ≃o Fin (y.len + 1) := @@ -790,9 +813,11 @@ theorem eq_id_of_epi {x : SimplexCategory} (i : x ⟶ x) [Epi i] : i = 𝟙 _ := infer_instance theorem eq_σ_of_epi {n : ℕ} (θ : ⦋n + 1⦌ ⟶ ⦋n⦌) [Epi θ] : ∃ i : Fin (n + 1), θ = σ i := by - rcases eq_σ_comp_of_not_injective θ (by - by_contra h - simpa using le_of_mono (mono_iff_injective.mpr h)) with ⟨i, θ', h⟩ + obtain ⟨i, θ', h⟩ := eq_σ_comp_of_not_injective θ (by + rw [← mono_iff_injective] + intro + have := le_of_mono θ + omega) use i haveI : Epi (σ i ≫ θ') := by rw [← h] @@ -801,9 +826,11 @@ theorem eq_σ_of_epi {n : ℕ} (θ : ⦋n + 1⦌ ⟶ ⦋n⦌) [Epi θ] : ∃ i : rw [h, eq_id_of_epi θ', Category.comp_id] theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i : Fin (n + 2), θ = δ i := by - rcases eq_comp_δ_of_not_surjective θ (by - by_contra h - simpa using le_of_epi (epi_iff_surjective.mpr h)) with ⟨i, θ', h⟩ + obtain ⟨i, θ', h⟩ := eq_comp_δ_of_not_surjective θ (by + rw [← epi_iff_surjective] + intro + have := le_of_epi θ + omega) use i haveI : Mono (θ' ≫ δ i) := by rw [← h] @@ -811,9 +838,9 @@ theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i haveI := CategoryTheory.mono_of_mono θ' (δ i) rw [h, eq_id_of_mono θ', Category.id_comp] -theorem len_lt_of_mono {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) [hi : Mono i] (hi' : Δ ≠ Δ') : +theorem len_lt_of_mono {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) [Mono i] (hi' : Δ ≠ Δ') : Δ'.len < Δ.len := by - rcases lt_or_eq_of_le (len_le_of_mono hi) with (h | h) + rcases lt_or_eq_of_le (len_le_of_mono i) with (h | h) · exact h · exfalso exact hi' (by ext; exact h.symm) @@ -836,9 +863,7 @@ theorem image_eq {Δ Δ' Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ haveI := strongEpi_of_epi e let e := image.isoStrongEpiMono e i fac ext - exact - le_antisymm (len_le_of_epi (inferInstance : Epi e.hom)) - (len_le_of_mono (inferInstance : Mono e.hom)) + exact le_antisymm (len_le_of_epi e.hom) (len_le_of_mono e.hom) theorem image_ι_eq {Δ Δ'' : SimplexCategory} {φ : Δ ⟶ Δ''} {e : Δ ⟶ image φ} [Epi e] {i : image φ ⟶ Δ''} [Mono i] (fac : e ≫ i = φ) : image.ι φ = i := by @@ -877,4 +902,33 @@ instance : HasTerminal SimplexCategory := noncomputable def topIsoZero : ⊤_ SimplexCategory ≅ ⦋0⦌ := terminalIsoIsTerminal isTerminalZero +lemma δ_injective {n : ℕ} : Function.Injective (δ (n := n)) := by + intro i j hij + wlog h : i < j + · simp only [not_lt] at h + obtain h | rfl := h.lt_or_eq + · exact (this hij.symm h).symm + · rfl + obtain ⟨i, rfl⟩ := Fin.eq_castSucc_of_ne_last (Fin.ne_last_of_lt h) + have : i.castSucc.succAbove i = j.succAbove i := by + change δ _ _ = δ _ _ + rw [hij] + simp [Fin.succAbove_of_castSucc_lt _ _ h, Fin.ext_iff] at this + +lemma σ_injective {n : ℕ} : Function.Injective (σ (n := n)) := by + intro i j hij + wlog h : i < j + · simp only [not_lt] at h + obtain h | rfl := h.lt_or_eq + · exact (this hij.symm h).symm + · rfl + exfalso + have : i.predAbove i.succ = j.predAbove i.succ := by + change σ _ _ = σ _ _ + rw [hij] + rw [← Fin.castSucc_inj, Fin.predAbove_succ_self, + Fin.predAbove_of_le_castSucc j _ (by simpa), + Fin.castSucc_castPred] at this + exact (Fin.castSucc_lt_succ _).ne this + end SimplexCategory From 2628148b5dc2756c35141c980bd1de072c70bd0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 5 Aug 2025 15:13:49 +0530 Subject: [PATCH 09/81] fixing the build --- Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean | 8 ++++---- .../AlgebraicTopology/DoldKan/SplitSimplicialObject.lean | 2 +- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 5 +++++ .../SimplexCategory/MorphismProperty.lean | 3 ++- Mathlib/AlgebraicTopology/SimplicialObject/Split.lean | 8 ++++---- Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean | 8 ++++---- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean index 8ab29441e07ef4..422669a5e2d3e2 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean @@ -55,13 +55,13 @@ theorem PInfty_comp_map_mono_eq_zero (X : SimplicialObject C) {n : ℕ} {Δ' : S subst hk obtain ⟨j₁ : Fin (_ + 1), i, rfl⟩ := eq_comp_δ_of_not_surjective i fun h => by - have h' := len_le_of_epi (SimplexCategory.epi_iff_surjective.2 h) - dsimp at h' + rw [← SimplexCategory.epi_iff_surjective] at h + have := le_of_epi i omega obtain ⟨j₂, i, rfl⟩ := eq_comp_δ_of_not_surjective i fun h => by - have h' := len_le_of_epi (SimplexCategory.epi_iff_surjective.2 h) - dsimp at h' + rw [← SimplexCategory.epi_iff_surjective] at h + have := le_of_epi i omega by_cases hj₁ : j₁ = 0 · subst hj₁ diff --git a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean index 2e370266f2e199..cc30abae91cbaa 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/SplitSimplicialObject.lean @@ -74,7 +74,7 @@ theorem σ_comp_πSummand_id_eq_zero {n : ℕ} (i : Fin (n + 1)) : rw [ne_comm] change ¬(A.epiComp (SimplexCategory.σ i).op).EqId rw [IndexSet.eqId_iff_len_eq] - have h := SimplexCategory.len_le_of_epi (inferInstance : Epi A.e) + have h := SimplexCategory.len_le_of_epi A.e dsimp at h ⊢ omega diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 3f3087e06b24b5..6b12b9a454f540 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -698,6 +698,11 @@ lemma isIso_iff_of_epi {n m : SimplexCategory} (f : n ⟶ m) [Epi f] : have h := epi_iff_surjective.1 (inferInstanceAs (Epi f)) exact isIso_of_bijective ⟨by rwa [Finite.injective_iff_surjective], h⟩ +instance : Balanced SimplexCategory where + isIso_of_mono_of_epi f _ _ := by + rw [isIso_iff_of_epi] + exact le_antisymm (len_le_of_mono f) (len_le_of_epi f) + instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by rw [mono_iff_injective] exact Fin.succAbove_right_injective diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/MorphismProperty.lean b/Mathlib/AlgebraicTopology/SimplexCategory/MorphismProperty.lean index cfede67f942de5..98925676f6efea 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/MorphismProperty.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/MorphismProperty.lean @@ -62,7 +62,8 @@ lemma Truncated.morphismProperty_eq_top exact W.comp_mem _ _ (σ_mem _ (by omega) _) (hc _ _ _ _ _ (by omega)) rw [← epi_iff_surjective] at h₁ rw [← mono_iff_injective] at h₂ - obtain rfl : a = b := le_antisymm (len_le_of_mono h₂) (len_le_of_epi h₁) + have := isIso_of_mono_of_epi f' + obtain rfl : a = b := len_eq_of_isIso f' obtain rfl : f = 𝟙 _ := eq_id_of_mono f' apply W.id_mem diff --git a/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean b/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean index c6b5f3a0ae2e1b..77ba18a858d9dd 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject/Split.lean @@ -81,7 +81,7 @@ theorem ext (A₁ A₂ : IndexSet Δ) (h₁ : A₁.1 = A₂.1) (h₂ : A₁.e instance : Fintype (IndexSet Δ) := Fintype.ofInjective (fun A => - ⟨⟨A.1.unop.len, Nat.lt_succ_iff.mpr (len_le_of_epi (inferInstance : Epi A.e))⟩, + ⟨⟨A.1.unop.len, Nat.lt_succ_iff.mpr (len_le_of_epi A.e)⟩, A.e.toOrderHom⟩ : IndexSet Δ → Sigma fun k : Fin (Δ.unop.len + 1) => Fin (Δ.unop.len + 1) → Fin (k + 1)) (by @@ -145,7 +145,7 @@ theorem eqId_iff_len_le : A.EqId ↔ Δ.unop.len ≤ A.1.unop.len := by constructor · intro h rw [h] - · exact le_antisymm (len_le_of_epi (inferInstance : Epi A.e)) + · exact le_antisymm (len_le_of_epi A.e) theorem eqId_iff_mono : A.EqId ↔ Mono A.e := by constructor @@ -154,9 +154,9 @@ theorem eqId_iff_mono : A.EqId ↔ Mono A.e := by subst h dsimp only [id, e] infer_instance - · intro h + · intro rw [eqId_iff_len_le] - exact len_le_of_mono h + exact len_le_of_mono A.e /-- Given `A : IndexSet Δ₁`, if `p.unop : unop Δ₂ ⟶ unop Δ₁` is an epi, this is the obvious element in `A : IndexSet Δ₂` associated to the composition diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index bcd2575ce3a19f..d9a33c66ad73c0 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -73,7 +73,7 @@ lemma mem_degenerate_iff (x : X _⦋n⦌) : constructor · rintro ⟨m, hm, f, y, hy⟩ rw [← image.fac f, op_comp] at hy - have : _ ≤ m := SimplexCategory.len_le_of_mono (f := image.ι f) inferInstance + have : _ ≤ m := SimplexCategory.len_le_of_mono (image.ι f) exact ⟨(image f).len, by omega, factorThruImage f, inferInstance, by aesop⟩ · rintro ⟨m, hm, f, hf, hx⟩ exact ⟨m, hm, f, hx⟩ @@ -86,8 +86,8 @@ lemma degenerate_eq_iUnion_range_σ : rw [mem_degenerate_iff] at hx obtain ⟨m, hm, f, hf, y, rfl⟩ := hx obtain ⟨i, θ, rfl⟩ := SimplexCategory.eq_σ_comp_of_not_injective f (fun hf ↦ by - have := SimplexCategory.le_of_mono (f := f) (by - rwa [SimplexCategory.mono_iff_injective]) + rw [← SimplexCategory.mono_iff_injective] at hf + have := SimplexCategory.le_of_mono f omega) aesop · intro hx @@ -121,7 +121,7 @@ lemma isIso_of_nonDegenerate (x : X.nonDegenerate n) refine hx ⟨_ ,?_, f, y, hy⟩ by_contra! obtain rfl : m = n := - le_antisymm (SimplexCategory.len_le_of_epi (f := f) inferInstance) this + le_antisymm (SimplexCategory.len_le_of_epi f) this obtain rfl := SimplexCategory.eq_id_of_epi f exact this inferInstance From 61ab0ddf2c8903fb25f447dc3e677f444224f9ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 5 Aug 2025 15:23:15 +0530 Subject: [PATCH 10/81] cleaning up --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 6b12b9a454f540..be029dc3f3bc5d 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -681,8 +681,7 @@ theorem isIso_of_bijective {x y : SimplexCategory} {f : x ⟶ y} lemma isIso_iff_of_mono {n m : SimplexCategory} (f : n ⟶ m) [Mono f] : IsIso f ↔ n.len = m.len := by - refine ⟨fun _ ↦ le_antisymm (SimplexCategory.len_le_of_mono f) - (SimplexCategory.len_le_of_epi f), fun h ↦ ?_⟩ + refine ⟨fun _ ↦ len_eq_of_isIso f, fun h ↦ ?_⟩ obtain rfl : n = m := by aesop have h := mono_iff_injective.1 (inferInstanceAs (Mono f)) exact isIso_of_bijective ⟨h, by rwa [← Finite.injective_iff_surjective]⟩ @@ -692,8 +691,7 @@ instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by lemma isIso_iff_of_epi {n m : SimplexCategory} (f : n ⟶ m) [Epi f] : IsIso f ↔ n.len = m.len := by - refine ⟨fun _ ↦ le_antisymm (SimplexCategory.len_le_of_mono f) - (SimplexCategory.len_le_of_epi f), fun h ↦ ?_⟩ + refine ⟨fun _ ↦ len_eq_of_isIso f, fun h ↦ ?_⟩ obtain rfl : n = m := by aesop have h := epi_iff_surjective.1 (inferInstanceAs (Epi f)) exact isIso_of_bijective ⟨by rwa [Finite.injective_iff_surjective], h⟩ From 3e04e02d9213f889d9864580388a7100265866b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 5 Aug 2025 15:32:38 +0530 Subject: [PATCH 11/81] cleaning up --- Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index d9a33c66ad73c0..3d18a8a69ca526 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -118,11 +118,8 @@ lemma isIso_of_nonDegenerate (x : X.nonDegenerate n) induction' m using SimplexCategory.rec with m rw [mem_nonDegenerate_iff_notMem_degenerate] at hx by_contra! - refine hx ⟨_ ,?_, f, y, hy⟩ - by_contra! - obtain rfl : m = n := - le_antisymm (SimplexCategory.len_le_of_epi f) this - obtain rfl := SimplexCategory.eq_id_of_epi f - exact this inferInstance + refine hx ⟨_, not_le.1 (fun h ↦ this ?_), f, y, hy⟩ + rw [SimplexCategory.isIso_iff_of_epi] + exact le_antisymm h (SimplexCategory.len_le_of_epi f) end SSet From cb64b877ea3317d9b558189d3ad5146c1e37cdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 5 Aug 2025 16:00:41 +0530 Subject: [PATCH 12/81] cleaning up --- .../SimplexCategory/Basic.lean | 61 +++++-------------- Mathlib/Data/Fin/Basic.lean | 8 +++ Mathlib/Order/Fin/Basic.lean | 18 ++++++ 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index be029dc3f3bc5d..260facedfeae9d 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -633,22 +633,7 @@ lemma eq_of_isIso {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [IsIso f] : n = m := len_eq_of_isIso f instance {n : ℕ} {i : Fin (n + 1)} : Epi (σ i) := by - rw [epi_iff_surjective] - intro b - simp only [σ, mkHom, Hom.toOrderHom_mk] - by_cases h : b ≤ i - · use b.castSucc - -- This was not needed before https://github.com/leanprover/lean4/pull/2644 - dsimp - rw [Fin.predAbove_of_le_castSucc i b.castSucc (by simpa only [Fin.coe_eq_castSucc] using h)] - simp only [len_mk, Fin.castPred_castSucc] - · use b.succ - -- This was not needed before https://github.com/leanprover/lean4/pull/2644 - dsimp - rw [Fin.predAbove_of_castSucc_lt i b.succ _, Fin.pred_succ] - rw [not_le] at h - rw [Fin.lt_iff_val_lt_val] at h ⊢ - simpa only [Fin.val_succ, Fin.coe_castSucc] using Nat.lt.step h + simpa only [epi_iff_surjective] using Fin.predAbove_surjective i instance : (forget SimplexCategory).ReflectsIsomorphisms := ⟨fun f hf => @@ -679,22 +664,23 @@ theorem isIso_of_bijective {x y : SimplexCategory} {f : x ⟶ y} haveI : IsIso ((forget SimplexCategory).map f) := (isIso_iff_bijective _).mpr hf isIso_of_reflects_iso f (forget SimplexCategory) -lemma isIso_iff_of_mono {n m : SimplexCategory} (f : n ⟶ m) [Mono f] : +lemma isIso_iff_of_mono {n m : SimplexCategory} (f : n ⟶ m) [hf : Mono f] : IsIso f ↔ n.len = m.len := by refine ⟨fun _ ↦ len_eq_of_isIso f, fun h ↦ ?_⟩ obtain rfl : n = m := by aesop - have h := mono_iff_injective.1 (inferInstanceAs (Mono f)) - exact isIso_of_bijective ⟨h, by rwa [← Finite.injective_iff_surjective]⟩ + rw [mono_iff_injective] at hf + exact isIso_of_bijective ⟨hf, by rwa [← Finite.injective_iff_surjective]⟩ + instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by rw [mono_iff_injective] exact Fin.succAbove_right_injective -lemma isIso_iff_of_epi {n m : SimplexCategory} (f : n ⟶ m) [Epi f] : +lemma isIso_iff_of_epi {n m : SimplexCategory} (f : n ⟶ m) [hf : Epi f] : IsIso f ↔ n.len = m.len := by refine ⟨fun _ ↦ len_eq_of_isIso f, fun h ↦ ?_⟩ obtain rfl : n = m := by aesop - have h := epi_iff_surjective.1 (inferInstanceAs (Epi f)) - exact isIso_of_bijective ⟨by rwa [Finite.injective_iff_surjective], h⟩ + rw [epi_iff_surjective] at hf + exact isIso_of_bijective ⟨by rwa [Finite.injective_iff_surjective], hf⟩ instance : Balanced SimplexCategory where isIso_of_mono_of_epi f _ _ := by @@ -907,31 +893,16 @@ noncomputable def topIsoZero : ⊤_ SimplexCategory ≅ ⦋0⦌ := lemma δ_injective {n : ℕ} : Function.Injective (δ (n := n)) := by intro i j hij - wlog h : i < j - · simp only [not_lt] at h - obtain h | rfl := h.lt_or_eq - · exact (this hij.symm h).symm - · rfl - obtain ⟨i, rfl⟩ := Fin.eq_castSucc_of_ne_last (Fin.ne_last_of_lt h) - have : i.castSucc.succAbove i = j.succAbove i := by - change δ _ _ = δ _ _ - rw [hij] - simp [Fin.succAbove_of_castSucc_lt _ _ h, Fin.ext_iff] at this + rw [← Fin.succAbove_left_inj] + ext k : 1 + change δ _ _ = δ _ _ + rw [hij] lemma σ_injective {n : ℕ} : Function.Injective (σ (n := n)) := by intro i j hij - wlog h : i < j - · simp only [not_lt] at h - obtain h | rfl := h.lt_or_eq - · exact (this hij.symm h).symm - · rfl - exfalso - have : i.predAbove i.succ = j.predAbove i.succ := by - change σ _ _ = σ _ _ - rw [hij] - rw [← Fin.castSucc_inj, Fin.predAbove_succ_self, - Fin.predAbove_of_le_castSucc j _ (by simpa), - Fin.castSucc_castPred] at this - exact (Fin.castSucc_lt_succ _).ne this + rw [← Fin.predAbove_left_inj] + ext k : 1 + change σ _ _ = σ _ _ + rw [hij] end SimplexCategory diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index 881aa40ac9b919..134a48db6143b6 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -1206,6 +1206,14 @@ lemma predAbove_last_apply {i : Fin (n + 2)} : · rw [hi, predAbove_right_last] · rw [predAbove_last_of_ne_last hi] +lemma predAbove_surjective {n : ℕ} (p : Fin n) : + Function.Surjective p.predAbove := by + intro i + by_cases hi : i ≤ p + · exact ⟨i.castSucc, predAbove_castSucc_of_le p i hi⟩ + · rw [Fin.not_le] at hi + exact ⟨i.succ, predAbove_succ_of_le p i (Fin.le_of_lt hi)⟩ + /-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p` then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/ @[simp] diff --git a/Mathlib/Order/Fin/Basic.lean b/Mathlib/Order/Fin/Basic.lean index 3b44aaf2052eae..0fdc703691e01d 100644 --- a/Mathlib/Order/Fin/Basic.lean +++ b/Mathlib/Order/Fin/Basic.lean @@ -284,6 +284,24 @@ lemma predAbove_le_predAbove {p q : Fin n} (hpq : p ≤ q) {i j : Fin (n + 1)} ( @[simps!] def predAboveOrderHom (p : Fin n) : Fin (n + 1) →o Fin n := ⟨p.predAbove, p.predAbove_right_monotone⟩ +/-- `predAbove` is injective at the pivot -/ +lemma predAbove_left_injective : Injective (@predAbove n) := by + intro i j hij + obtain ⟨n, rfl⟩ := Nat.exists_add_one_eq.2 i.size_positive + wlog h : i < j generalizing i j + · simp only [not_lt] at h + obtain h | rfl := h.lt_or_eq + · exact (this hij.symm h).symm + · rfl + replace hij := congr_fun hij i.succ + rw [predAbove_succ_self, Fin.predAbove_of_le_castSucc _ _ (by simpa), + ← Fin.castSucc_inj, castSucc_castPred] at hij + exact (i.castSucc_lt_succ.ne hij).elim + +/-- `predAbove` is injective at the pivot -/ +@[simp] lemma predAbove_left_inj {x y : Fin n} : x.predAbove = y.predAbove ↔ x = y := + predAbove_left_injective.eq_iff + /-! #### Order isomorphisms -/ /-- The equivalence `Fin n ≃ {i // i < n}` is an order isomorphism. -/ From 981ba52deaa62b377174c4ad813063ac44f75509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 6 Aug 2025 17:33:02 +0530 Subject: [PATCH 13/81] feat(AlgebraicTopology): the type of simplices of a simplicial set --- Mathlib.lean | 1 + .../SimplicialSet/Simplices.lean | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9d40c7e99012db..40280fd48f57a0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1305,6 +1305,7 @@ import Mathlib.AlgebraicTopology.SimplicialSet.Monoidal import Mathlib.AlgebraicTopology.SimplicialSet.Nerve import Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction import Mathlib.AlgebraicTopology.SimplicialSet.Path +import Mathlib.AlgebraicTopology.SimplicialSet.Simplices import Mathlib.AlgebraicTopology.SimplicialSet.StdSimplex import Mathlib.AlgebraicTopology.SimplicialSet.StrictSegal import Mathlib.AlgebraicTopology.SimplicialSet.Subcomplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean new file mode 100644 index 00000000000000..5e6a5cf7040833 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -0,0 +1,132 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.CategoryTheory.Elements +import Mathlib.AlgebraicTopology.SimplicialSet.StdSimplex + +/-! +# The type of simplices of a simplicial set + +In this file, we define the type `X.S` of simplices of a simplicial set `X`, +where a simplex consists of the data of `dim : ℕ` and `simplex : X _⦋dim⦌`. +We endow this type with a preorder defined by +`x ≤ y ↔ Subcomplex.ofSimplex x.simplex ≤ Subcomplex.ofSimplex y.simplex`. + +## TODO (@joelriou) + +* Extend the `S` structure to define the type of nondegenerate +simplices of a simplicial set `X`, and also the type of nondegenerate +simplices of a simplicial set `X` which do not belong to a given subcomplex. + +-/ + +universe u + +open CategoryTheory Simplicial + +namespace SSet + +variable (X : SSet.{u}) + +/-- The type of simplices of a simpliciat set `X`. -/ +structure S where + /-- the dimension of the simplex -/ + {dim : ℕ} + /-- the simplex -/ + simplex : X _⦋dim⦌ + +variable {X} + +namespace S + +lemma mk_surjective {s : X.S} : + ∃ (n : ℕ) (x : X _⦋n⦌), s = mk x := + ⟨s.1, s.2, rfl⟩ + +/-- The image of a simplex by a morphism of simplicial sets. -/ +def map {Y : SSet.{u}} (f : X ⟶ Y) (s : X.S) : Y.S := + S.mk (f.app _ s.2) + +lemma dim_eq_of_eq {s t : X.S} (h : s = t) : + s.dim = t.dim := + congr_arg dim h + +lemma dim_eq_of_mk_eq {n m : ℕ} {x : X _⦋n⦌} {y : X _⦋m⦌} + (h : S.mk x = S.mk y) : n = m := + dim_eq_of_eq h + +section + +variable (s : X.S) {d : ℕ} (hd : s.dim = d) + +/-- When `s : X.S` is such that `s.dim = d`, this is a term +that is equal to `s`, but whose dimension if definitionally equal to `d`. -/ +@[simps dim] +def cast : X.S where + dim := d + simplex := _root_.cast (by simp only [hd]) s.simplex + +lemma cast_eq_self : s.cast hd = s := by + obtain ⟨d, _, rfl⟩ := s.mk_surjective + obtain rfl := hd + rfl + +@[simp] +lemma cast_simplex_rfl : (s.cast rfl).simplex = s.simplex := rfl + +end + +lemma ext_iff' (s t : X.S) : + s = t ↔ ∃ (h : s.dim = t.dim), (s.cast h).2 = t.2 := + ⟨by rintro rfl; exact ⟨rfl, rfl⟩, fun ⟨h₁, h₂⟩ ↦ by + obtain ⟨_, _, rfl⟩ := s.mk_surjective + obtain ⟨_, _, rfl⟩ := t.mk_surjective + aesop⟩ + +lemma ext_iff {n : ℕ} (x y : X _⦋n⦌) : + S.mk x = S.mk y ↔ x = y := by + simp + +instance : Preorder X.S where + le x y := Subcomplex.ofSimplex x.2 ≤ Subcomplex.ofSimplex y.2 + le_refl _ := le_refl (α := Subcomplex X) _ + le_trans _ _ _ := le_trans (α := Subcomplex X) + +lemma le_iff {x y : X.S} : x ≤ y ↔ Subcomplex.ofSimplex x.2 ≤ Subcomplex.ofSimplex y.2 := + Iff.rfl + +lemma mk_map_le {n m : ℕ} (x : X _⦋n⦌) (f : ⦋m⦌ ⟶ ⦋n⦌) : + S.mk (X.map f.op x) ≤ S.mk x := by + rw [le_iff, Subcomplex.ofSimplex_le_iff] + exact ⟨f.op, rfl⟩ + +lemma mk_map_eq_iff_of_mono {n m : ℕ} (x : X _⦋n⦌) + (f : ⦋m⦌ ⟶ ⦋n⦌) [Mono f] : + S.mk (X.map f.op x) = S.mk x ↔ IsIso f := by + constructor + · intro h + obtain rfl := S.dim_eq_of_mk_eq h + obtain rfl := SimplexCategory.eq_id_of_mono f + infer_instance + · intro hf + obtain rfl := SimplexCategory.eq_of_isIso f + obtain rfl := SimplexCategory.eq_id_of_isIso f + simp + +/-- The type of simplices of `X : SSet.{u}` identifies to the type +of elements of `X` considered as a functor `SimplexCategoryᵒᵖ ⥤ Type u`. -/ +@[simps!] +def equivElements : X.S ≃ X.Elements where + toFun s := X.elementsMk _ s.2 + invFun := by + rintro ⟨⟨n⟩, x⟩ + induction n using SimplexCategory.rec + exact S.mk x + left_inv _ := rfl + right_inv _ := rfl + +end S + +end SSet From cae23d3ae9022633ed4368229e39bfd561d84047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:41:14 +0530 Subject: [PATCH 14/81] Update Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean Co-authored-by: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 260facedfeae9d..8906d59eec5e10 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -804,9 +804,7 @@ theorem eq_id_of_epi {x : SimplexCategory} (i : x ⟶ x) [Epi i] : i = 𝟙 _ := theorem eq_σ_of_epi {n : ℕ} (θ : ⦋n + 1⦌ ⟶ ⦋n⦌) [Epi θ] : ∃ i : Fin (n + 1), θ = σ i := by obtain ⟨i, θ', h⟩ := eq_σ_comp_of_not_injective θ (by rw [← mono_iff_injective] - intro - have := le_of_mono θ - omega) + grind [→ le_of_mono]) use i haveI : Epi (σ i ≫ θ') := by rw [← h] From 37f755cc5226dffed7fcd561d0f16f0230c72347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:41:22 +0530 Subject: [PATCH 15/81] Update Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean Co-authored-by: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 8906d59eec5e10..0c5f22400b22e6 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -815,9 +815,7 @@ theorem eq_σ_of_epi {n : ℕ} (θ : ⦋n + 1⦌ ⟶ ⦋n⦌) [Epi θ] : ∃ i : theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i : Fin (n + 2), θ = δ i := by obtain ⟨i, θ', h⟩ := eq_comp_δ_of_not_surjective θ (by rw [← epi_iff_surjective] - intro - have := le_of_epi θ - omega) + grind [→ le_of_epi]) use i haveI : Mono (θ' ≫ δ i) := by rw [← h] From 8747fa676542657c6bd7af07804828a3abb8d098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:41:38 +0530 Subject: [PATCH 16/81] Update Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean Co-authored-by: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 0c5f22400b22e6..58250c631e97bc 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -891,8 +891,7 @@ lemma δ_injective {n : ℕ} : Function.Injective (δ (n := n)) := by intro i j hij rw [← Fin.succAbove_left_inj] ext k : 1 - change δ _ _ = δ _ _ - rw [hij] + exact congr($hij k) lemma σ_injective {n : ℕ} : Function.Injective (σ (n := n)) := by intro i j hij From 32c58b0a4c95b7d457d969a29b6c3e493bcc4b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:41:47 +0530 Subject: [PATCH 17/81] Update Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean Co-authored-by: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 58250c631e97bc..7bb1427517287a 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -897,7 +897,6 @@ lemma σ_injective {n : ℕ} : Function.Injective (σ (n := n)) := by intro i j hij rw [← Fin.predAbove_left_inj] ext k : 1 - change σ _ _ = σ _ _ - rw [hij] + exact congr($hij k) end SimplexCategory From 0bc7517dff62660501b9e4bf51236c369c3a0084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 7 Aug 2025 00:44:36 +0530 Subject: [PATCH 18/81] removed duplicate instance --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 7bb1427517287a..8753da0a1eed35 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -687,10 +687,6 @@ instance : Balanced SimplexCategory where rw [isIso_iff_of_epi] exact le_antisymm (len_le_of_mono f) (len_le_of_epi f) -instance {n : ℕ} {i : Fin (n + 2)} : Mono (δ i) := by - rw [mono_iff_injective] - exact Fin.succAbove_right_injective - /-- An isomorphism in `SimplexCategory` induces an `OrderIso`. -/ @[simp] def orderIsoOfIso {x y : SimplexCategory} (e : x ≅ y) : Fin (x.len + 1) ≃o Fin (y.len + 1) := From 2f2662be6e60d86283cb7b97dfdec8635689ccbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:45:09 +0530 Subject: [PATCH 19/81] Update Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean Co-authored-by: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> --- Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean index 422669a5e2d3e2..61277dfd36a535 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean @@ -56,8 +56,7 @@ theorem PInfty_comp_map_mono_eq_zero (X : SimplicialObject C) {n : ℕ} {Δ' : S obtain ⟨j₁ : Fin (_ + 1), i, rfl⟩ := eq_comp_δ_of_not_surjective i fun h => by rw [← SimplexCategory.epi_iff_surjective] at h - have := le_of_epi i - omega + grind [→ le_of_epi] obtain ⟨j₂, i, rfl⟩ := eq_comp_δ_of_not_surjective i fun h => by rw [← SimplexCategory.epi_iff_surjective] at h From 3b3064c19966a649060f2edbd975cf4aec23892d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:45:17 +0530 Subject: [PATCH 20/81] Update Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean Co-authored-by: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> --- Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean index 61277dfd36a535..84ff256342d179 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean @@ -60,8 +60,7 @@ theorem PInfty_comp_map_mono_eq_zero (X : SimplicialObject C) {n : ℕ} {Δ' : S obtain ⟨j₂, i, rfl⟩ := eq_comp_δ_of_not_surjective i fun h => by rw [← SimplexCategory.epi_iff_surjective] at h - have := le_of_epi i - omega + grind [→ le_of_epi] by_cases hj₁ : j₁ = 0 · subst hj₁ rw [assoc, ← SimplexCategory.δ_comp_δ'' (Fin.zero_le _)] From 6c5ef9caa07c2b35c982ba57ddef769ba9411a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 7 Aug 2025 00:49:12 +0530 Subject: [PATCH 21/81] suggestion by robin-carlier --- Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 8753da0a1eed35..756cf6ec57cde9 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -821,10 +821,7 @@ theorem eq_δ_of_mono {n : ℕ} (θ : ⦋n⦌ ⟶ ⦋n + 1⦌) [Mono θ] : ∃ i theorem len_lt_of_mono {Δ' Δ : SimplexCategory} (i : Δ' ⟶ Δ) [Mono i] (hi' : Δ ≠ Δ') : Δ'.len < Δ.len := by - rcases lt_or_eq_of_le (len_le_of_mono i) with (h | h) - · exact h - · exfalso - exact hi' (by ext; exact h.symm) + grind [→ len_le_of_mono, SimplexCategory.ext] noncomputable instance : SplitEpiCategory SimplexCategory := skeletalEquivalence.inverse.splitEpiCategoryImpOfIsEquivalence From 6a0d3c0c3629aae253f0f20cf2df5a16224a418f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 7 Aug 2025 12:11:18 +0530 Subject: [PATCH 22/81] added comments about X.S not being the category of simplices --- .../SimplicialSet/Simplices.lean | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index 5e6a5cf7040833..9aecf10ddfb7cf 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -13,6 +13,9 @@ In this file, we define the type `X.S` of simplices of a simplicial set `X`, where a simplex consists of the data of `dim : ℕ` and `simplex : X _⦋dim⦌`. We endow this type with a preorder defined by `x ≤ y ↔ Subcomplex.ofSimplex x.simplex ≤ Subcomplex.ofSimplex y.simplex`. +In particular, as a preordered type, `X.S` is a category, but this is +not what is called "the category of simplices of `X`" in the literature +(and which is `X.Elementsᵒᵖ` in mathlib). ## TODO (@joelriou) @@ -30,7 +33,10 @@ namespace SSet variable (X : SSet.{u}) -/-- The type of simplices of a simpliciat set `X`. -/ +/-- The type of simplices of a simpliciat set `X`. This type `X.S` is in bijection +with `X.Elements` (see `SSet.equivElements`), but `X.S` is not what the literature +names "category of simplices of `X`", as the category on `X.S` comes from +a preorder (see `S.le_iff_nonempty_hom`). -/ structure S where /-- the dimension of the simplex -/ {dim : ℕ} @@ -116,7 +122,9 @@ lemma mk_map_eq_iff_of_mono {n m : ℕ} (x : X _⦋n⦌) simp /-- The type of simplices of `X : SSet.{u}` identifies to the type -of elements of `X` considered as a functor `SimplexCategoryᵒᵖ ⥤ Type u`. -/ +of elements of `X` considered as a functor `SimplexCategoryᵒᵖ ⥤ Type u`. +(Note that this is not an (anti)equivalence of categories, +see `S.le_iff_nonempty_hom`.) -/ @[simps!] def equivElements : X.S ≃ X.Elements where toFun s := X.elementsMk _ s.2 @@ -127,6 +135,15 @@ def equivElements : X.S ≃ X.Elements where left_inv _ := rfl right_inv _ := rfl +lemma le_iff_nonempty_hom (x y : X.S) : + x ≤ y ↔ Nonempty (equivElements y ⟶ equivElements x) := by + rw [le_iff, Subcomplex.ofSimplex_le_iff, Subpresheaf.ofSection_obj, Set.mem_setOf_eq] + constructor + · rintro ⟨f, hf⟩ + exact ⟨⟨f, hf⟩⟩ + · rintro ⟨f, hf⟩ + exact ⟨f, hf⟩ + end S end SSet From 8587fec07b91f6e3ec55414304975d68d633b512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 7 Aug 2025 12:14:42 +0530 Subject: [PATCH 23/81] better title --- Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index 9aecf10ddfb7cf..de2ba0330faee6 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -7,7 +7,7 @@ import Mathlib.CategoryTheory.Elements import Mathlib.AlgebraicTopology.SimplicialSet.StdSimplex /-! -# The type of simplices of a simplicial set +# The preordered type of simplices of a simplicial set In this file, we define the type `X.S` of simplices of a simplicial set `X`, where a simplex consists of the data of `dim : ℕ` and `simplex : X _⦋dim⦌`. From a1334aeb7bd41c5c68bf24250491eb7cd0a23502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 11 Aug 2025 11:41:56 +0530 Subject: [PATCH 24/81] fix --- Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index 628585ecd85527..f1899120bb7bf1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -171,7 +171,7 @@ private lemma le : m₁ ≤ m₂ := by end -variable {X} in +variable {X} in private lemma g_eq_id {x : X _⦋n⦌} {m : ℕ} {f₁ : ⦋n⦌ ⟶ ⦋m⦌} {y₁ : X.nonDegenerate m} (hy₁ : x = X.map f₁.op y₁) {f₂ : ⦋n⦌ ⟶ ⦋m⦌} {y₂ : X _⦋m⦌} (hy₂ : x = X.map f₂.op y₂) (hf₁ : SplitEpi f₁) : From 4c844524bf0add548acb0f97aa400c68a0178e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 11 Aug 2025 14:14:07 +0530 Subject: [PATCH 25/81] wip --- Mathlib.lean | 1 + .../SimplicialSet/Degenerate.lean | 12 +- .../SimplicialSet/NonDegenerateSimplices.lean | 168 ++++++++++++++++++ .../SimplicialSet/Simplices.lean | 11 +- .../SimplicialSet/StdSimplex.lean | 5 + Mathlib/CategoryTheory/EpiMono.lean | 22 +++ 6 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3109604635f70b..7487ca4a5cd24f 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1314,6 +1314,7 @@ import Mathlib.AlgebraicTopology.SimplicialSet.KanComplex import Mathlib.AlgebraicTopology.SimplicialSet.Monoidal import Mathlib.AlgebraicTopology.SimplicialSet.Nerve import Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction +import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplices import Mathlib.AlgebraicTopology.SimplicialSet.Path import Mathlib.AlgebraicTopology.SimplicialSet.Simplices import Mathlib.AlgebraicTopology.SimplicialSet.StdSimplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean index a25a4c8dbbe407..2195810c6883ed 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Degenerate.lean @@ -121,6 +121,15 @@ lemma isIso_of_nonDegenerate (x : X.nonDegenerate n) rw [SimplexCategory.isIso_iff_of_epi] exact le_antisymm h (SimplexCategory.len_le_of_epi f) +lemma mono_of_nonDegenerate (x : X.nonDegenerate n) + {m : SimplexCategory} (f : ⦋n⦌ ⟶ m) + (y : X.obj (op m)) (hy : X.map f.op y = x) : + Mono f := by + have := X.isIso_of_nonDegenerate x (factorThruImage f) (y := X.map (image.ι f).op y) (by + rw [← FunctorToTypes.map_comp_apply, ← op_comp, image.fac f, hy]) + rw [← image.fac f] + infer_instance + namespace unique_nonDegenerate /-! @@ -163,8 +172,7 @@ private lemma mono_g : Mono (g hf₁ f₂) := by private lemma le : m₁ ≤ m₂ := by have := isIso_factorThruImage_g hf₁ hy₁ hy₂ - exact SimplexCategory.len_le_of_mono - (f := factorThruImage (g hf₁ f₂) ≫ image.ι _) inferInstance + exact SimplexCategory.len_le_of_mono (factorThruImage (g hf₁ f₂) ≫ image.ι _) end diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean new file mode 100644 index 00000000000000..fa7804147ea48b --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -0,0 +1,168 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.Degenerate +import Mathlib.AlgebraicTopology.SimplicialSet.Simplices + +/-! +# The partially ordered type of non degenerate simplices of a simplicial set + +In this file, we introduce the partially ordered type `X.N` of +non degenerate simplices of a simplicial set `X`. We obtain +an embedding `X.orderEmbeddingN : X.N ↪o X.Subcomplex` which sends +a non degenerate simplex to the subcomplex of `X` it generates. + +Given an arbitrary simplex `x : X.S`, we show that there is a unique +non degenerate `x.toN : X.N` such that `x.toN.subcomplex = x.subcomplex`. + +-/ + +universe u + +open CategoryTheory Simplicial + +namespace SSet + +variable (X : SSet.{u}) + +/-- The type of non degenerate simplices of a simplicial set. -/ +structure N extends X.S where mk'' :: + nonDegenerate : simplex ∈ X.nonDegenerate _ + +namespace N + +variable {X} + +/-- Constructor in order to promote a simplex `s : X.S` into +a term in `X.N`. -/ +@[simps toS] +def mk' (s : X.S) (hs : s.2 ∈ X.nonDegenerate _) : X.N where + toS := s + nonDegenerate := hs + +lemma mk'_surjective (s : X.N) : + ∃ (t : X.S) (ht : t.2 ∈ X.nonDegenerate _), s = mk' t ht := + ⟨s.toS, s.nonDegenerate, rfl⟩ + +/-- Constructor for the type of non degenerate simplices of a simplicial set. -/ +@[simps] +def mk {n : ℕ} (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) : X.N where + simplex := x + nonDegenerate := hx + +lemma mk_surjective (x : X.N) : + ∃ (n : ℕ) (y : X.nonDegenerate n), x = N.mk _ y.2 := + ⟨x.1.1, ⟨_, x.nonDegenerate⟩, rfl⟩ + +instance : Preorder X.N := Preorder.lift toS + +lemma le_iff {x y : X.N} : x ≤ y ↔ x.subcomplex ≤ y.subcomplex := + Iff.rfl + +lemma le_iff_exists_mono {x y : X.N} : + x ≤ y ↔ ∃ (f : ⦋x.1.1⦌ ⟶ ⦋y.1.1⦌) (_ : Mono f), X.map f.op y.1.2 = x.1.2 := by + simp only [le_iff, CategoryTheory.Subpresheaf.ofSection_le_iff, + Subcomplex.mem_ofSimplex_obj_iff] + exact ⟨fun ⟨f, hf⟩ ↦ ⟨f, X.mono_of_nonDegenerate ⟨_, x.2⟩ f _ hf, hf⟩, by tauto⟩ + +lemma le_of_le {x y : X.N} (h : x ≤ y) : x.1.1 ≤ y.1.1 := by + rw [le_iff_exists_mono] at h + obtain ⟨f, hf, _⟩ := h + exact SimplexCategory.len_le_of_mono f + +instance : PartialOrder X.N where + le_antisymm x₁ x₂ h h' := by + obtain ⟨n₁, ⟨x₁, hx₁⟩, rfl⟩ := x₁.mk_surjective + obtain ⟨n₂, ⟨x₂, hx₂⟩, rfl⟩ := x₂.mk_surjective + obtain rfl : n₁ = n₂ := le_antisymm (le_of_le h) (le_of_le h') + rw [le_iff_exists_mono] at h + obtain ⟨f, hf, h⟩ := h + obtain rfl := SimplexCategory.eq_id_of_mono f + aesop + +lemma subcomplex_injective {x y : X.N} (h : x.subcomplex = y.subcomplex) : + x = y := by + apply le_antisymm + all_goals + · rw [le_iff, h] + +lemma subcomplex_injective_iff {x y : X.N} : + x.subcomplex = y.subcomplex ↔ x = y := + ⟨subcomplex_injective, by rintro rfl; rfl⟩ + +lemma eq_iff {x y : X.N} : + x = y ↔ x.subcomplex = y.subcomplex := + ⟨by rintro rfl; rfl, fun h ↦ by + apply le_antisymm + all_goals + · rw [le_iff, h]⟩ + +section + +variable (s : X.N) {d : ℕ} (hd : s.dim = d) + +/-- When `s : X.N` is such that `s.dim = d`, this is a term +that is equal to `s`, but whose dimension if definitionally equal to `d`. -/ +abbrev cast : X.N where + toS := s.toS.cast hd + nonDegenerate := by + subst hd + exact s.nonDegenerate + +lemma cast_eq_self : s.cast hd = s := by + subst hd + rfl + +end + +end N + +/-- The map which sends a non degenerate simplex of a simplicial set to +the subcomplex it generates is an order embedding. -/ +@[simps] +def orderEmbeddingN : X.N ↪o X.Subcomplex where + toFun x := x.subcomplex + inj' _ _ h := by + dsimp at h + apply le_antisymm <;> rw [N.le_iff, h] + map_rel_iff' := Iff.rfl + +namespace S + +variable {X} + +lemma existsUnique_n (x : X.S) : ∃! (y : X.N), y.subcomplex = x.subcomplex := + existsUnique_of_exists_of_unique (by + obtain ⟨n, x, hx, rfl⟩ := x.mk_surjective + obtain ⟨m, f, _, y, rfl⟩ := X.exists_nonDegenerate x + refine ⟨N.mk y.1 y.2, le_antisymm ?_ ?_⟩ + · simp only [Subcomplex.ofSimplex_le_iff] + have := isSplitEpi_of_epi f + have : Function.Injective (X.map f.op) := by + rw [← mono_iff_injective] + infer_instance + refine ⟨(section_ f).op, this ?_⟩ + dsimp + rw [← FunctorToTypes.map_comp_apply, ← FunctorToTypes.map_comp_apply, + ← op_comp, ← op_comp, Category.assoc, IsSplitEpi.id, Category.comp_id] + · simp only [Subcomplex.ofSimplex_le_iff] + exact ⟨f.op, rfl⟩) + (fun y₁ y₂ h₁ h₂ ↦ N.subcomplex_injective (by rw [h₁, h₂])) + +/-- This is the non degenerate simplex of a simplicial set which +generates the same subcomplex as a given simplex. -/ +noncomputable def toN (x : X.S) : X.N := x.existsUnique_n.exists.choose + +@[simp] +lemma subcomplex_toN (x : X.S) : x.toN.subcomplex = x.subcomplex := + x.existsUnique_n.exists.choose_spec + +lemma toN_eq_iff {x : X.S} {y : X.N} : + x.toN = y ↔ y.subcomplex = x.subcomplex := + ⟨by rintro rfl; simp, fun h ↦ x.existsUnique_n.unique (by simp) h⟩ + +end S + +end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index de2ba0330faee6..57f41caadd0e23 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -17,10 +17,13 @@ In particular, as a preordered type, `X.S` is a category, but this is not what is called "the category of simplices of `X`" in the literature (and which is `X.Elementsᵒᵖ` in mathlib). +In the file `AlgebraicTopology.SimplicialSet.NonDegenerateSimplices`, +the structure `SSet.S` is extended as `SSet.N` by adding the condition +that the simplex is non degenerate. + ## TODO (@joelriou) -* Extend the `S` structure to define the type of nondegenerate -simplices of a simplicial set `X`, and also the type of nondegenerate +* Extend the `SSet.N` structure to define the nondegenerate simplices of a simplicial set `X` which do not belong to a given subcomplex. -/ @@ -100,7 +103,9 @@ instance : Preorder X.S where le_refl _ := le_refl (α := Subcomplex X) _ le_trans _ _ _ := le_trans (α := Subcomplex X) -lemma le_iff {x y : X.S} : x ≤ y ↔ Subcomplex.ofSimplex x.2 ≤ Subcomplex.ofSimplex y.2 := +abbrev subcomplex (x : X.S) : X.Subcomplex := Subcomplex.ofSimplex x.2 + +lemma le_iff {x y : X.S} : x ≤ y ↔ x.subcomplex ≤ y.subcomplex := Iff.rfl lemma mk_map_le {n m : ℕ} (x : X _⦋n⦌) (f : ⦋m⦌ ⟶ ⦋n⦌) : diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 73da14375e00a3..3240b386294acc 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -194,6 +194,11 @@ lemma ofSimplex_le_iff {n : ℕ} (x : X _⦋n⦌) (A : X.Subcomplex) : ofSimplex x ≤ A ↔ x ∈ A.obj _ := Subpresheaf.ofSection_le_iff _ _ +lemma mem_ofSimplex_obj_iff {n : ℕ} (x : X _⦋n⦌) {m : SimplexCategoryᵒᵖ} (y : X.obj m) : + y ∈ (ofSimplex x).obj m ↔ ∃ (f : m.unop ⟶ ⦋n⦌), X.map f.op x = y := by + dsimp [ofSimplex, Subpresheaf.ofSection] + aesop + lemma yonedaEquiv_coe {A : X.Subcomplex} {n : SimplexCategory} (f : stdSimplex.obj n ⟶ A) : (DFunLike.coe (F := ((stdSimplex.obj n ⟶ Subpresheaf.toPresheaf A) ≃ A.obj (op n))) diff --git a/Mathlib/CategoryTheory/EpiMono.lean b/Mathlib/CategoryTheory/EpiMono.lean index 0c31fa6cb51cfa..d13c24e9249f87 100644 --- a/Mathlib/CategoryTheory/EpiMono.lean +++ b/Mathlib/CategoryTheory/EpiMono.lean @@ -272,4 +272,26 @@ lemma mono_comp_iff_of_mono {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) [Mono g] : end +section Opposite + +variable {X Y : C} {f : X ⟶ Y} + +/-- The opposite of a split mono is a split epi. -/ +def SplitMono.op (h : SplitMono f) : SplitEpi f.op where + section_ := h.retraction.op + id := Quiver.Hom.unop_inj (by simp) + +/-- The opposite of a split epi is a split mono. -/ +def SplitEpi.op (h : SplitEpi f) : SplitMono f.op where + retraction := h.section_.op + id := Quiver.Hom.unop_inj (by simp) + +instance [IsSplitMono f] : IsSplitEpi f.op := + .mk' IsSplitMono.exists_splitMono.some.op + +instance [IsSplitEpi f] : IsSplitMono f.op := + .mk' IsSplitEpi.exists_splitEpi.some.op + +end Opposite + end CategoryTheory From 1727da4d8025a7dd7be3f91e94ec86c46c3f6f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 11:14:18 +0530 Subject: [PATCH 26/81] added docstring --- Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index 57f41caadd0e23..1ae76c1c689d85 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -103,6 +103,7 @@ instance : Preorder X.S where le_refl _ := le_refl (α := Subcomplex X) _ le_trans _ _ _ := le_trans (α := Subcomplex X) +/-- The subcomplex generated by a simplex. -/ abbrev subcomplex (x : X.S) : X.Subcomplex := Subcomplex.ofSimplex x.2 lemma le_iff {x y : X.S} : x ≤ y ↔ x.subcomplex ≤ y.subcomplex := From 00f9a64545a5131fda76106a5ef72744f266acf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 11:27:31 +0530 Subject: [PATCH 27/81] added nondegenerate simplices not in a subcomplex --- Mathlib.lean | 1 + .../SimplicialSet/NonDegenerateSimplices.lean | 6 ++ .../NonDegenerateSimplicesSubcomplex.lean | 79 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean diff --git a/Mathlib.lean b/Mathlib.lean index a068803d7101ec..0fa8ada07bc42b 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1318,6 +1318,7 @@ import Mathlib.AlgebraicTopology.SimplicialSet.Monoidal import Mathlib.AlgebraicTopology.SimplicialSet.Nerve import Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplices +import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplicesSubcomplex import Mathlib.AlgebraicTopology.SimplicialSet.Path import Mathlib.AlgebraicTopology.SimplicialSet.Simplices import Mathlib.AlgebraicTopology.SimplicialSet.StdSimplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index fa7804147ea48b..30d605880e3df3 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -56,6 +56,12 @@ lemma mk_surjective (x : X.N) : ∃ (n : ℕ) (y : X.nonDegenerate n), x = N.mk _ y.2 := ⟨x.1.1, ⟨_, x.nonDegenerate⟩, rfl⟩ +lemma ext_iff (x y : X.N) : + x = y ↔ x.toS = y.toS := by + cases x + cases y + aesop + instance : Preorder X.N := Preorder.lift toS lemma le_iff {x y : X.N} : x ≤ y ↔ x.subcomplex ≤ y.subcomplex := diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean new file mode 100644 index 00000000000000..c9521ae15a6726 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean @@ -0,0 +1,79 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplices + +/-! +# The partially ordered type of non degenerate simplices not in a subcomplex + +In this file, given a subcomplex `A` of a simplicial set `X`, +we introduce the type `A.N` of non degenerate simplices of `X` +that are not in `A`. + +-/ + +universe u + +open CategoryTheory Simplicial + +namespace SSet.Subcomplex + +variable {X : SSet.{u}} (A : X.Subcomplex) + +/-- The type of nondegenerate simplices which do not belong to +a given subcomplex of a simplicial set. -/ +structure N extends X.N where mk' :: + notMem : simplex ∉ A.obj _ + +namespace N + +variable {A} + +lemma mk'_surjective (s : A.N) : + ∃ (t : X.N) (ht : t.simplex ∉ A.obj _), s = mk' t ht := + ⟨s.toN, s.notMem, rfl⟩ + +/-- Constructor for the type of nondegenerate simplices which +do not belong to a given subcomplex of a simplicial set. -/ +@[simps!] +def mk {n : ℕ} (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) + (hx' : x ∉ A.obj _) : A.N where + simplex := x + nonDegenerate := hx + notMem := hx' + +lemma mk_surjective (s : A.N) : + ∃ (n : ℕ) (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) + (hx' : x ∉ A.obj _), s = mk x hx hx' := + ⟨s.dim, s.simplex, s.nonDegenerate, s.notMem, rfl⟩ + +lemma ext_iff (x y : A.N) : + x = y ↔ x.toN = y.toN := by + cases x + cases y + aesop + +section + +variable (s : A.N) {d : ℕ} (hd : s.dim = d) + +/-- When `A` is a subcomplex of a simplicial set `X`, +and `s : A.N` is such that `s.dim = d`, this is a term +that is equal to `s`, but whose dimension if definitionally equal to `d`. -/ +abbrev cast : A.N where + toN := s.toN.cast hd + notMem := by + subst hd + exact s.notMem + +lemma cast_eq_self : s.cast hd = s := by + subst hd + rfl + +end + +end N + +end SSet.Subcomplex From b50128c687b00b17c53e496b89e9d0a05266a6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 13:08:15 +0530 Subject: [PATCH 28/81] definition of pairings --- Mathlib.lean | 2 + .../IsUniquelyCodimOneFace.lean | 89 +++++++++++++++ .../AnodyneExtensions/Pairing.lean | 105 ++++++++++++++++++ .../NonDegenerateSimplicesSubcomplex.lean | 6 + docs/references.bib | 18 +++ 5 files changed, 220 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0fa8ada07bc42b..7924a66683c8e7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1306,6 +1306,8 @@ import Mathlib.AlgebraicTopology.SimplicialNerve import Mathlib.AlgebraicTopology.SimplicialObject.Basic import Mathlib.AlgebraicTopology.SimplicialObject.Coskeletal import Mathlib.AlgebraicTopology.SimplicialObject.Split +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.IsUniquelyCodimOneFace +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.SimplicialSet.Boundary import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean new file mode 100644 index 00000000000000..d2375fb1b52cd8 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean @@ -0,0 +1,89 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplices + +/-! +# Simplices that are uniquely codimensional one faces + +Let `X` be a simplicial set. If `x : X _⦋d⦌` and `y : X _⦋d + 1⦌`, +we say that `x` is uniquely `1`-codimensional face of `y` if there +exists a unique `i : Fin (d + 2)` such that `X.δ i y = x`. In this file, +we extend this to a predicate `IsUniquelyCodimOneFace` involving two terms +in the type `X.S` of simplices of `X`. This is used in the +file `AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing` for the +study of strong (inner) anodyne extensions. + +## References +* [Sean Moss, *Another approach to the Kan-Quillen model structure*][moss-2020] + +-/ + +universe u + +open CategoryTheory Simplicial + +namespace SSet.S + +variable {X : SSet.{u}} (x y : X.S) + +/-- The property that a simplex is uniquely a `1`-codimensional face of another simplex -/ +def IsUniquelyCodimOneFace : Prop := + y.dim = x.dim + 1 ∧ ∃! (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌), Mono f ∧ X.map f.op y.simplex = x.simplex + +namespace IsUniquelyCodimOneFace + +lemma iff {d : ℕ} (x : X _⦋d⦌) (y : X _⦋d + 1⦌) : + IsUniquelyCodimOneFace (S.mk x) (S.mk y) ↔ + ∃! (i : Fin (d + 2)), X.δ i y = x := by + constructor + · rintro ⟨_, ⟨f, ⟨_, h₁⟩, h₂⟩⟩ + obtain ⟨i, rfl⟩ := SimplexCategory.eq_δ_of_mono f + exact ⟨i, h₁, fun j hj ↦ SimplexCategory.δ_injective (h₂ _ ⟨inferInstance, hj⟩)⟩ + · rintro ⟨i, h₁, h₂⟩ + refine ⟨rfl, SimplexCategory.δ i, ⟨inferInstance, h₁⟩, fun f ⟨h₃, h₄⟩ ↦ ?_⟩ + obtain ⟨j, rfl⟩ := SimplexCategory.eq_δ_of_mono f + obtain rfl : j = i := h₂ _ h₄ + rfl + +variable {x y} (hxy : IsUniquelyCodimOneFace x y) + +include hxy in +lemma dim_eq : y.dim = x.dim + 1 := hxy.1 + +section + +variable {d : ℕ} (hd : x.dim = d) + +lemma cast : IsUniquelyCodimOneFace (x.cast hd) (y.cast (by rw [hxy.dim_eq, hd])) := by + simpa only [cast_eq_self] + +lemma existsUnique_δ_cast_simplex : + ∃! (i : Fin (d + 2)), X.δ i (y.cast (by rw [hxy.dim_eq, hd])).simplex = + (x.cast hd).simplex := by + simpa only [S.cast, iff] using hxy.cast hd + +include hxy in +/-- When a `d`-dimensional simplex `x` is a `1`-codimensional face of `y`, this is +the only `i : Fin (d + 2)`, such that `X.δ i y = x` (with an abuse of notation: +see `δ_index` and `δ_eq_iff` for well typed statements). -/ +noncomputable def index : Fin (d + 2) := + (hxy.existsUnique_δ_cast_simplex hd).exists.choose + +lemma δ_index : + X.δ (hxy.index hd) (y.cast (by rw [hxy.dim_eq, hd])).simplex = (x.cast hd).simplex := + (hxy.existsUnique_δ_cast_simplex hd).exists.choose_spec + +lemma δ_eq_iff (i : Fin (d + 2)) : + X.δ i (y.cast (by rw [hxy.dim_eq, hd])).simplex = (x.cast hd).simplex ↔ + i = hxy.index hd := + ⟨fun h ↦ (hxy.existsUnique_δ_cast_simplex hd).unique h (hxy.δ_index hd), + by rintro rfl; apply δ_index⟩ + +end + +end IsUniquelyCodimOneFace + +end SSet.S diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean new file mode 100644 index 00000000000000..7f97db6f559544 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -0,0 +1,105 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplicesSubcomplex +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.IsUniquelyCodimOneFace + +/-! +# Pairings + +In this file, we introduce the definition of a pairing for a subcomplex `A` +of a simplicial set `X`, following the ideas by Sean Moss, +*Another approach to the Kan-Quillen model structure*, who gave a +complete combinatorial characterization of strong (inner) anodyne extensions. +Strong (inner) anodyne extensions are transfinite compositions of pushouts of coproducts +of (inner) horn inclusions, i.e. this is similar to (inner) anodyne extensions but +without the stability property under retracts. + +A pairing for `A` consists in the data of a partition of the nondegenerate +simplices of `X` not in `A` into type (I) simplices and type (II) simplices, +and of a bijection between the types of type (I) and type (II) simplices. +Indeed, the main observation is that when we attach a simplex along a horn +inclusions, exactly two nondegenerate simplices are added: this simplex, +and the unique face which is not in the image of the horn. The former shall be +considered as of type (I) and the latter as type (II). + +We say that a pairing is *regular* (typeclass `Pairing.IsRegular`) when +- it is proper (`Pairing.IsProper`), i.e. any type (II) simplex is uniquely +a face of the corresponding type (I) simplex. +- a certain ancestrality relation is well founded. +When these conditions are satisfied, the inclusion `A.ι : A ⟶ X` is +a strong anodyne extension (TODO @joelriou), and the converse is also true +(if `A.ι` is a strong anodyne extension, then there is a regular pairing for `A` (TODO)). + +## References +* [Sean Moss, *Another approach to the Kan-Quillen model structure*][moss-2020] + +-/ + +universe u + +namespace SSet.Subcomplex + +variable {X : SSet.{u}} (A : X.Subcomplex) + +/-- A pairing for a subcomplex `A` of a simplicial set `X` consists of a partition +of the nondegenerate simplices of `X` not in `A` in two types (I) and (II) of simplices, +and a bijection between the type (II) simplices and the type (I) simplices. +See the introduction of the file `AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing`. -/ +structure Pairing where + /-- the set of type (I) simplices -/ + I : Set A.N + /-- the set of type (II) simplices -/ + II : Set A.N + inter : I ∩ II = ∅ + union : I ∪ II = Set.univ + /-- a bijection from the type (II) simplices to the type (I) simplices -/ + p : II ≃ I + +namespace Pairing + +variable {A} (P : A.Pairing) + +/-- A pairing is regular when each type (II) simplex +is uniquely a `1`-codimensional face of the corresponding (I) +simplex. -/ +class IsProper where + isUniquelyCodimOneFace (x : P.II) : + S.IsUniquelyCodimOneFace x.1.toS (P.p x).1.toS + +lemma isUniquelyCodimOneFace [P.IsProper] (x : P.II) : + S.IsUniquelyCodimOneFace x.1.toS (P.p x).1.toS := + IsProper.isUniquelyCodimOneFace x + +/-- The condition that a pairing only involves inner horns. -/ +class IsInner [P.IsProper] : Prop where + ne_zero (x : P.II) {d : ℕ} (hd : x.1.dim = d) : + (P.isUniquelyCodimOneFace x).index hd ≠ 0 + ne_last (x : P.II) {d : ℕ} (hd : x.1.dim = d) : + (P.isUniquelyCodimOneFace x).index hd ≠ Fin.last _ + +/-- The ancestrality relation on type (II) simplices. -/ +def AncestralRel (x y : P.II) : Prop := + x ≠ y ∧ x.1 < (P.p y).1 + +/-- A proper pairing is regular when the ancestrality relation +is well founded. -/ +class IsRegular extends P.IsProper where + wf : WellFounded P.AncestralRel + +section + +variable [P.IsRegular] + +lemma wf : WellFounded P.AncestralRel := IsRegular.wf + +instance : IsWellFounded _ P.AncestralRel where + wf := P.wf + +end + +end Pairing + +end SSet.Subcomplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean index c9521ae15a6726..201697e1fc4d40 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean @@ -55,6 +55,12 @@ lemma ext_iff (x y : A.N) : cases y aesop +instance : PartialOrder A.N := + PartialOrder.lift toN (fun _ _ ↦ by simp [ext_iff]) + +lemma le_iff {x y : A.N} : x ≤ y ↔ x.toN ≤ y.toN := + Iff.rfl + section variable (s : A.N) {d : ℕ} (hd : s.dim = d) diff --git a/docs/references.bib b/docs/references.bib index 90eb4db05eebf3..3e8f2d69915fb8 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -3170,6 +3170,24 @@ @Article{ morrison-penney-enriched eprint = {https://academic.oup.com/imrn/article-pdf/2019/11/3527/28757603/rnx217.pdf} } + +@Article{ moss-2020, + author = {Moss, Sean}, + title = {Another approach to the {K}an-{Q}uillen model structure}, + journal = {J. Homotopy Relat. Struct.}, + fjournal = {Journal of Homotopy and Related Structures}, + volume = {15}, + year = {2020}, + number = {1}, + pages = {143--165}, + issn = {2193-8407,1512-2891}, + mrclass = {55U35 (55U10)}, + mrnumber = {4062882}, + doi = {10.1007/s40062-019-00247-y}, + url = {https://doi.org/10.1007/s40062-019-00247-y} +} + + @Article{ MR0236876, title = {A new proof that metric spaces are paracompact}, author = {Mary Ellen Rudin}, From 14f6d18cb3ee5e5c3f9bd8b82e38137c3d9152c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 15:01:18 +0530 Subject: [PATCH 29/81] feat(AlgebraicTopology/SimplicialSet): a helper structure to construct pairings --- Mathlib.lean | 1 + .../AnodyneExtensions/Pairing.lean | 17 ++ .../AnodyneExtensions/PairingCore.lean | 226 ++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7924a66683c8e7..697f61ece7f7af 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1308,6 +1308,7 @@ import Mathlib.AlgebraicTopology.SimplicialObject.Coskeletal import Mathlib.AlgebraicTopology.SimplicialObject.Split import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.IsUniquelyCodimOneFace import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.PairingCore import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.SimplicialSet.Boundary import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean index 7f97db6f559544..b7f1849ee8cd45 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -100,6 +100,23 @@ instance : IsWellFounded _ P.AncestralRel where end +lemma exists_or (x : A.N) : + ∃ (y : P.II), x = y ∨ x = P.p y := by + have := Set.mem_univ x + rw [← P.union, Set.mem_union] at this + obtain h | h := this + · obtain ⟨y, hy⟩ := P.p.surjective ⟨x, h⟩ + exact ⟨y, Or.inr (by rw [hy])⟩ + · exact ⟨⟨_, h⟩, Or.inl rfl⟩ + +lemma neq (x : P.I) (y : P.II) : + x.1 ≠ y.1 := by + obtain ⟨x, hx⟩ := x + obtain ⟨y, hy⟩ := y + rintro rfl + have : x ∈ P.I ∩ P.II := ⟨hx, hy⟩ + simp [P.inter] at this + end Pairing end SSet.Subcomplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean new file mode 100644 index 00000000000000..4915f4449ea489 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean @@ -0,0 +1,226 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing + +/-! +# Helper structure in order to construct pairings + +In this file, we introduce an helper structure `Subcomplex.PairingCore` +in order to construct a pairing for a subcomplex of a simplicial set. +The main differences with `Subcomplex.Pairing` are that we provide +an index type `ι` in order to parametrize type (I) and type (II) simplices, +and that the dimensions of these are definitionally `d` or `d + 1`. + +-/ + +universe v u + +open CategoryTheory Simplicial + +namespace SSet.Subcomplex + +variable {X : SSet.{u}} (A : X.Subcomplex) + +/-- An helper structure in order to construct a pairing for a subcomplex of a +simplicial set. The main differences with `Pairing` are that we provide +an index type `ι` in order to parametrize type (I) and type (II) simplices, +and that the dimensions of these are definitionally `d` or `d + 1`. -/ +structure PairingCore where + /-- the index type -/ + ι : Type v + /-- the dimension of a type (II) simplex -/ + d (s : ι) : ℕ + /-- a type (I) simplex -/ + simplex (s : ι) : X _⦋d s + 1⦌ + /-- the corresponding type (II) is the `1`-codimensional face given by this index -/ + index (s : ι) : Fin (d s + 2) + nonDegenerate₁ (s : ι) : simplex s ∈ X.nonDegenerate _ + nonDegenerate₂ (s : ι) : X.δ (index s) (simplex s) ∈ X.nonDegenerate _ + notMem₁ (s : ι) : simplex s ∉ A.obj _ + notMem₂ (s : ι) : X.δ (index s) (simplex s) ∉ A.obj _ + injective_type₁' {s t : ι} (h : S.mk (simplex s) = S.mk (simplex t)) : s = t + injective_type₂' {s t : ι} + (h : S.mk (X.δ (index s) (simplex s)) = S.mk (X.δ (index t) (simplex t))) : s = t + type₁_neq_type₂' (s t : ι) : S.mk (simplex s) ≠ S.mk (X.δ (index t) (simplex t)) + surjective' (x : A.N) : + ∃ (s : ι), x.toS = S.mk (simplex s) ∨ x.toS = S.mk (X.δ (index s) (simplex s)) + +variable {A} + +/-- The `PairingCore` structure induced by a pairing. The opposite construction +if `PairingCore.pairing`. -/ +noncomputable def Pairing.pairingCore (P : A.Pairing) [P.IsProper] : + A.PairingCore where + ι := P.II + d s := s.1.dim + simplex s := ((P.p s).1.cast (P.isUniquelyCodimOneFace s).dim_eq).simplex + index s := (P.isUniquelyCodimOneFace s).index rfl + nonDegenerate₁ s := ((P.p s).1.cast (P.isUniquelyCodimOneFace s).dim_eq).nonDegenerate + nonDegenerate₂ s := by + rw [(P.isUniquelyCodimOneFace s).δ_index rfl] + exact s.1.nonDegenerate + notMem₁ s := ((P.p s).1.cast (P.isUniquelyCodimOneFace s).dim_eq).notMem + notMem₂ s := by + rw [(P.isUniquelyCodimOneFace s).δ_index rfl] + exact s.1.notMem + injective_type₁' {s t} _ := by + apply P.p.injective + rwa [Subtype.ext_iff, N.ext_iff, SSet.N.ext_iff, + ← (P.p s).1.cast_eq_self (P.isUniquelyCodimOneFace s).dim_eq, + ← (P.p t).1.cast_eq_self (P.isUniquelyCodimOneFace t).dim_eq] + injective_type₂' {s t} h := by + rw [(P.isUniquelyCodimOneFace s).δ_index rfl, + (P.isUniquelyCodimOneFace t).δ_index rfl] at h + rwa [Subtype.ext_iff, N.ext_iff, SSet.N.ext_iff] + type₁_neq_type₂' s t h := (P.neq (P.p s) t) (by + rw [(P.isUniquelyCodimOneFace t).δ_index rfl] at h + rwa [← (P.p s).1.cast_eq_self (P.isUniquelyCodimOneFace s).dim_eq, + N.ext_iff, SSet.N.ext_iff]) + surjective' x := by + obtain ⟨s, rfl | rfl⟩ := P.exists_or x + · refine ⟨s, Or.inr ?_⟩ + rw [(P.isUniquelyCodimOneFace s).δ_index rfl] + rfl + · refine ⟨s, Or.inl ?_⟩ + nth_rw 1 [← (P.p s).1.cast_eq_self (P.isUniquelyCodimOneFace s).dim_eq] + rfl + +namespace PairingCore + +variable (h : A.PairingCore) + +/-- The type (I) simplices of `h : A.PairingCore`, as a family indexed by `h.ι`. -/ +@[simps!] +def type₁ (s : h.ι) : A.N := + Subcomplex.N.mk (h.simplex s) (h.nonDegenerate₁ s) (h.notMem₁ s) + +/-- The type (II) simplices of `h : A.PairingCore`, as a family indexed by `h.ι`. -/ +@[simps!] +def type₂ (s : h.ι) : A.N := + Subcomplex.N.mk (X.δ (h.index s) (h.simplex s)) (h.nonDegenerate₂ s) + (h.notMem₂ s) + +lemma injective_type₁ : Function.Injective h.type₁ := + fun _ _ hst ↦ h.injective_type₁' (by rwa [Subcomplex.N.ext_iff, SSet.N.ext_iff] at hst) + +lemma injective_type₂ : Function.Injective h.type₂ := + fun s t hst ↦ h.injective_type₂' (by rwa [Subcomplex.N.ext_iff, SSet.N.ext_iff] at hst) + +lemma type₁_neq_type₂ (s t : h.ι) : h.type₁ s ≠ h.type₂ t := by + simpa only [ne_eq, N.ext_iff, SSet.N.ext_iff] using h.type₁_neq_type₂' s t + +lemma surjective (x : A.N) : + ∃ (s : h.ι), x = h.type₁ s ∨ x = h.type₂ s := by + obtain ⟨s, _ | _⟩ := h.surjective' x + · exact ⟨s, Or.inl (by rwa [N.ext_iff, SSet.N.ext_iff])⟩ + · exact ⟨s, Or.inr (by rwa [N.ext_iff, SSet.N.ext_iff])⟩ + +/-- The type (I) simplices of `h : A.PairingCore`, as a subset of `A.N`. -/ +def I : Set A.N := Set.range h.type₁ + +/-- The type (II) simplices of `h : A.PairingCore`, as a subset of `A.N`. -/ +def II : Set A.N := Set.range h.type₂ + +/-- The bijection `h.ι ≃ h.I` when `h : A.PairingCore`. -/ +@[simps! apply_coe] +noncomputable def equivI : h.ι ≃ h.I := Equiv.ofInjective _ h.injective_type₁ + +/-- The bijection `h.ι ≃ h.II` when `h : A.PairingCore`. -/ +@[simps! apply_coe] +noncomputable def equivII : h.ι ≃ h.II := Equiv.ofInjective _ h.injective_type₂ + +/-- The pairing induced by `h : A.PairingCore`. -/ +@[simps I II] +noncomputable def pairing : A.Pairing where + I := h.I + II := h.II + inter := by + ext s + simp only [I, II, Set.mem_inter_iff, Set.mem_range, Set.mem_empty_iff_false, + iff_false, not_and, not_exists, forall_exists_index] + rintro t rfl s + exact (h.type₁_neq_type₂ t s).symm + union := by + ext s + have := h.surjective s + simp only [I, II, Set.mem_union, Set.mem_range, Set.mem_univ, iff_true] + aesop + p := h.equivII.symm.trans h.equivI + +@[simp] +lemma pairing_p_equivII (x : h.ι) : + DFunLike.coe (F := h.II ≃ h.I) h.pairing.p (h.equivII x) = h.equivI x := by + simp [pairing] + +@[simp] +lemma pairing_p_symm_equivI (x : h.ι) : + DFunLike.coe (F := h.I ≃ h.II) h.pairing.p.symm (h.equivI x) = h.equivII x := by + simp [pairing] + +/-- The condition that `h : A.PairingCore` is proper. -/ +class IsProper : Prop where + isUniquelyCodimOneFace (s : h.ι) : + S.IsUniquelyCodimOneFace (h.type₂ s).toS (h.type₁ s).toS + +lemma isUniquelyCodimOneFace [h.IsProper] (s : h.ι) : + S.IsUniquelyCodimOneFace (h.type₂ s).toS (h.type₁ s).toS := + IsProper.isUniquelyCodimOneFace _ + +instance [h.IsProper] : h.pairing.IsProper where + isUniquelyCodimOneFace x := by + obtain ⟨s, rfl⟩ := h.equivII.surjective x + simpa using h.isUniquelyCodimOneFace s + +@[simp] +lemma isUniquelyCodimOneFace_index [h.IsProper] (s : h.ι) : + (h.isUniquelyCodimOneFace s).index rfl = h.index s := by + symm + simp [← (h.isUniquelyCodimOneFace s).δ_eq_iff] + +lemma isUniquelyCodimOneFace_index_coe + [h.IsProper] (s : h.ι) {d : ℕ} (hd : h.d s = d) : + ((h.isUniquelyCodimOneFace s).index hd).1 = (h.index s).1 := by + subst hd + simp + +/-- The condition that `h : A.PairingCore` involves only inner horns. -/ +class IsInner where + ne_zero (s : h.ι) : h.index s ≠ 0 + ne_last (s : h.ι) : h.index s ≠ Fin.last _ + +instance [h.IsInner] [h.IsProper] : h.pairing.IsInner where + ne_zero x := by + obtain ⟨s, rfl⟩ := h.equivII.surjective x + rintro _ rfl + simpa using IsInner.ne_zero s + ne_last x := by + obtain ⟨s, rfl⟩ := h.equivII.surjective x + rintro _ rfl + simpa using IsInner.ne_last s + +/-- The ancestrality relation on the index type of `h : A.PairingCore`. -/ +def AncestralRel (s t : h.ι) : Prop := + s ≠ t ∧ h.type₂ s < h.type₁ t + +lemma ancestralRel_iff (s t : h.ι) : + h.AncestralRel s t ↔ h.pairing.AncestralRel (h.equivII s) (h.equivII t) := by + simp [AncestralRel, Pairing.AncestralRel] + +/-- When the ancestrality relation is well founded, we say that `h : A.PairingCore` +is regular. -/ +class IsRegular (h : A.PairingCore) extends h.IsProper where + wf (h) : WellFounded h.AncestralRel + +instance [h.IsRegular] : h.pairing.IsRegular where + wf := by + have := IsRegular.wf h + rw [WellFounded.wellFounded_iff_no_descending_seq, isEmpty_iff] at this ⊢ + rintro ⟨f, hf⟩ + exact this ⟨fun n ↦ h.equivII.symm (f n), fun n ↦ by simpa [ancestralRel_iff] using hf n⟩ + +end PairingCore + +end SSet.Subcomplex From 80d3a14f2b930fc01bae952425fc0b17498c7c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 17:25:01 +0530 Subject: [PATCH 30/81] fixing imports --- .../SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean index d2375fb1b52cd8..2fce96c3de40a4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean @@ -3,7 +3,7 @@ Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ -import Mathlib.AlgebraicTopology.SimplicialSet.NonDegenerateSimplices +import Mathlib.AlgebraicTopology.SimplicialSet.Simplices /-! # Simplices that are uniquely codimensional one faces From 307f01ad1d8535f7d3453511f33de8e172b22d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 18:35:08 +0530 Subject: [PATCH 31/81] wip --- Mathlib.lean | 1 + .../AnodyneExtensions/Pairing.lean | 6 + .../SimplicialSet/AnodyneExtensions/Rank.lean | 131 ++++++++++++++++++ .../SimplicialSet/NonDegenerateSimplices.lean | 16 ++- 4 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7924a66683c8e7..7e5c5f798bea31 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1308,6 +1308,7 @@ import Mathlib.AlgebraicTopology.SimplicialObject.Coskeletal import Mathlib.AlgebraicTopology.SimplicialObject.Split import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.IsUniquelyCodimOneFace import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.SimplicialSet.Boundary import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean index 7f97db6f559544..4885d6ff195533 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -84,6 +84,12 @@ class IsInner [P.IsProper] : Prop where def AncestralRel (x y : P.II) : Prop := x ≠ y ∧ x.1 < (P.p y).1 +variable {P} in +lemma AncestralRel.dim_le [P.IsProper] {x y : P.II} (hxy : P.AncestralRel x y) : + x.1.dim ≤ y.1.dim := by + simpa only [(P.isUniquelyCodimOneFace y).dim_eq, Nat.lt_succ_iff] using + SSet.N.dim_lt_of_lt hxy.2 + /-- A proper pairing is regular when the ancestrality relation is well founded. -/ class IsRegular extends P.IsProper where diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean new file mode 100644 index 00000000000000..e497ba91316a77 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean @@ -0,0 +1,131 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing +import Mathlib.Order.OrderIsoNat + +/-! +# Rank functions for pairings + +We introduce types of (weak) rank functions for a pairing `P` +of a subcomplex `A` of a simplicial set `X`. These are +functions `f : P.II → ι` such that `P.AncestralRel x y` implies `f x < f y` +(in the weak case, we require this only under the additional condition +that `x` and `y` are of the same dimension). Such rank functions +are used to show that the ancestral relation on `P.II` is well founded, +i.e. that `P` is regular (when we already know `P` is proper). + +## References +* [Sean Moss, *Another approach to the Kan-Quillen model structure*][moss-2020] + +-/ + +universe v u + +open CategoryTheory Simplicial + +namespace SSet.Subcomplex + +variable {X : SSet.{u}} {A : X.Subcomplex} + +namespace Pairing + +variable {X : SSet.{u}} {A : X.Subcomplex} (P : A.Pairing) + (α : Type v) [PartialOrder α] + +/-- A rank function for a pairing is a function from the type (II) simplices +to a partially ordered type which maps ancestrality relations to strict inequalities. -/ +structure RankFunction where + rank : P.II → α + lt {x y : P.II} : P.AncestralRel x y → rank x < rank y + +namespace RankFunction + +variable {P α} [WellFoundedLT α] (f : P.RankFunction α) + +include f + +lemma wf_ancestralRel : WellFounded P.AncestralRel := by + rw [WellFounded.wellFounded_iff_no_descending_seq] + exact ⟨fun ⟨g, hg⟩ ↦ not_strictAnti_of_wellFoundedLT (f.rank ∘ g) + (strictAnti_nat_of_succ_lt (fun n ↦ f.lt (hg n)))⟩ + +lemma isRegular [P.IsProper] : P.IsRegular where + wf := f.wf_ancestralRel + +end RankFunction + +/-- A weak rank function for a pairing is a function from the type (II) simplices +to a partially ordered type which maps an ancestrality relation between +simplices of the same dimension to a strict inequality. -/ +structure WeakRankFunction where + rank : P.II → α + lt {x y : P.II} : P.AncestralRel x y → x.1.dim = y.1.dim → rank x < rank y + +namespace WeakRankFunction + +variable {P α} [WellFoundedLT α] [P.IsProper] (f : P.WeakRankFunction α) + +include f + +lemma wf_ancestralRel : WellFounded P.AncestralRel := by + rw [WellFounded.wellFounded_iff_no_descending_seq] + refine ⟨fun ⟨g, hg⟩ ↦ ?_⟩ + obtain ⟨n₀, hn₀⟩ := + (wellFoundedGT_iff_monotone_chain_condition (α := ℕᵒᵈ)).1 + inferInstance ⟨fun n ↦ (g n).1.dim, + monotone_nat_of_le_succ (fun n ↦ (hg n).dim_le)⟩ + dsimp at hn₀ + refine not_strictAnti_of_wellFoundedLT (fun n ↦ f.rank (g (n₀ + n))) + (strictAnti_nat_of_succ_lt (fun n ↦ ?_)) + rw [← add_assoc] + exact f.lt (hg _) (by rw [← hn₀ (n₀ + n + 1) (by omega), ← hn₀ (n₀ + n) (by omega)]) + +lemma isRegular : P.IsRegular where + wf := f.wf_ancestralRel + +end WeakRankFunction + +@[simps] +def RankFunction.toWeakRankFunction (f : P.RankFunction α) : + P.WeakRankFunction α where + rank := f.rank + lt h _ := f.lt h + +end Pairing + +namespace PairingCore + +variable {X : SSet.{u}} {A : X.Subcomplex} (h : A.PairingCore) + (α : Type v) [PartialOrder α] + +/-- A rank function for `h : A.PairincgCore` is a function from the index type `h.ι` +to a partially ordered type which maps the ancestrality relations to strict inequalities. -/ +structure RankFunction where + rank : h.ι → α + lt {x y : h.ι} : h.AncestralRel x y → rank x < rank y + +/-- A weak rank function `h : A.PairingCore` is a function from the index type `h.ι` +to a partially ordered type which maps an ancestrality relation between +indices of the same dimension to a strict inequality. -/ +structure WeakRankFunction where + rank : h.ι → α + lt {x y : h.ι} : h.AncestralRel x y → h.d x = h.d y → rank x < rank y + +noncomputable def rankFunctionEquiv : + h.RankFunction α ≃ h.pairing.RankFunction α where + toFun f := + { rank s := f.rank (h.equivII.symm s) + lt := sorry } + invFun g := + { rank x := g.rank (h.equivII x) + lt := by + sorry } + left_inv := sorry + right_inv := sorry + +end PairingCore + +end SSet.Subcomplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index 30d605880e3df3..bd0d78278234d9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -73,16 +73,28 @@ lemma le_iff_exists_mono {x y : X.N} : Subcomplex.mem_ofSimplex_obj_iff] exact ⟨fun ⟨f, hf⟩ ↦ ⟨f, X.mono_of_nonDegenerate ⟨_, x.2⟩ f _ hf, hf⟩, by tauto⟩ -lemma le_of_le {x y : X.N} (h : x ≤ y) : x.1.1 ≤ y.1.1 := by +lemma dim_le_of_le {x y : X.N} (h : x ≤ y) : x.dim ≤ y.dim := by rw [le_iff_exists_mono] at h obtain ⟨f, hf, _⟩ := h exact SimplexCategory.len_le_of_mono f +lemma dim_lt_of_lt {x y : X.N} (h : x < y) : x.dim < y.dim := by + obtain h' | h' := (dim_le_of_le h.le).lt_or_eq + · exact h' + · exfalso + obtain ⟨f, _, hf⟩ := le_iff_exists_mono.1 h.le + obtain ⟨d, ⟨x, hx⟩, rfl⟩ := x.mk_surjective + obtain ⟨d', ⟨y, hy⟩, rfl⟩ := y.mk_surjective + obtain rfl : d = d' := h' + obtain rfl := SimplexCategory.eq_id_of_mono f + obtain rfl : y = x := by simpa using hf + simp at h + instance : PartialOrder X.N where le_antisymm x₁ x₂ h h' := by obtain ⟨n₁, ⟨x₁, hx₁⟩, rfl⟩ := x₁.mk_surjective obtain ⟨n₂, ⟨x₂, hx₂⟩, rfl⟩ := x₂.mk_surjective - obtain rfl : n₁ = n₂ := le_antisymm (le_of_le h) (le_of_le h') + obtain rfl : n₁ = n₂ := le_antisymm (dim_le_of_le h) (dim_le_of_le h') rw [le_iff_exists_mono] at h obtain ⟨f, hf, h⟩ := h obtain rfl := SimplexCategory.eq_id_of_mono f From 8a6417edadf701eebb7687ed94de9ea05fe1ed8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 18:36:45 +0530 Subject: [PATCH 32/81] better names --- .../SimplicialSet/NonDegenerateSimplices.lean | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index fa7804147ea48b..e1d37f6e49c2f0 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -67,16 +67,28 @@ lemma le_iff_exists_mono {x y : X.N} : Subcomplex.mem_ofSimplex_obj_iff] exact ⟨fun ⟨f, hf⟩ ↦ ⟨f, X.mono_of_nonDegenerate ⟨_, x.2⟩ f _ hf, hf⟩, by tauto⟩ -lemma le_of_le {x y : X.N} (h : x ≤ y) : x.1.1 ≤ y.1.1 := by +lemma dim_le_of_le {x y : X.N} (h : x ≤ y) : x.dim ≤ y.dim := by rw [le_iff_exists_mono] at h obtain ⟨f, hf, _⟩ := h exact SimplexCategory.len_le_of_mono f +lemma dim_lt_of_lt {x y : X.N} (h : x < y) : x.dim < y.dim := by + obtain h' | h' := (dim_le_of_le h.le).lt_or_eq + · exact h' + · exfalso + obtain ⟨f, _, hf⟩ := le_iff_exists_mono.1 h.le + obtain ⟨d, ⟨x, hx⟩, rfl⟩ := x.mk_surjective + obtain ⟨d', ⟨y, hy⟩, rfl⟩ := y.mk_surjective + obtain rfl : d = d' := h' + obtain rfl := SimplexCategory.eq_id_of_mono f + obtain rfl : y = x := by simpa using hf + simp at h + instance : PartialOrder X.N where le_antisymm x₁ x₂ h h' := by obtain ⟨n₁, ⟨x₁, hx₁⟩, rfl⟩ := x₁.mk_surjective obtain ⟨n₂, ⟨x₂, hx₂⟩, rfl⟩ := x₂.mk_surjective - obtain rfl : n₁ = n₂ := le_antisymm (le_of_le h) (le_of_le h') + obtain rfl : n₁ = n₂ := le_antisymm (dim_le_of_le h) (dim_le_of_le h') rw [le_iff_exists_mono] at h obtain ⟨f, hf, h⟩ := h obtain rfl := SimplexCategory.eq_id_of_mono f From 6bae3b849ca3163be02be1fa874ca2d0ef03b181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 18:48:08 +0530 Subject: [PATCH 33/81] cleaning up --- .../SimplicialSet/AnodyneExtensions/Rank.lean | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean index e497ba91316a77..2ed5964ee8d09f 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean @@ -3,7 +3,7 @@ Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ -import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.PairingCore import Mathlib.Order.OrderIsoNat /-! @@ -11,11 +11,16 @@ import Mathlib.Order.OrderIsoNat We introduce types of (weak) rank functions for a pairing `P` of a subcomplex `A` of a simplicial set `X`. These are -functions `f : P.II → ι` such that `P.AncestralRel x y` implies `f x < f y` +functions `f : P.II → α` such that `P.AncestralRel x y` implies `f x < f y` (in the weak case, we require this only under the additional condition that `x` and `y` are of the same dimension). Such rank functions -are used to show that the ancestral relation on `P.II` is well founded, +are used in order to show that the ancestral relation on `P.II` is well founded, i.e. that `P` is regular (when we already know `P` is proper). +Conversely, we shall show that if `P` is regular, +then `P.RankFunction ℕ` is non empty (TODO @joelriou). + +(We also introduce similar definitions for the structure `PairingCore`.) + ## References * [Sean Moss, *Another approach to the Kan-Quillen model structure*][moss-2020] @@ -38,6 +43,7 @@ variable {X : SSet.{u}} {A : X.Subcomplex} (P : A.Pairing) /-- A rank function for a pairing is a function from the type (II) simplices to a partially ordered type which maps ancestrality relations to strict inequalities. -/ structure RankFunction where + /-- the rank function -/ rank : P.II → α lt {x y : P.II} : P.AncestralRel x y → rank x < rank y @@ -61,6 +67,7 @@ end RankFunction to a partially ordered type which maps an ancestrality relation between simplices of the same dimension to a strict inequality. -/ structure WeakRankFunction where + /-- the (weak) rank function -/ rank : P.II → α lt {x y : P.II} : P.AncestralRel x y → x.1.dim = y.1.dim → rank x < rank y @@ -104,6 +111,7 @@ variable {X : SSet.{u}} {A : X.Subcomplex} (h : A.PairingCore) /-- A rank function for `h : A.PairincgCore` is a function from the index type `h.ι` to a partially ordered type which maps the ancestrality relations to strict inequalities. -/ structure RankFunction where + /-- the rank function -/ rank : h.ι → α lt {x y : h.ι} : h.AncestralRel x y → rank x < rank y @@ -111,20 +119,47 @@ structure RankFunction where to a partially ordered type which maps an ancestrality relation between indices of the same dimension to a strict inequality. -/ structure WeakRankFunction where + /-- the (weak) rank function -/ rank : h.ι → α lt {x y : h.ι} : h.AncestralRel x y → h.d x = h.d y → rank x < rank y +/-- Rank functions for `h : A.PairingCore` correspond to +rank functions for `h.pairing : A.Pairing`. -/ noncomputable def rankFunctionEquiv : h.RankFunction α ≃ h.pairing.RankFunction α where toFun f := { rank s := f.rank (h.equivII.symm s) - lt := sorry } + lt {x y} hxy := by + obtain ⟨x, rfl⟩ := h.equivII.surjective x + obtain ⟨y, rfl⟩ := h.equivII.surjective y + rw [← ancestralRel_iff] at hxy + simpa using f.lt hxy } + invFun g := + { rank x := g.rank (h.equivII x) + lt hxy := by + rw [ancestralRel_iff] at hxy + exact g.lt hxy } + left_inv _ := by simp + right_inv _ := by simp + +/-- Weak rank functions for `h : A.PairingCore` correspond to +weak rank functions for `h.pairing : A.Pairing`. -/ +noncomputable def weakRankFunctionEquiv : + h.WeakRankFunction α ≃ h.pairing.WeakRankFunction α where + toFun f := + { rank s := f.rank (h.equivII.symm s) + lt {x y} hxy := by + obtain ⟨x, rfl⟩ := h.equivII.surjective x + obtain ⟨y, rfl⟩ := h.equivII.surjective y + rw [← ancestralRel_iff] at hxy + simpa using f.lt hxy } invFun g := { rank x := g.rank (h.equivII x) - lt := by - sorry } - left_inv := sorry - right_inv := sorry + lt hxy := by + rw [ancestralRel_iff] at hxy + exact g.lt hxy } + left_inv _ := by simp + right_inv _ := by simp end PairingCore From 75af19d7ca7cb2472da4687d1c7670b95f97f7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 21:17:11 +0530 Subject: [PATCH 34/81] wip --- Mathlib.lean | 1 + .../SimplexCategory/Basic.lean | 4 + .../AnodyneExtensions/Pairing.lean | 5 + .../AnodyneExtensions/RankNat.lean | 99 +++++++++++++++++++ .../ConditionallyCompleteLattice/Finset.lean | 13 +++ 5 files changed, 122 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean diff --git a/Mathlib.lean b/Mathlib.lean index 20fa5272a12eb0..0c8a9526fd294d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1310,6 +1310,7 @@ import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.IsUniquelyCodim import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.PairingCore import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RankNat import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.SimplicialSet.Boundary import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations diff --git a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean index 7753fbe6ddee14..eeebe442dbb895 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory/Basic.lean @@ -26,6 +26,10 @@ open Simplicial CategoryTheory Limits namespace SimplexCategory +instance {a b : SimplexCategory} : Finite (a ⟶ b) := + Finite.of_injective (fun f ↦ f.toOrderHom.toFun) + (fun _ _ _ ↦ by aesop) + section Init lemma congr_toOrderHom_apply {a b : SimplexCategory} {f g : a ⟶ b} (h : f = g) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean index ff81f412e325bc..873ca74959815d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -73,6 +73,11 @@ lemma isUniquelyCodimOneFace [P.IsProper] (x : P.II) : S.IsUniquelyCodimOneFace x.1.toS (P.p x).1.toS := IsProper.isUniquelyCodimOneFace x +@[simp] +lemma dim_p [P.IsProper] (x : P.II) : + (P.p x).1.dim = x.1.dim + 1 := + (P.isUniquelyCodimOneFace x).dim_eq + /-- The condition that a pairing only involves inner horns. -/ class IsInner [P.IsProper] : Prop where ne_zero (x : P.II) {d : ℕ} (hd : x.1.dim = d) : diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean new file mode 100644 index 00000000000000..21c188fab64bef --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean @@ -0,0 +1,99 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank +import Mathlib.SetTheory.Ordinal.Rank + +/-! +# Existence of a rank function to natural numbers + +In this file, we show that if `P : A.Pairing` is +a regular pairing of subcomplex `A` of a simplicial set `X`, +then there exists a rank function for `P` with value in `ℕ`. + +-/ + +universe u + +open Ordinal Simplicial + +namespace SSet.Subcomplex.Pairing + +variable {X : SSet.{u}} {A : X.Subcomplex} (P : A.Pairing) + +instance (y : P.II) : Finite { x // P.AncestralRel x y } := by + let T := { x : P.II // P.AncestralRel x y } + let U := Σ (d : Fin ((P.p y).1.dim + 1)), ⦋d⦌ ⟶ ⦋(P.p y).1.1.1.1⦌ + let ψ : U → X.S := fun ⟨d, f⟩ ↦ S.mk (X.map f.op (P.p y).1.simplex) + have h (t : T) : ∃ u, ψ u = t.1.1.toS := by + obtain ⟨f, _, hf⟩ := N.le_iff_exists_mono.1 t.2.2.le + refine ⟨⟨⟨t.1.1.dim, ?_⟩, f⟩, ?_⟩ + · simpa only [Nat.lt_succ_iff] using SSet.N.dim_le_of_le t.2.2.le + · rwa [SSet.S.ext_iff] + choose φ hφ using h + apply Finite.of_injective φ + intro t₁ t₂ h + rw [Subtype.ext_iff, Subtype.ext_iff, N.ext_iff, SSet.N.ext_iff, ← hφ, ← hφ, h] + +section IsRegular + +variable [P.IsRegular] + +/-- The rank function with values in ordinals relative to the well founded +ancestrality relation of a regular pairing. -/ +noncomputable def rank' : + P.II → Ordinal.{u} := + IsWellFounded.rank P.AncestralRel + +lemma rank'_lt {x y : P.II} (h : P.AncestralRel x y) : + P.rank' x < P.rank' y := + IsWellFounded.rank_lt_of_rel h + +lemma rank'_lt_omega (x : P.II) : + P.rank' x < ω := by + induction x using IsWellFounded.induction P.AncestralRel with + | ind y hy => + dsimp only [rank'] at hy ⊢ + rw [IsWellFounded.rank_eq, ciSup_lt_iff_of_finite_of_bot_lt _ Ordinal.omega0_pos] + rintro x + have := hy _ x.2 + rw [Ordinal.lt_omega0] at this ⊢ + obtain ⟨n, hn⟩ := this + exact ⟨n + 1, by simp [hn]⟩ + +/-- The rank function with values in `ℕ` relative to the well founded +ancestrality relation of a regular pairing. -/ +noncomputable def rank (x : P.II) : ℕ := + (Ordinal.lt_omega0.1 (P.rank'_lt_omega x)).choose + +@[simp] +lemma coe_rank (x : P.II) : (P.rank x) = P.rank' x := + (Ordinal.lt_omega0.1 (P.rank'_lt_omega x)).choose_spec.symm + +variable {P} in +lemma rank_lt {x y : P.II} (h : P.AncestralRel x y) : + P.rank x < P.rank y := by + simpa only [← coe_rank, Nat.cast_lt] using P.rank'_lt h + +/-- The canonical rank function with values in `ℕ` of a regular pairing. -/ +noncomputable def rankFunction : P.RankFunction ℕ where + rank := P.rank + lt := P.rank_lt + +instance : Nonempty (P.RankFunction ℕ) := ⟨P.rankFunction⟩ + +instance : Nonempty (P.WeakRankFunction ℕ) := ⟨P.rankFunction.toWeakRankFunction⟩ + +end IsRegular + +lemma isRegular_iff_nonempty_rankFunction [P.IsProper] : + P.IsRegular ↔ Nonempty (P.RankFunction ℕ) := + ⟨fun _ ↦ inferInstance, fun ⟨h⟩ ↦ h.isRegular⟩ + +lemma isRegular_iff_nonempty_weakRankFunction [P.IsProper] : + P.IsRegular ↔ Nonempty (P.WeakRankFunction ℕ) := + ⟨fun _ ↦ inferInstance, fun ⟨h⟩ ↦ h.isRegular⟩ + +end SSet.Subcomplex.Pairing diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 235a96fa6b8b9a..0c3b8888b4474a 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -49,6 +49,19 @@ theorem Set.Finite.lt_csInf_iff (hs : s.Finite) (h : s.Nonempty) : a < sInf s variable (f : ι → α) +/-- In a conditionally complete linear order with `Bot`, +then the supremum of a finite family is `< x` +iff all the elements are `< x` (provided `⊥ < x`). -/ +lemma ciSup_lt_iff_of_finite_of_bot_lt + {ι α : Type*} [ConditionallyCompleteLinearOrderBot α] + [Finite ι] (f : ι → α) {x : α} (hx : ⊥ < x) : + ⨆ a, f a < x ↔ ∀ (a : ι), f a < x := by + dsimp [iSup] + by_cases hα : Nonempty ι + · simp [Set.Finite.csSup_lt_iff (Set.finite_range _) (Set.range_nonempty _)] + · rw [not_nonempty_iff] at hα + simpa [show Set.range f = ∅ by simpa] + theorem Finset.ciSup_eq_max'_image {s : Finset ι} (h : ∃ x ∈ s, sSup ∅ ≤ f x) (h' : (s.image f).Nonempty := by classical exact image_nonempty.mpr (h.imp fun _ ↦ And.left)) : ⨆ i ∈ s, f i = (s.image f).max' h' := by From dade326cd6d052fd769c3f473183b8e98530cb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 13 Aug 2025 21:55:43 +0530 Subject: [PATCH 35/81] little improvements --- .../AnodyneExtensions/RankNat.lean | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean index 21c188fab64bef..d5be4942df8d8c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean @@ -25,12 +25,12 @@ variable {X : SSet.{u}} {A : X.Subcomplex} (P : A.Pairing) instance (y : P.II) : Finite { x // P.AncestralRel x y } := by let T := { x : P.II // P.AncestralRel x y } - let U := Σ (d : Fin ((P.p y).1.dim + 1)), ⦋d⦌ ⟶ ⦋(P.p y).1.1.1.1⦌ + let U := Σ (d : Fin (P.p y).1.dim), ⦋d⦌ ⟶ ⦋(P.p y).1.1.1.1⦌ let ψ : U → X.S := fun ⟨d, f⟩ ↦ S.mk (X.map f.op (P.p y).1.simplex) have h (t : T) : ∃ u, ψ u = t.1.1.toS := by obtain ⟨f, _, hf⟩ := N.le_iff_exists_mono.1 t.2.2.le refine ⟨⟨⟨t.1.1.dim, ?_⟩, f⟩, ?_⟩ - · simpa only [Nat.lt_succ_iff] using SSet.N.dim_le_of_le t.2.2.le + · simpa using SSet.N.dim_lt_of_lt t.2.2 · rwa [SSet.S.ext_iff] choose φ hφ using h apply Finite.of_injective φ @@ -41,21 +41,10 @@ section IsRegular variable [P.IsRegular] -/-- The rank function with values in ordinals relative to the well founded -ancestrality relation of a regular pairing. -/ -noncomputable def rank' : - P.II → Ordinal.{u} := - IsWellFounded.rank P.AncestralRel - -lemma rank'_lt {x y : P.II} (h : P.AncestralRel x y) : - P.rank' x < P.rank' y := - IsWellFounded.rank_lt_of_rel h - -lemma rank'_lt_omega (x : P.II) : - P.rank' x < ω := by +lemma isWellFoundedRank_lt_omega (x : P.II) : + IsWellFounded.rank P.AncestralRel x < ω := by induction x using IsWellFounded.induction P.AncestralRel with | ind y hy => - dsimp only [rank'] at hy ⊢ rw [IsWellFounded.rank_eq, ciSup_lt_iff_of_finite_of_bot_lt _ Ordinal.omega0_pos] rintro x have := hy _ x.2 @@ -66,16 +55,16 @@ lemma rank'_lt_omega (x : P.II) : /-- The rank function with values in `ℕ` relative to the well founded ancestrality relation of a regular pairing. -/ noncomputable def rank (x : P.II) : ℕ := - (Ordinal.lt_omega0.1 (P.rank'_lt_omega x)).choose + (Ordinal.lt_omega0.1 (P.isWellFoundedRank_lt_omega x)).choose @[simp] -lemma coe_rank (x : P.II) : (P.rank x) = P.rank' x := - (Ordinal.lt_omega0.1 (P.rank'_lt_omega x)).choose_spec.symm +lemma coe_rank (x : P.II) : P.rank x = IsWellFounded.rank P.AncestralRel x := + (Ordinal.lt_omega0.1 (P.isWellFoundedRank_lt_omega x)).choose_spec.symm variable {P} in lemma rank_lt {x y : P.II} (h : P.AncestralRel x y) : P.rank x < P.rank y := by - simpa only [← coe_rank, Nat.cast_lt] using P.rank'_lt h + simpa [← coe_rank, Nat.cast_lt] using IsWellFounded.rank_lt_of_rel h /-- The canonical rank function with values in `ℕ` of a regular pairing. -/ noncomputable def rankFunction : P.RankFunction ℕ where From 7aeee279e44ea12d809c9e5d01f54db5cb56dec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 14 Aug 2025 08:46:56 +0530 Subject: [PATCH 36/81] removed imports to set theory --- .../AnodyneExtensions/RankNat.lean | 43 ++++++++++--------- .../ConditionallyCompleteLattice/Finset.lean | 13 ------ 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean index d5be4942df8d8c..fef9450bef19a1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank -import Mathlib.SetTheory.Ordinal.Rank /-! # Existence of a rank function to natural numbers @@ -17,7 +16,7 @@ then there exists a rank function for `P` with value in `ℕ`. universe u -open Ordinal Simplicial +open Simplicial namespace SSet.Subcomplex.Pairing @@ -37,34 +36,38 @@ instance (y : P.II) : Finite { x // P.AncestralRel x y } := by intro t₁ t₂ h rw [Subtype.ext_iff, Subtype.ext_iff, N.ext_iff, SSet.N.ext_iff, ← hφ, ← hφ, h] +section + +variable {y : P.II} (hy : Acc P.AncestralRel y) + +noncomputable def rank' : ℕ := + Acc.recOn hy (fun y _ r ↦ ⨆ (x : { x // P.AncestralRel x y }), r x x.2 + 1) + +lemma rank'_eq : + P.rank' hy = ⨆ (x : { x // P.AncestralRel x y }), P.rank' (hy.inv x.2) + 1 := by + change P.rank' (Acc.intro y fun _ => hy.inv) = _ + rfl + +lemma rank'_lt {x : P.II} (r : P.AncestralRel x y) : + P.rank' (hy.inv r) < P.rank' hy := by + rw [P.rank'_eq hy, ← Nat.add_one_le_iff] + exact le_csSup (Finite.bddAbove_range _) ⟨⟨x, r⟩, rfl⟩ + +end + section IsRegular variable [P.IsRegular] -lemma isWellFoundedRank_lt_omega (x : P.II) : - IsWellFounded.rank P.AncestralRel x < ω := by - induction x using IsWellFounded.induction P.AncestralRel with - | ind y hy => - rw [IsWellFounded.rank_eq, ciSup_lt_iff_of_finite_of_bot_lt _ Ordinal.omega0_pos] - rintro x - have := hy _ x.2 - rw [Ordinal.lt_omega0] at this ⊢ - obtain ⟨n, hn⟩ := this - exact ⟨n + 1, by simp [hn]⟩ - /-- The rank function with values in `ℕ` relative to the well founded ancestrality relation of a regular pairing. -/ noncomputable def rank (x : P.II) : ℕ := - (Ordinal.lt_omega0.1 (P.isWellFoundedRank_lt_omega x)).choose - -@[simp] -lemma coe_rank (x : P.II) : P.rank x = IsWellFounded.rank P.AncestralRel x := - (Ordinal.lt_omega0.1 (P.isWellFoundedRank_lt_omega x)).choose_spec.symm + P.rank' (P.wf.apply x) variable {P} in lemma rank_lt {x y : P.II} (h : P.AncestralRel x y) : - P.rank x < P.rank y := by - simpa [← coe_rank, Nat.cast_lt] using IsWellFounded.rank_lt_of_rel h + P.rank x < P.rank y := + P.rank'_lt _ h /-- The canonical rank function with values in `ℕ` of a regular pairing. -/ noncomputable def rankFunction : P.RankFunction ℕ where diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean index 0c3b8888b4474a..235a96fa6b8b9a 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Finset.lean @@ -49,19 +49,6 @@ theorem Set.Finite.lt_csInf_iff (hs : s.Finite) (h : s.Nonempty) : a < sInf s variable (f : ι → α) -/-- In a conditionally complete linear order with `Bot`, -then the supremum of a finite family is `< x` -iff all the elements are `< x` (provided `⊥ < x`). -/ -lemma ciSup_lt_iff_of_finite_of_bot_lt - {ι α : Type*} [ConditionallyCompleteLinearOrderBot α] - [Finite ι] (f : ι → α) {x : α} (hx : ⊥ < x) : - ⨆ a, f a < x ↔ ∀ (a : ι), f a < x := by - dsimp [iSup] - by_cases hα : Nonempty ι - · simp [Set.Finite.csSup_lt_iff (Set.finite_range _) (Set.range_nonempty _)] - · rw [not_nonempty_iff] at hα - simpa [show Set.range f = ∅ by simpa] - theorem Finset.ciSup_eq_max'_image {s : Finset ι} (h : ∃ x ∈ s, sSup ∅ ≤ f x) (h' : (s.image f).Nonempty := by classical exact image_nonempty.mpr (h.imp fun _ ↦ And.left)) : ⨆ i ∈ s, f i = (s.image f).max' h' := by From ee65af9ad12346942aa319d2ebcc7cd51edf705b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 15 Aug 2025 14:32:59 +0530 Subject: [PATCH 37/81] wip --- Mathlib.lean | 1 + .../RelativeCellComplex.lean | 125 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4ec885f0b9af5a..d921fa7105b315 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1316,6 +1316,7 @@ import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.PairingCore import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RankNat +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RelativeCellComplex import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.SimplicialSet.Boundary import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean new file mode 100644 index 00000000000000..8840b47ab8ec4d --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -0,0 +1,125 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +import Mathlib.AlgebraicTopology.RelativeCellComplex.Basic +import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank +import Mathlib.AlgebraicTopology.SimplicialSet.Horn + +/-! +# The relative cell complex attached to a rank function for a pairing + +-/ + +universe v u + +open CategoryTheory HomotopicalAlgebra Simplicial + +namespace SSet.Subcomplex.Pairing + +variable {X : SSet.{u}} {A : X.Subcomplex} {P : A.Pairing} + + +namespace RankFunction + +variable [P.IsProper] {ι : Type v} [LinearOrder ι] (f : P.RankFunction ι) + +def Cells (i : ι) : Type u := { s : P.II // f.rank s = i } + +namespace Cells + +variable {f} {i : ι} (c : f.Cells i) + +abbrev dim : ℕ := c.1.1.dim + +noncomputable def index : Fin (c.dim + 2) := + (P.isUniquelyCodimOneFace c.1).index rfl + +protected noncomputable def horn : + (Δ[c.dim + 1] : SSet.{u}).Subcomplex := + SSet.horn _ c.index + +abbrev cast : A.N := (P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq + +abbrev simplex : X _⦋c.dim + 1⦌ := c.cast.simplex + +end Cells + +noncomputable abbrev basicCell (i : ι) (c : f.Cells i) := c.horn.ι + +def filtration (i : ι) : X.Subcomplex := + A ⊔ ⨆ (j : ι) (_ : j < i) (c : f.Cells j), .ofSimplex c.simplex + +lemma simplex_le_filtration {j : ι} (c : f.Cells j) {i : ι} (h : j < i) : + Subcomplex.ofSimplex c.simplex ≤ f.filtration i := by + refine le_trans ?_ le_sup_right + refine le_trans ?_ (le_iSup _ j) + refine le_trans ?_ (le_iSup _ h) + exact le_trans (by rfl) (le_iSup _ c) + +@[simp] +lemma le_filtration (i : ι) : A ≤ f.filtration i := le_sup_left + +lemma filtration_bot [OrderBot ι] : f.filtration ⊥ = A := by + simp [filtration] + +lemma monotone_filtration : Monotone f.filtration := by + intro i₁ i₂ h + rw [filtration] + simp only [sup_le_iff, iSup_le_iff, le_filtration, true_and] + intro j hj c + exact f.simplex_le_filtration c (lt_of_lt_of_le hj h) + +lemma filtration_succ [SuccOrder ι] (i : ι) (hi : ¬ IsMax i) : + f.filtration (Order.succ i) = + f.filtration i ⊔ ⨆ (c : f.Cells i), .ofSimplex c.simplex := by + apply le_antisymm + · rw [filtration] + simp only [sup_le_iff, iSup_le_iff] + refine ⟨(f.le_filtration _).trans le_sup_left, fun j hj c ↦ ?_⟩ + rw [Order.lt_succ_iff_of_not_isMax hi] at hj + obtain hj | rfl := hj.lt_or_eq + · exact (f.simplex_le_filtration _ hj).trans le_sup_left + · exact le_trans (le_trans (by rfl) (le_iSup _ c)) le_sup_right + · simp only [sup_le_iff, iSup_le_iff] + exact ⟨f.monotone_filtration (Order.le_succ i), + fun c ↦ f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hi)⟩ + +lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] + (i : ι) (hi : Order.IsSuccLimit i) : + f.filtration i = ⨆ (j : ι) (_ : j < i), f.filtration j := by + apply le_antisymm + · rw [filtration] + simp only [sup_le_iff, iSup_le_iff] + constructor + · refine le_trans ?_ (le_iSup _ ⊥) + exact le_trans (by simp) (le_iSup _ hi.bot_lt) + · intro j hj c + refine le_trans ?_ (le_iSup _ (Order.succ j)) + refine le_trans ?_ (le_iSup _ + (by rwa [← Order.IsSuccLimit.succ_lt_iff hi] at hj)) + exact f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hj.not_isMax) + · simp only [iSup_le_iff] + intro j hj + exact f.monotone_filtration hj.le + +lemma iSup_filtration : + ⨆ (i : ι), f.filtration i = ⊤ := + le_antisymm le_top (by + sorry) + +variable [OrderBot ι] [SuccOrder ι] [WellFoundedLT ι] + +noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι where + F := f.monotone_filtration.functor ⋙ by + sorry + isoBot := sorry + isColimit := sorry + isWellOrderContinuous := sorry + incl := sorry + attachCells := sorry + +end RankFunction + +end SSet.Subcomplex.Pairing From 4b4be15edceacdd030416e60a9449fcf65f6f10a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 15 Aug 2025 14:39:55 +0530 Subject: [PATCH 38/81] fix --- .../AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean index 2ed5964ee8d09f..e26633f10e84f6 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean @@ -95,6 +95,7 @@ lemma isRegular : P.IsRegular where end WeakRankFunction +/-- The weak rank function attached to a rank function. -/ @[simps] def RankFunction.toWeakRankFunction (f : P.RankFunction α) : P.WeakRankFunction α where From a1ff860f971c6c4d0db07f4fac8b7022de2c07bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 15 Aug 2025 14:42:06 +0530 Subject: [PATCH 39/81] fix --- .../SimplicialSet/AnodyneExtensions/RankNat.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean index fef9450bef19a1..2854c25c6919df 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean @@ -40,6 +40,7 @@ section variable {y : P.II} (hy : Acc P.AncestralRel y) +/-- Auxiliary definition for `SSet.Subcomplex.Pairing.Rank`. -/ noncomputable def rank' : ℕ := Acc.recOn hy (fun y _ r ↦ ⨆ (x : { x // P.AncestralRel x y }), r x x.2 + 1) From c1e3f588e41a92daf86eb49ef205e3b4253b9518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 29 Sep 2025 20:12:55 +0200 Subject: [PATCH 40/81] better syntax --- .../SimplicialSet/NonDegenerateSimplices.lean | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index e1d37f6e49c2f0..63052421e18499 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -38,12 +38,12 @@ variable {X} /-- Constructor in order to promote a simplex `s : X.S` into a term in `X.N`. -/ @[simps toS] -def mk' (s : X.S) (hs : s.2 ∈ X.nonDegenerate _) : X.N where +def mk' (s : X.S) (hs : s.simplex ∈ X.nonDegenerate _) : X.N where toS := s nonDegenerate := hs lemma mk'_surjective (s : X.N) : - ∃ (t : X.S) (ht : t.2 ∈ X.nonDegenerate _), s = mk' t ht := + ∃ (t : X.S) (ht : t.simplex ∈ X.nonDegenerate _), s = mk' t ht := ⟨s.toS, s.nonDegenerate, rfl⟩ /-- Constructor for the type of non degenerate simplices of a simplicial set. -/ @@ -53,8 +53,8 @@ def mk {n : ℕ} (x : X _⦋n⦌) (hx : x ∈ X.nonDegenerate n) : X.N where nonDegenerate := hx lemma mk_surjective (x : X.N) : - ∃ (n : ℕ) (y : X.nonDegenerate n), x = N.mk _ y.2 := - ⟨x.1.1, ⟨_, x.nonDegenerate⟩, rfl⟩ + ∃ (n : ℕ) (y : X.nonDegenerate n), x = N.mk _ y.prop := + ⟨x.dim, ⟨_, x.nonDegenerate⟩, rfl⟩ instance : Preorder X.N := Preorder.lift toS @@ -62,10 +62,10 @@ lemma le_iff {x y : X.N} : x ≤ y ↔ x.subcomplex ≤ y.subcomplex := Iff.rfl lemma le_iff_exists_mono {x y : X.N} : - x ≤ y ↔ ∃ (f : ⦋x.1.1⦌ ⟶ ⦋y.1.1⦌) (_ : Mono f), X.map f.op y.1.2 = x.1.2 := by + x ≤ y ↔ ∃ (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌) (_ : Mono f), X.map f.op y.simplex = x.simplex := by simp only [le_iff, CategoryTheory.Subpresheaf.ofSection_le_iff, Subcomplex.mem_ofSimplex_obj_iff] - exact ⟨fun ⟨f, hf⟩ ↦ ⟨f, X.mono_of_nonDegenerate ⟨_, x.2⟩ f _ hf, hf⟩, by tauto⟩ + exact ⟨fun ⟨f, hf⟩ ↦ ⟨f, X.mono_of_nonDegenerate ⟨_, x.nonDegenerate⟩ f _ hf, hf⟩, by tauto⟩ lemma dim_le_of_le {x y : X.N} (h : x ≤ y) : x.dim ≤ y.dim := by rw [le_iff_exists_mono] at h @@ -149,7 +149,7 @@ lemma existsUnique_n (x : X.S) : ∃! (y : X.N), y.subcomplex = x.subcomplex := existsUnique_of_exists_of_unique (by obtain ⟨n, x, hx, rfl⟩ := x.mk_surjective obtain ⟨m, f, _, y, rfl⟩ := X.exists_nonDegenerate x - refine ⟨N.mk y.1 y.2, le_antisymm ?_ ?_⟩ + refine ⟨N.mk _ y.prop, le_antisymm ?_ ?_⟩ · simp only [Subcomplex.ofSimplex_le_iff] have := isSplitEpi_of_epi f have : Function.Injective (X.map f.op) := by From 8c52040091586e717ef2b7779ec9e54639e81daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 8 Oct 2025 19:27:12 +0200 Subject: [PATCH 41/81] suggestions by dagurtomas --- .../SimplicialSet/NonDegenerateSimplices.lean | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index 63052421e18499..97a196b32c729e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -28,20 +28,13 @@ namespace SSet variable (X : SSet.{u}) /-- The type of non degenerate simplices of a simplicial set. -/ -structure N extends X.S where mk'' :: +structure N extends X.S where mk' :: nonDegenerate : simplex ∈ X.nonDegenerate _ namespace N variable {X} -/-- Constructor in order to promote a simplex `s : X.S` into -a term in `X.N`. -/ -@[simps toS] -def mk' (s : X.S) (hs : s.simplex ∈ X.nonDegenerate _) : X.N where - toS := s - nonDegenerate := hs - lemma mk'_surjective (s : X.N) : ∃ (t : X.S) (ht : t.simplex ∈ X.nonDegenerate _), s = mk' t ht := ⟨s.toS, s.nonDegenerate, rfl⟩ @@ -75,8 +68,7 @@ lemma dim_le_of_le {x y : X.N} (h : x ≤ y) : x.dim ≤ y.dim := by lemma dim_lt_of_lt {x y : X.N} (h : x < y) : x.dim < y.dim := by obtain h' | h' := (dim_le_of_le h.le).lt_or_eq · exact h' - · exfalso - obtain ⟨f, _, hf⟩ := le_iff_exists_mono.1 h.le + · obtain ⟨f, _, hf⟩ := le_iff_exists_mono.1 h.le obtain ⟨d, ⟨x, hx⟩, rfl⟩ := x.mk_surjective obtain ⟨d', ⟨y, hy⟩, rfl⟩ := y.mk_surjective obtain rfl : d = d' := h' From 31c6dfc9e9e6d26b5f2c5613f57e6294d7d9e5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 9 Oct 2025 15:44:54 +0200 Subject: [PATCH 42/81] typos --- .../SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean | 2 +- .../SimplicialSet/AnodyneExtensions/Pairing.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean index 2fce96c3de40a4..4cfd55ee238523 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean @@ -9,7 +9,7 @@ import Mathlib.AlgebraicTopology.SimplicialSet.Simplices # Simplices that are uniquely codimensional one faces Let `X` be a simplicial set. If `x : X _⦋d⦌` and `y : X _⦋d + 1⦌`, -we say that `x` is uniquely `1`-codimensional face of `y` if there +we say that `x` is uniquely a `1`-codimensional face of `y` if there exists a unique `i : Fin (d + 2)` such that `X.δ i y = x`. In this file, we extend this to a predicate `IsUniquelyCodimOneFace` involving two terms in the type `X.S` of simplices of `X`. This is used in the diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean index 7f97db6f559544..a23477aadec43a 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -21,7 +21,7 @@ A pairing for `A` consists in the data of a partition of the nondegenerate simplices of `X` not in `A` into type (I) simplices and type (II) simplices, and of a bijection between the types of type (I) and type (II) simplices. Indeed, the main observation is that when we attach a simplex along a horn -inclusions, exactly two nondegenerate simplices are added: this simplex, +inclusion, exactly two nondegenerate simplices are added: this simplex, and the unique face which is not in the image of the horn. The former shall be considered as of type (I) and the latter as type (II). From aea81178b21a5f8a34634d12e4fa1893c4651210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 9 Oct 2025 15:49:30 +0200 Subject: [PATCH 43/81] typo --- .../SimplicialSet/AnodyneExtensions/PairingCore.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean index 4915f4449ea489..c63e1698306b96 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean @@ -51,7 +51,7 @@ structure PairingCore where variable {A} /-- The `PairingCore` structure induced by a pairing. The opposite construction -if `PairingCore.pairing`. -/ +is `PairingCore.pairing`. -/ noncomputable def Pairing.pairingCore (P : A.Pairing) [P.IsProper] : A.PairingCore where ι := P.II From b5b607ff87e9b6e0a4581e7ffb21a11e91d4ce23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 9 Oct 2025 15:53:27 +0200 Subject: [PATCH 44/81] fixed references.bib --- docs/references.bib | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/references.bib b/docs/references.bib index 2ad5c1bf736319..2357f11806d66a 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -3381,7 +3381,6 @@ @Article{ morrison-penney-enriched eprint = {https://academic.oup.com/imrn/article-pdf/2019/11/3527/28757603/rnx217.pdf} } - @Article{ moss-2020, author = {Moss, Sean}, title = {Another approach to the {K}an-{Q}uillen model structure}, @@ -3398,7 +3397,6 @@ @Article{ moss-2020 url = {https://doi.org/10.1007/s40062-019-00247-y} } - @Article{ MR0236876, title = {A new proof that metric spaces are paracompact}, author = {Mary Ellen Rudin}, From 0f96e03db25f4480e1e127753c80c6c08f196a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 9 Oct 2025 22:39:51 +0200 Subject: [PATCH 45/81] fix --- .../SimplicialSet/AnodyneExtensions/PairingCore.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean index c63e1698306b96..b354a005bf8881 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/PairingCore.lean @@ -217,9 +217,9 @@ class IsRegular (h : A.PairingCore) extends h.IsProper where instance [h.IsRegular] : h.pairing.IsRegular where wf := by have := IsRegular.wf h - rw [WellFounded.wellFounded_iff_no_descending_seq, isEmpty_iff] at this ⊢ - rintro ⟨f, hf⟩ - exact this ⟨fun n ↦ h.equivII.symm (f n), fun n ↦ by simpa [ancestralRel_iff] using hf n⟩ + rw [wellFounded_iff_isEmpty_descending_chain] at this ⊢ + exact ⟨fun ⟨f, hf⟩ ↦ this.false + ⟨fun n ↦ h.equivII.symm (f n), fun n ↦ by simpa [ancestralRel_iff] using hf n⟩⟩ end PairingCore From 2e11888d646b5974cfe3487c3d416a8c78c24e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 9 Oct 2025 22:42:01 +0200 Subject: [PATCH 46/81] fix --- .../SimplicialSet/AnodyneExtensions/Rank.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean index e26633f10e84f6..d3b6b44ffcaa60 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Rank.lean @@ -54,7 +54,7 @@ variable {P α} [WellFoundedLT α] (f : P.RankFunction α) include f lemma wf_ancestralRel : WellFounded P.AncestralRel := by - rw [WellFounded.wellFounded_iff_no_descending_seq] + rw [wellFounded_iff_isEmpty_descending_chain] exact ⟨fun ⟨g, hg⟩ ↦ not_strictAnti_of_wellFoundedLT (f.rank ∘ g) (strictAnti_nat_of_succ_lt (fun n ↦ f.lt (hg n)))⟩ @@ -78,7 +78,7 @@ variable {P α} [WellFoundedLT α] [P.IsProper] (f : P.WeakRankFunction α) include f lemma wf_ancestralRel : WellFounded P.AncestralRel := by - rw [WellFounded.wellFounded_iff_no_descending_seq] + rw [wellFounded_iff_isEmpty_descending_chain] refine ⟨fun ⟨g, hg⟩ ↦ ?_⟩ obtain ⟨n₀, hn₀⟩ := (wellFoundedGT_iff_monotone_chain_condition (α := ℕᵒᵈ)).1 From 4beab6cfd7d665cd9cbd38fd89cfa6a1a3c67e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 9 Oct 2025 22:45:51 +0200 Subject: [PATCH 47/81] fix --- .../SimplicialSet/AnodyneExtensions/RankNat.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean index 2854c25c6919df..24ce9c31a3ad20 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank +import Mathlib.Data.Finite.Sigma /-! # Existence of a rank function to natural numbers From 8daa67c1435c4fd32ad78ca90db99887b23f3c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 22 Oct 2025 14:58:07 +0200 Subject: [PATCH 48/81] wip --- .../RelativeCellComplex.lean | 10 ++--- .../SimplicialSet/Subcomplex.lean | 40 +++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 8840b47ab8ec4d..5b8ceb9f52c205 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -14,13 +14,12 @@ import Mathlib.AlgebraicTopology.SimplicialSet.Horn universe v u -open CategoryTheory HomotopicalAlgebra Simplicial +open CategoryTheory HomotopicalAlgebra Simplicial Limits namespace SSet.Subcomplex.Pairing variable {X : SSet.{u}} {A : X.Subcomplex} {P : A.Pairing} - namespace RankFunction variable [P.IsProper] {ι : Type v} [LinearOrder ι] (f : P.RankFunction ι) @@ -112,12 +111,11 @@ lemma iSup_filtration : variable [OrderBot ι] [SuccOrder ι] [WellFoundedLT ι] noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι where - F := f.monotone_filtration.functor ⋙ by - sorry - isoBot := sorry + F := f.monotone_filtration.functor ⋙ Subcomplex.toSSetFunctor + isoBot := Subcomplex.isoOfEq (filtration_bot _) isColimit := sorry isWellOrderContinuous := sorry - incl := sorry + incl.app i := (f.filtration i).ι attachCells := sorry end RankFunction diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean index 1bc04a7a573d2a..ce3efffbf6375c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean @@ -63,6 +63,46 @@ abbrev ι (A : Subcomplex X) : Quiver.Hom (V := SSet) A X := Subpresheaf.ι A instance (A : X.Subcomplex) : Mono A.ι := inferInstanceAs (Mono (Subpresheaf.ι A)) +section + +variable {S₁ S₂ : X.Subcomplex} (h : S₁ ≤ S₂) + +/-- Given an inequality `S₁ ≤ S₂` between subcomplexes of a simplicial set, +this is the induced morphism in the category `SSet`. -/ +abbrev homOfLE : (S₁ : SSet.{u}) ⟶ (S₂ : SSet.{u}) := Subpresheaf.homOfLe h + +@[reassoc] +lemma homOfLE_comp {S₃ : X.Subcomplex} (h' : S₂ ≤ S₃) : + homOfLE h ≫ homOfLE h' = homOfLE (h.trans h') := rfl + +variable (S₁) in +@[simp] +lemma homOfLE_refl : homOfLE (by rfl : S₁ ≤ S₁) = 𝟙 _ := rfl + +@[simp] +lemma homOfLE_app_val (Δ : SimplexCategoryᵒᵖ) (x : S₁.obj Δ) : + ((homOfLE h).app Δ x).val = x.val := rfl + +@[reassoc (attr := simp)] +lemma homOfLE_ι : homOfLE h ≫ S₂.ι = S₁.ι := rfl + +instance mono_homOfLE : Mono (homOfLE h) := mono_of_mono_fac (homOfLE_ι h) + +/-- This is the isomorphism of simplicial sets corresponding to +an equality of subcomplexes. -/ +@[simps] +def isoOfEq (h : S₁ = S₂) : (S₁ : SSet.{u}) ≅ S₂ where + hom := homOfLE h.le + inv := homOfLE h.symm.le + +end + +/-- The functor which sends `A : X.Subcomplex` to `A.toSSet`. -/ +@[simps] +def toSSetFunctor : X.Subcomplex ⥤ SSet.{u} where + obj A := A + map h := homOfLE (leOfHom h) + /-- The subcomplex of a simplicial set that is generated by a simplex. -/ abbrev ofSimplex {n : ℕ} (x : X _⦋n⦌) : X.Subcomplex := Subpresheaf.ofSection x From 2f2ee29720c020df3a087679a387f747e6785892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 22 Oct 2025 16:26:50 +0200 Subject: [PATCH 49/81] wip --- .../RelativeCellComplex.lean | 86 +++++++++++++++++-- .../SimplicialSet/Subcomplex.lean | 32 +++++++ 2 files changed, 113 insertions(+), 5 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 5b8ceb9f52c205..e785a92ef385cd 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -43,6 +43,10 @@ abbrev cast : A.N := (P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq abbrev simplex : X _⦋c.dim + 1⦌ := c.cast.simplex +abbrev map {j : ι} (c : f.Cells j) : + Δ[c.dim + 1] ⟶ X := + yonedaEquiv.symm c.simplex + end Cells noncomputable abbrev basicCell (i : ι) (c : f.Cells i) := c.horn.ι @@ -103,12 +107,73 @@ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] intro j hj exact f.monotone_filtration hj.le -lemma iSup_filtration : - ⨆ (i : ι), f.filtration i = ⊤ := - le_antisymm le_top (by +lemma filtration_le_iSup (i : ι) : + f.filtration i ≤ ⨆ (i : ι), f.filtration i := + le_iSup _ i + +lemma iSup_filtration [OrderBot ι] : + ⨆ (i : ι), f.filtration i = ⊤ := by + let B := ⨆ (i : ι), f.filtration i + suffices ∀ (s : A.N), s.simplex ∈ B.obj _ by + rw [eq_top_iff_contains_nonDegenerate] + intro n s hs + by_cases hs₀ : s ∈ A.obj _ + · exact f.filtration_le_iSup ⊥ _ (by rwa [filtration_bot]) + · exact this (N.mk _ hs hs₀) + intro s + obtain ⟨y, (rfl | rfl)⟩ := P.exists_or s + · sorry + · sorry + +def Cells.mapToSucc {j : ι} [SuccOrder ι] (c : f.Cells j) : + Δ[c.dim + 1] ⟶ f.filtration (Order.succ j) := + Subcomplex.lift c.map (by sorry) -variable [OrderBot ι] [SuccOrder ι] [WellFoundedLT ι] +@[reassoc (attr := simp)] +lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] (c : f.Cells j) : + c.mapToSucc ≫ (f.filtration (Order.succ j)).ι = c.map := + rfl + +section + +noncomputable abbrev sigmaHorn (j : ι) := ∐ (fun (c : f.Cells j) ↦ (c.horn : SSet)) + +noncomputable abbrev Cells.ιSigmaHorn {j : ι} (c : f.Cells j) : + (c.horn : SSet) ⟶ f.sigmaHorn j := + Sigma.ι (fun (c : f.Cells j) ↦ (c.horn : SSet)) c + +noncomputable abbrev sigmaStdSimplex (j : ι) := ∐ (fun (i : f.Cells j) ↦ Δ[i.dim + 1]) + +noncomputable abbrev Cells.ιSigmaStdSimplex {j : ι} (c : f.Cells j) : + Δ[c.dim + 1] ⟶ f.sigmaStdSimplex j := + Sigma.ι (fun (c : f.Cells j) ↦ Δ[c.dim + 1]) c + +noncomputable def m (j : ι) : f.sigmaHorn j ⟶ f.sigmaStdSimplex j := + Limits.Sigma.map (basicCell _ _) + +@[reassoc (attr := simp)] +lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : + c.ιSigmaHorn ≫ f.m j = c.horn.ι ≫ c.ιSigmaStdSimplex:= by + simp [m] + +noncomputable def t (j : ι) : f.sigmaHorn j ⟶ f.filtration j := + sorry + +variable [SuccOrder ι] + +noncomputable def b (j : ι) : + f.sigmaStdSimplex j ⟶ f.filtration (Order.succ j) := + Sigma.desc (fun c ↦ c.mapToSucc) + +lemma isPushout (j : ι) (hj : ¬ IsMax j) : + IsPushout (f.t j) (f.m j) + (homOfLE (f.monotone_filtration (Order.le_succ j))) (f.b j) := by + sorry + +end + +variable [SuccOrder ι] [OrderBot ι] [WellFoundedLT ι] noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι where F := f.monotone_filtration.functor ⋙ Subcomplex.toSSetFunctor @@ -116,7 +181,18 @@ noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι whe isColimit := sorry isWellOrderContinuous := sorry incl.app i := (f.filtration i).ι - attachCells := sorry + attachCells j hj := + { ι := f.Cells j + π := id + cofan₁ := _ + cofan₂ := _ + isColimit₁ := colimit.isColimit _ + isColimit₂ := colimit.isColimit _ + m := f.m j + hm c := c.ιSigmaHorn_m + g₁ := f.t j + g₂ := f.b j + isPushout := f.isPushout j hj } end RankFunction diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean index ce3efffbf6375c..875e4f2dfbabb0 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean @@ -147,6 +147,38 @@ instance [Mono f] : IsIso (toRange f) := end +section + +variable (X) + +@[simps! inv_app_coe] +def topIso : ((⊤ : X.Subcomplex) : SSet) ≅ X := + NatIso.ofComponents (fun n ↦ (Equiv.Set.univ (X.obj n)).toIso) + +@[simp] +lemma topIso_hom : (topIso X).hom = Subcomplex.ι _ := rfl + +@[reassoc (attr := simp)] +lemma topIso_inv_ι : (topIso X).inv ≫ Subpresheaf.ι _ = 𝟙 _ := rfl + +end + +section + +variable (f : X ⟶ Y) {B : Y.Subcomplex} (hf : B.preimage f = ⊤) + +def lift : X ⟶ B := + (topIso X).inv ≫ homOfLE (by simp [hf]) ≫ B.fromPreimage f + +@[reassoc (attr := simp)] +lemma lift_ι : lift f hf ≫ B.ι = f := rfl + +@[simp] +lemma lift_app_coe {n : SimplexCategoryᵒᵖ} (x : X.obj n) : + ((lift f hf).app _ x).1 = f.app _ x := rfl + +end + end Subcomplex end SSet From 497de492f5be1844c10ad41a3763ea1df94d30d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 19 Nov 2025 22:19:10 +0100 Subject: [PATCH 50/81] fix --- .../SimplicialSet/AnodyneExtensions/RankNat.lean | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean index 24ce9c31a3ad20..806e741fbe8798 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RankNat.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ -import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank -import Mathlib.Data.Finite.Sigma +module + +public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank +public import Mathlib.Data.Finite.Sigma /-! # Existence of a rank function to natural numbers @@ -15,6 +17,8 @@ then there exists a rank function for `P` with value in `ℕ`. -/ +@[expose] public section + universe u open Simplicial From 82c35495b9ccc9d9c522d1bf84efb1e0b55666cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 20 Nov 2025 07:53:42 +0100 Subject: [PATCH 51/81] wip --- .../IsUniquelyCodimOneFace.lean | 8 +++ .../RelativeCellComplex.lean | 68 ++++++++++++++----- .../SimplicialSet/Simplices.lean | 5 ++ .../SimplicialSet/StdSimplex.lean | 4 +- .../SimplicialSet/Subcomplex.lean | 6 ++ 5 files changed, 73 insertions(+), 18 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean index cf1ac27c488739..ef43f657d3dcb4 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean @@ -86,6 +86,14 @@ lemma δ_eq_iff (i : Fin (d + 2)) : ⟨fun h ↦ (hxy.existsUnique_δ_cast_simplex hd).unique h (hxy.δ_index hd), by rintro rfl; apply δ_index⟩ +include hxy in +lemma le : x ≤ y := by + have := hxy.δ_index rfl + simp only [cast_simplex_rfl] at this + rw [S.le_def, ← y.subcomplex_cast hxy.dim_eq, Subpresheaf.ofSection_le_iff, + ← this] + exact ⟨(SimplexCategory.δ _).op, rfl⟩ + end end IsUniquelyCodimOneFace diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index e785a92ef385cd..d0d41692840fdc 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -111,7 +111,7 @@ lemma filtration_le_iSup (i : ι) : f.filtration i ≤ ⨆ (i : ι), f.filtration i := le_iSup _ i -lemma iSup_filtration [OrderBot ι] : +lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : ⨆ (i : ι), f.filtration i = ⊤ := by let B := ⨆ (i : ι), f.filtration i suffices ∀ (s : A.N), s.simplex ∈ B.obj _ by @@ -120,18 +120,26 @@ lemma iSup_filtration [OrderBot ι] : by_cases hs₀ : s ∈ A.obj _ · exact f.filtration_le_iSup ⊥ _ (by rwa [filtration_bot]) · exact this (N.mk _ hs hs₀) - intro s - obtain ⟨y, (rfl | rfl)⟩ := P.exists_or s - · sorry - · sorry - -def Cells.mapToSucc {j : ι} [SuccOrder ι] (c : f.Cells j) : + suffices ∀ (y : P.II), ofSimplex (P.p y).1.simplex ≤ B by + intro s + obtain ⟨y, (rfl | rfl)⟩ := P.exists_or s + · rw [← Subcomplex.ofSimplex_le_iff] + refine ((S.le_def ..).1 (P.isUniquelyCodimOneFace y).le).trans (this y) + · rw [← Subcomplex.ofSimplex_le_iff] + exact this y + intro y + exact le_trans (by simp [Cells.simplex]) + ((f.simplex_le_filtration ⟨y, rfl⟩ (Order.lt_succ (f.rank y))).trans + (f.filtration_le_iSup _)) + +def Cells.mapToSucc {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.filtration (Order.succ j) := Subcomplex.lift c.map (by - sorry) + rw [range_eq_ofSimplex, Cells.map, Equiv.apply_symm_apply] + exact f.simplex_le_filtration c (Order.lt_succ _)) @[reassoc (attr := simp)] -lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] (c : f.Cells j) : +lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) : c.mapToSucc ≫ (f.filtration (Order.succ j)).ι = c.map := rfl @@ -154,30 +162,58 @@ noncomputable def m (j : ι) : f.sigmaHorn j ⟶ f.sigmaStdSimplex j := @[reassoc (attr := simp)] lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : - c.ιSigmaHorn ≫ f.m j = c.horn.ι ≫ c.ιSigmaStdSimplex:= by + c.ιSigmaHorn ≫ f.m j = c.horn.ι ≫ c.ιSigmaStdSimplex := by simp [m] +@[simp] +lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : + (f.filtration j).preimage c.map = c.horn := sorry + +def Cells.mapHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.filtration j := + Subcomplex.lift (c.horn.ι ≫ c.map) (by + simp [← image_top, image_le_iff, preimage_comp, c.preimage_filtration_map]) + +@[reassoc (attr := simp)] +lemma Cells.mapHorn_ι {j : ι} (c : f.Cells j) : + c.mapHorn ≫ (f.filtration j).ι = c.horn.ι ≫ c.map := rfl + noncomputable def t (j : ι) : f.sigmaHorn j ⟶ f.filtration j := - sorry + Limits.Sigma.desc (fun c ↦ c.mapHorn) -variable [SuccOrder ι] +@[reassoc (attr := simp)] +lemma Cells.ιSigmaHorn_t {j : ι} (c : f.Cells j) : + c.ιSigmaHorn ≫ f.t j = c.mapHorn:= by + simp [t] + +variable [SuccOrder ι] [NoMaxOrder ι] noncomputable def b (j : ι) : f.sigmaStdSimplex j ⟶ f.filtration (Order.succ j) := Sigma.desc (fun c ↦ c.mapToSucc) +@[reassoc (attr := simp)] +lemma ι_b {j : ι} (c : f.Cells j) : + c.ιSigmaStdSimplex ≫ f.b j = c.mapToSucc := by simp [b] + +@[reassoc] +lemma w (j : ι) : + f.t j ≫ homOfLE (f.monotone_filtration (Order.le_succ j)) = f.m j ≫ f.b j := by + ext c : 1 + simp [← cancel_mono (Subcomplex.ι _)] + lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) - (homOfLE (f.monotone_filtration (Order.le_succ j))) (f.b j) := by - sorry + (homOfLE (f.monotone_filtration (Order.le_succ j))) (f.b j) where + w := f.w j + isColimit' := sorry end -variable [SuccOrder ι] [OrderBot ι] [WellFoundedLT ι] +variable [SuccOrder ι] [OrderBot ι] [NoMaxOrder ι] [WellFoundedLT ι] noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι where F := f.monotone_filtration.functor ⋙ Subcomplex.toSSetFunctor - isoBot := Subcomplex.isoOfEq (filtration_bot _) + isoBot := Subcomplex.eqToIso (filtration_bot _) isColimit := sorry isWellOrderContinuous := sorry incl.app i := (f.filtration i).ι diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index 11909202d5989c..9e0d919d79e037 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -102,6 +102,11 @@ lemma ext_iff {n : ℕ} (x y : X _⦋n⦌) : /-- The subcomplex generated by a simplex. -/ abbrev subcomplex (s : X.S) : X.Subcomplex := Subcomplex.ofSimplex s.simplex +@[simp] +lemma subcomplex_cast (s : X.S) {d : ℕ} (hd : s.dim = d) : + (s.cast hd).subcomplex = s.subcomplex := by + rw [cast_eq_self] + /-- If `s : X.S` and `t : X.S` are simplices of a simplicial set, `s ≤ t` means that the subcomplex generated by `s` is contained in the subcomplex generated by `t`, see `SSet.S.le_def` and `SSet.S.le_iff`. Note that the diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 65af70fe1921f4..95c144fab9573b 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -185,7 +185,7 @@ namespace Subcomplex variable {X : SSet.{u}} lemma range_eq_ofSimplex {n : ℕ} (f : Δ[n] ⟶ X) : - Subpresheaf.range f = ofSimplex (yonedaEquiv f) := + Subcomplex.range f = ofSimplex (yonedaEquiv f) := Subpresheaf.range_eq_ofSection' _ lemma yonedaEquiv_coe {A : X.Subcomplex} {n : SimplexCategory} @@ -255,7 +255,7 @@ lemma ofSimplex_yonedaEquiv_δ {n : ℕ} (i : Fin (n + 2)) : @[simp] lemma range_δ {n : ℕ} (i : Fin (n + 2)) : - Subpresheaf.range (stdSimplex.δ i) = face.{u} {i}ᶜ := by + Subcomplex.range (stdSimplex.δ i) = face.{u} {i}ᶜ := by rw [Subcomplex.range_eq_ofSimplex] exact ofSimplex_yonedaEquiv_δ i diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean index 710e2dff17ee71..eb33c18dcdf92d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean @@ -235,6 +235,12 @@ lemma preimage_iSup {ι : Type*} (A : ι → X.Subcomplex) (p : Y ⟶ X) : lemma preimage_iInf {ι : Type*} (A : ι → X.Subcomplex) (p : Y ⟶ X) : (⨅ i, A i).preimage p = ⨅ i, (A i).preimage p := by aesop +lemma preimage_comp {Z : SSet.{u}} (A : Z.Subcomplex) (f : X ⟶ Y) (g : Y ⟶ Z) : + A.preimage (f ≫ g) = (A.preimage g).preimage f := rfl + +@[simp] +lemma preimage_ι (A : X.Subcomplex) : A.preimage A.ι = ⊤ := by aesop + end section From d260aa14dc336f8cb78a74ad976149cc54566d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 10:04:13 +0100 Subject: [PATCH 52/81] wip --- Mathlib.lean | 1 + .../RelativeCellComplex.lean | 51 +++++++++++++++---- .../SimplicialSet/SubcomplexEvaluation.lean | 48 +++++++++++++++++ Mathlib/CategoryTheory/Limits/Preorder.lean | 41 ++++++++++----- 4 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexEvaluation.lean diff --git a/Mathlib.lean b/Mathlib.lean index ab3e947cf43936..76d0e077d2cb11 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1432,6 +1432,7 @@ public import Mathlib.AlgebraicTopology.SimplicialSet.Simplices public import Mathlib.AlgebraicTopology.SimplicialSet.StdSimplex public import Mathlib.AlgebraicTopology.SimplicialSet.StrictSegal public import Mathlib.AlgebraicTopology.SimplicialSet.Subcomplex +public import Mathlib.AlgebraicTopology.SimplicialSet.SubcomplexEvaluation public import Mathlib.AlgebraicTopology.SingularHomology.Basic public import Mathlib.AlgebraicTopology.SingularSet public import Mathlib.AlgebraicTopology.TopologicalSimplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index d0d41692840fdc..5f22902b5756ed 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -3,15 +3,20 @@ Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ -import Mathlib.AlgebraicTopology.RelativeCellComplex.Basic -import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank -import Mathlib.AlgebraicTopology.SimplicialSet.Horn +module + +public import Mathlib.AlgebraicTopology.RelativeCellComplex.Basic +public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank +public import Mathlib.AlgebraicTopology.SimplicialSet.Horn +public import Mathlib.AlgebraicTopology.SimplicialSet.SubcomplexEvaluation /-! # The relative cell complex attached to a rank function for a pairing -/ +@[expose] public section + universe v u open CategoryTheory HomotopicalAlgebra Simplicial Limits @@ -67,7 +72,7 @@ lemma le_filtration (i : ι) : A ≤ f.filtration i := le_sup_left lemma filtration_bot [OrderBot ι] : f.filtration ⊥ = A := by simp [filtration] -lemma monotone_filtration : Monotone f.filtration := by +lemma filtration_monotone : Monotone f.filtration := by intro i₁ i₂ h rw [filtration] simp only [sup_le_iff, iSup_le_iff, le_filtration, true_and] @@ -86,7 +91,7 @@ lemma filtration_succ [SuccOrder ι] (i : ι) (hi : ¬ IsMax i) : · exact (f.simplex_le_filtration _ hj).trans le_sup_left · exact le_trans (le_trans (by rfl) (le_iSup _ c)) le_sup_right · simp only [sup_le_iff, iSup_le_iff] - exact ⟨f.monotone_filtration (Order.le_succ i), + exact ⟨f.filtration_monotone (Order.le_succ i), fun c ↦ f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hi)⟩ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] @@ -105,7 +110,7 @@ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] exact f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hj.not_isMax) · simp only [iSup_le_iff] intro j hj - exact f.monotone_filtration hj.le + exact f.filtration_monotone hj.le lemma filtration_le_iSup (i : ι) : f.filtration i ≤ ⨆ (i : ι), f.filtration i := @@ -132,6 +137,18 @@ lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : ((f.simplex_le_filtration ⟨y, rfl⟩ (Order.lt_succ (f.rank y))).trans (f.filtration_le_iSup _)) +lemma iSup_filtration_iio [OrderBot ι] [SuccOrder ι] (m : ι) (hm : Order.IsSuccLimit m) : + ⨆ (i : Set.Iio m), f.filtration i = f.filtration m := + le_antisymm (by + simp only [iSup_le_iff, Subtype.forall, Set.mem_Iio] + intro j hj + exact f.filtration_monotone hj.le) (by + rw [filtration] + simp only [sup_le_iff, iSup_le_iff, ← f.filtration_bot] + exact ⟨le_trans (by rfl) (le_iSup _ ⟨⊥, hm.bot_lt⟩), fun j hj c ↦ + (f.simplex_le_filtration c (Order.lt_succ_of_not_isMax (not_isMax_of_lt hj))).trans + (le_trans (by rfl) (le_iSup _ ⟨Order.succ j, hm.succ_lt_iff.2 hj⟩))⟩) + def Cells.mapToSucc {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.filtration (Order.succ j) := Subcomplex.lift c.map (by @@ -197,13 +214,13 @@ lemma ι_b {j : ι} (c : f.Cells j) : @[reassoc] lemma w (j : ι) : - f.t j ≫ homOfLE (f.monotone_filtration (Order.le_succ j)) = f.m j ≫ f.b j := by + f.t j ≫ homOfLE (f.filtration_monotone (Order.le_succ j)) = f.m j ≫ f.b j := by ext c : 1 simp [← cancel_mono (Subcomplex.ι _)] lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) - (homOfLE (f.monotone_filtration (Order.le_succ j))) (f.b j) where + (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j isColimit' := sorry @@ -211,11 +228,23 @@ end variable [SuccOrder ι] [OrderBot ι] [NoMaxOrder ι] [WellFoundedLT ι] +instance : f.filtration_monotone.functor.IsWellOrderContinuous where + nonempty_isColimit m hm := ⟨Preorder.isColimitOfIsLUB _ _ (by + dsimp + rw [← f.iSup_filtration_iio m hm] + apply isLUB_iSup)⟩ + noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι where - F := f.monotone_filtration.functor ⋙ Subcomplex.toSSetFunctor + F := f.filtration_monotone.functor ⋙ Subcomplex.toSSetFunctor isoBot := Subcomplex.eqToIso (filtration_bot _) - isColimit := sorry - isWellOrderContinuous := sorry + isColimit := + IsColimit.ofIsoColimit (isColimitOfPreserves Subcomplex.toSSetFunctor + (Preorder.colimitCoconeOfIsLUB f.filtration_monotone.functor (pt := ⊤) + (by rw [← f.iSup_filtration]; apply isLUB_iSup)).isColimit) + (Cocones.ext (Subcomplex.topIso _)) + isWellOrderContinuous := + ⟨fun m hm ↦ ⟨isColimitOfPreserves Subcomplex.toSSetFunctor + (Functor.isColimitOfIsWellOrderContinuous f.filtration_monotone.functor m hm)⟩⟩ incl.app i := (f.filtration i).ι attachCells j hj := { ι := f.Cells j diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexEvaluation.lean b/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexEvaluation.lean new file mode 100644 index 00000000000000..04f3cb027885e7 --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/SubcomplexEvaluation.lean @@ -0,0 +1,48 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.AlgebraicTopology.SimplicialSet.Subcomplex +public import Mathlib.CategoryTheory.Limits.Preorder +public import Mathlib.CategoryTheory.Limits.Set + +/-! +# The evaluation functor on subcomplexes + +We define an evaluation functor `SSet.Subcomplex.evalution : X.Subcomplex ⥤ Set (X.obj j)` +when `X : SSet` and `j : SimplexCategoryᵒᵖ`. We use it to show that the functor +`Subcomplex.toSSetFunctor : X.Subcomplex ⥤ SSet` preserves filtered colimits. + +-/ + +@[expose] public section + +universe u + +open CategoryTheory Limits + +namespace SSet.Subcomplex + +/-- The evaluation functor `X.Subcomplex ⥤ Set (X.obj j)` when `X : SSet` +and `j : SimplexCategoryᵒᵖ`. -/ +@[simps] +def evaluation (X : SSet.{u}) (j : SimplexCategoryᵒᵖ) : + X.Subcomplex ⥤ Set (X.obj j) where + obj A := A.obj j + map f := CategoryTheory.homOfLE (leOfHom f j) + +instance {J : Type*} [Category J] {X : SSet.{u}} [IsFilteredOrEmpty J] : + PreservesColimitsOfShape J (Subcomplex.toSSetFunctor (X := X)) where + preservesColimit {F} := + preservesColimit_of_preserves_colimit_cocone + (Preorder.colimitCoconeOfIsLUB F isLUB_iSup).isColimit + (evaluationJointlyReflectsColimits _ (fun j ↦ IsColimit.ofIsoColimit + (isColimitOfPreserves Set.functorToTypes + ((Preorder.colimitCoconeOfIsLUB (F ⋙ evaluation _ j) isLUB_iSup).isColimit)) + (Cocones.ext (Set.functorToTypes.mapIso + (CategoryTheory.eqToIso (by cat_disch)))))) + +end SSet.Subcomplex diff --git a/Mathlib/CategoryTheory/Limits/Preorder.lean b/Mathlib/CategoryTheory/Limits/Preorder.lean index 33f75a82656c6b..0243b3b19d6c41 100644 --- a/Mathlib/CategoryTheory/Limits/Preorder.lean +++ b/Mathlib/CategoryTheory/Limits/Preorder.lean @@ -35,6 +35,7 @@ variable {J : Type u'} [Category.{v} J] variable (F : J ⥤ C) /-- The cone associated to a lower bound of a functor. -/ +@[simps] def coneOfLowerBound {x : C} (h : x ∈ lowerBounds (Set.range F.obj)) : Cone F where pt := x π := { app i := homOfLE (h (Set.mem_range_self _)) } @@ -51,13 +52,24 @@ lemma isGLB_of_isLimit {c : Cone F} (h : IsLimit c) : IsGLB (Set.range F.obj) c. def isLimitOfIsGLB (c : Cone F) (h : IsGLB (Set.range F.obj) c.pt) : IsLimit c where lift d := (h.2 (conePt_mem_lowerBounds F d)).hom +/-- The limit cone for a functor `F : J ⥤ C` to a preorder when `pt : C` +is the greatest lower bound of `Set.range F.obj` -/ +@[simps] +def limitConeOfIsGLB {pt : C} (h : IsGLB (Set.range F.obj) pt) : + LimitCone F where + cone := coneOfLowerBound _ h.1 + isLimit := isLimitOfIsGLB _ _ h + /-- A functor has a limit iff there exists a glb. -/ -lemma hasLimit_iff_hasGLB : HasLimit F ↔ ∃ x, IsGLB (Set.range F.obj) x := by - constructor <;> intro h - · let limitCone := getLimitCone F - exact ⟨limitCone.cone.pt, isGLB_of_isLimit F limitCone.isLimit⟩ - · obtain ⟨l, isGLB⟩ := h - exact ⟨⟨⟨coneOfLowerBound F isGLB.1, isLimitOfIsGLB F _ isGLB⟩⟩⟩ +lemma hasLimit_iff_hasGLB : HasLimit F ↔ ∃ x, IsGLB (Set.range F.obj) x := + ⟨fun _ ↦ ⟨_, isGLB_of_isLimit _ (limit.isLimit _)⟩, + fun ⟨_, h⟩ ↦ ⟨⟨limitConeOfIsGLB _ h⟩⟩⟩ + +/-- The cocone associated to an upper bound of a functor. -/ +@[simps] +def coconeOfUpperBound {x : C} (h : x ∈ upperBounds (Set.range F.obj)) : Cocone F where + pt := x + ι := { app i := homOfLE (h (Set.mem_range_self _)) } /-- The cocone associated to an upper bound of a functor -/ def coconePt_mem_upperBounds {x : C} (h : x ∈ upperBounds (Set.range F.obj)) : Cocone F where @@ -76,14 +88,19 @@ lemma isLUB_of_isColimit {c : Cocone F} (h : IsColimit c) : IsLUB (Set.range F.o def isColimitOfIsLUB (c : Cocone F) (h : IsLUB (Set.range F.obj) c.pt) : IsColimit c where desc d := (h.2 (upperBoundOfCocone F d)).hom +/-- The colimit cocone for a functor `F : J ⥤ C` to a preorder when `pt : C` +is the least upper bound of `Set.range F.obj` -/ +@[simps] +def colimitCoconeOfIsLUB {pt : C} (h : IsLUB (Set.range F.obj) pt) : + ColimitCocone F where + cocone := coconeOfUpperBound _ h.1 + isColimit := isColimitOfIsLUB _ _ h + /-- A functor has a colimit iff there exists a lub. -/ lemma hasColimit_iff_hasLUB : - HasColimit F ↔ ∃ x, IsLUB (Set.range F.obj) x := by - constructor <;> intro h - · let limitCocone := getColimitCocone F - exact ⟨limitCocone.cocone.pt, isLUB_of_isColimit F limitCocone.isColimit⟩ - · obtain ⟨l, isLUB⟩ := h - exact ⟨⟨⟨coconePt_mem_upperBounds F isLUB.1, isColimitOfIsLUB F _ isLUB⟩⟩⟩ + HasColimit F ↔ ∃ x, IsLUB (Set.range F.obj) x := + ⟨fun _ ↦ ⟨_, isLUB_of_isColimit _ (colimit.isColimit _)⟩, + fun ⟨_, h⟩ ↦ ⟨⟨colimitCoconeOfIsLUB _ h⟩⟩⟩ end From 9b7a2402c2e1ead07ea01f75484c76435131959a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 10:20:43 +0100 Subject: [PATCH 53/81] wip --- .../RelativeCellComplex.lean | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 5f22902b5756ed..cc3de4e7c98553 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -100,11 +100,10 @@ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] apply le_antisymm · rw [filtration] simp only [sup_le_iff, iSup_le_iff] - constructor + refine ⟨?_, fun j hj c ↦ ?_⟩ · refine le_trans ?_ (le_iSup _ ⊥) exact le_trans (by simp) (le_iSup _ hi.bot_lt) - · intro j hj c - refine le_trans ?_ (le_iSup _ (Order.succ j)) + · refine le_trans ?_ (le_iSup _ (Order.succ j)) refine le_trans ?_ (le_iSup _ (by rwa [← Order.IsSuccLimit.succ_lt_iff hi] at hj)) exact f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hj.not_isMax) @@ -112,10 +111,6 @@ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] intro j hj exact f.filtration_monotone hj.le -lemma filtration_le_iSup (i : ι) : - f.filtration i ≤ ⨆ (i : ι), f.filtration i := - le_iSup _ i - lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : ⨆ (i : ι), f.filtration i = ⊤ := by let B := ⨆ (i : ι), f.filtration i @@ -123,7 +118,7 @@ lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : rw [eq_top_iff_contains_nonDegenerate] intro n s hs by_cases hs₀ : s ∈ A.obj _ - · exact f.filtration_le_iSup ⊥ _ (by rwa [filtration_bot]) + · exact le_iSup f.filtration ⊥ _ (by rwa [filtration_bot]) · exact this (N.mk _ hs hs₀) suffices ∀ (y : P.II), ofSimplex (P.p y).1.simplex ≤ B by intro s @@ -135,7 +130,7 @@ lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : intro y exact le_trans (by simp [Cells.simplex]) ((f.simplex_le_filtration ⟨y, rfl⟩ (Order.lt_succ (f.rank y))).trans - (f.filtration_le_iSup _)) + (le_iSup f.filtration _)) lemma iSup_filtration_iio [OrderBot ι] [SuccOrder ι] (m : ι) (hm : Order.IsSuccLimit m) : ⨆ (i : Set.Iio m), f.filtration i = f.filtration m := @@ -222,7 +217,12 @@ lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j - isColimit' := sorry + isColimit' := ⟨evaluationJointlyReflectsColimits _ (fun ⟨d⟩ ↦ by + induction d using SimplexCategory.rec with | _ d + refine (isColimitMapCoconePushoutCoconeEquiv _ _).2 + (IsPushout.isColimit ?_) + dsimp + sorry)⟩ end From ad229f2dce2cad18b5f915fa3b3eda3e4294c658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 15:02:19 +0100 Subject: [PATCH 54/81] feat(CategoryTheory): improve API for limits in preorders --- Mathlib/CategoryTheory/Limits/Preorder.lean | 41 +++++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Preorder.lean b/Mathlib/CategoryTheory/Limits/Preorder.lean index 33f75a82656c6b..0243b3b19d6c41 100644 --- a/Mathlib/CategoryTheory/Limits/Preorder.lean +++ b/Mathlib/CategoryTheory/Limits/Preorder.lean @@ -35,6 +35,7 @@ variable {J : Type u'} [Category.{v} J] variable (F : J ⥤ C) /-- The cone associated to a lower bound of a functor. -/ +@[simps] def coneOfLowerBound {x : C} (h : x ∈ lowerBounds (Set.range F.obj)) : Cone F where pt := x π := { app i := homOfLE (h (Set.mem_range_self _)) } @@ -51,13 +52,24 @@ lemma isGLB_of_isLimit {c : Cone F} (h : IsLimit c) : IsGLB (Set.range F.obj) c. def isLimitOfIsGLB (c : Cone F) (h : IsGLB (Set.range F.obj) c.pt) : IsLimit c where lift d := (h.2 (conePt_mem_lowerBounds F d)).hom +/-- The limit cone for a functor `F : J ⥤ C` to a preorder when `pt : C` +is the greatest lower bound of `Set.range F.obj` -/ +@[simps] +def limitConeOfIsGLB {pt : C} (h : IsGLB (Set.range F.obj) pt) : + LimitCone F where + cone := coneOfLowerBound _ h.1 + isLimit := isLimitOfIsGLB _ _ h + /-- A functor has a limit iff there exists a glb. -/ -lemma hasLimit_iff_hasGLB : HasLimit F ↔ ∃ x, IsGLB (Set.range F.obj) x := by - constructor <;> intro h - · let limitCone := getLimitCone F - exact ⟨limitCone.cone.pt, isGLB_of_isLimit F limitCone.isLimit⟩ - · obtain ⟨l, isGLB⟩ := h - exact ⟨⟨⟨coneOfLowerBound F isGLB.1, isLimitOfIsGLB F _ isGLB⟩⟩⟩ +lemma hasLimit_iff_hasGLB : HasLimit F ↔ ∃ x, IsGLB (Set.range F.obj) x := + ⟨fun _ ↦ ⟨_, isGLB_of_isLimit _ (limit.isLimit _)⟩, + fun ⟨_, h⟩ ↦ ⟨⟨limitConeOfIsGLB _ h⟩⟩⟩ + +/-- The cocone associated to an upper bound of a functor. -/ +@[simps] +def coconeOfUpperBound {x : C} (h : x ∈ upperBounds (Set.range F.obj)) : Cocone F where + pt := x + ι := { app i := homOfLE (h (Set.mem_range_self _)) } /-- The cocone associated to an upper bound of a functor -/ def coconePt_mem_upperBounds {x : C} (h : x ∈ upperBounds (Set.range F.obj)) : Cocone F where @@ -76,14 +88,19 @@ lemma isLUB_of_isColimit {c : Cocone F} (h : IsColimit c) : IsLUB (Set.range F.o def isColimitOfIsLUB (c : Cocone F) (h : IsLUB (Set.range F.obj) c.pt) : IsColimit c where desc d := (h.2 (upperBoundOfCocone F d)).hom +/-- The colimit cocone for a functor `F : J ⥤ C` to a preorder when `pt : C` +is the least upper bound of `Set.range F.obj` -/ +@[simps] +def colimitCoconeOfIsLUB {pt : C} (h : IsLUB (Set.range F.obj) pt) : + ColimitCocone F where + cocone := coconeOfUpperBound _ h.1 + isColimit := isColimitOfIsLUB _ _ h + /-- A functor has a colimit iff there exists a lub. -/ lemma hasColimit_iff_hasLUB : - HasColimit F ↔ ∃ x, IsLUB (Set.range F.obj) x := by - constructor <;> intro h - · let limitCocone := getColimitCocone F - exact ⟨limitCocone.cocone.pt, isLUB_of_isColimit F limitCocone.isColimit⟩ - · obtain ⟨l, isLUB⟩ := h - exact ⟨⟨⟨coconePt_mem_upperBounds F isLUB.1, isColimitOfIsLUB F _ isLUB⟩⟩⟩ + HasColimit F ↔ ∃ x, IsLUB (Set.range F.obj) x := + ⟨fun _ ↦ ⟨_, isLUB_of_isColimit _ (colimit.isColimit _)⟩, + fun ⟨_, h⟩ ↦ ⟨⟨colimitCoconeOfIsLUB _ h⟩⟩⟩ end From a5a57afe70c0acb2e8a49dcedac0ba343afe43f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 18:20:56 +0100 Subject: [PATCH 55/81] feat(CategoryTheory/Limits/Types): more results on pushout squares --- .../Limits/Shapes/Pullback/HasPullback.lean | 10 ++ .../Limits/Types/Pullbacks.lean | 42 ++++++ .../CategoryTheory/Limits/Types/Pushouts.lean | 129 +++++++++++++++++- 3 files changed, 176 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean index 70aa537899d749..5a3446b905449b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/HasPullback.lean @@ -128,12 +128,22 @@ abbrev pullback.lift {W X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} [HasPullback f g] (k : W ⟶ Y) (w : h ≫ f = k ≫ g := by cat_disch) : W ⟶ pullback f g := limit.lift _ (PullbackCone.mk h k w) +lemma pullback.exists_lift {W X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] + (h : W ⟶ X) (k : W ⟶ Y) (w : h ≫ f = k ≫ g := by cat_disch) : + ∃ (l : W ⟶ pullback f g), l ≫ pullback.fst f g = h ∧ l ≫ pullback.snd f g = k := + ⟨pullback.lift h k, by simp⟩ + /-- A pair of morphisms `h : Y ⟶ W` and `k : Z ⟶ W` satisfying `f ≫ h = g ≫ k` induces a morphism `pushout.desc : pushout f g ⟶ W`. -/ abbrev pushout.desc {W X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} [HasPushout f g] (h : Y ⟶ W) (k : Z ⟶ W) (w : f ≫ h = g ≫ k := by cat_disch) : pushout f g ⟶ W := colimit.desc _ (PushoutCocone.mk h k w) +lemma pushout.exists_desc {W X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) [HasPushout f g] + (h : Y ⟶ W) (k : Z ⟶ W) (w : f ≫ h = g ≫ k := by cat_disch) : + ∃ (l : pushout f g ⟶ W), pushout.inl f g ≫ l = h ∧ pushout.inr f g ≫ l = k := + ⟨pushout.desc h k, by simp⟩ + /-- The cone associated to a pullback is a limit cone. -/ abbrev pullback.isLimit {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] : IsLimit (pullback.cone f g) := diff --git a/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean index f9fe77cc95d857..bb96267556dc02 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean @@ -201,4 +201,46 @@ lemma range_pullbackFst : Set.range (pullback.fst f g) = f ⁻¹' Set.range g := lemma range_pullbackSnd : Set.range (pullback.snd f g) = g ⁻¹' Set.range f := range_snd_of_isPullback (.of_hasPullback f g) +section + +variable {X₁ X₂ X₃ X₄ : Type u} {t : X₁ ⟶ X₂} {r : X₂ ⟶ X₄} + {l : X₁ ⟶ X₃} {b : X₃ ⟶ X₄} + +lemma ext_of_isPullback (h : IsPullback t l r b) {x₁ y₁ : X₁} + (h₁ : t x₁ = t y₁) (h₂ : l x₁ = l y₁) : x₁ = y₁ := + (h.isLimit.conePointUniqueUpToIso (Types.pullbackLimitCone _ _).isLimit).toEquiv.injective + (by dsimp; ext <;> assumption) + +lemma exists_of_isPullback (h : IsPullback t l r b) + (x₂ : X₂) (x₃ : X₃) (hx : r x₂ = b x₃) : + ∃ x₁, t x₁ = x₂ ∧ l x₁ = x₃ := by + obtain ⟨x₁, hx₁⟩ := + (PullbackCone.IsLimit.equivPullbackObj h.isLimit).surjective ⟨⟨x₂, x₃⟩, hx⟩ + rw [Subtype.ext_iff] at hx₁ + exact ⟨x₁, congr_arg _root_.Prod.fst hx₁, + congr_arg _root_.Prod.snd hx₁⟩ + +variable (t l r b) in +lemma isPullback_iff : + IsPullback t l r b ↔ t ≫ r = l ≫ b ∧ + (∀ x₁ y₁, t x₁ = t y₁ ∧ l x₁ = l y₁ → x₁ = y₁) ∧ + ∀ x₂ x₃, r x₂ = b x₃ → ∃ x₁, t x₁ = x₂ ∧ l x₁ = x₃:= by + constructor + · intro h + exact ⟨h.w, fun x₁ y₁ ⟨h₁, h₂⟩ ↦ ext_of_isPullback h h₁ h₂, exists_of_isPullback h⟩ + · rintro ⟨w, h₁, h₂⟩ + let φ : X₁ ⟶ PullbackObj r b := fun x₁ ↦ ⟨⟨t x₁, l x₁⟩, congr_fun w x₁⟩ + have hφ : IsIso φ := by + rw [isIso_iff_bijective] + constructor + · intro x₁ y₁ h + rw [Subtype.ext_iff, _root_.Prod.ext_iff] at h + exact h₁ _ _ h + · rintro ⟨⟨x₂, x₃⟩, h⟩ + obtain ⟨x₁, rfl, rfl⟩ := h₂ x₂ x₃ h + exact ⟨x₁, rfl⟩ + exact ⟨⟨w⟩, ⟨IsLimit.ofIsoLimit ((Types.pullbackLimitCone r b).isLimit) + (PullbackCone.ext (asIso φ)).symm⟩⟩ +end + end CategoryTheory.Limits.Types diff --git a/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean b/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean index b6b6f3803ac621..0e84a6697a90f5 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean @@ -5,8 +5,8 @@ Authors: Joël Riou -/ module -public import Mathlib.CategoryTheory.Limits.Shapes.Pullback.HasPullback -public import Mathlib.CategoryTheory.Limits.Types.Colimits +public import Mathlib.CategoryTheory.Limits.Types.Pullbacks +public import Mathlib.CategoryTheory.MorphismProperty.Limits /-! @@ -30,8 +30,6 @@ namespace CategoryTheory.Limits.Types instance : HasPushouts.{u} (Type u) := hasPushouts_of_hasWidePushouts.{u} (Type u) -section Pushout - variable {S X₁ X₂ : Type u} (f : S ⟶ X₁) (g : S ⟶ X₂) /-- The pushout of two maps `f : S ⟶ X₁` and `g : S ⟶ X₂` is the quotient @@ -256,6 +254,127 @@ instance [Mono g] : Mono (pushout.inl f g) := pushoutCocone_inr_mono_of_isColimit (PushoutCocone.flipIsColimit (pushoutIsPushout f g)) -end Pushout +section + +variable {X₁ X₂ X₃ X₄ X₅ : Type u} {t : X₁ ⟶ X₂} {r : X₂ ⟶ X₄} + {l : X₁ ⟶ X₃} {b : X₃ ⟶ X₄} + +lemma eq_or_eq_of_isPushout (h : IsPushout t l r b) + (x₄ : X₄) : (∃ x₂, r x₂ = x₄) ∨ ∃ x₃, b x₃ = x₄ := by + obtain ⟨j, x, rfl⟩ := jointly_surjective_of_isColimit h.isColimit x₄ + obtain (_ | _ | _) := j + · exact Or.inl ⟨t x, by simp⟩ + · exact Or.inl ⟨x, rfl⟩ + · exact Or.inr ⟨x, rfl⟩ + +lemma eq_or_eq_of_isPushout' (h : IsPushout t l r b) + (x₄ : X₄) : (∃ x₂, r x₂ = x₄) ∨ ∃ x₃, b x₃ = x₄ ∧ x₃ ∉ Set.range l := by + obtain h₁ | ⟨x₃, hx₃⟩ := eq_or_eq_of_isPushout h x₄ + · refine Or.inl h₁ + · by_cases h₂ : x₃ ∈ Set.range l + · obtain ⟨x₁, rfl⟩ := h₂ + exact Or.inl ⟨t x₁, by simpa only [← hx₃] using congr_fun h.w x₁⟩ + · exact Or.inr ⟨x₃, hx₃, h₂⟩ + +lemma isPullback_of_isPushout (h : IsPushout t l r b) (ht : Function.Injective t) : + IsPullback t l r b := by + rw [isPullback_iff] + refine ⟨h.w, fun x₁ y₁ ⟨h₂, _⟩ ↦ ht h₂, fun x₂ x₃ hx ↦ ?_⟩ + have := (pushoutCocone_inl_eq_inr_iff_of_isColimit h.isColimit ht x₂ x₃).1 hx + grind + +/-- Consider a pushout square involving types `X₁`, `X₂`, `X₃` and `X₄`: +``` + t + X₁ ⟶ X₂ +l| |r \ + v b v \ r' + X₃ ⟶ X₄ \ + \ k\ | + \ b' v v + \______> X₅ +``` +Let `k : X₄ ⟶ X₅`, `r' : X₂ ⟶ X₅` and `b' : X₃ ⟶ X₅` be such +that `r ≫ k = r'` and `b ≫ k = b'`. Assume that +the outer square is a pullback, that `r'` is a monomorphism +and that `b'` is injective on the complement of the range of `l`, +then `k : X₄ ⟶ X₅` is a monomorphism. -/ +lemma mono_of_isPushout_of_isPullback {k : X₄ ⟶ X₅} (h₁ : IsPushout t l r b) + {r' : X₂ ⟶ X₅} {b' : X₃ ⟶ X₅} (h₂ : IsPullback t l r' b') + (facr : r ≫ k = r') (facb : b ≫ k = b') [hr' : Mono r'] + (H : ∀ (x₃ y₃ : X₃) (_ : x₃ ∉ Set.range l) (_ : y₃ ∉ Set.range l), + b' x₃ = b' y₃ → x₃ = y₃) : + Mono k := by + subst facr facb + have hl : Mono l := + (MorphismProperty.monomorphisms _).of_isPullback h₂ (.infer_property _) + rw [mono_iff_injective] at hr' hl ⊢ + have w := congr_fun h₁.w + dsimp at w + intro x₃ y₃ eq + obtain (⟨x₂, rfl⟩ | ⟨x₃, rfl, hx₃⟩) := eq_or_eq_of_isPushout' h₁ x₃ <;> + obtain (⟨y₂, rfl⟩ | ⟨y₃, rfl, hy₃⟩) := eq_or_eq_of_isPushout' h₁ y₃ + · obtain rfl : x₂ = y₂ := hr' eq + rfl + · obtain ⟨x₁, rfl, rfl⟩ := exists_of_isPullback h₂ x₂ y₃ eq + rw [w] + · obtain ⟨x₁, rfl, rfl⟩ := exists_of_isPullback h₂ y₂ x₃ eq.symm + rw [w] + · obtain rfl := H x₃ y₃ hx₃ hy₃ eq + rfl + +/-- Consider a diagram where the outer square involving types `X₁`, `X₂`, `X₃` and `X₅` +is a pullback, where the two bottom and right triangles commute: +``` + t + X₁ ⟶ X₂ +l| |r \ + v b v \ r' + X₃ ⟶ X₄ \ + \ k\ | + \ b' v v + \______> X₅ +``` +Assume that `r'` and `k` are monomorphisms, that `r` and `b` are jointly surjective, +and that `b'` is injective on the complement of the range of `l`, then +the top-left square is a pushout. -/ +lemma isPushout_of_isPullback_of_mono {k : X₄ ⟶ X₅} + {r' : X₂ ⟶ X₅} {b' : X₃ ⟶ X₅} (h₁ : IsPullback t l r' b') + (facr : r ≫ k = r') (facb : b ≫ k = b') [Mono r'] [Mono k] + (h₂ : Set.range r ⊔ Set.range b = Set.univ) + (H : ∀ (x₃ y₃ : X₃) (_ : x₃ ∉ Set.range l) (_ : y₃ ∉ Set.range l), + b' x₃ = b' y₃ → x₃ = y₃) : + IsPushout t l r b := by + obtain ⟨φ, hφ₁, hφ₂⟩ := pushout.exists_desc t l r b + (by simp only [← cancel_mono k, Category.assoc, facr, facb, h₁.w]) + have := mono_of_isPushout_of_isPullback (IsPushout.of_hasPushout t l) h₁ + (k := φ ≫ k) (by cat_disch) (by cat_disch) H + have := mono_of_mono φ k + have : Epi φ := by + rw [epi_iff_surjective] + intro x₄ + have hx₄ := Set.mem_univ x₄ + simp only [← h₂, Set.sup_eq_union, Set.mem_union, Set.mem_range] at hx₄ + obtain (⟨x₂, rfl⟩ | ⟨x₃, rfl⟩) := hx₄ + · exact ⟨_, congr_fun hφ₁ x₂⟩ + · exact ⟨_, congr_fun hφ₂ x₃⟩ + have := isIso_of_mono_of_epi φ + exact IsPushout.of_iso (IsPushout.of_hasPushout t l) + (Iso.refl _) (Iso.refl _) (Iso.refl _) (asIso φ) (by simp) (by simp) + (by simpa) (by simpa) + +/-- Consider a pullback square of types where the right map is a monomorphism. +If the right and bottom map are jointly surjective, and the bottom map +is injective on the complement on the range of the left map, then the square +is a pushout square. -/ +lemma isPushout_of_isPullback_of_mono' + (h₁ : IsPullback t l r b) [Mono r] + (h₂ : Set.range r ⊔ Set.range b = Set.univ) + (H : ∀ (x₃ y₃ : X₃) (_ : x₃ ∉ Set.range l) (_ : y₃ ∉ Set.range l), + b x₃ = b y₃ → x₃ = y₃) : + IsPushout t l r b := + isPushout_of_isPullback_of_mono (k := 𝟙 _) h₁ (by simp) (by simp) h₂ H + +end end CategoryTheory.Limits.Types From 5f770fad521ccdc6312ccf5d8f51fddebb2d0733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 18:24:31 +0100 Subject: [PATCH 56/81] better syntax --- Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean b/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean index bb96267556dc02..9b41d58f4c493b 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Pullbacks.lean @@ -234,7 +234,7 @@ lemma isPullback_iff : rw [isIso_iff_bijective] constructor · intro x₁ y₁ h - rw [Subtype.ext_iff, _root_.Prod.ext_iff] at h + rw [Subtype.ext_iff, Prod.ext_iff] at h exact h₁ _ _ h · rintro ⟨⟨x₂, x₃⟩, h⟩ obtain ⟨x₁, rfl, rfl⟩ := h₂ x₂ x₃ h From cd5156f9b25f7eb5dabcc24a406e4c38def0cff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 18:44:35 +0100 Subject: [PATCH 57/81] trying to reduce imports --- .../CategoryTheory/Limits/Types/Pushouts.lean | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean b/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean index 0e84a6697a90f5..77c005c84f0d30 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Pushouts.lean @@ -6,8 +6,6 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.Limits.Types.Pullbacks -public import Mathlib.CategoryTheory.MorphismProperty.Limits - /-! # Pushouts in `Type` @@ -306,9 +304,10 @@ lemma mono_of_isPushout_of_isPullback {k : X₄ ⟶ X₅} (h₁ : IsPushout t l b' x₃ = b' y₃ → x₃ = y₃) : Mono k := by subst facr facb - have hl : Mono l := - (MorphismProperty.monomorphisms _).of_isPullback h₂ (.infer_property _) - rw [mono_iff_injective] at hr' hl ⊢ + have : Function.Injective l := + fun x₁ y₁ h ↦ ext_of_isPullback h₂ ((mono_iff_injective _).1 hr' + ((congr_fun h₂.w x₁).trans (Eq.trans (by simp [h]) (congr_fun h₂.w.symm y₁)))) h + rw [mono_iff_injective] at hr' ⊢ have w := congr_fun h₁.w dsimp at w intro x₃ y₃ eq @@ -349,16 +348,14 @@ lemma isPushout_of_isPullback_of_mono {k : X₄ ⟶ X₅} (by simp only [← cancel_mono k, Category.assoc, facr, facb, h₁.w]) have := mono_of_isPushout_of_isPullback (IsPushout.of_hasPushout t l) h₁ (k := φ ≫ k) (by cat_disch) (by cat_disch) H - have := mono_of_mono φ k - have : Epi φ := by - rw [epi_iff_surjective] - intro x₄ + have : IsIso φ := by + rw [isIso_iff_bijective] + refine ⟨(mono_iff_injective _).1 (mono_of_mono φ k), fun x₄ ↦ ?_⟩ have hx₄ := Set.mem_univ x₄ simp only [← h₂, Set.sup_eq_union, Set.mem_union, Set.mem_range] at hx₄ obtain (⟨x₂, rfl⟩ | ⟨x₃, rfl⟩) := hx₄ · exact ⟨_, congr_fun hφ₁ x₂⟩ · exact ⟨_, congr_fun hφ₂ x₃⟩ - have := isIso_of_mono_of_epi φ exact IsPushout.of_iso (IsPushout.of_hasPushout t l) (Iso.refl _) (Iso.refl _) (Iso.refl _) (asIso φ) (by simp) (by simp) (by simpa) (by simpa) From c061ef53b2aa2d82211ead6c6ef4581aaca61005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 22:36:05 +0100 Subject: [PATCH 58/81] fix names --- Mathlib/CategoryTheory/Limits/Preorder.lean | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Preorder.lean b/Mathlib/CategoryTheory/Limits/Preorder.lean index 0243b3b19d6c41..2287284d18f594 100644 --- a/Mathlib/CategoryTheory/Limits/Preorder.lean +++ b/Mathlib/CategoryTheory/Limits/Preorder.lean @@ -71,22 +71,17 @@ def coconeOfUpperBound {x : C} (h : x ∈ upperBounds (Set.range F.obj)) : Cocon pt := x ι := { app i := homOfLE (h (Set.mem_range_self _)) } -/-- The cocone associated to an upper bound of a functor -/ -def coconePt_mem_upperBounds {x : C} (h : x ∈ upperBounds (Set.range F.obj)) : Cocone F where - pt := x - ι := { app i := homOfLE (h (Set.mem_range_self _)) } - /-- The point of a cocone is an upper bound. -/ -lemma upperBoundOfCocone (c : Cocone F) : c.pt ∈ upperBounds (Set.range F.obj) := by +lemma coconePt_mem_upperBounds (c : Cocone F) : c.pt ∈ upperBounds (Set.range F.obj) := by intro x ⟨i, p⟩; rw [← p]; exact (c.ι.app i).le /-- If a cocone is a colimit, its point is a lub. -/ lemma isLUB_of_isColimit {c : Cocone F} (h : IsColimit c) : IsLUB (Set.range F.obj) c.pt := - ⟨(upperBoundOfCocone F c), fun _ k ↦ (h.desc (coconePt_mem_upperBounds F k)).le⟩ + ⟨(coconePt_mem_upperBounds F c), fun _ k ↦ (h.desc (coconePt_mem_upperBounds F k)).le⟩ /-- If the point of cocone is a lub, the cocone is a .colimit -/ def isColimitOfIsLUB (c : Cocone F) (h : IsLUB (Set.range F.obj) c.pt) : IsColimit c where - desc d := (h.2 (upperBoundOfCocone F d)).hom + desc d := (h.2 (coconePt_mem_upperBounds F d)).hom /-- The colimit cocone for a functor `F : J ⥤ C` to a preorder when `pt : C` is the least upper bound of `Set.range F.obj` -/ From 6f7a9f64a439aac6321ef19247b678ae3878804e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 23:59:43 +0100 Subject: [PATCH 59/81] fix --- Mathlib/CategoryTheory/Limits/Preorder.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Limits/Preorder.lean b/Mathlib/CategoryTheory/Limits/Preorder.lean index 2287284d18f594..72e9357fe043fb 100644 --- a/Mathlib/CategoryTheory/Limits/Preorder.lean +++ b/Mathlib/CategoryTheory/Limits/Preorder.lean @@ -77,7 +77,7 @@ lemma coconePt_mem_upperBounds (c : Cocone F) : c.pt ∈ upperBounds (Set.range /-- If a cocone is a colimit, its point is a lub. -/ lemma isLUB_of_isColimit {c : Cocone F} (h : IsColimit c) : IsLUB (Set.range F.obj) c.pt := - ⟨(coconePt_mem_upperBounds F c), fun _ k ↦ (h.desc (coconePt_mem_upperBounds F k)).le⟩ + ⟨(coconePt_mem_upperBounds F c), fun _ k ↦ (h.desc (coconeOfUpperBound F k)).le⟩ /-- If the point of cocone is a lub, the cocone is a .colimit -/ def isColimitOfIsLUB (c : Cocone F) (h : IsLUB (Set.range F.obj) c.pt) : IsColimit c where From 76324337f3614ce1de4fa5158d79236765e5f44f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 28 Nov 2025 08:05:40 +0100 Subject: [PATCH 60/81] wip --- .../AnodyneExtensions/RelativeCellComplex.lean | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index cc3de4e7c98553..ae57fbbf63de6b 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -9,6 +9,9 @@ public import Mathlib.AlgebraicTopology.RelativeCellComplex.Basic public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Rank public import Mathlib.AlgebraicTopology.SimplicialSet.Horn public import Mathlib.AlgebraicTopology.SimplicialSet.SubcomplexEvaluation +public import Mathlib.CategoryTheory.Limits.Types.Pushouts +public import Mathlib.CategoryTheory.Limits.Types.Limits +public import Mathlib.CategoryTheory.Limits.FunctorCategory.Basic /-! # The relative cell complex attached to a rank function for a pairing @@ -19,7 +22,7 @@ public import Mathlib.AlgebraicTopology.SimplicialSet.SubcomplexEvaluation universe v u -open CategoryTheory HomotopicalAlgebra Simplicial Limits +open CategoryTheory HomotopicalAlgebra Simplicial Limits Opposite namespace SSet.Subcomplex.Pairing @@ -213,6 +216,12 @@ lemma w (j : ι) : ext c : 1 simp [← cancel_mono (Subcomplex.ι _)] +lemma isPullback (j : ι) (hj : ¬ IsMax j) : + IsPullback (f.t j) (f.m j) + (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where + w := f.w j + isLimit' := ⟨sorry⟩ + lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where @@ -222,7 +231,10 @@ lemma isPushout (j : ι) (hj : ¬ IsMax j) : refine (isColimitMapCoconePushoutCoconeEquiv _ _).2 (IsPushout.isColimit ?_) dsimp - sorry)⟩ + refine Limits.Types.isPushout_of_isPullback_of_mono' + ((f.isPullback j hj).map ((CategoryTheory.evaluation _ _).obj (op ⦋d⦌))) + sorry sorry + )⟩ end From f4b069d88a65787b2fb0bdd5c89b00fb1b2ea7cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 6 Dec 2025 15:16:48 +0100 Subject: [PATCH 61/81] wip --- .../RelativeCellComplex.lean | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index ae57fbbf63de6b..d2776015ddd341 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -175,6 +175,15 @@ noncomputable abbrev Cells.ιSigmaStdSimplex {j : ι} (c : f.Cells j) : noncomputable def m (j : ι) : f.sigmaHorn j ⟶ f.sigmaStdSimplex j := Limits.Sigma.map (basicCell _ _) +instance (j : ι) : Mono (f.m j) := + have : (MorphismProperty.monomorphisms + SSet.{u}).IsStableUnderCoproductsOfShape (f.Cells j) := sorry + MorphismProperty.colimitsOfShape_le (W := .monomorphisms _) _ + (MorphismProperty.colimitsOfShape_colimMap _ (fun ⟨c⟩ ↦ by + dsimp only [Discrete.functor_obj_eq_as, Discrete.natTrans_app] + simp only [MorphismProperty.monomorphisms.iff] + infer_instance)) + @[reassoc (attr := simp)] lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : c.ιSigmaHorn ≫ f.m j = c.horn.ι ≫ c.ιSigmaStdSimplex := by @@ -220,8 +229,21 @@ lemma isPullback (j : ι) (hj : ¬ IsMax j) : IsPullback (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j - isLimit' := ⟨sorry⟩ + isLimit' := ⟨evaluationJointlyReflectsLimits _ (fun ⟨d⟩ ↦ by + refine (isLimitMapConePullbackConeEquiv _ _).2 + (IsPullback.isLimit ?_) + induction d using SimplexCategory.rec with | _ d + rw [Types.isPullback_iff] + dsimp + refine ⟨congr_app (f.w j) (op ⦋d⦌), ?_, ?_⟩ + · intro a₁ a₂ ⟨ht, hm⟩ + have : Mono (f.m j) := inferInstance + rw [NatTrans.mono_iff_mono_app] at this + exact (mono_iff_injective _).1 (this _) hm + · sorry + )⟩ +#exit lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where From 778f1dffeed95ab5355233913647f7281fabdcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 24 Dec 2025 14:04:51 +0100 Subject: [PATCH 62/81] lemmas about the dimension --- .../AnodyneExtensions/RelativeCellComplex.lean | 5 +++-- .../SimplicialSet/Boundary.lean | 5 +++++ .../AlgebraicTopology/SimplicialSet/Horn.lean | 9 +++++++++ .../SimplicialSet/StdSimplex.lean | 18 ++++++++++++++++++ Mathlib/Data/Fintype/Basic.lean | 6 ++++++ Mathlib/Order/Fin/Basic.lean | 5 +++++ 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 44a299c32c7f00..31f6293bcfe595 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -190,7 +190,9 @@ lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : @[simp] lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : - (f.filtration j).preimage c.map = c.horn := sorry + (f.filtration j).preimage c.map = c.horn := by + obtain ⟨x, hx⟩ := c + sorry def Cells.mapHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.filtration j := Subcomplex.lift (c.horn.ι ≫ c.map) (by @@ -242,7 +244,6 @@ lemma isPullback (j : ι) (hj : ¬ IsMax j) : · sorry )⟩ -#exit lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean index f4b6aa0f6b4642..8039878147c405 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Boundary.lean @@ -47,4 +47,9 @@ lemma boundary_eq_iSup (n : ℕ) : simp [stdSimplex.face_obj, boundary, Function.Surjective] tauto +instance {n : ℕ} : HasDimensionLT (boundary n) n := by + rw [boundary_eq_iSup, hasDimensionLT_iSup_iff] + intro i + exact stdSimplex.hasDimensionLT_face _ _ (by simp [Finset.card_compl]) + end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index cdb454ac2d71e2..975f590b0c5dc9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -39,6 +39,10 @@ def horn (n : ℕ) (i : Fin (n + 1)) : (Δ[n] : SSet.{u}).Subcomplex where /-- The `i`-th horn `Λ[n, i]` of the standard `n`-simplex -/ scoped[Simplicial] notation3 "Λ[" n ", " i "]" => SSet.horn (n : ℕ) i +lemma stdSimplex.mem_horn_iff {n : ℕ} (i : Fin (n + 1)) {m : SimplexCategoryᵒᵖ} + (x : (Δ[n] : SSet.{u}).obj m) : + x ∈ (horn n i).obj m ↔ Set.range (stdSimplex.asOrderHom x) ∪ {i} ≠ Set.univ := Iff.rfl + lemma horn_eq_iSup (n : ℕ) (i : Fin (n + 1)) : horn.{u} n i = ⨆ (j : ({i}ᶜ : Set (Fin (n + 1)))), stdSimplex.face {j.1}ᶜ := by @@ -46,6 +50,11 @@ lemma horn_eq_iSup (n : ℕ) (i : Fin (n + 1)) : simp [stdSimplex.face_obj, horn, Set.eq_univ_iff_forall] rfl +instance {n : ℕ} (i : Fin (n + 1)) : HasDimensionLT (horn.{u} n i) n := by + rw [horn_eq_iSup, hasDimensionLT_iSup_iff] + intro i + exact stdSimplex.hasDimensionLT_face _ _ (by simp [Finset.card_compl]) + lemma face_le_horn {n : ℕ} (i j : Fin (n + 1)) (h : i ≠ j) : stdSimplex.face.{u} {i}ᶜ ≤ horn n j := by rw [horn_eq_iSup] diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 23efcb68add7a2..cb3901e475d754 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -185,6 +185,12 @@ lemma face_inter_face {n : ℕ} (S₁ S₂ : Finset (Fin (n + 1))) : face S₁ ⊓ face S₂ = face (S₁ ⊓ S₂) := by aesop +@[simp] +lemma face_bot (n : ℕ) : + face.{u} (∅ : Finset (Fin (n + 1))) = ⊥ := by + ext + simpa using Finset.univ_neq_empty _ + end stdSimplex lemma yonedaEquiv_comp {X Y : SSet.{u}} {n : SimplexCategory} @@ -409,6 +415,18 @@ instance {X : SSet.{u}} {n : ℕ} (x : X _⦋n⦌) : rw [← Subcomplex.range_eq_ofSimplex] infer_instance +lemma hasDimensionLT_face {n : ℕ} (S : Finset (Fin (n + 1))) + (d : ℕ) (hd : S.card ≤ d) : + HasDimensionLT (face.{u} S) d := by + generalize hm : S.card = m + obtain _ | m := m + · obtain rfl : S = ∅ := by rwa [← Finset.card_eq_zero] + rw [face_bot] + infer_instance + · rw [← hasDimensionLT_iff_of_iso + (isoOfRepresentableBy (faceRepresentableBy S m (monoEquivOfFin S (by simpa))))] + exact hasDimensionLT_of_le _ (m + 1) _ + end stdSimplex section Examples diff --git a/Mathlib/Data/Fintype/Basic.lean b/Mathlib/Data/Fintype/Basic.lean index 947236b4792127..ebe6abdfd40751 100644 --- a/Mathlib/Data/Fintype/Basic.lean +++ b/Mathlib/Data/Fintype/Basic.lean @@ -294,3 +294,9 @@ theorem exists_seq_of_forall_finset_exists' {α : Type*} (P : α → Prop) (r : · unfold Function.onFun apply symm exact hf' n m h + +lemma Finset.univ_neq_empty (α : Type*) [Fintype α] [Nonempty α] : + (Finset.univ : Finset α) ≠ ∅ := by + intro h + have := Finset.mem_univ (Classical.arbitrary α) + simp [h] at this diff --git a/Mathlib/Order/Fin/Basic.lean b/Mathlib/Order/Fin/Basic.lean index d140a825f94f57..b4444fb09baee6 100644 --- a/Mathlib/Order/Fin/Basic.lean +++ b/Mathlib/Order/Fin/Basic.lean @@ -402,6 +402,11 @@ def natAddOrderEmb (n) : Fin m ↪o Fin (n + m) := .ofStrictMono (natAdd n) (str def succAboveOrderEmb (p : Fin (n + 1)) : Fin n ↪o Fin (n + 1) := OrderEmbedding.ofStrictMono (succAbove p) (strictMono_succAbove p) +@[simp] +lemma range_succAboveOrderEmb {n : ℕ} (i : Fin (n + 1)) : + Set.range (Fin.succAboveOrderEmb i) = {i}ᶜ := by + aesop + /-! ### Uniqueness of order isomorphisms -/ variable {α : Type*} [Preorder α] From 557980374e70a1a8dac96c7a39bedbf3974b4f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 5 Mar 2026 09:45:36 +0000 Subject: [PATCH 63/81] fix --- .../SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index c3429ba7c67c59..ef68409fcab0cd 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -115,6 +115,7 @@ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] intro j hj exact f.filtration_monotone hj.le +set_option backward.isDefEq.respectTransparency false in lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : ⨆ (i : ι), f.filtration i = ⊤ := by let B := ⨆ (i : ι), f.filtration i From 6ac50106fa561ee0d344ab75cddefd7eef926179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 26 Mar 2026 14:58:10 +0100 Subject: [PATCH 64/81] wip --- .../RelativeCellComplex.lean | 76 ++++++++++++++----- .../AlgebraicTopology/SimplicialSet/Horn.lean | 16 ++++ Mathlib/CategoryTheory/Subfunctor/Basic.lean | 6 +- 3 files changed, 78 insertions(+), 20 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 9ad60bdbd25c92..452b340703587d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -44,7 +44,7 @@ abbrev dim : ℕ := c.1.1.dim noncomputable def index : Fin (c.dim + 2) := (P.isUniquelyCodimOneFace c.1).index rfl -protected noncomputable def horn : +protected noncomputable abbrev horn : (Δ[c.dim + 1] : SSet.{u}).Subcomplex := SSet.horn _ c.index @@ -52,10 +52,15 @@ abbrev cast : A.N := (P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq abbrev simplex : X _⦋c.dim + 1⦌ := c.cast.simplex -abbrev map {j : ι} (c : f.Cells j) : +abbrev map : Δ[c.dim + 1] ⟶ X := yonedaEquiv.symm c.simplex +lemma map_add_objEquiv_symm_δ_index : + c.map.app (op ⦋_⦌) (stdSimplex.objEquiv.symm (SimplexCategory.δ c.index)) = + c.1.1.simplex := + (P.isUniquelyCodimOneFace c.1).δ_index rfl + end Cells noncomputable abbrev basicCell (i : ι) (c : f.Cells i) := c.horn.ι @@ -160,6 +165,22 @@ lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) c.mapToSucc ≫ (f.filtration (Order.succ j)).ι = c.map := rfl +variable {f} in +lemma Cells.simplex_not_mem_filtration_obj {j : ι} (x : f.Cells j) : + x.1.1.simplex ∉ (f.filtration j).obj _ := by + simp only [filtration, Subfunctor.max_obj, Subfunctor.iSup_obj, Set.mem_union, + Set.mem_iUnion, not_or, not_exists] + refine ⟨x.1.1.notMem, fun i hi y h ↦ ?_⟩ + rw [← x.2, ← y.2] at hi + have : P.AncestralRel x.1 y.1 := by + refine ⟨fun hxy ↦ ?_, lt_of_le_of_ne ?_ ((P.ne _ _).symm)⟩ + · rw [hxy] at hi + exact (lt_irrefl _ hi).elim + · rw [← ofSimplex_le_iff] at h + rw [Subcomplex.N.le_iff, SSet.N.le_iff] + exact le_of_le_of_eq h (S.subcomplex_cast _ (by simp)) + exact lt_irrefl _ (hi.trans (f.lt this)) + section noncomputable abbrev sigmaHorn (j : ι) := ∐ (fun (c : f.Cells j) ↦ (c.horn : SSet)) @@ -174,6 +195,14 @@ noncomputable abbrev Cells.ιSigmaStdSimplex {j : ι} (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.sigmaStdSimplex j := Sigma.ι (fun (c : f.Cells j) ↦ Δ[c.dim + 1]) c +omit [P.IsProper] in +lemma ιSigmaStdSimplex_jointly_surjective + {d : ℕ} {j : ι} (a : (f.sigmaStdSimplex j) _⦋d⦌) : + ∃ (c : f.Cells j) (x : Δ[c.dim + 1] _⦋d⦌), c.ιSigmaStdSimplex.app _ x = a := + Limits.Cofan.inj_jointly_surjective_of_isColimit + ((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ + (coproductIsCoproduct _))) a + noncomputable def m (j : ι) : f.sigmaHorn j ⟶ f.sigmaStdSimplex j := Limits.Sigma.map (basicCell _ _) @@ -192,8 +221,12 @@ lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : @[simp] lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : (f.filtration j).preimage c.map = c.horn := by - obtain ⟨x, hx⟩ := c - sorry + refine le_antisymm ?_ ?_ + · rw [stdSimplex.subcomplex_le_horn_iff, stdSimplex.face_singleton_compl, + Subfunctor.ofSection_le_iff, preimage_obj, Set.mem_preimage] + refine fun h ↦ c.simplex_not_mem_filtration_obj ?_ + rwa [Cells.map_add_objEquiv_symm_δ_index] at h + · sorry noncomputable def Cells.mapHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.filtration j := Subcomplex.lift (c.horn.ι ≫ c.map) (by @@ -208,7 +241,7 @@ noncomputable def t (j : ι) : f.sigmaHorn j ⟶ f.filtration j := set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] -lemma Cells.ιSigmaHorn_t {j : ι} (c : f.Cells j) : +lemma Cells.ι_t {j : ι} (c : f.Cells j) : c.ιSigmaHorn ≫ f.t j = c.mapHorn:= by simp [t] @@ -220,7 +253,7 @@ noncomputable def b (j : ι) : set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] -lemma ι_b {j : ι} (c : f.Cells j) : +lemma Cells.ι_b {j : ι} (c : f.Cells j) : c.ιSigmaStdSimplex ≫ f.b j = c.mapToSucc := by simp [b] @[reassoc] @@ -229,8 +262,8 @@ lemma w (j : ι) : ext c : 1 simp [← cancel_mono (Subcomplex.ι _)] -set_option backward.isDefEq.respectTransparency false in -lemma isPullback (j : ι) (hj : ¬ IsMax j) : +--set_option backward.isDefEq.respectTransparency false in +lemma isPullback (j : ι) (_ : ¬ IsMax j) : IsPullback (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j @@ -240,13 +273,23 @@ lemma isPullback (j : ι) (hj : ¬ IsMax j) : induction d using SimplexCategory.rec with | _ d rw [Types.isPullback_iff] dsimp - refine ⟨congr_app (f.w j) (op ⦋d⦌), ?_, ?_⟩ - · intro a₁ a₂ ⟨ht, hm⟩ - have : Mono (f.m j) := inferInstance - rw [NatTrans.mono_iff_mono_app] at this - exact (mono_iff_injective _).1 (this _) hm - · sorry - )⟩ + refine ⟨congr_app (f.w j) (op ⦋d⦌), + fun a₁ a₂ h ↦ (mono_iff_injective _).1 + ((NatTrans.mono_iff_mono_app (f.m j)).1 inferInstance _) h.2, fun y b h ↦ ?_⟩ + obtain ⟨x, b, rfl⟩ := f.ιSigmaStdSimplex_jointly_surjective b + have hb : b ∈ Λ[_, x.index].obj _ := by + obtain ⟨y, hy⟩ := y + simp only [← x.preimage_filtration_map] + rw [Subtype.ext_iff] at h + dsimp at h + subst h + rwa [← FunctorToTypes.comp, x.ι_b] at hy + refine ⟨x.ιSigmaHorn.app _ ⟨b, hb⟩, ?_, by simp [← FunctorToTypes.comp]⟩ + rw [Subtype.ext_iff] at h ⊢ + dsimp at h + rw [← FunctorToTypes.comp, x.ι_b] at h + rw [← FunctorToTypes.comp, x.ι_t] + exact h.symm)⟩ set_option backward.isDefEq.respectTransparency false in lemma isPushout (j : ι) (hj : ¬ IsMax j) : @@ -260,8 +303,7 @@ lemma isPushout (j : ι) (hj : ¬ IsMax j) : dsimp refine Limits.Types.isPushout_of_isPullback_of_mono' ((f.isPullback j hj).map ((CategoryTheory.evaluation _ _).obj (op ⦋d⦌))) - sorry sorry - )⟩ + sorry sorry)⟩ end diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index 36dabad57abc57..02a98eeae53855 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -83,6 +83,22 @@ lemma horn_obj_zero (n : ℕ) (i : Fin (n + 3)) : fin_cases a exact Ne.symm hk.2 +lemma stdSimplex.subcomplex_le_horn_iff {n : ℕ} + (A : (Δ[n + 1] : SSet.{u}).Subcomplex) (i : Fin (n + 2)) : + A ≤ horn (n + 1) i ↔ ¬ face {i}ᶜ ≤ A := by + refine ⟨fun hA h ↦ ?_, fun h ↦ ?_⟩ + · replace h := h.trans hA + rw [face_singleton_compl, Subcomplex.ofSimplex_le_iff, mem_horn_iff] at h + apply h + change Set.range (Fin.succAboveOrderEmb i) ∪ _ = _ + rw [Fin.range_succAboveOrderEmb] + exact Set.compl_union_self {i} + · rw [Subcomplex.le_iff_contains_nonDegenerate] + intro d x hx + by_cases! hd : d < n + · sorry + · sorry + namespace horn open SimplexCategory Finset Opposite diff --git a/Mathlib/CategoryTheory/Subfunctor/Basic.lean b/Mathlib/CategoryTheory/Subfunctor/Basic.lean index 6c4a89dbe70309..bb44994bd201dd 100644 --- a/Mathlib/CategoryTheory/Subfunctor/Basic.lean +++ b/Mathlib/CategoryTheory/Subfunctor/Basic.lean @@ -109,12 +109,12 @@ lemma sInf_obj (S : Set (Subfunctor F)) (U : C) : (sInf S).obj U = sInf (Set.image (fun T ↦ T.obj U) S) := rfl @[simp] -lemma iSup_obj {ι : Type*} (S : ι → Subfunctor F) (U : C) : +lemma iSup_obj {ι : Sort*} (S : ι → Subfunctor F) (U : C) : (⨆ i, S i).obj U = ⋃ i, (S i).obj U := by simp [iSup, sSup_obj] @[simp] -lemma iInf_obj {ι : Type*} (S : ι → Subfunctor F) (U : C) : +lemma iInf_obj {ι : Sort*} (S : ι → Subfunctor F) (U : C) : (⨅ i, S i).obj U = ⋂ i, (S i).obj U := by simp [iInf, sInf_obj] @@ -130,7 +130,7 @@ lemma max_min (S₁ S₂ T : Subfunctor F) : (S₁ ⊔ S₂) ⊓ T = (S₁ ⊓ T) ⊔ (S₂ ⊓ T) := by aesop -lemma iSup_min {ι : Type*} (S : ι → Subfunctor F) (T : Subfunctor F) : +lemma iSup_min {ι : Sort*} (S : ι → Subfunctor F) (T : Subfunctor F) : (⨆ i, S i) ⊓ T = ⨆ i, S i ⊓ T := by aesop From 9449aa3bcf14cceaa46e80b54fe4207bfdc2ee90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 27 Mar 2026 17:16:16 +0100 Subject: [PATCH 65/81] wip --- .../IsUniquelyCodimOneFace.lean | 7 + .../AnodyneExtensions/Pairing.lean | 8 + .../RelativeCellComplex.lean | 159 +++++++++++++----- .../AlgebraicTopology/SimplicialSet/Horn.lean | 40 ++++- .../SimplicialSet/NonDegenerateSimplices.lean | 20 +++ .../NonDegenerateSimplicesSubcomplex.lean | 15 ++ .../SimplicialSet/Simplices.lean | 3 + .../SimplicialSet/StdSimplex.lean | 98 +++++++++++ 8 files changed, 305 insertions(+), 45 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean index cd19b48a6cdecd..ae49b956529d95 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/IsUniquelyCodimOneFace.lean @@ -95,6 +95,13 @@ lemma le : x ≤ y := by ← this] exact ⟨(SimplexCategory.δ _).op, rfl⟩ +set_option backward.isDefEq.respectTransparency false in +include hxy in +lemma unique (f : ⦋d⦌ ⟶ ⦋d + 1⦌) [Mono f] + (hf : X.map f.op (y.cast (by rw [hxy.dim_eq, hd])).simplex = (x.cast hd).simplex) : + f = SimplexCategory.δ (hxy.index hd) := + (hxy.cast hd).2.unique ⟨inferInstance, hf⟩ ⟨inferInstance, hxy.δ_index hd⟩ + end end IsUniquelyCodimOneFace diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean index db7323c6db44b3..f9c34a351865eb 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Pairing.lean @@ -134,6 +134,14 @@ lemma ne (x : P.I) (y : P.II) : have : x ∈ P.I ∩ P.II := ⟨hx, hy⟩ simp [P.inter] at this +lemma le [P.IsProper] (x : P.II) : + x.1 ≤ (P.p x).1 := + (P.isUniquelyCodimOneFace x).le + +lemma lt [P.IsProper] (x : P.II) : + x.1 < (P.p x).1 := + lt_of_le_of_ne' (P.le x) (P.ne _ _) + end Pairing end SSet.Subcomplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 452b340703587d..0dad013ba672c9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -25,13 +25,23 @@ universe v u open CategoryTheory HomotopicalAlgebra Simplicial Limits Opposite +namespace SSet + +lemma stdSimplex.map_objEquiv_op_apply + {X : SSet.{u}} {n : SimplexCategory} (x : X.obj (op n)) + {m : SimplexCategoryᵒᵖ} (y : (stdSimplex.obj n).obj m) : + X.map (stdSimplex.objEquiv y).op x = (yonedaEquiv.symm x).app m y := + rfl + +end SSet + namespace SSet.Subcomplex.Pairing variable {X : SSet.{u}} {A : X.Subcomplex} {P : A.Pairing} namespace RankFunction -variable [P.IsProper] {ι : Type v} [LinearOrder ι] (f : P.RankFunction ι) +variable {ι : Type v} [LinearOrder ι] (f : P.RankFunction ι) def Cells (i : ι) : Type u := { s : P.II // f.rank s = i } @@ -41,6 +51,8 @@ variable {f} {i : ι} (c : f.Cells i) abbrev dim : ℕ := c.1.1.dim +variable [P.IsProper] + noncomputable def index : Fin (c.dim + 2) := (P.isUniquelyCodimOneFace c.1).index rfl @@ -50,26 +62,66 @@ protected noncomputable abbrev horn : abbrev cast : A.N := (P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq -abbrev simplex : X _⦋c.dim + 1⦌ := c.cast.simplex +--abbrev simplex : X _⦋c.dim + 1⦌ := c.cast.simplex + +/-lemma ofSimplex_simplex : + Subcomplex.ofSimplex c.simplex = (P.p c.1).1.subcomplex := by + rw [S.ofSimplex_eq_subcomplex_mk] + congr 1 + exact S.cast_eq_self _ (by simp)-/ abbrev map : Δ[c.dim + 1] ⟶ X := - yonedaEquiv.symm c.simplex + yonedaEquiv.symm c.cast.simplex + +@[simp] +lemma range_map : Subcomplex.range c.map = (P.p c.1).1.subcomplex := by + rw [range_eq_ofSimplex, Equiv.apply_symm_apply, S.ofSimplex_eq_subcomplex_mk, + ← S.cast_eq_self _ (P.dim_p c.1)] + rfl lemma map_add_objEquiv_symm_δ_index : c.map.app (op ⦋_⦌) (stdSimplex.objEquiv.symm (SimplexCategory.δ c.index)) = c.1.1.simplex := (P.isUniquelyCodimOneFace c.1).δ_index rfl +lemma subcomplex_not_le_image_horn : + ¬ c.1.1.subcomplex ≤ c.horn.image c.map := by + intro h + simp only [Subfunctor.ofSection_le_iff, image_obj, Set.mem_image] at h + obtain ⟨x, h₁, h₂⟩ := h + obtain ⟨g, rfl⟩ := stdSimplex.objEquiv.symm.surjective x + dsimp at g + rw [← stdSimplex.map_objEquiv_op_apply, Equiv.apply_symm_apply] at h₂ + have := mono_of_nonDegenerate (x:= ⟨_, c.1.1.nonDegenerate⟩) _ _ _ h₂ + obtain rfl := (P.isUniquelyCodimOneFace c.1).unique rfl _ h₂ + rw [← ofSimplex_le_iff, stdSimplex.subcomplex_le_horn_iff, + ← stdSimplex.face_singleton_compl] at h₁ + tauto + +lemma image_horn_lt_subcomplex : + c.horn.image c.map < (P.p c.1).1.subcomplex := by + rw [lt_iff_le_and_ne] + refine ⟨by simpa using image_le_range c.horn c.map, + fun h ↦ c.subcomplex_not_le_image_horn (by simpa only [h] using P.le c.1)⟩ + +@[simp] +lemma image_face_index_compl : + (stdSimplex.face {c.index}ᶜ).image c.map = c.1.1.subcomplex := by + rw [stdSimplex.face_singleton_compl, image_ofSimplex] + congr 1 + exact (P.isUniquelyCodimOneFace c.1).δ_index rfl + end Cells +variable [P.IsProper] in noncomputable abbrev basicCell (i : ι) (c : f.Cells i) := c.horn.ι def filtration (i : ι) : X.Subcomplex := - A ⊔ ⨆ (j : ι) (_ : j < i) (c : f.Cells j), .ofSimplex c.simplex + A ⊔ ⨆ (j : ι) (_ : j < i) (c : f.Cells j), (P.p c.1).1.subcomplex -lemma simplex_le_filtration {j : ι} (c : f.Cells j) {i : ι} (h : j < i) : - Subcomplex.ofSimplex c.simplex ≤ f.filtration i := by +lemma subcomplex_le_filtration {j : ι} (c : f.Cells j) {i : ι} (h : j < i) : + (P.p c.1).1.subcomplex ≤ f.filtration i := by refine le_trans ?_ le_sup_right refine le_trans ?_ (le_iSup _ j) refine le_trans ?_ (le_iSup _ h) @@ -78,6 +130,7 @@ lemma simplex_le_filtration {j : ι} (c : f.Cells j) {i : ι} (h : j < i) : @[simp] lemma le_filtration (i : ι) : A ≤ f.filtration i := le_sup_left +@[simp] lemma filtration_bot [OrderBot ι] : f.filtration ⊥ = A := by simp [filtration] @@ -86,22 +139,22 @@ lemma filtration_monotone : Monotone f.filtration := by rw [filtration] simp only [sup_le_iff, iSup_le_iff, le_filtration, true_and] intro j hj c - exact f.simplex_le_filtration c (lt_of_lt_of_le hj h) + exact f.subcomplex_le_filtration c (lt_of_lt_of_le hj h) lemma filtration_succ [SuccOrder ι] (i : ι) (hi : ¬ IsMax i) : f.filtration (Order.succ i) = - f.filtration i ⊔ ⨆ (c : f.Cells i), .ofSimplex c.simplex := by + f.filtration i ⊔ ⨆ (c : f.Cells i), (P.p c.1).1.subcomplex := by apply le_antisymm · rw [filtration] simp only [sup_le_iff, iSup_le_iff] refine ⟨(f.le_filtration _).trans le_sup_left, fun j hj c ↦ ?_⟩ rw [Order.lt_succ_iff_of_not_isMax hi] at hj obtain hj | rfl := hj.lt_or_eq - · exact (f.simplex_le_filtration _ hj).trans le_sup_left + · exact (f.subcomplex_le_filtration _ hj).trans le_sup_left · exact le_trans (le_trans (by rfl) (le_iSup _ c)) le_sup_right · simp only [sup_le_iff, iSup_le_iff] exact ⟨f.filtration_monotone (Order.le_succ i), - fun c ↦ f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hi)⟩ + fun c ↦ f.subcomplex_le_filtration _ (Order.lt_succ_of_not_isMax hi)⟩ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] (i : ι) (hi : Order.IsSuccLimit i) : @@ -115,33 +168,11 @@ lemma filtration_of_isSuccLimit [OrderBot ι] [SuccOrder ι] · refine le_trans ?_ (le_iSup _ (Order.succ j)) refine le_trans ?_ (le_iSup _ (by rwa [← Order.IsSuccLimit.succ_lt_iff hi] at hj)) - exact f.simplex_le_filtration _ (Order.lt_succ_of_not_isMax hj.not_isMax) + exact f.subcomplex_le_filtration _ (Order.lt_succ_of_not_isMax hj.not_isMax) · simp only [iSup_le_iff] intro j hj exact f.filtration_monotone hj.le -set_option backward.isDefEq.respectTransparency false in -lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : - ⨆ (i : ι), f.filtration i = ⊤ := by - let B := ⨆ (i : ι), f.filtration i - suffices ∀ (s : A.N), s.simplex ∈ B.obj _ by - rw [eq_top_iff_contains_nonDegenerate] - intro n s hs - by_cases hs₀ : s ∈ A.obj _ - · exact le_iSup f.filtration ⊥ _ (by rwa [filtration_bot]) - · exact this (N.mk _ hs hs₀) - suffices ∀ (y : P.II), ofSimplex (P.p y).1.simplex ≤ B by - intro s - obtain ⟨y, (rfl | rfl)⟩ := P.exists_or s - · rw [← Subcomplex.ofSimplex_le_iff] - refine ((S.le_def ..).1 (P.isUniquelyCodimOneFace y).le).trans (this y) - · rw [← Subcomplex.ofSimplex_le_iff] - exact this y - intro y - exact le_trans (by simp [Cells.simplex]) - ((f.simplex_le_filtration ⟨y, rfl⟩ (Order.lt_succ (f.rank y))).trans - (le_iSup f.filtration _)) - lemma iSup_filtration_iio [OrderBot ι] [SuccOrder ι] (m : ι) (hm : Order.IsSuccLimit m) : ⨆ (i : Set.Iio m), f.filtration i = f.filtration m := le_antisymm (by @@ -151,23 +182,43 @@ lemma iSup_filtration_iio [OrderBot ι] [SuccOrder ι] (m : ι) (hm : Order.IsSu rw [filtration] simp only [sup_le_iff, iSup_le_iff, ← f.filtration_bot] exact ⟨le_trans (by rfl) (le_iSup _ ⟨⊥, hm.bot_lt⟩), fun j hj c ↦ - (f.simplex_le_filtration c (Order.lt_succ_of_not_isMax (not_isMax_of_lt hj))).trans + (f.subcomplex_le_filtration c (Order.lt_succ_of_not_isMax (not_isMax_of_lt hj))).trans (le_trans (by rfl) (le_iSup _ ⟨Order.succ j, hm.succ_lt_iff.2 hj⟩))⟩) +variable [P.IsProper] + +set_option backward.isDefEq.respectTransparency false in +lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : + ⨆ (i : ι), f.filtration i = ⊤ := by + refine le_antisymm (by simp) ?_ + rw [N.subcomplex_le_iff] + intro s _ + induction s using SSet.Subcomplex.N.cases A with + | mem s hs => exact hs.trans (le_trans (by simp) (le_iSup _ ⊥)) + | notMem s => + obtain ⟨t, ht⟩ := P.exists_or s + refine le_trans ?_ + (le_trans (f.subcomplex_le_filtration ⟨t, rfl⟩ (Order.lt_succ _)) (le_iSup _ _)) + obtain rfl | rfl := ht + · exact P.le t + · rfl + def Cells.mapToSucc {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.filtration (Order.succ j) := Subcomplex.lift c.map (by - rw [range_eq_ofSimplex, Cells.map, Equiv.apply_symm_apply] - exact f.simplex_le_filtration c (Order.lt_succ _)) + rw [range_map] + exact f.subcomplex_le_filtration c (Order.lt_succ _)) @[reassoc (attr := simp)] lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) : c.mapToSucc ≫ (f.filtration (Order.succ j)).ι = c.map := rfl +omit [P.IsProper] in variable {f} in -lemma Cells.simplex_not_mem_filtration_obj {j : ι} (x : f.Cells j) : - x.1.1.simplex ∉ (f.filtration j).obj _ := by +lemma Cells.subcomplex_not_le_filtration {j : ι} (x : f.Cells j) : + ¬ x.1.1.subcomplex ≤ f.filtration j := by + rw [ofSimplex_le_iff] simp only [filtration, Subfunctor.max_obj, Subfunctor.iSup_obj, Set.mem_union, Set.mem_iUnion, not_or, not_exists] refine ⟨x.1.1.notMem, fun i hi y h ↦ ?_⟩ @@ -177,8 +228,7 @@ lemma Cells.simplex_not_mem_filtration_obj {j : ι} (x : f.Cells j) : · rw [hxy] at hi exact (lt_irrefl _ hi).elim · rw [← ofSimplex_le_iff] at h - rw [Subcomplex.N.le_iff, SSet.N.le_iff] - exact le_of_le_of_eq h (S.subcomplex_cast _ (by simp)) + rwa [Subcomplex.N.le_iff, SSet.N.le_iff] exact lt_irrefl _ (hi.trans (f.lt this)) section @@ -222,11 +272,34 @@ lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : (f.filtration j).preimage c.map = c.horn := by refine le_antisymm ?_ ?_ - · rw [stdSimplex.subcomplex_le_horn_iff, stdSimplex.face_singleton_compl, + · simpa only [stdSimplex.subcomplex_le_horn_iff, ← Subcomplex.image_le_iff, + Cells.image_face_index_compl] using c.subcomplex_not_le_filtration + /-rw [stdSimplex.subcomplex_le_horn_iff, stdSimplex.face_singleton_compl, Subfunctor.ofSection_le_iff, preimage_obj, Set.mem_preimage] refine fun h ↦ c.simplex_not_mem_filtration_obj ?_ - rwa [Cells.map_add_objEquiv_symm_δ_index] at h - · sorry + rwa [Cells.map_add_objEquiv_symm_δ_index] at h-/ + · rw [← Subcomplex.image_le_iff, N.subcomplex_le_iff] + intro s hs + induction s using SSet.Subcomplex.N.cases A with + | mem s hs' => exact hs'.trans (by simp) + | notMem s => + obtain ⟨t, ht⟩ := P.exists_or s + rw [← c.prop] + refine le_trans ?_ (f.subcomplex_le_filtration ⟨t, rfl⟩ (f.lt ?_)) + · obtain rfl | rfl := ht + · exact P.le t + · simp + · replace hs : t.1.subcomplex ≤ c.horn.image c.map := by + obtain rfl | rfl := ht + · exact hs + · refine le_trans ?_ hs + rw [← S.le_def] + exact (P.isUniquelyCodimOneFace t).le + refine ⟨?_, ?_⟩ + · rintro rfl + exact c.subcomplex_not_le_image_horn hs + · rw [Subcomplex.N.lt_iff, SSet.N.lt_iff] + exact lt_of_le_of_lt hs (c.image_horn_lt_subcomplex) noncomputable def Cells.mapHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.filtration j := Subcomplex.lift (c.horn.ι ≫ c.map) (by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index 02a98eeae53855..8f3ccc0a303bca 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -83,6 +83,26 @@ lemma horn_obj_zero (n : ℕ) (i : Fin (n + 3)) : fin_cases a exact Ne.symm hk.2 +set_option backward.isDefEq.respectTransparency false in +lemma horn_obj_eq_top {n : ℕ} (i : Fin (n + 1)) (m : ℕ) (h : m + 1 < n := by lia) : + (horn.{u} n i).obj (op ⦋m⦌) = ⊤ := by + ext x + obtain ⟨f, rfl⟩ := stdSimplex.objEquiv.symm.surjective x + obtain ⟨j, hij, hj⟩ : ∃ (j : Fin (n + 1)), j ≠ i ∧ j ∉ Set.range f.toOrderHom := by + by_contra! + have : Finset.image f.toOrderHom ⊤ ∪ {i} = ⊤ := by + ext k + by_cases k = i <;> aesop + have := (congr_arg Finset.card this).symm.le.trans (Finset.card_union_le _ _) + simp only [SimplexCategory.len_mk, Finset.top_eq_univ, Finset.card_univ, Fintype.card_fin, + Finset.card_singleton, add_le_add_iff_right] at this + have : n ≤ m + 1 := by simpa using this.trans Finset.card_image_le + lia + simp only [Set.top_eq_univ, horn_eq_iSup, Subfunctor.iSup_obj, Set.iUnion_coe_set, + Set.mem_compl_iff, Set.mem_singleton_iff, Set.mem_iUnion, stdSimplex.mem_face_iff, + Finset.mem_compl, Finset.mem_singleton, exists_prop, Set.mem_univ, iff_true] + exact ⟨j, hij, fun k hk ↦ hj ⟨k, hk⟩⟩ + lemma stdSimplex.subcomplex_le_horn_iff {n : ℕ} (A : (Δ[n + 1] : SSet.{u}).Subcomplex) (i : Fin (n + 2)) : A ≤ horn (n + 1) i ↔ ¬ face {i}ᶜ ≤ A := by @@ -96,8 +116,24 @@ lemma stdSimplex.subcomplex_le_horn_iff {n : ℕ} · rw [Subcomplex.le_iff_contains_nonDegenerate] intro d x hx by_cases! hd : d < n - · sorry - · sorry + · simp [horn_obj_eq_top i d] + · obtain ⟨⟨S, hS⟩, rfl⟩ := stdSimplex.nonDegenerateEquiv'.symm.surjective x + dsimp at hS + simp only [stdSimplex.nonDegenerateEquiv'_symm_mem_iff_face_le] at hx ⊢ + obtain hd | rfl := hd.lt_or_eq + · obtain rfl : S = .univ := by + rw [← Finset.card_eq_iff_eq_univ, Fintype.card_fin] + exact le_antisymm (card_finset_fin_le S) (by lia) + exact (h (le_trans (by simp) hx)).elim + · replace hS : Sᶜ.card = 1 := by + have := S.card_compl_add_card + rw [Fintype.card_fin] at this + lia + obtain ⟨j, rfl⟩ : ∃ j, S = {j}ᶜ := by + rw [Finset.card_eq_one] at hS + obtain ⟨j, hS⟩ := hS + exact ⟨j, by simp [← hS]⟩ + exact face_le_horn _ _ (by rintro rfl; tauto) namespace horn diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index 316fe1700ea0ad..d68f4dbfffba8c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -53,6 +53,12 @@ lemma mk_surjective (x : X.N) : ∃ (n : ℕ) (y : X.nonDegenerate n), x = N.mk _ y.prop := ⟨x.dim, ⟨_, x.nonDegenerate⟩, rfl⟩ +@[elab_as_elim] +def induction {motive : X.N → Sort*} + (mk : ∀ (n : ℕ) (x : X.nonDegenerate n), motive (mk x.1 x.2)) (s : X.N) : + motive s := + mk s.dim ⟨_, s.nonDegenerate⟩ + lemma ext_iff (x y : X.N) : x = y ↔ x.toS = y.toS := by grind [cases SSet.N] @@ -62,6 +68,9 @@ instance : Preorder X.N := Preorder.lift toS lemma le_iff {x y : X.N} : x ≤ y ↔ x.subcomplex ≤ y.subcomplex := Iff.rfl +lemma lt_iff {x y : X.N} : x < y ↔ x.subcomplex < y.subcomplex := + Iff.rfl + lemma le_iff_exists_mono {x y : X.N} : x ≤ y ↔ ∃ (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌) (_ : Mono f), X.map f.op y.simplex = x.simplex := by simp only [le_iff, CategoryTheory.Subfunctor.ofSection_le_iff, @@ -136,6 +145,17 @@ lemma iSup_subcomplex_eq_top : rintro ⟨d, s, hs⟩ exact le_trans (by rfl) (le_iSup _ (N.mk _ hs))) +lemma subcomplex_le_iff {A B : X.Subcomplex} : + A ≤ B ↔ ∀ (s : X.N), s.subcomplex ≤ A → s.subcomplex ≤ B := by + rw [Subcomplex.le_iff_contains_nonDegenerate] + refine ⟨fun h s ↦ ?_, fun h n x hx ↦ ?_⟩ + · induction s using N.induction with + | mk n x => + intro hx + simp only [Subfunctor.ofSection_le_iff, mk_dim, mk_simplex] at hx ⊢ + exact h _ _ hx + · simpa using h (N.mk _ x.prop) (by simpa) + end N /-- The map which sends a non degenerate simplex of a simplicial set to diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean index b386b8cf7d002b..5603741d4ed7b9 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean @@ -57,11 +57,26 @@ lemma ext_iff (x y : A.N) : x = y ↔ x.toN = y.toN := by grind [cases SSet.Subcomplex.N] +variable (A) in +@[elab_as_elim] +lemma cases {motive : X.N → Prop} + (mem : ∀ (s : X.N), s.subcomplex ≤ A → motive s) + (notMem : ∀ (s : A.N), motive s.toN) + (s : X.N) : + motive s := by + by_cases hs : s.subcomplex ≤ A + · exact mem s hs + · exact notMem (.mk' s (by simpa using hs)) + instance : PartialOrder A.N := PartialOrder.lift toN (fun _ _ ↦ by simp [ext_iff]) lemma le_iff {x y : A.N} : x ≤ y ↔ x.toN ≤ y.toN := Iff.rfl + +lemma lt_iff {x y : A.N} : x < y ↔ x.toN < y.toN := + Iff.rfl + section variable (s : A.N) {d : ℕ} (hd : s.dim = d) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean index 07fe73e34f8713..ce08c8c892f20a 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Simplices.lean @@ -102,6 +102,9 @@ lemma ext_iff {n : ℕ} (x y : X _⦋n⦌) : /-- The subcomplex generated by a simplex. -/ abbrev subcomplex (s : X.S) : X.Subcomplex := Subcomplex.ofSimplex s.simplex +lemma ofSimplex_eq_subcomplex_mk {n : ℕ} (x : X _⦋n⦌) : + Subcomplex.ofSimplex x = (S.mk x).subcomplex := rfl + @[simp] lemma subcomplex_cast (s : X.S) {d : ℕ} (hd : s.dim = d) : (s.cast hd).subcomplex = s.subcomplex := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index 2eff31824ccc8e..e0220639ab2fd8 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -244,6 +244,14 @@ lemma face_bot (n : ℕ) : ext simpa using Finset.univ_neq_empty _ +@[simp] +lemma face_univ (n : ℕ) : + face.{u} (.univ : Finset (Fin (n + 1))) = ⊤ := by + ext + dsimp + simp only [Set.mem_univ, iff_true] + apply Finset.subset_univ + end stdSimplex lemma yonedaEquiv_comp {X Y : SSet.{u}} {n : SimplexCategory} @@ -454,6 +462,96 @@ noncomputable def facePairIso {n : ℕ} (i j : Fin (n + 1)) (hij : i < j) : stdSimplex.isoOfRepresentableBy (stdSimplex.faceRepresentableBy.{u} _ _ (Fin.orderIsoPair i j hij)) +set_option backward.isDefEq.respectTransparency false in +variable (n) in +lemma bijective_image_objEquiv_toOrderHom_univ (m : ℕ) : + Function.Bijective (fun (⟨x, hx⟩ : (Δ[n] : SSet.{u}).nonDegenerate m) ↦ + (⟨Finset.image (objEquiv x).toOrderHom .univ, by + dsimp + rw [mem_nonDegenerate_iff_mono, SimplexCategory.mono_iff_injective] at hx + rw [Finset.card_image_of_injective _ (by exact hx), Finset.card_univ, + Fintype.card_fin]⟩ : { S : Finset (Fin (n + 1)) | S.card = m + 1 })) := by + constructor + · rintro ⟨x₁, h₁⟩ ⟨x₂, h₂⟩ h₃ + obtain ⟨f₁, rfl⟩ := objEquiv.symm.surjective x₁ + obtain ⟨f₂, rfl⟩ := objEquiv.symm.surjective x₂ + simp only [mem_nonDegenerate_iff_mono, Equiv.apply_symm_apply, + SimplexCategory.mono_iff_injective, SimplexCategory.len_mk] at h₁ h₂ + simp only [Set.mem_setOf_eq, SimplexCategory.len_mk, Equiv.apply_symm_apply, + Subtype.mk.injEq, EmbeddingLike.apply_eq_iff_eq] at h₃ ⊢ + apply SimplexCategory.Hom.ext + rw [← OrderHom.range_eq_iff h₁ h₂] + ext x + simpa using congr_fun (congrArg Membership.mem h₃) x + · intro ⟨S, hS⟩ + dsimp at hS + let e := monoEquivOfFin S (k := m + 1) (by simpa using hS) + refine ⟨⟨objMk ((OrderHom.Subtype.val _).comp (e.toOrderEmbedding.toOrderHom)), ?_⟩, ?_⟩ + · rw [mem_nonDegenerate_iff_mono, SimplexCategory.mono_iff_injective] + intro a b h + apply e.injective + ext : 1 + exact h + · simp [e, ← Finset.image_image, Finset.image_univ_of_surjective e.surjective] + +noncomputable def nonDegenerateEquiv' {n m : ℕ} : (Δ[n] : SSet.{u}).nonDegenerate m ≃ + { S : Finset (Fin (n + 1)) | S.card = m + 1 } := + Equiv.ofBijective _ (bijective_image_objEquiv_toOrderHom_univ n m) + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma nonDegenerateEquiv'_iff {n m : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate m) (j : Fin (n + 1)) : + j ∈ (nonDegenerateEquiv' x).1 ↔ ∃ (i : Fin (m + 1)), x.1 i = j := by + dsimp [nonDegenerateEquiv'] + aesop + +set_option backward.isDefEq.respectTransparency false in +noncomputable def orderIsoOfNonDegenerate {n m : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate m) : + Fin (m + 1) ≃o (nonDegenerateEquiv' x).1 where + toEquiv := Equiv.ofBijective (fun i ↦ ⟨x.1 i, Finset.mem_image_of_mem _ (by simp)⟩) (by + constructor + · have := (mem_nonDegenerate_iff_mono x.1).1 x.2 + rw [SimplexCategory.mono_iff_injective] at this + exact fun _ _ h ↦ this (by simpa using h) + · rintro ⟨j, hj⟩ + rw [nonDegenerateEquiv'_iff] at hj + aesop) + map_rel_iff' := by + have := (mem_nonDegenerate_iff_mono x.1).1 x.2 + rw [SimplexCategory.mono_iff_injective] at this + intro a b + dsimp + simp only [Subtype.mk_le_mk] + constructor + · rw [← not_lt, ← not_lt] + intro h h' + apply h + obtain h'' | h'' := (monotone_apply x.1 h'.le).lt_or_eq + · assumption + · simp only [this h'', lt_self_iff_false] at h' + · intro h + exact monotone_apply _ h + +lemma face_nonDegenerateEquiv' {n m : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate m) : + face (nonDegenerateEquiv' x).1 = Subcomplex.ofSimplex x.1 := + face_eq_ofSimplex.{u} _ _ (orderIsoOfNonDegenerate x) + +set_option backward.isDefEq.respectTransparency false in +lemma nonDegenerateEquiv'_symm_apply_mem {n m : ℕ} + (S : { S : Finset (Fin (n + 1)) | S.card = m + 1 }) (i : Fin (m + 1)) : + (nonDegenerateEquiv'.{u}.symm S).1 i ∈ S.1 := by + obtain ⟨f, rfl⟩ := nonDegenerateEquiv'.{u}.surjective S + dsimp [nonDegenerateEquiv'] + simp only [Equiv.ofBijective_symm_apply_apply, Finset.mem_image, Finset.mem_univ, true_and] + exact ⟨i, rfl⟩ + +lemma nonDegenerateEquiv'_symm_mem_iff_face_le {n m : ℕ} + (S : { S : Finset (Fin (n + 1)) | S.card = m + 1 }) + (A : (Δ[n] : SSet.{u}).Subcomplex) : + (nonDegenerateEquiv'.symm S).1 ∈ A.obj _ ↔ face S ≤ A := by + obtain ⟨x, rfl⟩ := nonDegenerateEquiv'.{u}.surjective S + rw [face_nonDegenerateEquiv' x, Equiv.symm_apply_apply, Subcomplex.ofSimplex_le_iff] + instance (n : SimplexCategory) (d : SimplexCategoryᵒᵖ) : Finite ((stdSimplex.{u}.obj n).obj d) := by rw [objEquiv.finite_iff] From d810afc8b3e9391b578cd2a5e39ec0927e9f599a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 27 Mar 2026 18:17:24 +0100 Subject: [PATCH 66/81] wip --- .../RelativeCellComplex.lean | 26 ++++++++++++++----- .../AlgebraicTopology/SimplicialSet/Horn.lean | 11 ++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 0dad013ba672c9..fc02cc6f47c735 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -274,10 +274,6 @@ lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : refine le_antisymm ?_ ?_ · simpa only [stdSimplex.subcomplex_le_horn_iff, ← Subcomplex.image_le_iff, Cells.image_face_index_compl] using c.subcomplex_not_le_filtration - /-rw [stdSimplex.subcomplex_le_horn_iff, stdSimplex.face_singleton_compl, - Subfunctor.ofSection_le_iff, preimage_obj, Set.mem_preimage] - refine fun h ↦ c.simplex_not_mem_filtration_obj ?_ - rwa [Cells.map_add_objEquiv_symm_δ_index] at h-/ · rw [← Subcomplex.image_le_iff, N.subcomplex_le_iff] intro s hs induction s using SSet.Subcomplex.N.cases A with @@ -364,6 +360,23 @@ lemma isPullback (j : ι) (_ : ¬ IsMax j) : rw [← FunctorToTypes.comp, x.ι_t] exact h.symm)⟩ +set_option backward.isDefEq.respectTransparency false in +lemma range_homOfLE_app_union_range_b_app (j : ι) (d : SimplexCategoryᵒᵖ) : + Set.range ((homOfLE (f.filtration_monotone (Order.le_succ j))).app d) ⊔ + Set.range ((f.b j).app d) = Set.univ := by + ext ⟨x, hx⟩ + simp only [filtration, Order.lt_succ_iff, Subfunctor.max_obj, Subfunctor.iSup_obj, Set.mem_union, + Set.mem_iUnion, exists_prop, Subfunctor.toFunctor_obj, Set.sup_eq_union, Set.mem_range, + Subtype.ext_iff, Subfunctor.homOfLe_app_coe, Subtype.exists, exists_eq_right, Set.mem_univ, + iff_true] at hx ⊢ + obtain hx | ⟨i, hi, c, hx⟩ := hx + · exact Or.inl (Or.inl hx) + · obtain hi | rfl := hi.lt_or_eq + · exact Or.inl (Or.inr ⟨i, hi, c, hx⟩) + · rw [← c.range_map, ← c.mapToSucc_ι, ← c.ι_b_assoc] at hx + obtain ⟨y, hy⟩ := hx + exact Or.inr ⟨_, hy⟩ + set_option backward.isDefEq.respectTransparency false in lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) @@ -375,8 +388,9 @@ lemma isPushout (j : ι) (hj : ¬ IsMax j) : (IsPushout.isColimit ?_) dsimp refine Limits.Types.isPushout_of_isPullback_of_mono' - ((f.isPullback j hj).map ((CategoryTheory.evaluation _ _).obj (op ⦋d⦌))) - sorry sorry)⟩ + ((f.isPullback j hj).map ((CategoryTheory.evaluation _ _).obj _)) + (f.range_homOfLE_app_union_range_b_app _ _) (fun x y hx hy h ↦ ?_) + sorry)⟩ end diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index 8f3ccc0a303bca..7c069b0a36f836 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -135,6 +135,17 @@ lemma stdSimplex.subcomplex_le_horn_iff {n : ℕ} exact ⟨j, by simp [← hS]⟩ exact face_le_horn _ _ (by rintro rfl; tauto) +lemma stdSimplex.face_le_horn_iff {n : ℕ} (S : Finset (Fin (n + 2))) (j : Fin (n + 2)) : + stdSimplex.face.{u} S ≤ horn (n + 1) j ↔ S ≠ .univ ∧ S ≠ {j}ᶜ := by + rw [stdSimplex.subcomplex_le_horn_iff, face_le_face_iff, ← not_iff_not] + simp only [Finset.le_eq_subset, Decidable.not_not, ne_eq, not_and_or] + refine ⟨fun h ↦ ?_, by rintro (rfl | rfl) <;> simp⟩ + rw [← Finset.compl_subset_compl, compl_compl, + Finset.subset_singleton_iff, Finset.compl_eq_empty_iff] at h + obtain h | h := h + · exact Or.inl h + · exact Or.inr (by simp [← h]) + namespace horn open SimplexCategory Finset Opposite From 6ea70dd5755db48978e7dfe12418fa6ca9f50037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 27 Mar 2026 19:14:19 +0100 Subject: [PATCH 67/81] wip --- .../AnodyneExtensions/RelativeCellComplex.lean | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index fc02cc6f47c735..cf2830fe4ebd00 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -33,6 +33,14 @@ lemma stdSimplex.map_objEquiv_op_apply X.map (stdSimplex.objEquiv y).op x = (yonedaEquiv.symm x).app m y := rfl +lemma Subcomplex.existsN {X : SSet.{u}} {n : ℕ} (s : X _⦋n⦌) {A : X.Subcomplex} + (hs : s ∉ A.obj _) : + ∃ (x : A.N) (f : ⦋n⦌ ⟶ ⦋x.dim⦌), Epi f ∧ X.map f.op x.simplex = s := by + refine ⟨⟨(S.mk s).toN, fun h ↦ hs ?_⟩, ?_⟩ + · simp only [← ofSimplex_le_iff] at h ⊢ + simpa using h + · sorry + end SSet namespace SSet.Subcomplex.Pairing From 780994465d1e0459ed0ef1f461acd3dbe1caf6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 27 Mar 2026 22:53:27 +0100 Subject: [PATCH 68/81] wip --- .../RelativeCellComplex.lean | 205 +++++++++++++++--- .../SimplicialSet/StdSimplex.lean | 5 + 2 files changed, 185 insertions(+), 25 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index cf2830fe4ebd00..52c0d18786dd2c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -41,6 +41,32 @@ lemma Subcomplex.existsN {X : SSet.{u}} {n : ℕ} (s : X _⦋n⦌) {A : X.Subcom simpa using h · sorry +lemma Subcomplex.N.eq_iff_sMk_eq {X : SSet.{u}} {A : X.Subcomplex} (x y : A.N) : + x = y ↔ S.mk x.1.1.2 = S.mk y.1.1.2 := by + rw [N.ext_iff, SSet.N.ext_iff] + +@[simp] +lemma Subcomplex.ofSimplex_map {X : SSet.{u}} {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [Epi f] + (x : X _⦋m⦌) : + ofSimplex (X.map f.op x) = ofSimplex x := by + sorry + +lemma S.eq_iff_ofSimplex_eq {X : SSet.{u}} {n m : ℕ} (x : X _⦋n⦌) (y : X _⦋m⦌) + (hx : x ∈ X.nonDegenerate _) (hy : y ∈ X.nonDegenerate _) : + S.mk x = S.mk y ↔ Subcomplex.ofSimplex x = Subcomplex.ofSimplex y := by + sorry + + +lemma objEquiv_symm_notMem_horn_of_isIso {n : ℕ} (i : Fin (n + 1)) + {d : SimplexCategory} (f : d ⟶ ⦋n⦌) [IsIso f] : + stdSimplex.objEquiv.symm f ∉ (horn n i).obj (op d) := by + sorry + +lemma objEquiv_symm_δ_mem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : + stdSimplex.objEquiv.symm (SimplexCategory.δ i) ∈ (horn _ j).obj _ ↔ + i ≠ j := by + sorry + end SSet namespace SSet.Subcomplex.Pairing @@ -57,6 +83,11 @@ namespace Cells variable {f} {i : ι} (c : f.Cells i) +variable {c} in +@[ext] +lemma ext {c' : f.Cells i} (h : c.1 = c'.1) : c = c' := + Subtype.ext h + abbrev dim : ℕ := c.1.1.dim variable [P.IsProper] @@ -88,7 +119,7 @@ lemma range_map : Subcomplex.range c.map = (P.p c.1).1.subcomplex := by ← S.cast_eq_self _ (P.dim_p c.1)] rfl -lemma map_add_objEquiv_symm_δ_index : +lemma map_app_objEquiv_symm_δ_index : c.map.app (op ⦋_⦌) (stdSimplex.objEquiv.symm (SimplexCategory.δ c.index)) = c.1.1.simplex := (P.isUniquelyCodimOneFace c.1).δ_index rfl @@ -193,6 +224,22 @@ lemma iSup_filtration_iio [OrderBot ι] [SuccOrder ι] (m : ι) (hm : Order.IsSu (f.subcomplex_le_filtration c (Order.lt_succ_of_not_isMax (not_isMax_of_lt hj))).trans (le_trans (by rfl) (le_iSup _ ⟨Order.succ j, hm.succ_lt_iff.2 hj⟩))⟩) +variable {f} in +lemma Cells.subcomplex_not_le_filtration {j : ι} (x : f.Cells j) : + ¬ x.1.1.subcomplex ≤ f.filtration j := by + rw [ofSimplex_le_iff] + simp only [filtration, Subfunctor.max_obj, Subfunctor.iSup_obj, Set.mem_union, + Set.mem_iUnion, not_or, not_exists] + refine ⟨x.1.1.notMem, fun i hi y h ↦ ?_⟩ + rw [← x.2, ← y.2] at hi + have : P.AncestralRel x.1 y.1 := by + refine ⟨fun hxy ↦ ?_, lt_of_le_of_ne ?_ ((P.ne _ _).symm)⟩ + · rw [hxy] at hi + exact (lt_irrefl _ hi).elim + · rw [← ofSimplex_le_iff] at h + rwa [Subcomplex.N.le_iff, SSet.N.le_iff] + exact lt_irrefl _ (hi.trans (f.lt this)) + variable [P.IsProper] set_option backward.isDefEq.respectTransparency false in @@ -222,37 +269,29 @@ lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) c.mapToSucc ≫ (f.filtration (Order.succ j)).ι = c.map := rfl -omit [P.IsProper] in -variable {f} in -lemma Cells.subcomplex_not_le_filtration {j : ι} (x : f.Cells j) : - ¬ x.1.1.subcomplex ≤ f.filtration j := by - rw [ofSimplex_le_iff] - simp only [filtration, Subfunctor.max_obj, Subfunctor.iSup_obj, Set.mem_union, - Set.mem_iUnion, not_or, not_exists] - refine ⟨x.1.1.notMem, fun i hi y h ↦ ?_⟩ - rw [← x.2, ← y.2] at hi - have : P.AncestralRel x.1 y.1 := by - refine ⟨fun hxy ↦ ?_, lt_of_le_of_ne ?_ ((P.ne _ _).symm)⟩ - · rw [hxy] at hi - exact (lt_irrefl _ hi).elim - · rw [← ofSimplex_le_iff] at h - rwa [Subcomplex.N.le_iff, SSet.N.le_iff] - exact lt_irrefl _ (hi.trans (f.lt this)) - section -noncomputable abbrev sigmaHorn (j : ι) := ∐ (fun (c : f.Cells j) ↦ (c.horn : SSet)) +noncomputable abbrev sigmaHorn (j : ι) : SSet.{u} := + ∐ fun (c : f.Cells j) ↦ c.horn noncomputable abbrev Cells.ιSigmaHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.sigmaHorn j := Sigma.ι (fun (c : f.Cells j) ↦ (c.horn : SSet)) c -noncomputable abbrev sigmaStdSimplex (j : ι) := ∐ (fun (i : f.Cells j) ↦ Δ[i.dim + 1]) +noncomputable abbrev sigmaStdSimplex (j : ι) : SSet.{u} := + ∐ fun (i : f.Cells j) ↦ Δ[i.dim + 1] noncomputable abbrev Cells.ιSigmaStdSimplex {j : ι} (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.sigmaStdSimplex j := Sigma.ι (fun (c : f.Cells j) ↦ Δ[c.dim + 1]) c +lemma ιSigmaHorn_jointly_surjective + {d : ℕ} {j : ι} (a : (f.sigmaHorn j) _⦋d⦌) : + ∃ (c : f.Cells j) (x : (c.horn : SSet) _⦋d⦌), c.ιSigmaHorn.app _ x = a := + Limits.Cofan.inj_jointly_surjective_of_isColimit + ((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ + (coproductIsCoproduct _))) a + omit [P.IsProper] in lemma ιSigmaStdSimplex_jointly_surjective {d : ℕ} {j : ι} (a : (f.sigmaStdSimplex j) _⦋d⦌) : @@ -261,6 +300,22 @@ lemma ιSigmaStdSimplex_jointly_surjective ((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ (coproductIsCoproduct _))) a +lemma ιSigmaStdSimplex_eq_iff {j : ι} {d : ℕ} + (x : f.Cells j) (s : (Δ[x.dim + 1] : SSet.{u}) _⦋d⦌) + (y : f.Cells j) (t : (Δ[y.dim + 1] : SSet.{u}) _⦋d⦌) : + x.ιSigmaStdSimplex.app (op ⦋d⦌) s = y.ιSigmaStdSimplex.app (op ⦋d⦌) t ↔ + ∃ (h : x = y), t = cast (by rw [h]) s := by + sorry + +instance {j : ι} (c : f.Cells j) : + Mono c.ιSigmaStdSimplex := by + rw [NatTrans.mono_iff_mono_app] + rintro ⟨d⟩ + induction d using SimplexCategory.rec with | _ d + rw [mono_iff_injective] + intro x y h + simpa [f.ιSigmaStdSimplex_eq_iff] using h.symm + noncomputable def m (j : ι) : f.sigmaHorn j ⟶ f.sigmaStdSimplex j := Limits.Sigma.map (basicCell _ _) @@ -272,7 +327,7 @@ instance (j : ι) : Mono (f.m j) := infer_instance)) @[reassoc (attr := simp)] -lemma Cells.ιSigmaHorn_m {j : ι} (c : f.Cells j) : +lemma Cells.ι_m {j : ι} (c : f.Cells j) : c.ιSigmaHorn ≫ f.m j = c.horn.ι ≫ c.ιSigmaStdSimplex := by simp [m] @@ -339,7 +394,41 @@ lemma w (j : ι) : ext c : 1 simp [← cancel_mono (Subcomplex.ι _)] ---set_option backward.isDefEq.respectTransparency false in +@[simps] +noncomputable def Cells.type₁ {j : ι} (c : f.Cells j) : + (Subcomplex.range (f.m j)).N where + simplex := c.ιSigmaStdSimplex.app _ (stdSimplex.objEquiv.symm (𝟙 _)) + nonDegenerate := by + rw [nonDegenerate_iff_of_mono, + stdSimplex.mem_nonDegenerate_iff_mono, + Equiv.apply_symm_apply] + infer_instance + notMem := by + rintro ⟨y, hy⟩ + obtain ⟨x', ⟨y, hy'⟩, rfl⟩ := f.ιSigmaHorn_jointly_surjective y + rw [← FunctorToTypes.comp, ι_m, FunctorToTypes.comp, + ιSigmaStdSimplex_eq_iff] at hy + obtain ⟨rfl, rfl⟩ := hy + exact objEquiv_symm_notMem_horn_of_isIso _ _ hy' + +@[simps] +noncomputable def Cells.type₂ {j : ι} (c : f.Cells j) : + (Subcomplex.range (f.m j)).N where + simplex := c.ιSigmaStdSimplex.app _ + (stdSimplex.objEquiv.symm (SimplexCategory.δ c.index)) + nonDegenerate := by + rw [nonDegenerate_iff_of_mono, + stdSimplex.mem_nonDegenerate_iff_mono, + Equiv.apply_symm_apply] + infer_instance + notMem := by + rintro ⟨y, hy⟩ + obtain ⟨x', ⟨y, hy'⟩, rfl⟩ := f.ιSigmaHorn_jointly_surjective y + rw [← FunctorToTypes.comp, ι_m, FunctorToTypes.comp, + ιSigmaStdSimplex_eq_iff] at hy + obtain ⟨rfl, rfl⟩ := hy + simpa using (objEquiv_symm_δ_mem_horn_iff _ _).1 hy' + lemma isPullback (j : ι) (_ : ¬ IsMax j) : IsPullback (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where @@ -385,6 +474,58 @@ lemma range_homOfLE_app_union_range_b_app (j : ι) (d : SimplexCategoryᵒᵖ) : obtain ⟨y, hy⟩ := hx exact Or.inr ⟨_, hy⟩ +noncomputable def mapN {j : ι} (x : (Subcomplex.range (f.m j)).N) : X.S := + S.mk ((f.b j).app _ x.1.1.2).1 + +@[simp] +lemma mapN_type₁ {j : ι} (c : f.Cells j) : + f.mapN c.type₁ = S.mk (P.p c.1).1.simplex := by + dsimp only [Cells.type₁, mapN] + rw [← S.cast_eq_self _ (P.dim_p c.1)] + dsimp + rw [S.ext_iff, ← FunctorToTypes.comp, c.ι_b] + apply yonedaEquiv_symm_app_id + +@[simp] +lemma mapN_type₂ {j : ι} (c : f.Cells j) : + f.mapN c.type₂ = S.mk c.1.1.simplex := by + dsimp [mapN] + rw [S.ext_iff, ← FunctorToTypes.comp, c.ι_b, Cells.mapToSucc, + lift_app_coe, Cells.map_app_objEquiv_symm_δ_index] + +lemma exists_or_of_range_m_N {j : ι} + (s : (Subcomplex.range (f.m j)).N) : + ∃ (c : f.Cells j), s = c.type₁ ∨ s = c.type₂ := by + sorry + +lemma isPushout_aux₁ {j : ι} + (s : (Subcomplex.range (f.m j)).N) : + (f.mapN s).simplex ∈ SSet.nonDegenerate _ _ := by + obtain ⟨c, rfl | rfl⟩ := f.exists_or_of_range_m_N s + · rw [f.mapN_type₁] + exact (P.p c.1).1.nonDegenerate + · rw [f.mapN_type₂] + exact c.1.1.nonDegenerate + +lemma isPushout_aux₂ {j : ι} : + Function.Injective (f.mapN (j := j)) := by + intro s t h + obtain ⟨c, rfl | rfl⟩ := f.exists_or_of_range_m_N s <;> + obtain ⟨c', rfl | rfl⟩ := f.exists_or_of_range_m_N t <;> + simp only [mapN_type₁, mapN_type₂, ← Subcomplex.N.eq_iff_sMk_eq, + ← Subtype.ext_iff] at h + · obtain rfl : c = c' := by + ext : 1 + exact P.p.injective h + rfl + · exact (P.ne _ _ h).elim + · exact (P.ne _ _ h.symm).elim + · rw [h] + +lemma isPushout_aux₃ {j : ι} : + Function.Injective fun (x : (Subcomplex.range (f.m j)).N) ↦ S.mk ((f.b j).app _ x.1.1.2) := + fun _ _ h ↦ f.isPushout_aux₂ (congr_arg (S.map (Subcomplex.ι _)) h) + set_option backward.isDefEq.respectTransparency false in lemma isPushout (j : ι) (hj : ¬ IsMax j) : IsPushout (f.t j) (f.m j) @@ -397,8 +538,22 @@ lemma isPushout (j : ι) (hj : ¬ IsMax j) : dsimp refine Limits.Types.isPushout_of_isPullback_of_mono' ((f.isPullback j hj).map ((CategoryTheory.evaluation _ _).obj _)) - (f.range_homOfLE_app_union_range_b_app _ _) (fun x y hx hy h ↦ ?_) - sorry)⟩ + (f.range_homOfLE_app_union_range_b_app _ _) (fun x₁ x₂ hx₁ hx₂ h ↦ ?_) + obtain ⟨s₁, g₁, _, hg₁⟩ := (Subcomplex.range (f.m j)).existsN x₁ hx₁ + obtain ⟨s₂, g₂, _, hg₂⟩ := (Subcomplex.range (f.m j)).existsN x₂ hx₂ + obtain rfl : s₁ = s₂ := f.isPushout_aux₃ (by + dsimp + rw [S.eq_iff_ofSimplex_eq, + ← Subcomplex.ofSimplex_map g₁, ← FunctorToTypes.naturality, + ← Subcomplex.ofSimplex_map g₂, ← FunctorToTypes.naturality, + hg₁, hg₂, h] + all_goals + · rw [Subcomplex.mem_nonDegenerate_iff] + apply f.isPushout_aux₁) + obtain rfl := X.unique_nonDegenerate_map (x := (((f.b _)).app _ x₁).1) + g₁ ⟨_, f.isPushout_aux₁ s₁⟩ (by simp [mapN, ← hg₁, FunctorToTypes.naturality]) + g₂ ⟨_, f.isPushout_aux₁ s₁⟩ (by simp [mapN, h, ← hg₂, FunctorToTypes.naturality]) + rw [← hg₁, hg₂])⟩ end @@ -430,7 +585,7 @@ noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι whe isColimit₁ := colimit.isColimit _ isColimit₂ := colimit.isColimit _ m := f.m j - hm c := c.ιSigmaHorn_m + hm c := c.ι_m g₁ := f.t j g₂ := f.b j isPushout := f.isPushout j hj } diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index e0220639ab2fd8..f47fbee19957bf 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -258,6 +258,11 @@ lemma yonedaEquiv_comp {X Y : SSet.{u}} {n : SimplexCategory} (f : stdSimplex.obj n ⟶ X) (g : X ⟶ Y) : yonedaEquiv (f ≫ g) = g.app _ (yonedaEquiv f) := rfl +@[simp] +lemma yonedaEquiv_symm_app_id {X : SSet.{u}} {n : ℕ} (x : X _⦋n⦌) : + (yonedaEquiv.symm x).app _ (yonedaEquiv (𝟙 _)) = x := + yonedaEquiv.symm.injective (by simp [← yonedaEquiv_symm_comp]) + namespace Subcomplex variable {X : SSet.{u}} From 1d56f5cf16c7e32b96fce50cfc49f6b52f5cc5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 27 Mar 2026 23:56:35 +0100 Subject: [PATCH 69/81] wip --- .../RelativeCellComplex.lean | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 52c0d18786dd2c..8604dda8fc4bf1 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -49,13 +49,20 @@ lemma Subcomplex.N.eq_iff_sMk_eq {X : SSet.{u}} {A : X.Subcomplex} (x y : A.N) : lemma Subcomplex.ofSimplex_map {X : SSet.{u}} {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [Epi f] (x : X _⦋m⦌) : ofSimplex (X.map f.op x) = ofSimplex x := by - sorry + refine le_antisymm ?_ ?_ + · simp only [Subfunctor.ofSection_le_iff] + exact ⟨f.op, by simp⟩ + · simp only [Subfunctor.ofSection_le_iff] + have := isSplitEpi_of_epi f + exact ⟨(section_ f).op, by simp [← FunctorToTypes.map_comp_apply, ← op_comp]⟩ lemma S.eq_iff_ofSimplex_eq {X : SSet.{u}} {n m : ℕ} (x : X _⦋n⦌) (y : X _⦋m⦌) (hx : x ∈ X.nonDegenerate _) (hy : y ∈ X.nonDegenerate _) : S.mk x = S.mk y ↔ Subcomplex.ofSimplex x = Subcomplex.ofSimplex y := by - sorry - + trans N.mk x hx = N.mk y hy + · exact (N.ext_iff (N.mk x hx) (N.mk y hy)).symm + · simp only [le_antisymm_iff] + rfl lemma objEquiv_symm_notMem_horn_of_isIso {n : ℕ} (i : Fin (n + 1)) {d : SimplexCategory} (f : d ⟶ ⦋n⦌) [IsIso f] : @@ -429,8 +436,7 @@ noncomputable def Cells.type₂ {j : ι} (c : f.Cells j) : obtain ⟨rfl, rfl⟩ := hy simpa using (objEquiv_symm_δ_mem_horn_iff _ _).1 hy' -lemma isPullback (j : ι) (_ : ¬ IsMax j) : - IsPullback (f.t j) (f.m j) +lemma isPullback (j : ι) : IsPullback (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j isLimit' := ⟨evaluationJointlyReflectsLimits _ (fun ⟨d⟩ ↦ by @@ -527,7 +533,7 @@ lemma isPushout_aux₃ {j : ι} : fun _ _ h ↦ f.isPushout_aux₂ (congr_arg (S.map (Subcomplex.ι _)) h) set_option backward.isDefEq.respectTransparency false in -lemma isPushout (j : ι) (hj : ¬ IsMax j) : +lemma isPushout (j : ι) : IsPushout (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j @@ -537,7 +543,7 @@ lemma isPushout (j : ι) (hj : ¬ IsMax j) : (IsPushout.isColimit ?_) dsimp refine Limits.Types.isPushout_of_isPullback_of_mono' - ((f.isPullback j hj).map ((CategoryTheory.evaluation _ _).obj _)) + ((f.isPullback j).map ((CategoryTheory.evaluation _ _).obj _)) (f.range_homOfLE_app_union_range_b_app _ _) (fun x₁ x₂ hx₁ hx₂ h ↦ ?_) obtain ⟨s₁, g₁, _, hg₁⟩ := (Subcomplex.range (f.m j)).existsN x₁ hx₁ obtain ⟨s₂, g₂, _, hg₂⟩ := (Subcomplex.range (f.m j)).existsN x₂ hx₂ @@ -577,7 +583,7 @@ noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι whe ⟨fun m hm ↦ ⟨isColimitOfPreserves Subcomplex.toSSetFunctor (Functor.isColimitOfIsWellOrderContinuous f.filtration_monotone.functor m hm)⟩⟩ incl.app i := (f.filtration i).ι - attachCells j hj := + attachCells j _ := { ι := f.Cells j π := id cofan₁ := _ @@ -588,7 +594,7 @@ noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι whe hm c := c.ι_m g₁ := f.t j g₂ := f.b j - isPushout := f.isPushout j hj } + isPushout := f.isPushout j } end RankFunction From 8b8aa03c9eabb11f257e435d9413a1397d017965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 11:21:04 +0100 Subject: [PATCH 70/81] wip --- .../RelativeCellComplex.lean | 106 ++++++++++-------- .../AlgebraicTopology/SimplicialSet/Horn.lean | 12 +- .../SimplicialSet/NonDegenerateSimplices.lean | 33 ++++++ .../Limits/Types/Coproducts.lean | 11 ++ 4 files changed, 112 insertions(+), 50 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 8604dda8fc4bf1..b9a22978117c10 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -36,10 +36,9 @@ lemma stdSimplex.map_objEquiv_op_apply lemma Subcomplex.existsN {X : SSet.{u}} {n : ℕ} (s : X _⦋n⦌) {A : X.Subcomplex} (hs : s ∉ A.obj _) : ∃ (x : A.N) (f : ⦋n⦌ ⟶ ⦋x.dim⦌), Epi f ∧ X.map f.op x.simplex = s := by - refine ⟨⟨(S.mk s).toN, fun h ↦ hs ?_⟩, ?_⟩ - · simp only [← ofSimplex_le_iff] at h ⊢ - simpa using h - · sorry + refine ⟨⟨(S.mk s).toN, fun h ↦ hs ?_⟩, ⟨(S.mk s).toNπ, inferInstance, by simp⟩⟩ + simp only [← ofSimplex_le_iff] at h ⊢ + simpa using h lemma Subcomplex.N.eq_iff_sMk_eq {X : SSet.{u}} {A : X.Subcomplex} (x y : A.N) : x = y ↔ S.mk x.1.1.2 = S.mk y.1.1.2 := by @@ -66,13 +65,22 @@ lemma S.eq_iff_ofSimplex_eq {X : SSet.{u}} {n m : ℕ} (x : X _⦋n⦌) (y : X _ lemma objEquiv_symm_notMem_horn_of_isIso {n : ℕ} (i : Fin (n + 1)) {d : SimplexCategory} (f : d ⟶ ⦋n⦌) [IsIso f] : - stdSimplex.objEquiv.symm f ∉ (horn n i).obj (op d) := by - sorry + stdSimplex.objEquiv.symm f ∉ (horn.{u} n i).obj (op d) := by + rw [mem_horn_iff, ne_eq, Decidable.not_not] + ext i + simpa using Or.inr ⟨inv f i, by change (inv f ≫ f) i = i; cat_disch⟩ lemma objEquiv_symm_δ_mem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : - stdSimplex.objEquiv.symm (SimplexCategory.δ i) ∈ (horn _ j).obj _ ↔ - i ≠ j := by - sorry + (stdSimplex.objEquiv (m := op ⦋n⦌)).symm + (SimplexCategory.δ i) ∈ (horn.{u} (n + 1) j).obj (op ⦋n⦌) ↔ i ≠ j := by + dsimp + rw [← Subcomplex.ofSimplex_le_iff, ← stdSimplex.face_singleton_compl, face_le_horn_iff] + simp + +lemma objEquiv_symm_δ_notMem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : + (stdSimplex.objEquiv (m := op ⦋n⦌)).symm + (SimplexCategory.δ i) ∉ (horn.{u} _ j).obj (op ⦋n⦌) ↔ i = j := by + simp [objEquiv_symm_δ_mem_horn_iff.{u}] end SSet @@ -108,14 +116,6 @@ protected noncomputable abbrev horn : abbrev cast : A.N := (P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq ---abbrev simplex : X _⦋c.dim + 1⦌ := c.cast.simplex - -/-lemma ofSimplex_simplex : - Subcomplex.ofSimplex c.simplex = (P.p c.1).1.subcomplex := by - rw [S.ofSimplex_eq_subcomplex_mk] - congr 1 - exact S.cast_eq_self _ (by simp)-/ - abbrev map : Δ[c.dim + 1] ⟶ X := yonedaEquiv.symm c.cast.simplex @@ -141,8 +141,7 @@ lemma subcomplex_not_le_image_horn : rw [← stdSimplex.map_objEquiv_op_apply, Equiv.apply_symm_apply] at h₂ have := mono_of_nonDegenerate (x:= ⟨_, c.1.1.nonDegenerate⟩) _ _ _ h₂ obtain rfl := (P.isUniquelyCodimOneFace c.1).unique rfl _ h₂ - rw [← ofSimplex_le_iff, stdSimplex.subcomplex_le_horn_iff, - ← stdSimplex.face_singleton_compl] at h₁ + rw [← ofSimplex_le_iff, subcomplex_le_horn_iff, ← stdSimplex.face_singleton_compl] at h₁ tauto lemma image_horn_lt_subcomplex : @@ -307,12 +306,15 @@ lemma ιSigmaStdSimplex_jointly_surjective ((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ (coproductIsCoproduct _))) a +omit [P.IsProper] in lemma ιSigmaStdSimplex_eq_iff {j : ι} {d : ℕ} (x : f.Cells j) (s : (Δ[x.dim + 1] : SSet.{u}) _⦋d⦌) (y : f.Cells j) (t : (Δ[y.dim + 1] : SSet.{u}) _⦋d⦌) : x.ιSigmaStdSimplex.app (op ⦋d⦌) s = y.ιSigmaStdSimplex.app (op ⦋d⦌) t ↔ - ∃ (h : x = y), t = cast (by rw [h]) s := by - sorry + ∃ (h : x = y), t = cast (by rw [h]) s := + Cofan.inj_apply_eq_iff_of_isColimit + (((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ + (coproductIsCoproduct _)))) _ _ instance {j : ι} (c : f.Cells j) : Mono c.ιSigmaStdSimplex := by @@ -342,7 +344,7 @@ lemma Cells.ι_m {j : ι} (c : f.Cells j) : lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : (f.filtration j).preimage c.map = c.horn := by refine le_antisymm ?_ ?_ - · simpa only [stdSimplex.subcomplex_le_horn_iff, ← Subcomplex.image_le_iff, + · simpa only [subcomplex_le_horn_iff, ← Subcomplex.image_le_iff, Cells.image_face_index_compl] using c.subcomplex_not_le_filtration · rw [← Subcomplex.image_le_iff, N.subcomplex_le_iff] intro s hs @@ -384,23 +386,6 @@ lemma Cells.ι_t {j : ι} (c : f.Cells j) : c.ιSigmaHorn ≫ f.t j = c.mapHorn:= by simp [t] -variable [SuccOrder ι] [NoMaxOrder ι] - -noncomputable def b (j : ι) : - f.sigmaStdSimplex j ⟶ f.filtration (Order.succ j) := - Sigma.desc (fun c ↦ c.mapToSucc) - -set_option backward.isDefEq.respectTransparency false in -@[reassoc (attr := simp)] -lemma Cells.ι_b {j : ι} (c : f.Cells j) : - c.ιSigmaStdSimplex ≫ f.b j = c.mapToSucc := by simp [b] - -@[reassoc] -lemma w (j : ι) : - f.t j ≫ homOfLE (f.filtration_monotone (Order.le_succ j)) = f.m j ≫ f.b j := by - ext c : 1 - simp [← cancel_mono (Subcomplex.ι _)] - @[simps] noncomputable def Cells.type₁ {j : ι} (c : f.Cells j) : (Subcomplex.range (f.m j)).N where @@ -436,6 +421,44 @@ noncomputable def Cells.type₂ {j : ι} (c : f.Cells j) : obtain ⟨rfl, rfl⟩ := hy simpa using (objEquiv_symm_δ_mem_horn_iff _ _).1 hy' +lemma exists_or_of_range_m_N {j : ι} + (s : (Subcomplex.range (f.m j)).N) : + ∃ (c : f.Cells j), s = c.type₁ ∨ s = c.type₂ := by + obtain ⟨d, s, hs, hs', rfl⟩ := s.mk_surjective + obtain ⟨x, s, rfl⟩ := f.ιSigmaStdSimplex_jointly_surjective s + replace hs' : s ∉ (horn _ x.index).obj _ := + fun h ↦ hs' ⟨x.ιSigmaHorn.app _ ⟨_, h⟩, by simp [← FunctorToTypes.comp]⟩ + obtain ⟨g, rfl⟩ := stdSimplex.objEquiv.symm.surjective s + rw [nonDegenerate_iff_of_mono, stdSimplex.mem_nonDegenerate_iff_mono, + Equiv.apply_symm_apply] at hs + obtain hd | rfl := (SimplexCategory.le_of_mono g).lt_or_eq + · rw [Nat.lt_succ_iff] at hd + obtain hd | rfl := hd.lt_or_eq + · exact (hs' (by simp [horn_obj_eq_top x.index d (by lia)])).elim + · obtain ⟨i, rfl⟩ := SimplexCategory.eq_δ_of_mono g + obtain rfl := (objEquiv_symm_δ_notMem_horn_iff _ _).1 hs' + exact ⟨x, Or.inr rfl⟩ + · obtain rfl := SimplexCategory.eq_id_of_mono g + exact ⟨x, Or.inl rfl⟩ + +variable [SuccOrder ι] [NoMaxOrder ι] + +noncomputable def b (j : ι) : + f.sigmaStdSimplex j ⟶ f.filtration (Order.succ j) := + Sigma.desc (fun c ↦ c.mapToSucc) + +set_option backward.isDefEq.respectTransparency false in +@[reassoc (attr := simp)] +lemma Cells.ι_b {j : ι} (c : f.Cells j) : + c.ιSigmaStdSimplex ≫ f.b j = c.mapToSucc := by simp [b] + +@[reassoc] +lemma w (j : ι) : + f.t j ≫ homOfLE (f.filtration_monotone (Order.le_succ j)) = f.m j ≫ f.b j := by + ext c : 1 + simp [← cancel_mono (Subcomplex.ι _)] + + lemma isPullback (j : ι) : IsPullback (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j @@ -499,11 +522,6 @@ lemma mapN_type₂ {j : ι} (c : f.Cells j) : rw [S.ext_iff, ← FunctorToTypes.comp, c.ι_b, Cells.mapToSucc, lift_app_coe, Cells.map_app_objEquiv_symm_δ_index] -lemma exists_or_of_range_m_N {j : ι} - (s : (Subcomplex.range (f.m j)).N) : - ∃ (c : f.Cells j), s = c.type₁ ∨ s = c.type₂ := by - sorry - lemma isPushout_aux₁ {j : ι} (s : (Subcomplex.range (f.m j)).N) : (f.mapN s).simplex ∈ SSet.nonDegenerate _ _ := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index 7c069b0a36f836..31f6bcd163bdfd 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -39,7 +39,7 @@ def horn (n : ℕ) (i : Fin (n + 1)) : (Δ[n] : SSet.{u}).Subcomplex where /-- The `i`-th horn `Λ[n, i]` of the standard `n`-simplex -/ scoped[Simplicial] notation3 "Λ[" n ", " i "]" => SSet.horn (n : ℕ) i -lemma stdSimplex.mem_horn_iff {n : ℕ} (i : Fin (n + 1)) {m : SimplexCategoryᵒᵖ} +lemma mem_horn_iff {n : ℕ} (i : Fin (n + 1)) {m : SimplexCategoryᵒᵖ} (x : (Δ[n] : SSet.{u}).obj m) : x ∈ (horn n i).obj m ↔ Set.range (stdSimplex.asOrderHom x) ∪ {i} ≠ Set.univ := Iff.rfl @@ -103,12 +103,12 @@ lemma horn_obj_eq_top {n : ℕ} (i : Fin (n + 1)) (m : ℕ) (h : m + 1 < n := by Finset.mem_compl, Finset.mem_singleton, exists_prop, Set.mem_univ, iff_true] exact ⟨j, hij, fun k hk ↦ hj ⟨k, hk⟩⟩ -lemma stdSimplex.subcomplex_le_horn_iff {n : ℕ} +lemma subcomplex_le_horn_iff {n : ℕ} (A : (Δ[n + 1] : SSet.{u}).Subcomplex) (i : Fin (n + 2)) : - A ≤ horn (n + 1) i ↔ ¬ face {i}ᶜ ≤ A := by + A ≤ horn (n + 1) i ↔ ¬ stdSimplex.face {i}ᶜ ≤ A := by refine ⟨fun hA h ↦ ?_, fun h ↦ ?_⟩ · replace h := h.trans hA - rw [face_singleton_compl, Subcomplex.ofSimplex_le_iff, mem_horn_iff] at h + rw [stdSimplex.face_singleton_compl, Subcomplex.ofSimplex_le_iff, mem_horn_iff] at h apply h change Set.range (Fin.succAboveOrderEmb i) ∪ _ = _ rw [Fin.range_succAboveOrderEmb] @@ -135,9 +135,9 @@ lemma stdSimplex.subcomplex_le_horn_iff {n : ℕ} exact ⟨j, by simp [← hS]⟩ exact face_le_horn _ _ (by rintro rfl; tauto) -lemma stdSimplex.face_le_horn_iff {n : ℕ} (S : Finset (Fin (n + 2))) (j : Fin (n + 2)) : +lemma face_le_horn_iff {n : ℕ} (S : Finset (Fin (n + 2))) (j : Fin (n + 2)) : stdSimplex.face.{u} S ≤ horn (n + 1) j ↔ S ≠ .univ ∧ S ≠ {j}ᶜ := by - rw [stdSimplex.subcomplex_le_horn_iff, face_le_face_iff, ← not_iff_not] + rw [subcomplex_le_horn_iff, stdSimplex.face_le_face_iff, ← not_iff_not] simp only [Finset.le_eq_subset, Decidable.not_not, ne_eq, not_and_or] refine ⟨fun h ↦ ?_, by rintro (rfl | rfl) <;> simp⟩ rw [← Finset.compl_subset_compl, compl_compl, diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index d68f4dbfffba8c..b0d0be1d904543 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -172,6 +172,14 @@ namespace S variable {X} +lemma subcomplex_eq_of_epi (x y : X.S) (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌) [Epi f] + (hf : X.map f.op y.simplex = x.simplex) : + x.subcomplex = y.subcomplex := by + refine le_antisymm ?_ ?_ <;> simp only [Subcomplex.ofSimplex_le_iff] + · exact ⟨_, hf⟩ + · have := isSplitEpi_of_epi f + exact ⟨(section_ f).op, by simp [← hf, ← FunctorToTypes.map_comp_apply, ← op_comp]⟩ + lemma existsUnique_n (x : X.S) : ∃! (y : X.N), y.subcomplex = x.subcomplex := existsUnique_of_exists_of_unique (by obtain ⟨n, x, hx, rfl⟩ := x.mk_surjective @@ -202,6 +210,31 @@ lemma toN_eq_iff {x : X.S} {y : X.N} : x.toN = y ↔ y.subcomplex = x.subcomplex := ⟨by rintro rfl; simp, fun h ↦ x.existsUnique_n.unique (by simp) h⟩ +set_option backward.isDefEq.respectTransparency false in +lemma existsUnique_toNπ {x : X.S} {y : X.N} (hy : x.toN = y) : + ∃! (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌), Epi f ∧ X.map f.op y.simplex = x.simplex := by + obtain ⟨n, x, hx, rfl⟩ := x.mk_surjective + obtain ⟨m, f, _, z, rfl⟩ := X.exists_nonDegenerate x + obtain rfl : y = N.mk _ z.2 := by + rw [toN_eq_iff] at hy + rw [← N.subcomplex_injective_iff, hy] + exact subcomplex_eq_of_epi _ _ f rfl + refine existsUnique_of_exists_of_unique ⟨f, inferInstance, rfl⟩ + (fun f₁ f₂ ⟨_, hf₁⟩ ⟨_, hf₂⟩ ↦ unique_nonDegenerate_map _ _ _ _ hf₁.symm _ _ hf₂.symm) + +noncomputable def toNπ (x : X.S) : ⦋x.dim⦌ ⟶ ⦋x.toN.dim⦌ := + (existsUnique_toNπ rfl).exists.choose + +instance (x : X.S) : Epi x.toNπ := (existsUnique_toNπ rfl).exists.choose_spec.1 + +@[simp] +lemma map_toNπ_op_apply (x : X.S) : + X.map x.toNπ.op x.toN.simplex = x.simplex := (existsUnique_toNπ rfl).exists.choose_spec.2 + +lemma dim_toN_le (x : X.S) : + x.toN.dim ≤ x.dim := + SimplexCategory.le_of_epi x.toNπ + end S end SSet diff --git a/Mathlib/CategoryTheory/Limits/Types/Coproducts.lean b/Mathlib/CategoryTheory/Limits/Types/Coproducts.lean index 5bbd31219421fb..1a26dcd921c629 100644 --- a/Mathlib/CategoryTheory/Limits/Types/Coproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Types/Coproducts.lean @@ -133,6 +133,13 @@ lemma eq_of_inj_apply_eq_of_isColimit i₁ = i₂ := congr_arg Sigma.fst ((equivOfIsColimit hc).injective (a₁ := ⟨i₁, y₁⟩) (a₂ := ⟨i₂, y₂⟩) h) +lemma inj_apply_eq_iff_of_isColimit + {i₁ i₂ : C} (y₁ : F i₁) (y₂ : F i₂) : + c.inj i₁ y₁ = c.inj i₂ y₂ ↔ ∃ (h : i₁ = i₂), y₂ = cast (by rw [h]) y₁ := by + refine ⟨fun h ↦ ?_, fun ⟨h₁, h₂⟩ ↦ by subst h₁ h₂; rfl⟩ + obtain rfl := eq_of_inj_apply_eq_of_isColimit hc _ _ h + exact ⟨rfl, (inj_injective_of_isColimit hc i₁ h).symm⟩ + end end CofanTypes @@ -177,6 +184,10 @@ lemma eq_of_inj_apply_eq_of_isColimit (hc : IsColimit c) i₁ = i₂ := CofanTypes.eq_of_inj_apply_eq_of_isColimit ((isColimit_cofanTypes_iff c).2 ⟨hc⟩) _ _ h +lemma inj_apply_eq_iff_of_isColimit (hc : IsColimit c) {i j : C} (x : F i) (y : F j) : + c.inj i x = c.inj j y ↔ ∃ (hij : i = j), y = cast (by rw [hij]) x := + CofanTypes.inj_apply_eq_iff_of_isColimit ((isColimit_cofanTypes_iff c).2 ⟨hc⟩) _ _ + end Cofan namespace Types From 769b815027f79d6101cecc5dbcf11492c29e74f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 11:55:13 +0100 Subject: [PATCH 71/81] wip --- .../AlgebraicTopology/SimplicialSet/Horn.lean | 4 +-- .../SimplicialSet/StdSimplex.lean | 30 +++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index 31f6bcd163bdfd..5defcbf4e503c2 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -90,9 +90,7 @@ lemma horn_obj_eq_top {n : ℕ} (i : Fin (n + 1)) (m : ℕ) (h : m + 1 < n := by obtain ⟨f, rfl⟩ := stdSimplex.objEquiv.symm.surjective x obtain ⟨j, hij, hj⟩ : ∃ (j : Fin (n + 1)), j ≠ i ∧ j ∉ Set.range f.toOrderHom := by by_contra! - have : Finset.image f.toOrderHom ⊤ ∪ {i} = ⊤ := by - ext k - by_cases k = i <;> aesop + have : Finset.image f.toOrderHom ⊤ ∪ {i} = ⊤ := by ext k; by_cases k = i <;> aesop have := (congr_arg Finset.card this).symm.le.trans (Finset.card_union_le _ _) simp only [SimplexCategory.len_mk, Finset.top_eq_univ, Finset.card_univ, Fintype.card_fin, Finset.card_singleton, add_le_add_iff_right] at this diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index f47fbee19957bf..f2c1589ad5f31c 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -499,20 +499,24 @@ lemma bijective_image_objEquiv_toOrderHom_univ (m : ℕ) : exact h · simp [e, ← Finset.image_image, Finset.image_univ_of_surjective e.surjective] -noncomputable def nonDegenerateEquiv' {n m : ℕ} : (Δ[n] : SSet.{u}).nonDegenerate m ≃ - { S : Finset (Fin (n + 1)) | S.card = m + 1 } := - Equiv.ofBijective _ (bijective_image_objEquiv_toOrderHom_univ n m) +/-- Nondegenerate `d`-dimensional simplices of the standard simplex `Δ[n]` +identify to subsets of `Fin (n + 1)` of cardinality `d + 1`. -/ +noncomputable def nonDegenerateEquiv' {n d : ℕ} : (Δ[n] : SSet.{u}).nonDegenerate d ≃ + { S : Finset (Fin (n + 1)) | S.card = d + 1 } := + Equiv.ofBijective _ (bijective_image_objEquiv_toOrderHom_univ n d) set_option backward.isDefEq.respectTransparency false in -@[simp] -lemma nonDegenerateEquiv'_iff {n m : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate m) (j : Fin (n + 1)) : - j ∈ (nonDegenerateEquiv' x).1 ↔ ∃ (i : Fin (m + 1)), x.1 i = j := by +lemma nonDegenerateEquiv'_iff {n d : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate d) (j : Fin (n + 1)) : + j ∈ (nonDegenerateEquiv' x).1 ↔ ∃ (i : Fin (d + 1)), x.1 i = j := by + simp only [Set.mem_setOf_eq, Set.coe_setOf] dsimp [nonDegenerateEquiv'] aesop set_option backward.isDefEq.respectTransparency false in -noncomputable def orderIsoOfNonDegenerate {n m : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate m) : - Fin (m + 1) ≃o (nonDegenerateEquiv' x).1 where +/-- If `x` is a nondegenerate `d`-simplex of `Δ[n]`, this is the order isomorphism +between `Fin (d + 1)` and the corresponding subset of `Fin (n + 1)` of cardinality `d + 1`. -/ +noncomputable def orderIsoOfNonDegenerate {n d : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate d) : + Fin (d + 1) ≃o (nonDegenerateEquiv' x).1 where toEquiv := Equiv.ofBijective (fun i ↦ ⟨x.1 i, Finset.mem_image_of_mem _ (by simp)⟩) (by constructor · have := (mem_nonDegenerate_iff_mono x.1).1 x.2 @@ -537,21 +541,21 @@ noncomputable def orderIsoOfNonDegenerate {n m : ℕ} (x : (Δ[n] : SSet.{u}).no · intro h exact monotone_apply _ h -lemma face_nonDegenerateEquiv' {n m : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate m) : +lemma face_nonDegenerateEquiv' {n d : ℕ} (x : (Δ[n] : SSet.{u}).nonDegenerate d) : face (nonDegenerateEquiv' x).1 = Subcomplex.ofSimplex x.1 := face_eq_ofSimplex.{u} _ _ (orderIsoOfNonDegenerate x) set_option backward.isDefEq.respectTransparency false in -lemma nonDegenerateEquiv'_symm_apply_mem {n m : ℕ} - (S : { S : Finset (Fin (n + 1)) | S.card = m + 1 }) (i : Fin (m + 1)) : +lemma nonDegenerateEquiv'_symm_apply_mem {n d : ℕ} + (S : { S : Finset (Fin (n + 1)) | S.card = d + 1 }) (i : Fin (d + 1)) : (nonDegenerateEquiv'.{u}.symm S).1 i ∈ S.1 := by obtain ⟨f, rfl⟩ := nonDegenerateEquiv'.{u}.surjective S dsimp [nonDegenerateEquiv'] simp only [Equiv.ofBijective_symm_apply_apply, Finset.mem_image, Finset.mem_univ, true_and] exact ⟨i, rfl⟩ -lemma nonDegenerateEquiv'_symm_mem_iff_face_le {n m : ℕ} - (S : { S : Finset (Fin (n + 1)) | S.card = m + 1 }) +lemma nonDegenerateEquiv'_symm_mem_iff_face_le {n d : ℕ} + (S : { S : Finset (Fin (n + 1)) | S.card = d + 1 }) (A : (Δ[n] : SSet.{u}).Subcomplex) : (nonDegenerateEquiv'.symm S).1 ∈ A.obj _ ↔ face S ≤ A := by obtain ⟨x, rfl⟩ := nonDegenerateEquiv'.{u}.surjective S From 665ce6b2d50f68467bced86c7839aaf7830fbc1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 13:32:01 +0100 Subject: [PATCH 72/81] moved lemmas --- .../RelativeCellComplex.lean | 59 ------------------- .../AlgebraicTopology/SimplicialSet/Horn.lean | 20 +++++++ .../SimplicialSet/NonDegenerateSimplices.lean | 8 +++ .../NonDegenerateSimplicesSubcomplex.lean | 11 ++++ .../SimplicialSet/StdSimplex.lean | 6 ++ .../SimplicialSet/Subcomplex.lean | 11 ++++ 6 files changed, 56 insertions(+), 59 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index b9a22978117c10..f6dae522ccf583 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -25,65 +25,6 @@ universe v u open CategoryTheory HomotopicalAlgebra Simplicial Limits Opposite -namespace SSet - -lemma stdSimplex.map_objEquiv_op_apply - {X : SSet.{u}} {n : SimplexCategory} (x : X.obj (op n)) - {m : SimplexCategoryᵒᵖ} (y : (stdSimplex.obj n).obj m) : - X.map (stdSimplex.objEquiv y).op x = (yonedaEquiv.symm x).app m y := - rfl - -lemma Subcomplex.existsN {X : SSet.{u}} {n : ℕ} (s : X _⦋n⦌) {A : X.Subcomplex} - (hs : s ∉ A.obj _) : - ∃ (x : A.N) (f : ⦋n⦌ ⟶ ⦋x.dim⦌), Epi f ∧ X.map f.op x.simplex = s := by - refine ⟨⟨(S.mk s).toN, fun h ↦ hs ?_⟩, ⟨(S.mk s).toNπ, inferInstance, by simp⟩⟩ - simp only [← ofSimplex_le_iff] at h ⊢ - simpa using h - -lemma Subcomplex.N.eq_iff_sMk_eq {X : SSet.{u}} {A : X.Subcomplex} (x y : A.N) : - x = y ↔ S.mk x.1.1.2 = S.mk y.1.1.2 := by - rw [N.ext_iff, SSet.N.ext_iff] - -@[simp] -lemma Subcomplex.ofSimplex_map {X : SSet.{u}} {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [Epi f] - (x : X _⦋m⦌) : - ofSimplex (X.map f.op x) = ofSimplex x := by - refine le_antisymm ?_ ?_ - · simp only [Subfunctor.ofSection_le_iff] - exact ⟨f.op, by simp⟩ - · simp only [Subfunctor.ofSection_le_iff] - have := isSplitEpi_of_epi f - exact ⟨(section_ f).op, by simp [← FunctorToTypes.map_comp_apply, ← op_comp]⟩ - -lemma S.eq_iff_ofSimplex_eq {X : SSet.{u}} {n m : ℕ} (x : X _⦋n⦌) (y : X _⦋m⦌) - (hx : x ∈ X.nonDegenerate _) (hy : y ∈ X.nonDegenerate _) : - S.mk x = S.mk y ↔ Subcomplex.ofSimplex x = Subcomplex.ofSimplex y := by - trans N.mk x hx = N.mk y hy - · exact (N.ext_iff (N.mk x hx) (N.mk y hy)).symm - · simp only [le_antisymm_iff] - rfl - -lemma objEquiv_symm_notMem_horn_of_isIso {n : ℕ} (i : Fin (n + 1)) - {d : SimplexCategory} (f : d ⟶ ⦋n⦌) [IsIso f] : - stdSimplex.objEquiv.symm f ∉ (horn.{u} n i).obj (op d) := by - rw [mem_horn_iff, ne_eq, Decidable.not_not] - ext i - simpa using Or.inr ⟨inv f i, by change (inv f ≫ f) i = i; cat_disch⟩ - -lemma objEquiv_symm_δ_mem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : - (stdSimplex.objEquiv (m := op ⦋n⦌)).symm - (SimplexCategory.δ i) ∈ (horn.{u} (n + 1) j).obj (op ⦋n⦌) ↔ i ≠ j := by - dsimp - rw [← Subcomplex.ofSimplex_le_iff, ← stdSimplex.face_singleton_compl, face_le_horn_iff] - simp - -lemma objEquiv_symm_δ_notMem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : - (stdSimplex.objEquiv (m := op ⦋n⦌)).symm - (SimplexCategory.δ i) ∉ (horn.{u} _ j).obj (op ⦋n⦌) ↔ i = j := by - simp [objEquiv_symm_δ_mem_horn_iff.{u}] - -end SSet - namespace SSet.Subcomplex.Pairing variable {X : SSet.{u}} {A : X.Subcomplex} {P : A.Pairing} diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean index 5defcbf4e503c2..7a6bb5136591ec 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Horn.lean @@ -144,6 +144,26 @@ lemma face_le_horn_iff {n : ℕ} (S : Finset (Fin (n + 2))) (j : Fin (n + 2)) : · exact Or.inl h · exact Or.inr (by simp [← h]) +lemma objEquiv_symm_notMem_horn_of_isIso {n : ℕ} (i : Fin (n + 1)) + {d : SimplexCategory} (f : d ⟶ ⦋n⦌) [IsIso f] : + stdSimplex.objEquiv.symm f ∉ (horn.{u} n i).obj (op d) := by + rw [mem_horn_iff, ne_eq, Decidable.not_not] + ext i + simpa using Or.inr ⟨inv f i, by change (inv f ≫ f) i = i; cat_disch⟩ + +lemma objEquiv_symm_δ_mem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : + (stdSimplex.objEquiv (m := op ⦋n⦌)).symm + (SimplexCategory.δ i) ∈ (horn.{u} (n + 1) j).obj (op ⦋n⦌) ↔ i ≠ j := by + dsimp + rw [← Subcomplex.ofSimplex_le_iff, ← stdSimplex.face_singleton_compl, face_le_horn_iff] + simp + +lemma objEquiv_symm_δ_notMem_horn_iff {n : ℕ} (i j : Fin (n + 2)) : + (stdSimplex.objEquiv (m := op ⦋n⦌)).symm + (SimplexCategory.δ i) ∉ (horn.{u} _ j).obj (op ⦋n⦌) ↔ i = j := by + simp [objEquiv_symm_δ_mem_horn_iff.{u}] + + namespace horn open SimplexCategory Finset Opposite diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index b0d0be1d904543..3bc3b8d6657c1a 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -172,6 +172,14 @@ namespace S variable {X} +lemma eq_iff_ofSimplex_eq {X : SSet.{u}} {n m : ℕ} (x : X _⦋n⦌) (y : X _⦋m⦌) + (hx : x ∈ X.nonDegenerate _) (hy : y ∈ X.nonDegenerate _) : + S.mk x = S.mk y ↔ Subcomplex.ofSimplex x = Subcomplex.ofSimplex y := by + trans N.mk x hx = N.mk y hy + · exact (N.ext_iff (N.mk x hx) (N.mk y hy)).symm + · simp only [le_antisymm_iff] + rfl + lemma subcomplex_eq_of_epi (x y : X.S) (f : ⦋x.dim⦌ ⟶ ⦋y.dim⦌) [Epi f] (hf : X.map f.op y.simplex = x.simplex) : x.subcomplex = y.subcomplex := by diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean index 5603741d4ed7b9..7e26fb99dfb221 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplicesSubcomplex.lean @@ -68,6 +68,10 @@ lemma cases {motive : X.N → Prop} · exact mem s hs · exact notMem (.mk' s (by simpa using hs)) +lemma eq_iff_sMk_eq {X : SSet.{u}} {A : X.Subcomplex} (x y : A.N) : + x = y ↔ S.mk x.1.1.2 = S.mk y.1.1.2 := by + rw [N.ext_iff, SSet.N.ext_iff] + instance : PartialOrder A.N := PartialOrder.lift toN (fun _ _ ↦ by simp [ext_iff]) @@ -96,4 +100,11 @@ end end N +lemma existsN {X : SSet.{u}} {n : ℕ} (s : X _⦋n⦌) {A : X.Subcomplex} + (hs : s ∉ A.obj _) : + ∃ (x : A.N) (f : ⦋n⦌ ⟶ ⦋x.dim⦌), Epi f ∧ X.map f.op x.simplex = s := by + refine ⟨⟨(S.mk s).toN, fun h ↦ hs ?_⟩, ⟨(S.mk s).toNπ, inferInstance, by simp⟩⟩ + simp only [← ofSimplex_le_iff] at h ⊢ + simpa using h + end SSet.Subcomplex diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean index f2c1589ad5f31c..dbf6a1ced7fe03 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/StdSimplex.lean @@ -162,6 +162,12 @@ lemma yonedaEquiv_map {n m : SimplexCategory} (f : n ⟶ m) : yonedaEquiv.{u} (stdSimplex.map f) = objEquiv.symm f := yonedaEquiv.symm.injective rfl +lemma map_objEquiv_op_apply + {X : SSet.{u}} {n : SimplexCategory} (x : X.obj (op n)) + {m : SimplexCategoryᵒᵖ} (y : (stdSimplex.obj n).obj m) : + dsimp% X.map (stdSimplex.objEquiv y).op x = (yonedaEquiv.symm x).app m y := by + rfl + lemma yonedaEquiv_symm_app_objEquiv_symm {X : SSet.{u}} {n : SimplexCategory} (x : X.obj (op n)) {m : SimplexCategoryᵒᵖ} (f : unop m ⟶ n) : dsimp% (yonedaEquiv.symm x).app _ (stdSimplex.objEquiv.symm f) = diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean index a5cc522c7a0d38..efc090c68d7d9d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Subcomplex.lean @@ -159,6 +159,17 @@ lemma mem_ofSimplex_obj_iff {n : ℕ} (x : X _⦋n⦌) {m : SimplexCategoryᵒ dsimp [ofSimplex, Subfunctor.ofSection] aesop +@[simp] +lemma ofSimplex_map {X : SSet.{u}} {n m : ℕ} (f : ⦋n⦌ ⟶ ⦋m⦌) [Epi f] + (x : X _⦋m⦌) : + ofSimplex (X.map f.op x) = ofSimplex x := by + refine le_antisymm ?_ ?_ + · simp only [Subfunctor.ofSection_le_iff] + exact ⟨f.op, by simp⟩ + · simp only [Subfunctor.ofSection_le_iff] + have := isSplitEpi_of_epi f + exact ⟨(section_ f).op, by simp [← FunctorToTypes.map_comp_apply, ← op_comp]⟩ + section variable (f : X ⟶ Y) From d062934048e1d04a9f1fb82a978b8d680abce80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 13:55:03 +0100 Subject: [PATCH 73/81] docstrings --- .../RelativeCellComplex.lean | 63 ++++++++++++++++--- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index f6dae522ccf583..7393da39db1c2e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -33,6 +33,9 @@ namespace RankFunction variable {ι : Type v} [LinearOrder ι] (f : P.RankFunction ι) +/-- Given a rank function `f : P.RankFunction ι` for a +pairing `P` of a subcomplex `A` of `X : SSet`, and `i : ι`, +this is the type of type (II) simplices of rank `i`. -/ def Cells (i : ι) : Type u := { s : P.II // f.rank s = i } namespace Cells @@ -44,22 +47,35 @@ variable {c} in lemma ext {c' : f.Cells i} (h : c.1 = c'.1) : c = c' := Subtype.ext h +/-- The dimension `c.dim` of a cell `c` of a rank function for a +pairing `P` of a subcomplex of a simplicial set. This is defined +as the dimension of the corresponding type (II) simplex. +(In the case `P` is proper, the corresponding type (I) simplex +will be of dimension `c.dim + 1`.) -/ abbrev dim : ℕ := c.1.1.dim variable [P.IsProper] +/-- If `c` is a cell of a rank function for a proper pairing `P` +of a subcomplex of a simplicial set, this is the index +in `Fin (c.dim + 2)` of the face of the type (I) simplex +given by the corresponding type (II) simplex. -/ noncomputable def index : Fin (c.dim + 2) := (P.isUniquelyCodimOneFace c.1).index rfl +/-- The horn in the standard simplex corresponding to a cell +of a rank function for a proper pairing of a subcomplex of +a simplicial set. -/ protected noncomputable abbrev horn : (Δ[c.dim + 1] : SSet.{u}).Subcomplex := SSet.horn _ c.index -abbrev cast : A.N := (P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq - +/-- The morphism `Δ[c.dim + 1] ⟶ X` corresponding to a cell of rank +function for a proper pairing of a subcomplex of `X : SSet`. -/ abbrev map : Δ[c.dim + 1] ⟶ X := - yonedaEquiv.symm c.cast.simplex + yonedaEquiv.symm + ((P.p c.1).1.cast (P.isUniquelyCodimOneFace c.1).dim_eq).simplex @[simp] lemma range_map : Subcomplex.range c.map = (P.p c.1).1.subcomplex := by @@ -101,8 +117,12 @@ lemma image_face_index_compl : end Cells variable [P.IsProper] in +/-- The horn inclusion corresponding to a cell of a rank function +for a proper pairing of a subcomplex of a simplicial set. -/ noncomputable abbrev basicCell (i : ι) (c : f.Cells i) := c.horn.ι +/-- The filtration of a simplicial set given by a rank function +for a proper pairing of a subcomplex. -/ def filtration (i : ι) : X.Subcomplex := A ⊔ ⨆ (j : ι) (_ : j < i) (c : f.Cells j), (P.p c.1).1.subcomplex @@ -205,6 +225,9 @@ lemma iSup_filtration [OrderBot ι] [SuccOrder ι] [NoMaxOrder ι] : · exact P.le t · rfl +/-- The morphism `Δ[c.dim + 1] ⟶ f.filtration (Order.succ j)` given +by `c : f.Cells j`, when `f` is a rank function for a proper pairing +of a subcomplex of a simplicial set. -/ def Cells.mapToSucc {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.filtration (Order.succ j) := Subcomplex.lift c.map (by @@ -218,16 +241,28 @@ lemma Cells.mapToSucc_ι {j : ι} [SuccOrder ι] [NoMaxOrder ι] (c : f.Cells j) section +/-- Given a rank function for a proper pairing of a subcomplex of a +simplicial set, this is coproduct of the horns corresponding to +all cells of rank `j`. -/ noncomputable abbrev sigmaHorn (j : ι) : SSet.{u} := ∐ fun (c : f.Cells j) ↦ c.horn +/-- Given a cell `c` of rank `j` for a rank function `f` for a proper +pairing of a subcomplex of a simplicial set, this is the inclusion of +`c.horn` into `f.sigmaHorn j`. -/ noncomputable abbrev Cells.ιSigmaHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.sigmaHorn j := Sigma.ι (fun (c : f.Cells j) ↦ (c.horn : SSet)) c +/-- Given a rank function for a proper pairing of a subcomplex of a +simplicial set, this is coproduct of the standard simplices corresponding +to all cells of rank `j`. -/ noncomputable abbrev sigmaStdSimplex (j : ι) : SSet.{u} := ∐ fun (i : f.Cells j) ↦ Δ[i.dim + 1] +/-- Given a cell `c` of rank `j` for a rank function `f` for a proper +pairing of a subcomplex of a simplicial set, this is the inclusion of +`Δ[c.dim + 1]` into `f.sigmaStdSimplex j`. -/ noncomputable abbrev Cells.ιSigmaStdSimplex {j : ι} (c : f.Cells j) : Δ[c.dim + 1] ⟶ f.sigmaStdSimplex j := Sigma.ι (fun (c : f.Cells j) ↦ Δ[c.dim + 1]) c @@ -235,7 +270,7 @@ noncomputable abbrev Cells.ιSigmaStdSimplex {j : ι} (c : f.Cells j) : lemma ιSigmaHorn_jointly_surjective {d : ℕ} {j : ι} (a : (f.sigmaHorn j) _⦋d⦌) : ∃ (c : f.Cells j) (x : (c.horn : SSet) _⦋d⦌), c.ιSigmaHorn.app _ x = a := - Limits.Cofan.inj_jointly_surjective_of_isColimit + Cofan.inj_jointly_surjective_of_isColimit ((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ (coproductIsCoproduct _))) a @@ -243,7 +278,7 @@ omit [P.IsProper] in lemma ιSigmaStdSimplex_jointly_surjective {d : ℕ} {j : ι} (a : (f.sigmaStdSimplex j) _⦋d⦌) : ∃ (c : f.Cells j) (x : Δ[c.dim + 1] _⦋d⦌), c.ιSigmaStdSimplex.app _ x = a := - Limits.Cofan.inj_jointly_surjective_of_isColimit + Cofan.inj_jointly_surjective_of_isColimit ((isColimitCofanMkObjOfIsColimit ((CategoryTheory.evaluation _ _).obj _) _ _ (coproductIsCoproduct _))) a @@ -266,6 +301,9 @@ instance {j : ι} (c : f.Cells j) : intro x y h simpa [f.ιSigmaStdSimplex_eq_iff] using h.symm +/-- The coproduct of the horn inclusions corresponding to all the cells +of rank `j` for a rank function for a proper pairing of a subcomplex +of a simplicila set. -/ noncomputable def m (j : ι) : f.sigmaHorn j ⟶ f.sigmaStdSimplex j := Limits.Sigma.map (basicCell _ _) @@ -310,7 +348,11 @@ lemma Cells.preimage_filtration_map {j : ι} (c : f.Cells j) : · rw [Subcomplex.N.lt_iff, SSet.N.lt_iff] exact lt_of_le_of_lt hs (c.image_horn_lt_subcomplex) -noncomputable def Cells.mapHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f.filtration j := +/-- Given a cell `c` of rank `j` for a rank function `f` for a proper +pairing of a subcomplex of a simplicial set, this is the induced +morphism `c.horn ⟶ f.filtration j`. -/ +noncomputable def Cells.mapHorn {j : ι} (c : f.Cells j) : + (c.horn : SSet) ⟶ f.filtration j := Subcomplex.lift (c.horn.ι ≫ c.map) (by simp [← image_top, image_le_iff, preimage_comp, c.preimage_filtration_map]) @@ -318,8 +360,11 @@ noncomputable def Cells.mapHorn {j : ι} (c : f.Cells j) : (c.horn : SSet) ⟶ f lemma Cells.mapHorn_ι {j : ι} (c : f.Cells j) : c.mapHorn ≫ (f.filtration j).ι = c.horn.ι ≫ c.map := rfl +/-- Given a rank function `f : P.RankFunction ι` for a proper pairing `P` +of a subcomplex of a simplicial set, this is the induced morphism +`f.sigmaHorn j ⟶ f.filtration j` for any `j : ι`. -/ noncomputable def t (j : ι) : f.sigmaHorn j ⟶ f.filtration j := - Limits.Sigma.desc (fun c ↦ c.mapHorn) + Sigma.desc (fun c ↦ c.mapHorn) set_option backward.isDefEq.respectTransparency false in @[reassoc (attr := simp)] @@ -501,7 +546,7 @@ lemma isPushout (j : ι) : refine (isColimitMapCoconePushoutCoconeEquiv _ _).2 (IsPushout.isColimit ?_) dsimp - refine Limits.Types.isPushout_of_isPullback_of_mono' + refine Types.isPushout_of_isPullback_of_mono' ((f.isPullback j).map ((CategoryTheory.evaluation _ _).obj _)) (f.range_homOfLE_app_union_range_b_app _ _) (fun x₁ x₂ hx₁ hx₂ h ↦ ?_) obtain ⟨s₁, g₁, _, hg₁⟩ := (Subcomplex.range (f.m j)).existsN x₁ hx₁ @@ -556,5 +601,5 @@ noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι whe isPushout := f.isPushout j } end RankFunction - +#lint end SSet.Subcomplex.Pairing From d93dfc507e97d892918bfe4d149f6098684207f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 14:50:55 +0100 Subject: [PATCH 74/81] wip --- .../RelativeCellComplex.lean | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index 7393da39db1c2e..f988e543d09428 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -17,6 +17,14 @@ public import Mathlib.CategoryTheory.Limits.FunctorCategory.Basic /-! # The relative cell complex attached to a rank function for a pairing +Let `A` be a subcomplex of a simplicial set `X`. Let `P : A.Pairing` +be a proper pairing (in the sense of Moss) and `f : P.RankFunction ι` +a rank function. We show that the inclusion `A.ι` is a relative +cell complex with basic cells given by horn inclusions. + +## References +* [Sean Moss, *Another approach to the Kan-Quillen model structure*][moss-2020] + -/ @[expose] public section @@ -372,6 +380,11 @@ lemma Cells.ι_t {j : ι} (c : f.Cells j) : c.ιSigmaHorn ≫ f.t j = c.mapHorn:= by simp [t] +/-- Given a rank `j` cell `c` for a rank function `f` for a proper +pairing of a subcomplex of a simplicial set, this is +the nondegenerate simplex in `f.sigmaStdSimplex j` +not in the image of `f.m j : f.sigmaHorn j ⟶ f.sigmaStdSimplex j` +which corresponds to `c.ιSigmaStdSimplex`. -/ @[simps] noncomputable def Cells.type₁ {j : ι} (c : f.Cells j) : (Subcomplex.range (f.m j)).N where @@ -389,6 +402,11 @@ noncomputable def Cells.type₁ {j : ι} (c : f.Cells j) : obtain ⟨rfl, rfl⟩ := hy exact objEquiv_symm_notMem_horn_of_isIso _ _ hy' +/-- Given a rank `j` cell `c` for a rank function `f` for a proper +pairing of a subcomplex of a simplicial set, this is +the nondegenerate simplex in `f.sigmaStdSimplex j` +not in the image of `f.m j : f.sigmaHorn j ⟶ f.sigmaStdSimplex j` +which corresponds to the `c.index`-face of `c.type₁`. -/ @[simps] noncomputable def Cells.type₂ {j : ι} (c : f.Cells j) : (Subcomplex.range (f.m j)).N where @@ -429,6 +447,9 @@ lemma exists_or_of_range_m_N {j : ι} variable [SuccOrder ι] [NoMaxOrder ι] +/-- Given a rank function `f : P.RankFunction ι` for a proper pairing `P` +of a subcomplex of a simplicial set, this is the induced morphism +`f.sigmaStdSimplex j ⟶ f.filtration (Order.succ j)` for any `j : ι`. -/ noncomputable def b (j : ι) : f.sigmaStdSimplex j ⟶ f.filtration (Order.succ j) := Sigma.desc (fun c ↦ c.mapToSucc) @@ -444,7 +465,6 @@ lemma w (j : ι) : ext c : 1 simp [← cancel_mono (Subcomplex.ι _)] - lemma isPullback (j : ι) : IsPullback (f.t j) (f.m j) (homOfLE (f.filtration_monotone (Order.le_succ j))) (f.b j) where w := f.w j @@ -489,6 +509,9 @@ lemma range_homOfLE_app_union_range_b_app (j : ι) (d : SimplexCategoryᵒᵖ) : obtain ⟨y, hy⟩ := hx exact Or.inr ⟨_, hy⟩ +/-- Given a rank function `f : P.RankFunction ι` for a proper pairing +of a subcomplex of a simplicial set `X`, this is the simplex of `X` +corresponding to an element in `(Subcomplex.range (f.m j)).N`. -/ noncomputable def mapN {j : ι} (x : (Subcomplex.range (f.m j)).N) : X.S := S.mk ((f.b j).app _ x.1.1.2).1 @@ -575,7 +598,12 @@ instance : f.filtration_monotone.functor.IsWellOrderContinuous where rw [← f.iSup_filtration_iio m hm] apply isLUB_iSup)⟩ -noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι where +/-- Given a rank function `f : P.RankFunction ι` for a +proper pairing `P` of a subcomplex `A` of simplicial set `X`, +the inclusion `A.ι` is a relative cell complex with basic cells +given by horn inclusions. -/ +noncomputable def relativeCellComplex : + RelativeCellComplex f.basicCell A.ι where F := f.filtration_monotone.functor ⋙ Subcomplex.toSSetFunctor isoBot := Subcomplex.eqToIso (filtration_bot _) isColimit := @@ -601,5 +629,5 @@ noncomputable def relativeCellComplex : RelativeCellComplex f.basicCell A.ι whe isPushout := f.isPushout j } end RankFunction -#lint + end SSet.Subcomplex.Pairing From 4511fd3585a643604f7333b7153735213d54b828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 14:52:59 +0100 Subject: [PATCH 75/81] wip --- .../SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean index f988e543d09428..df05bbfe6fb08e 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ From ade16f5ea0a46433dbf506a2f4548f11ab3fb3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 19:09:44 +0100 Subject: [PATCH 76/81] docstrings --- .../SimplicialSet/NonDegenerateSimplices.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean index 3bc3b8d6657c1a..4e839bb7362e5f 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/NonDegenerateSimplices.lean @@ -53,6 +53,8 @@ lemma mk_surjective (x : X.N) : ∃ (n : ℕ) (y : X.nonDegenerate n), x = N.mk _ y.prop := ⟨x.dim, ⟨_, x.nonDegenerate⟩, rfl⟩ +/-- Induction principle for the type `X.N` of nondegenerate simplices of +a simplicial set `X`. -/ @[elab_as_elim] def induction {motive : X.N → Sort*} (mk : ∀ (n : ℕ) (x : X.nonDegenerate n), motive (mk x.1 x.2)) (s : X.N) : @@ -230,6 +232,10 @@ lemma existsUnique_toNπ {x : X.S} {y : X.N} (hy : x.toN = y) : refine existsUnique_of_exists_of_unique ⟨f, inferInstance, rfl⟩ (fun f₁ f₂ ⟨_, hf₁⟩ ⟨_, hf₂⟩ ↦ unique_nonDegenerate_map _ _ _ _ hf₁.symm _ _ hf₂.symm) +/-- Given a simplex `x : X.S` of a simplicial set `X`, this is the unique +(epi)morphism `f : ⦋x.dim⦌ ⟶ ⦋x.toN.dim⦌` such that `x.simplex` is +`X.map f.op x.toN.simplex` where `x.toN : X.N` is the unique nondegenerate +simplex of `X` which generates the same subcomplex as `x`. -/ noncomputable def toNπ (x : X.S) : ⦋x.dim⦌ ⟶ ⦋x.toN.dim⦌ := (existsUnique_toNπ rfl).exists.choose From a1b1644733a440471dc534c0df1daa2ad4b99772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 21:05:33 +0100 Subject: [PATCH 77/81] feat(AlgebraicTopology/SimplicialSet): anodyne extensions --- .../AnodyneExtensions/Basic.lean | 137 ++++++++++++++++++ .../SimplicialSet/CategoryWithFibrations.lean | 10 +- .../MorphismProperty/LiftingProperty.lean | 2 + .../TransfiniteCompositionLifting.lean | 2 + 4 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean new file mode 100644 index 00000000000000..f103c1d7dc492b --- /dev/null +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean @@ -0,0 +1,137 @@ +/- +Copyright (c) 2026 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RankNat +public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RelativeCellComplex +public import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations +public import Mathlib.CategoryTheory.SmallObject.TransfiniteCompositionLifting + +/-! +# Anodyne extensions + +Anodyne extensions form a property of morphisms in the category of simplicial +sets. It contains horn inclusions and it is closed under coproducts, pushouts, +transfinite compositions and retracts. Equivalently, using the small +object argument, anodyne extensions can be defined (and are defined here) +as the class of morphisms that satisfy the left lifting property with respect +to the class of fibrations (for the Quillen model category structure: +fibrations are morphisms that have the right lifting property with respect +to horn inclusions). When the Quillen model category structure is fully +upstreamed (TODO @joelriou), it can be shown that a morphism `f` is an +anodyne extension iff `f` is a cofibration that is also a weak equivalence. + +We also introduce the class of strong anodyne extensions that could be defined +as a closure similarly as anodyne extensions, but without taking the closure +under retracts. Sean Moss has given a combinatorial description of these +strong anodyne extensions: the inclusion `A.ι : A ⟶ X` of a subcomplex `A` +of a simplicial set `X` is a strong anodyne extension iff there exists +a regular pairing for `A`. In this file, we define strong anodyne extensions +in terms of such regular pairings, and using the main result of the file +`Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/RelativeCellComplex.lean` +we show that a strong anodyne extension is an anodyne extension. + +## TODO +* introduce inner variants of these definitions +* show that strong anodyne extensions are indeed stable under coproducts, + transfinite compositions and pushouts (the proof should reduce to the + construction of pairings) +* use the small object argument to show that any anodyne extensions is indeed + a retract of a transfinite composition of pushouts of coproducts of horn + inclusions (@joelriou) +* study the interaction between anodyne extension and binary products: + the critical case consists in showing that inclusions + `Λ[m, i] ⊗ Δ[n] ∪ Δ[m] ⊗ ∂Δ[n] ⟶ Δ[m] ⊗ Δ[n]` are strong anodyne extensions (@joelriou) +* show that anodyne extensions are stable under the subdivision functor (@joelriou) + +## References +* [P. Gabriel, M. Zisman, *Calculus of fractions and homotopy theory*, IV.2][gabriel-zisman-1967] +* [Sean Moss, *Another approach to the Kan-Quillen model structure*][moss-2020] + +-/ + +@[expose] public section + +universe u + +open CategoryTheory HomotopicalAlgebra Simplicial + +namespace SSet + +open MorphismProperty + +open modelCategoryQuillen in +/-- In the category of simplicial sets, an anodyne extension is a morphism +that has the left lifting property with respect to fibrations, where +a fibration is a morphism that has the right lifting property with respect +to horn inclusions. We do not introduce a typeclass for anodyne extensions +because when the Quillen model structure is fully upstreamed (TODO 0joelriou), +the assumption `anodyneExtensions f` can be spelled as +`[Cofibration f] [WeakEquivalence f]`. -/ +def anodyneExtensions : MorphismProperty SSet.{u} := (fibrations _).llp +deriving IsMultiplicative, RespectsIso, IsStableUnderCobaseChange, + IsStableUnderRetracts, IsStableUnderTransfiniteComposition, + IsStableUnderCoproducts + +lemma anodyneExtensions.of_isIso {X Y : SSet.{u}} (f : X ⟶ Y) [IsIso f] : + anodyneExtensions f := + MorphismProperty.of_isIso anodyneExtensions f + +lemma anodyneExtensions_eq_llp_rlp : + anodyneExtensions.{u} = modelCategoryQuillen.J.rlp.llp := + rfl + +lemma anodyneExtensions.horn_ι {n : ℕ} [NeZero n] (i : Fin (n + 1)) : + anodyneExtensions.{u} Λ[n, i].ι := by + rw [anodyneExtensions_eq_llp_rlp] + exact le_llp_rlp _ _ (modelCategoryQuillen.horn_ι_mem_J n i) + +/-- In the category of simplicial sets, a strong anodyne extension is a morphism +which belongs to the closure of horn inclusions by pushouts, coproducts, +transfinite compositions (but not by retracts). We define this class here +by saying that `f : X ⟶ Y` is a strong anodyne extension if `f` is a monomorphism +and there exists a regular pairing (in the sense of Moss) for the subcomplex +`Subcomplex.range f` of `Y`. -/ +def strongAnodyneExtensions : MorphismProperty SSet.{u} := + fun _ _ f ↦ Mono f ∧ ∃ (P : (Subcomplex.range f).Pairing), P.IsRegular + +lemma Subcomplex.Pairing.strongAnodyneExtensions {X : SSet.{u}} {A : X.Subcomplex} + (P : A.Pairing) [P.IsRegular] : + strongAnodyneExtensions A.ι := + ⟨inferInstance, by + generalize h : Subcomplex.range A.ι = B + obtain rfl : B = A := by simpa using h.symm + exact ⟨P, inferInstance⟩⟩ + +lemma strongAnodyneExtensions_ι_iff {X : SSet.{u}} (A : X.Subcomplex) : + strongAnodyneExtensions A.ι ↔ ∃ (P : A.Pairing), P.IsRegular := + ⟨fun hA ↦ by + obtain ⟨_, P, _, rfl⟩ : + ∃ (B : X.Subcomplex) (P : B.Pairing), P.IsRegular ∧ B = A := by + obtain ⟨_, P, _⟩ := hA + exact ⟨_, P, inferInstance, by simp⟩ + exact ⟨P, inferInstance⟩, + fun ⟨P, _⟩ ↦ P.strongAnodyneExtensions⟩ + + +lemma Subcomplex.Pairing.anodyneExtensions {X : SSet.{u}} {A : X.Subcomplex} + (P : A.Pairing) [P.IsRegular] : + anodyneExtensions A.ι := + transfiniteCompositionsOfShape_le _ _ _ + ⟨P.rankFunction.relativeCellComplex.toTransfiniteCompositionOfShape, fun j hj ↦ by + refine (?_ : (_ : MorphismProperty _) ≤ _ ) _ + (P.rankFunction.relativeCellComplex.attachCells j hj).pushouts_coproducts + simp only [pushouts_le_iff, coproducts_le_iff] + rintro _ _ _ ⟨c⟩ + exact .horn_ι c.index⟩ + +lemma strongAnodyneExtensions_le_anodyneExtensions : + strongAnodyneExtensions.{u} ≤ anodyneExtensions := by + rintro X Y f ⟨_, P, _⟩ + rw [← Subfunctor.toRange_ι f] + exact comp_mem _ _ _ (.of_isIso _) P.anodyneExtensions + +end SSet diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/CategoryWithFibrations.lean b/Mathlib/AlgebraicTopology/SimplicialSet/CategoryWithFibrations.lean index 873b6cfa3be7d8..5b55870981194d 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/CategoryWithFibrations.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/CategoryWithFibrations.lean @@ -46,10 +46,12 @@ which consists of horn inclusions `Λ[n, i].ι : Λ[n, i] ⟶ Δ[n]` (for positi def J : MorphismProperty SSet.{u} := ⨆ n, .ofHoms (fun (i : Fin (n + 2)) ↦ Λ[n + 1, i].ι) -lemma horn_ι_mem_J (n : ℕ) (i : Fin (n + 2)) : - J (horn.{u} (n + 1) i).ι := by - simp only [J, iSup_iff] - exact ⟨n, ⟨i⟩⟩ +lemma horn_ι_mem_J (n : ℕ) [NeZero n] (i : Fin (n + 1)) : + J (horn.{u} n i).ι := by + obtain _ | n := n + · exact (NeZero.ne 0 rfl).elim + · simp only [J, iSup_iff] + exact ⟨n, ⟨i⟩⟩ lemma I_le_monomorphisms : I.{u} ≤ monomorphisms _ := by rintro _ _ _ ⟨n⟩ diff --git a/Mathlib/CategoryTheory/MorphismProperty/LiftingProperty.lean b/Mathlib/CategoryTheory/MorphismProperty/LiftingProperty.lean index 936af363ac772c..63c7882673c4f6 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/LiftingProperty.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/LiftingProperty.lean @@ -90,6 +90,8 @@ instance llp_isStableUnderCoproductsOfShape (J : Type*) : have := fun j ↦ hf j _ hp infer_instance +instance : IsStableUnderCoproducts.{w} T.llp where + instance rlp_isStableUnderProductsOfShape (J : Type*) : T.rlp.IsStableUnderProductsOfShape J := by apply IsStableUnderProductsOfShape.mk diff --git a/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean b/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean index 7c4063c214d76d..ed16741dfaab4a 100644 --- a/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean +++ b/Mathlib/CategoryTheory/SmallObject/TransfiniteCompositionLifting.lean @@ -294,6 +294,8 @@ lemma retracts_transfiniteComposition_pushouts_coproducts_le_llp_rlp : rw [le_llp_iff_le_rlp, rlp_retracts, ← le_llp_iff_le_rlp] apply transfiniteCompositions_pushouts_coproducts_le_llp_rlp +instance : MorphismProperty.IsStableUnderTransfiniteComposition.{w} W.llp where + end MorphismProperty end CategoryTheory From 2ccd8e111e6bd0fdbc4db77479668a03fb9ef1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 28 Mar 2026 21:05:51 +0100 Subject: [PATCH 78/81] updated Mathlib.lean --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index 50de6c14162d8a..9a9ef6040c78cf 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1499,6 +1499,7 @@ public import Mathlib.AlgebraicTopology.SimplicialObject.Homotopy public import Mathlib.AlgebraicTopology.SimplicialObject.II public import Mathlib.AlgebraicTopology.SimplicialObject.Op public import Mathlib.AlgebraicTopology.SimplicialObject.Split +public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Basic public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.IsUniquelyCodimOneFace public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.Pairing public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.PairingCore From 6b3cd49cd2a6a7e8736427de8b4a19c0b838f3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 29 Mar 2026 12:13:43 +0200 Subject: [PATCH 79/81] wip --- .../AnodyneExtensions/Basic.lean | 29 ++++++++++++++++++- .../MorphismProperty/IsSmall.lean | 5 ++++ Mathlib/SetTheory/Ordinal/Basic.lean | 5 ++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean index f103c1d7dc492b..f659b602b36a44 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean @@ -8,7 +8,8 @@ module public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RankNat public import Mathlib.AlgebraicTopology.SimplicialSet.AnodyneExtensions.RelativeCellComplex public import Mathlib.AlgebraicTopology.SimplicialSet.CategoryWithFibrations -public import Mathlib.CategoryTheory.SmallObject.TransfiniteCompositionLifting +public import Mathlib.AlgebraicTopology.SimplicialSet.Presentable +public import Mathlib.CategoryTheory.SmallObject.Basic /-! # Anodyne extensions @@ -89,6 +90,32 @@ lemma anodyneExtensions.horn_ι {n : ℕ} [NeZero n] (i : Fin (n + 1)) : rw [anodyneExtensions_eq_llp_rlp] exact le_llp_rlp _ _ (modelCategoryQuillen.horn_ι_mem_J n i) +attribute [local instance] Cardinal.fact_isRegular_aleph0 + Cardinal.orderBotAleph0OrdToType + +instance (n : ℕ) : MorphismProperty.IsSmall.{u} + (MorphismProperty.ofHoms.{u} (fun (i : Fin (n + 2)) ↦ Λ[n + 1, i].ι)) := + isSmall_ofHoms .. + +instance : MorphismProperty.IsSmall.{u} modelCategoryQuillen.J.{u} := + isSmall_iSup .. + +instance : IsCardinalForSmallObjectArgument modelCategoryQuillen.J.{u} Cardinal.aleph0.{u} where + preservesColimit {A B X Y} i hi f hf := by + have : IsFinitelyPresentable.{u} A := by + simp only [modelCategoryQuillen.J, iSup_iff] at hi + obtain ⟨n, ⟨i⟩⟩ := hi + infer_instance + infer_instance + +instance : HasSmallObjectArgument.{u} modelCategoryQuillen.J.{u} := + ⟨.aleph0, inferInstance, inferInstance, inferInstance⟩ + +lemma anodyneExtensions_eq_retracts_transfiniteCompositions : + anodyneExtensions = (transfiniteCompositions.{u} + (coproducts.{u} modelCategoryQuillen.J.{u}).pushouts).retracts := by + rw [anodyneExtensions_eq_llp_rlp, llp_rlp_of_hasSmallObjectArgument] + /-- In the category of simplicial sets, a strong anodyne extension is a morphism which belongs to the closure of horn inclusions by pushouts, coproducts, transfinite compositions (but not by retracts). We define this class here diff --git a/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean b/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean index 6799b2bee8a431..dc7e586380ccaa 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean @@ -61,6 +61,11 @@ lemma isSmall_iff_eq_ofHoms : · rintro ⟨_, _, _, _, rfl⟩ infer_instance +instance isSmall_iSup {α : Type*} (W : α → MorphismProperty C) + [Small.{w} α] [∀ a, IsSmall.{w} (W a)] : + IsSmall.{w} (iSup W) := by + sorry + end MorphismProperty end CategoryTheory diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index c87d089e3f61f3..05909742a41fca 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -1354,6 +1354,11 @@ noncomputable def toTypeOrderBot {c : Cardinal} (hc : c ≠ 0) : OrderBot c.ord.ToType := Ordinal.toTypeOrderBot (fun h ↦ hc (ord_injective (by simpa using h))) +/-- This can be made a local instance in order to get `⊥` +in `Cardinal.aleph0.ord.ToType`. -/ +abbrev orderBotAleph0OrdToType : OrderBot Cardinal.aleph0.ord.ToType := by + exact Cardinal.toTypeOrderBot Cardinal.aleph0_ne_zero + end Cardinal namespace Ordinal From 40ec110abb7b55eb404b38972d37ec9cebe278cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 29 Mar 2026 12:25:04 +0200 Subject: [PATCH 80/81] removed sorry --- Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean b/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean index dc7e586380ccaa..d0317673a56845 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/IsSmall.lean @@ -63,8 +63,15 @@ lemma isSmall_iff_eq_ofHoms : instance isSmall_iSup {α : Type*} (W : α → MorphismProperty C) [Small.{w} α] [∀ a, IsSmall.{w} (W a)] : - IsSmall.{w} (iSup W) := by - sorry + IsSmall.{w} (iSup W) where + small_toSet := by + rw [toSet_iSup] + refine small_of_surjective (f := fun (⟨i, f⟩ : Σ i, (W i).toSet) ↦ + ⟨f, by rw [Set.mem_iUnion]; exact ⟨i, f.prop⟩⟩) ?_ + rintro ⟨f, hf⟩ + simp only [Set.mem_iUnion] at hf + obtain ⟨i, hf⟩ := hf + exact ⟨⟨i, ⟨_, hf⟩⟩, rfl⟩ end MorphismProperty From 14dbc638c6c238c03f971fa2b2f0882c2b993d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 29 Mar 2026 15:43:48 +0200 Subject: [PATCH 81/81] cleaning up --- .../SimplicialSet/AnodyneExtensions/Basic.lean | 7 ++++++- .../IsCardinalForSmallObjectArgument.lean | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean index f659b602b36a44..489ac47495412b 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/AnodyneExtensions/Basic.lean @@ -116,6 +116,12 @@ lemma anodyneExtensions_eq_retracts_transfiniteCompositions : (coproducts.{u} modelCategoryQuillen.J.{u}).pushouts).retracts := by rw [anodyneExtensions_eq_llp_rlp, llp_rlp_of_hasSmallObjectArgument] +lemma anodyneExtensions_eq_retracts_transfiniteCompositionsOfShape : + anodyneExtensions = (transfiniteCompositionsOfShape + (coproducts.{u} modelCategoryQuillen.J.{u}).pushouts ℕ).retracts := by + rw [anodyneExtensions_eq_llp_rlp, + SmallObject.llp_rlp_of_isCardinalForSmallObjectArgument_aleph0] + /-- In the category of simplicial sets, a strong anodyne extension is a morphism which belongs to the closure of horn inclusions by pushouts, coproducts, transfinite compositions (but not by retracts). We define this class here @@ -143,7 +149,6 @@ lemma strongAnodyneExtensions_ι_iff {X : SSet.{u}} (A : X.Subcomplex) : exact ⟨P, inferInstance⟩, fun ⟨P, _⟩ ↦ P.strongAnodyneExtensions⟩ - lemma Subcomplex.Pairing.anodyneExtensions {X : SSet.{u}} {A : X.Subcomplex} (P : A.Pairing) [P.IsRegular] : anodyneExtensions A.ι := diff --git a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean index b53c3e024b96f3..e32810a60d41e4 100644 --- a/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean +++ b/Mathlib/CategoryTheory/SmallObject/IsCardinalForSmallObjectArgument.lean @@ -478,6 +478,18 @@ lemma llp_rlp_of_isCardinalForSmallObjectArgument' : { i := Arrow.homMk (𝟙 _) sq.lift r := Arrow.homMk (𝟙 _) (πObj I κ f) } +omit κ in +attribute [local instance] Cardinal.fact_isRegular_aleph0 + Cardinal.orderBotAleph0OrdToType in +lemma llp_rlp_of_isCardinalForSmallObjectArgument_aleph0 + [I.IsCardinalForSmallObjectArgument Cardinal.aleph0.{w}] : + I.rlp.llp = (transfiniteCompositionsOfShape (coproducts.{w} I).pushouts ℕ).retracts := by + let e : ℕ ≃o Cardinal.aleph0.{w}.ord.ToType := + ULift.orderIso.{w}.symm.trans + (OrderIso.ofRelIsoLT (Nonempty.some (by simp [← Ordinal.type_eq]))) + rw [SmallObject.llp_rlp_of_isCardinalForSmallObjectArgument' _ Cardinal.aleph0, + MorphismProperty.transfiniteCompositionsOfShape_eq_of_orderIso _ e] + /-- If `κ` is a suitable cardinal for the small object argument for `I : MorphismProperty C`, then the class `I.rlp.llp` is exactly the class of morphisms that are retracts of transfinite compositions of pushouts of coproducts of maps in `I`. -/