Skip to content

Commit d8f2354

Browse files
Merge commit '94d28b26c73a37e1d406ea48b0213d6295385cf3' into CWForward_colimits
2 parents ea40707 + 94d28b2 commit d8f2354

File tree

11 files changed

+575
-39
lines changed

11 files changed

+575
-39
lines changed

Mathlib/CategoryTheory/Discrete/Basic.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,18 @@ theorem functor_map_id (F : Discrete J ⥤ C) {j : Discrete J} (f : j ⟶ j) :
276276

277277
end Discrete
278278

279+
@[simp]
280+
lemma Discrete.forall {α : Type*} {p : Discrete α → Prop} :
281+
(∀ (a : Discrete α), p a) ↔ ∀ (a' : α), p ⟨a'⟩ := by
282+
rw [iff_iff_eq, discreteEquiv.forall_congr_left]
283+
simp [discreteEquiv]
284+
285+
@[simp]
286+
lemma Discrete.exists {α : Type*} {p : Discrete α → Prop} :
287+
(∃ (a : Discrete α), p a) ↔ ∃ (a' : α), p ⟨a'⟩ := by
288+
rw [iff_iff_eq, discreteEquiv.exists_congr_left]
289+
simp [discreteEquiv]
290+
279291
/-- The equivalence of categories `(J → C) ≌ (Discrete J ⥤ C)`. -/
280292
@[simps]
281293
def piEquivalenceFunctorDiscrete (J : Type u₂) (C : Type u₁) [Category.{v₁} C] :

Mathlib/Data/Set/Subset.lean

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Miguel Marco
55
-/
66
import Mathlib.Data.Set.Function
77
import Mathlib.Data.Set.Functor
8+
import Mathlib.Tactic.HigherOrder
89

910
/-!
1011
# Sets in subtypes
@@ -144,4 +145,34 @@ lemma image_val_preimage_val_subset_self : ↑(A ↓∩ B) ⊆ B :=
144145
lemma preimage_val_image_val_eq_self : A ↓∩ ↑D = D :=
145146
Function.Injective.preimage_image Subtype.val_injective _
146147

148+
variable {α : Type*} {s t : Set α}
149+
150+
/-- When `s ⊆ t`, `Set.inclusion` can be lifted into a map into `t ↓∩ s`. -/
151+
def inclusionPreimageVal (h : s ⊆ t) : s → t ↓∩ s := fun x ↦ ⟨Set.inclusion h x, by simp⟩
152+
153+
@[simp]
154+
lemma inclusionPreimageVal_mk (h : s ⊆ t) (x : α) (hx : x ∈ s) :
155+
inclusionPreimageVal h ⟨x, hx⟩ = ⟨⟨x, h hx⟩, hx⟩ := rfl
156+
157+
@[simp, higher_order val_comp_inclusionPreimageVal]
158+
lemma val_inclusionPreimageVal (h : s ⊆ t) (x : s) :
159+
Subtype.val (inclusionPreimageVal h x) = Set.inclusion h x := rfl
160+
161+
attribute [simp] val_comp_inclusionPreimageVal
162+
163+
164+
variable (s t) in
165+
/-- The 'identity' function recognizing values of the intersection `s ↓∩ t` as values of `t`. -/
166+
@[simp]
167+
def preimageValInclusion : s ↓∩ t → t := fun x ↦ ⟨x, by simpa [-Subtype.coe_prop] using x.2
168+
169+
lemma preimageValInclusion_injective : (preimageValInclusion s t).Injective := by
170+
rintro ⟨x, hx⟩ ⟨y, hy⟩ h
171+
simpa [Subtype.val_inj] using h
172+
173+
/-- When `s ⊆ t`, `s ≃ t ↓∩ s`. -/
174+
@[simps]
175+
def _root_.Equiv.Set.preimageVal (h : s ⊆ t) : s ≃ t ↓∩ s where
176+
toFun := inclusionPreimageVal h
177+
invFun := preimageValInclusion _ _
147178
end Set

Mathlib/Logic/Equiv/PartialEquiv.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,16 @@ noncomputable def InjOn.toPartialEquiv [Nonempty α] (f : α → β) (s : Set α
919919

920920
end Set
921921

922+
namespace Function
923+
924+
/-- Any injective function induces a partial equivalence from its domain to its range. -/
925+
@[simps! -fullyApplied]
926+
noncomputable def Injective.toPartialEquiv
927+
{α β : Type*} [Nonempty α] {f : α → β} (hf : f.Injective) : PartialEquiv α β :=
928+
hf.injOn.toPartialEquiv f univ
929+
930+
end Function
931+
922932
namespace Equiv
923933

924934
/- `Equiv`s give rise to `PartialEquiv`s. We set up simp lemmas to reduce most properties of the
@@ -985,4 +995,10 @@ theorem trans_transEquiv (e : PartialEquiv α β) (e' : PartialEquiv β γ) (f''
985995
(e.trans e').transEquiv f'' = e.trans (e'.transEquiv f'') := by
986996
simp only [transEquiv_eq_trans, trans_assoc]
987997

998+
/-- `Subtype.val` induces a partial equivalence from `univ : Set (Subtype p)` to `p`. -/
999+
@[simps! -fullyApplied]
1000+
noncomputable def subtype {α : Type*} (p : α → Prop) [Nonempty (Subtype p)] :
1001+
PartialEquiv (Subtype p) α :=
1002+
Subtype.val_injective.injOn.toPartialEquiv Subtype.val univ
1003+
9881004
end PartialEquiv

Mathlib/Topology/CWComplex/Classical/Basic.lean

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -563,35 +563,22 @@ lemma CWComplex.cellFrontier_subset_finite_openCell [CWComplex C] (n : ℕ) (i :
563563
lemma RelCWComplex.isCoherentWith_closedCells [T2Space X] [𝓔 : RelCWComplex C D] :
564564
IsCoherentWith (insert (C ↓∩ D) (range (Sigma.rec fun n j ↦ C ↓∩ 𝓔.closedCell n j))) := by
565565
apply IsCoherentWith.of_isClosed
566-
intro t ht
567-
have hC {s : Set X} (hs : IsClosed s) : IsClosed (C ↓∩ s) := by
568-
rw [IsClosed.inter_preimage_val_iff isClosed]
569-
exact IsClosed.inter isClosed hs
570-
have hC' : coinduced (↑) (inferInstanceAs (TopologicalSpace C)) ≤ ‹TopologicalSpace X› := by
571-
rw [coinduced_le_iff_le_induced]
572-
exact continuous_subtype_val.le_induced
573-
replace hC' s := hC' s
574-
simp_rw [forall_mem_insert, forall_mem_range, Sigma.forall] at ht
566+
simp_intro t ht .. only [forall_mem_insert, forall_mem_range, Sigma.forall]
575567
rcases ht with ⟨htD, ht_cells⟩
576-
simp only [isClosedBase C, hC, IsClosed.inter_preimage_val_iff,
577-
isClosed_closedCell] at htD ht_cells
578-
rw [isClosed_induced_iff]
568+
simp only [IsClosed.preimage_val _ |>.inter_preimage_val_iff, isClosedBase C,
569+
isClosed_closedCell] at htD ht_cells
570+
simp_rw [isClosed_induced_iff] at htD ht_cells ⊢
579571
refine ⟨Subtype.val '' t, ?closed, by simp⟩
580572
rw [closed C _ (Subtype.coe_image_subset C t)]
581-
constructor
573+
split_ands
582574
· intro n j
583-
specialize ht_cells n j
584-
rw [isClosed_induced_iff] at ht_cells
585-
rcases ht_cells with ⟨tnj, tnj_closed, htnj⟩
586-
apply_fun (image Subtype.val) at htnj
587-
rw [← inter_comm, ← inter_eq_self_of_subset_right (closedCell_subset_complex n j)]
588-
simp at htnj
575+
rcases ht_cells n j with ⟨tnj, tnj_closed, htnj⟩
576+
rw [inter_comm, ← inter_eq_self_of_subset_right (closedCell_subset_complex n j)]
577+
apply_fun (image Subtype.val) at htnj; simp at htnj
589578
simpa [← htnj] using IsClosed.inter isClosed tnj_closed
590-
· rw [isClosed_induced_iff] at htD
591-
rcases htD with ⟨tD, tD_closed, htD⟩
592-
apply_fun (image Subtype.val) at htD
579+
· rcases htD with ⟨tD, tD_closed, htD⟩
593580
rw [inter_comm, ← inter_eq_self_of_subset_right (base_subset_complex (C := C))]
594-
simp at htD
581+
apply_fun (image Subtype.val) at htD; simp at htD
595582
simpa [← htD] using IsClosed.inter isClosed tD_closed
596583

597584
/-- A CW complex is coherent with its closed cells. -/
@@ -615,7 +602,7 @@ namespace RelCWComplex
615602

616603
/-- A subcomplex is a closed subspace of a CW complex that is the union of open cells of the
617604
CW complex. -/
618-
structure Subcomplex (C : Set X) {D : Set X} [RelCWComplex C D] where
605+
structure Subcomplex (C : Set X) {D : Set X} [𝓔 : RelCWComplex C D] where
619606
/-- The underlying set of the subcomplex. -/
620607
carrier : Set X
621608
/-- The indexing set of cells of the subcomplex. -/
@@ -791,7 +778,7 @@ the base and some points.
791778
The standard `skeleton` is defined in terms of `skeletonLT`. `skeletonLT` is preferred
792779
in statements. You should then derive the statement about `skeleton`. -/
793780
@[simps! -isSimp, irreducible]
794-
def skeletonLT (C : Set X) {D : Set X} [RelCWComplex C D] (n : ℕ∞) : Subcomplex C :=
781+
def skeletonLT (C : Set X) {D : Set X} [𝓔 : RelCWComplex C D] (n : ℕ∞) : Subcomplex C :=
795782
Subcomplex.mk' _ (D ∪ ⋃ (m : ℕ) (_ : m < n) (j : cell C m), closedCell m j)
796783
(fun l ↦ {x : cell C l | l < n})
797784
(by
@@ -808,7 +795,7 @@ def skeletonLT (C : Set X) {D : Set X} [RelCWComplex C D] (n : ℕ∞) : Subcomp
808795

809796
/-- The `n`-skeleton of a CW complex, for `n ∈ ℕ ∪ {∞}`. For statements use `skeletonLT` instead
810797
and then derive the statement about `skeleton`. -/
811-
abbrev skeleton (C : Set X) {D : Set X} [RelCWComplex C D] (n : ℕ∞) : Subcomplex C :=
798+
abbrev skeleton (C : Set X) {D : Set X} [𝓔 : RelCWComplex C D] (n : ℕ∞) : Subcomplex C :=
812799
skeletonLT C (n + 1)
813800

814801
end RelCWComplex
@@ -825,6 +812,9 @@ lemma RelCWComplex.skeletonLT_zero_eq_base [RelCWComplex C D] : skeletonLT C 0 =
825812
lemma CWComplex.skeletonLT_zero_eq_empty [CWComplex C] : (skeletonLT C 0 : Set X) = ∅ :=
826813
RelCWComplex.skeletonLT_zero_eq_base
827814

815+
instance CWComplex.instIsEmptySkeletonLTZero [CWComplex C] : IsEmpty (skeletonLT C (0 : ℕ)) :=
816+
isEmpty_coe_sort.mpr skeletonLT_zero_eq_empty
817+
828818
@[simp] lemma RelCWComplex.skeletonLT_top [RelCWComplex C D] : skeletonLT C ⊤ = C := by
829819
simp [coe_skeletonLT, union]
830820

@@ -917,6 +907,13 @@ lemma RelCWComplex.iUnion_openCell_eq_skeleton [RelCWComplex C D] (n : ℕ∞) :
917907
D ∪ ⋃ (m : ℕ) (_ : m < n + 1) (j : cell C m), openCell m j = skeleton C n :=
918908
iUnion_openCell_eq_skeletonLT _
919909

910+
lemma RelCWComplex.skeletonLT_union_iUnion_openCell_eq_skeletonLT_succ [RelCWComplex C D] (n : ℕ) :
911+
↑(skeletonLT C n) ∪ ⋃ (j : cell C n), openCell n j = skeletonLT C (n + 1) := by
912+
simp_rw [← iUnion_openCell_eq_skeletonLT, union_assoc, ENat.coe_lt_coe,
913+
← biUnion_le (fun i ↦ ⋃ (j : cell C i), openCell i j) n, ← Nat.lt_succ_iff, Nat.succ_eq_add_one,
914+
← ENat.coe_lt_coe]
915+
rfl
916+
920917
lemma CWComplex.iUnion_openCell_eq_skeleton [CWComplex C] (n : ℕ∞) :
921918
⋃ (m : ℕ) (_ : m < n + 1) (j : cell C m), openCell m j = skeleton C n :=
922919
iUnion_openCell_eq_skeletonLT _
@@ -1009,6 +1006,38 @@ lemma RelCWComplex.disjoint_interior_base_iUnion_closedCell [T2Space X] [RelCWCo
10091006
simp_rw [disjoint_iff_inter_eq_empty, inter_iUnion, disjoint_interior_base_closedCell.inter_eq,
10101007
iUnion_empty]
10111008

1009+
/-- All cell frontiers are disjoint from open cells of the same dimension. -/
1010+
lemma RelCWComplex.disjoint_openCell_cellFrontier [RelCWComplex C D]
1011+
{n m : ℕ} (h : m ≤ n) (j : cell C n) (k : cell C m) :
1012+
Disjoint (openCell n j) (cellFrontier m k) := by
1013+
obtain ⟨I, hI⟩ := cellFrontier_subset_finite_openCell m k
1014+
fapply disjoint_of_subset_right hI
1015+
simp_rw [disjoint_union_right, disjoint_iUnion_right]
1016+
split_ands
1017+
· fapply disjoint_of_subset_left (subset_iUnion₂ _ _)
1018+
symm
1019+
exact disjoint_base_iUnion_openCell
1020+
· rintro k hk i hi
1021+
replace hk : n ≠ k := ne_of_gt (trans hk h)
1022+
exact disjoint_openCell_of_ne (by simp [hk])
1023+
1024+
/-- A point that is known to be in `Metric.closedBall 0 1` that is also in the preimage of
1025+
a cell frontier is in `Metric.sphere 0 1`. -/
1026+
lemma RelCWComplex.map_mem_cellFrontier_iff [RelCWComplex C D] {n} {j : cell C n} {x}
1027+
(hx : x ∈ Metric.closedBall 0 1) : map n j x ∈ cellFrontier n j ↔ x ∈ Metric.sphere 0 1 := by
1028+
have : x ∈ Metric.ball 0 1 → (map n j x) ∉ cellFrontier n j := by
1029+
intro hx hx'
1030+
have : (map n j x) ∈ openCell n j := mem_image_of_mem _ hx
1031+
exact (disjoint_openCell_cellFrontier (le_refl _) _ _).notMem_of_mem_right hx' this
1032+
constructor
1033+
· rintro ⟨y, hy, h⟩
1034+
by_contra hx'
1035+
replace hx : ‖x - 0‖ < 1 := by simpa using lt_of_le_of_ne hx hx'
1036+
rw [← mem_ball_iff_norm] at hx
1037+
fapply this hx
1038+
rw [← h]; exact mem_image_of_mem _ hy
1039+
· intro hx; exact ⟨x, hx, rfl⟩
1040+
10121041
namespace CWComplex
10131042

10141043
export RelCWComplex (pairwiseDisjoint disjoint_openCell_of_ne openCell_subset_closedCell
@@ -1017,15 +1046,15 @@ export RelCWComplex (pairwiseDisjoint disjoint_openCell_of_ne openCell_subset_cl
10171046
isClosed_cellFrontier closure_openCell_eq_closedCell skeletonLT_top skeleton_top skeletonLT_mono
10181047
skeleton_mono skeletonLT_monotone skeleton_monotone closedCell_subset_skeletonLT
10191048
closedCell_subset_skeleton closedCell_subset_complex openCell_subset_skeletonLT
1020-
openCell_subset_skeleton
1049+
openCell_subset_skeleton skeletonLT_union_iUnion_openCell_eq_skeletonLT_succ
10211050
openCell_subset_complex cellFrontier_subset_skeletonLT cellFrontier_subset_skeleton
1022-
cellFrontier_subset_complex iUnion_cellFrontier_subset_skeletonLT
1051+
cellFrontier_subset_complex iUnion_cellFrontier_subset_skeletonLT map_mem_cellFrontier_iff
10231052
iUnion_cellFrontier_subset_skeleton closedCell_zero_eq_singleton openCell_zero_eq_singleton
10241053
cellFrontier_zero_eq_empty isClosed skeletonLT_union_iUnion_closedCell_eq_skeletonLT_succ
10251054
skeleton_union_iUnion_closedCell_eq_skeleton_succ iUnion_skeletonLT_eq_complex
10261055
iUnion_skeleton_eq_complex eq_of_not_disjoint_openCell disjoint_skeletonLT_openCell
10271056
disjoint_skeleton_openCell skeletonLT_inter_closedCell_eq_skeletonLT_inter_cellFrontier
1028-
skeleton_inter_closedCell_eq_skeleton_inter_cellFrontier)
1057+
skeleton_inter_closedCell_eq_skeleton_inter_cellFrontier disjoint_openCell_cellFrontier)
10291058

10301059
end CWComplex
10311060

0 commit comments

Comments
 (0)