-
Notifications
You must be signed in to change notification settings - Fork 234
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: port Analysis.Convex.SimplicialComplex.Basic (#3643)
- Loading branch information
Showing
2 changed files
with
269 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
/- | ||
Copyright (c) 2021 YaΓ«l Dillies, Bhavik Mehta. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: YaΓ«l Dillies, Bhavik Mehta | ||
! This file was ported from Lean 3 source module analysis.convex.simplicial_complex.basic | ||
! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a | ||
! Please do not edit these lines, except to modify the commit id | ||
! if you have ported upstream changes. | ||
-/ | ||
import Mathlib.Analysis.Convex.Hull | ||
import Mathlib.LinearAlgebra.AffineSpace.Independent | ||
|
||
/-! | ||
# Simplicial complexes | ||
In this file, we define simplicial complexes in `π`-modules. A simplicial complex is a collection | ||
of simplices closed by inclusion (of vertices) and intersection (of underlying sets). | ||
We model them by a downward-closed set of affine independent finite sets whose convex hulls "glue | ||
nicely", each finite set and its convex hull corresponding respectively to the vertices and the | ||
underlying set of a simplex. | ||
## Main declarations | ||
* `SimplicialComplex π E`: A simplicial complex in the `π`-module `E`. | ||
* `SimplicialComplex.vertices`: The zero dimensional faces of a simplicial complex. | ||
* `SimplicialComplex.facets`: The maximal faces of a simplicial complex. | ||
## Notation | ||
`s β K` means that `s` is a face of `K`. | ||
`K β€ L` means that the faces of `K` are faces of `L`. | ||
## Implementation notes | ||
"glue nicely" usually means that the intersection of two faces (as sets in the ambient space) is a | ||
face. Given that we store the vertices, not the faces, this would be a bit awkward to spell. | ||
Instead, `SimplicialComplex.inter_subset_convexHull` is an equivalent condition which works on the | ||
vertices. | ||
## TODO | ||
Simplicial complexes can be generalized to affine spaces once `ConvexHull` has been ported. | ||
-/ | ||
|
||
|
||
open Finset Set | ||
|
||
variable (π E : Type _) {ΞΉ : Type _} [OrderedRing π] [AddCommGroup E] [Module π E] | ||
|
||
namespace Geometry | ||
|
||
-- TODO: update to new binder order? not sure what binder order is correct for `down_closed`. | ||
/-- A simplicial complex in a `π`-module is a collection of simplices which glue nicely together. | ||
Note that the textbook meaning of "glue nicely" is given in | ||
`Geometry.SimplicialComplex.disjoint_or_exists_inter_eq_convexHull`. It is mostly useless, as | ||
`Geometry.SimplicialComplex.convexHull_inter_convexHull` is enough for all purposes. -/ | ||
@[ext] | ||
structure SimplicialComplex where | ||
faces : Set (Finset E) | ||
not_empty_mem : β β faces | ||
indep : β {s}, s β faces β AffineIndependent π ((β) : s β E) | ||
down_closed : β {s t}, s β faces β t β s β t β β β t β faces | ||
inter_subset_convexHull : β {s t}, s β faces β t β faces β | ||
convexHull π βs β© convexHull π βt β convexHull π (s β© t : Set E) | ||
#align geometry.simplicial_complex Geometry.SimplicialComplex | ||
|
||
namespace SimplicialComplex | ||
|
||
variable {π E} | ||
variable {K : SimplicialComplex π E} {s t : Finset E} {x : E} | ||
|
||
/-- A `Finset` belongs to a `SimplicialComplex` if it's a face of it. -/ | ||
instance : Membership (Finset E) (SimplicialComplex π E) := | ||
β¨fun s K => s β K.facesβ© | ||
|
||
/-- The underlying space of a simplicial complex is the union of its faces. -/ | ||
def space (K : SimplicialComplex π E) : Set E := | ||
β s β K.faces, convexHull π (s : Set E) | ||
#align geometry.simplicial_complex.space Geometry.SimplicialComplex.space | ||
|
||
-- Porting note: Expanded `β s β K.faces` to get the type to match more closely with Lean 3 | ||
theorem mem_space_iff : x β K.space β β (s : _) (_ : s β K.faces), x β convexHull π (s : Set E) := | ||
mem_unionα΅’β | ||
#align geometry.simplicial_complex.mem_space_iff Geometry.SimplicialComplex.mem_space_iff | ||
|
||
-- Porting note: Original proof was `:= subset_bunionα΅’_of_mem hs` | ||
theorem convexHull_subset_space (hs : s β K.faces) : convexHull π βs β K.space := by | ||
convert subset_bunionα΅’_of_mem hs | ||
rfl | ||
#align geometry.simplicial_complex.convex_hull_subset_space Geometry.SimplicialComplex.convexHull_subset_space | ||
|
||
protected theorem subset_space (hs : s β K.faces) : (s : Set E) β K.space := | ||
(subset_convexHull π _).trans <| convexHull_subset_space hs | ||
#align geometry.simplicial_complex.subset_space Geometry.SimplicialComplex.subset_space | ||
|
||
theorem convexHull_inter_convexHull (hs : s β K.faces) (ht : t β K.faces) : | ||
convexHull π βs β© convexHull π βt = convexHull π (s β© t : Set E) := | ||
(K.inter_subset_convexHull hs ht).antisymm <| | ||
subset_inter (convexHull_mono <| Set.inter_subset_left _ _) <| | ||
convexHull_mono <| Set.inter_subset_right _ _ | ||
#align geometry.simplicial_complex.convex_hull_inter_convex_hull Geometry.SimplicialComplex.convexHull_inter_convexHull | ||
|
||
/-- The conclusion is the usual meaning of "glue nicely" in textbooks. It turns out to be quite | ||
unusable, as it's about faces as sets in space rather than simplices. Further, additional structure | ||
on `π` means the only choice of `u` is `s β© t` (but it's hard to prove). -/ | ||
theorem disjoint_or_exists_inter_eq_convexHull (hs : s β K.faces) (ht : t β K.faces) : | ||
Disjoint (convexHull π (s : Set E)) (convexHull π βt) β¨ | ||
β u β K.faces, convexHull π (s : Set E) β© convexHull π βt = convexHull π βu := by | ||
classical | ||
by_contra' h | ||
refine' h.2 (s β© t) (K.down_closed hs (inter_subset_left _ _) fun hst => h.1 <| | ||
disjoint_iff_inf_le.mpr <| (K.inter_subset_convexHull hs ht).trans _) _ | ||
Β· rw [β coe_inter, hst, coe_empty, convexHull_empty] | ||
rfl | ||
Β· rw [coe_inter, convexHull_inter_convexHull hs ht] | ||
#align geometry.simplicial_complex.disjoint_or_exists_inter_eq_convex_hull Geometry.SimplicialComplex.disjoint_or_exists_inter_eq_convexHull | ||
|
||
/-- Construct a simplicial complex by removing the empty face for you. -/ | ||
@[simps] | ||
def ofErase (faces : Set (Finset E)) (indep : β s β faces, AffineIndependent π ((β) : s β E)) | ||
(down_closed : β s β faces, β (t) (_ : t β s), t β faces) | ||
(inter_subset_convexHull : β (s) (_ : s β faces) (t) (_ : t β faces), | ||
convexHull π βs β© convexHull π βt β convexHull π (s β© t : Set E)) : | ||
SimplicialComplex π E where | ||
faces := faces \ {β } | ||
not_empty_mem h := h.2 (mem_singleton _) | ||
indep hs := indep _ hs.1 | ||
down_closed hs hts ht := β¨down_closed _ hs.1 _ hts, htβ© | ||
inter_subset_convexHull hs ht := inter_subset_convexHull _ hs.1 _ ht.1 | ||
#align geometry.simplicial_complex.of_erase Geometry.SimplicialComplex.ofErase | ||
|
||
/-- Construct a simplicial complex as a subset of a given simplicial complex. -/ | ||
@[simps] | ||
def ofSubcomplex (K : SimplicialComplex π E) (faces : Set (Finset E)) (subset : faces β K.faces) | ||
(down_closed : β {s t}, s β faces β t β s β t β faces) : SimplicialComplex π E := | ||
{ faces | ||
not_empty_mem := fun h => K.not_empty_mem (subset h) | ||
indep := fun hs => K.indep (subset hs) | ||
down_closed := fun hs hts _ => down_closed hs hts | ||
inter_subset_convexHull := fun hs ht => K.inter_subset_convexHull (subset hs) (subset ht) } | ||
#align geometry.simplicial_complex.of_subcomplex Geometry.SimplicialComplex.ofSubcomplex | ||
|
||
/-! ### Vertices -/ | ||
|
||
|
||
/-- The vertices of a simplicial complex are its zero dimensional faces. -/ | ||
def vertices (K : SimplicialComplex π E) : Set E := | ||
{ x | {x} β K.faces } | ||
#align geometry.simplicial_complex.vertices Geometry.SimplicialComplex.vertices | ||
|
||
theorem mem_vertices : x β K.vertices β {x} β K.faces := Iff.rfl | ||
#align geometry.simplicial_complex.mem_vertices Geometry.SimplicialComplex.mem_vertices | ||
|
||
theorem vertices_eq : K.vertices = β k β K.faces, (k : Set E) := by | ||
ext x | ||
refine' β¨fun h => mem_bunionα΅’ h <| mem_coe.2 <| mem_singleton_self x, fun h => _β© | ||
obtain β¨s, hs, hxβ© := mem_unionα΅’β.1 h | ||
exact K.down_closed hs (Finset.singleton_subset_iff.2 <| mem_coe.1 hx) (singleton_ne_empty _) | ||
#align geometry.simplicial_complex.vertices_eq Geometry.SimplicialComplex.vertices_eq | ||
|
||
theorem vertices_subset_space : K.vertices β K.space := | ||
vertices_eq.subset.trans <| unionα΅’β_mono fun x _ => subset_convexHull π (x : Set E) | ||
#align geometry.simplicial_complex.vertices_subset_space Geometry.SimplicialComplex.vertices_subset_space | ||
|
||
theorem vertex_mem_convexHull_iff (hx : x β K.vertices) (hs : s β K.faces) : | ||
x β convexHull π (s : Set E) β x β s := by | ||
refine' β¨fun h => _, fun h => subset_convexHull π _ hβ© | ||
classical | ||
have h := K.inter_subset_convexHull hx hs β¨by simp, hβ© | ||
by_contra H | ||
rwa [β coe_inter, Finset.disjoint_iff_inter_eq_empty.1 (Finset.disjoint_singleton_right.2 H).symm, | ||
coe_empty, convexHull_empty] at h | ||
#align geometry.simplicial_complex.vertex_mem_convex_hull_iff Geometry.SimplicialComplex.vertex_mem_convexHull_iff | ||
|
||
/-- A face is a subset of another one iff its vertices are. -/ | ||
theorem face_subset_face_iff (hs : s β K.faces) (ht : t β K.faces) : | ||
convexHull π (s : Set E) β convexHull π βt β s β t := | ||
β¨fun h _ hxs => | ||
(vertex_mem_convexHull_iff | ||
(K.down_closed hs (Finset.singleton_subset_iff.2 hxs) <| singleton_ne_empty _) ht).1 | ||
(h (subset_convexHull π (βs) hxs)), | ||
convexHull_monoβ© | ||
#align geometry.simplicial_complex.face_subset_face_iff Geometry.SimplicialComplex.face_subset_face_iff | ||
|
||
/-! ### Facets -/ | ||
|
||
|
||
/-- A facet of a simplicial complex is a maximal face. -/ | ||
def facets (K : SimplicialComplex π E) : Set (Finset E) := | ||
{ s β K.faces | β β¦tβ¦, t β K.faces β s β t β s = t } | ||
#align geometry.simplicial_complex.facets Geometry.SimplicialComplex.facets | ||
|
||
theorem mem_facets : s β K.facets β s β K.faces β§ β t β K.faces, s β t β s = t := | ||
mem_sep_iff | ||
#align geometry.simplicial_complex.mem_facets Geometry.SimplicialComplex.mem_facets | ||
|
||
theorem facets_subset : K.facets β K.faces := fun _ hs => hs.1 | ||
#align geometry.simplicial_complex.facets_subset Geometry.SimplicialComplex.facets_subset | ||
|
||
theorem not_facet_iff_subface (hs : s β K.faces) : s β K.facets β β t, t β K.faces β§ s β t := by | ||
refine' β¨fun hs' : Β¬(_ β§ _) => _, _β© | ||
Β· push_neg at hs' | ||
obtain β¨t, htβ© := hs' hs | ||
exact β¨t, ht.1, β¨ht.2.1, fun hts => ht.2.2 (Subset.antisymm ht.2.1 hts)β©β© | ||
Β· rintro β¨t, htβ© β¨hs, hs'β© | ||
have := hs' ht.1 ht.2.1 | ||
rw [this] at ht | ||
exact ht.2.2 (Subset.refl t) | ||
#align geometry.simplicial_complex.not_facet_iff_subface Geometry.SimplicialComplex.not_facet_iff_subface | ||
|
||
/-! | ||
### The semilattice of simplicial complexes | ||
`K β€ L` means that `K.faces β L.faces`. | ||
-/ | ||
|
||
|
||
-- `HasSSubset.SSubset.ne` would be handy here | ||
variable (π E) | ||
|
||
/-- The complex consisting of only the faces present in both of its arguments. -/ | ||
instance : Inf (SimplicialComplex π E) := | ||
β¨fun K L => | ||
{ faces := K.faces β© L.faces | ||
not_empty_mem := fun h => K.not_empty_mem (Set.inter_subset_left _ _ h) | ||
indep := fun hs => K.indep hs.1 | ||
down_closed := fun hs hst ht => β¨K.down_closed hs.1 hst ht, L.down_closed hs.2 hst htβ© | ||
inter_subset_convexHull := fun hs ht => K.inter_subset_convexHull hs.1 ht.1 }β© | ||
|
||
instance : SemilatticeInf (SimplicialComplex π E) := | ||
{ PartialOrder.lift faces SimplicialComplex.ext with | ||
inf := (Β· β Β·) | ||
inf_le_left := fun _ _ _ hs => hs.1 | ||
inf_le_right := fun _ _ _ hs => hs.2 | ||
le_inf := fun _ _ _ hKL hKM _ hs => β¨hKL hs, hKM hsβ© } | ||
|
||
instance hasBot : Bot (SimplicialComplex π E) := | ||
β¨{ faces := β | ||
not_empty_mem := Set.not_mem_empty β | ||
indep := fun hs => (Set.not_mem_empty _ hs).elim | ||
down_closed := fun hs => (Set.not_mem_empty _ hs).elim | ||
inter_subset_convexHull := fun hs => (Set.not_mem_empty _ hs).elim }β© | ||
|
||
instance : OrderBot (SimplicialComplex π E) := | ||
{ SimplicialComplex.hasBot π E with bot_le := fun _ => Set.empty_subset _ } | ||
|
||
instance : Inhabited (SimplicialComplex π E) := | ||
β¨β₯β© | ||
|
||
variable {π E} | ||
|
||
theorem faces_bot : (β₯ : SimplicialComplex π E).faces = β := rfl | ||
#align geometry.simplicial_complex.faces_bot Geometry.SimplicialComplex.faces_bot | ||
|
||
theorem space_bot : (β₯ : SimplicialComplex π E).space = β := | ||
Set.bunionα΅’_empty _ | ||
#align geometry.simplicial_complex.space_bot Geometry.SimplicialComplex.space_bot | ||
|
||
theorem facets_bot : (β₯ : SimplicialComplex π E).facets = β := | ||
eq_empty_of_subset_empty facets_subset | ||
#align geometry.simplicial_complex.facets_bot Geometry.SimplicialComplex.facets_bot | ||
|
||
end SimplicialComplex | ||
|
||
end Geometry |