|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Olivia Röhrig. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Olivia Röhrig |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.Analysis.Convex.Extreme |
| 9 | +public import Mathlib.Geometry.Convex.Cone.Pointed |
| 10 | + |
| 11 | +/-! |
| 12 | +# Faces of pointed cones |
| 13 | +
|
| 14 | +This file defines what it means for a pointed cone to be a face of another pointed cone and |
| 15 | +establishes basic properties of this relation. |
| 16 | +A subcone `F` of a cone `C` is a face if any two points in `C` that have a positive combination |
| 17 | +in `F` are also in `F`. |
| 18 | +
|
| 19 | +## Main declarations |
| 20 | +
|
| 21 | +* `IsFaceOf F C`: States that the pointed cone `F` is a face of the pointed cone `C`. |
| 22 | +
|
| 23 | +## Implementation notes |
| 24 | +
|
| 25 | +* We do not use `IsExtreme` as a definition because this is an affine notion and does not allow the |
| 26 | + flexibility necessary to deal wth cones over general rings. E.g. the cone of positive integers has |
| 27 | + no proper subset that are extreme. We prove that every face is an extreme set of its cone. |
| 28 | +* Most results proven over a division ring hold more generally over an Archimedean ring. In |
| 29 | + particular, `iff_mem_of_add_mem_left` holds whenever for every `x ∈ R` there is a `y ∈ R` with |
| 30 | + `1 ≤ x * y`. |
| 31 | +
|
| 32 | +-/ |
| 33 | + |
| 34 | +open Submodule |
| 35 | + |
| 36 | +public section |
| 37 | + |
| 38 | +namespace PointedCone |
| 39 | + |
| 40 | +variable {R M N : Type*} |
| 41 | + |
| 42 | +section Semiring |
| 43 | + |
| 44 | +variable [Semiring R] [PartialOrder R] [IsOrderedRing R] |
| 45 | +variable [AddCommGroup M] [Module R M] |
| 46 | + |
| 47 | +/-- A sub-cone `F` of a pointed cone `C` is a face of `C` if any two points of `C` with a strictly |
| 48 | +positive combination in `F` are also in `F`. -/ |
| 49 | +@[mk_iff] |
| 50 | +structure IsFaceOf (F C : PointedCone R M) : Prop where |
| 51 | + le : F ≤ C |
| 52 | + mem_of_smul_add_mem {x y : M} {a : R} : |
| 53 | + x ∈ C → y ∈ C → 0 < a → a • x + y ∈ F → x ∈ F |
| 54 | + |
| 55 | +variable {C C₁ C₂ F F₁ F₂ : PointedCone R M} |
| 56 | + |
| 57 | +namespace IsFaceOf |
| 58 | + |
| 59 | +theorem mem_of_smul_add_smul_mem_left {x y : M} {a b : R} (hF : F.IsFaceOf C) (hx : x ∈ C) |
| 60 | + (hy : y ∈ C) (ha : 0 < a) (hb : 0 < b) (h : a • x + b • y ∈ F) : x ∈ F := |
| 61 | + hF.2 hx (smul_mem _ hb.le hy) ha h |
| 62 | + |
| 63 | +theorem mem_of_smul_add_smul_mem_right {x y : M} {a b : R} (hF : F.IsFaceOf C) (hx : x ∈ C) |
| 64 | + (hy : y ∈ C) (ha : 0 < a) (hb : 0 < b) (h : a • x + b • y ∈ F) : y ∈ F := |
| 65 | + by apply hF.2 hy (smul_mem _ ha.le hx) hb; rwa [add_comm] |
| 66 | + |
| 67 | +/-- A pointed cone `C` is a face of itself. -/ |
| 68 | +@[refl, simp] |
| 69 | +protected theorem refl (C : PointedCone R M) : C.IsFaceOf C := ⟨fun _ a ↦ a, fun hx _ _ _ ↦ hx⟩ |
| 70 | + |
| 71 | +protected theorem rfl {C : PointedCone R M} : C.IsFaceOf C := .refl _ |
| 72 | + |
| 73 | +/-- A face of a cone is a face of another if and only if they are contained in each other. -/ |
| 74 | +theorem isFaceOf_iff_le (h₁ : F₁.IsFaceOf C) (h₂ : F₂.IsFaceOf C) : |
| 75 | + F₁.IsFaceOf F₂ ↔ F₁ ≤ F₂ := |
| 76 | + ⟨IsFaceOf.le, fun h ↦ ⟨h, fun hx hy ha hxy ↦ h₁.2 (h₂.le hx) (h₂.le hy) ha hxy⟩⟩ |
| 77 | + |
| 78 | +/-- A face of a cone is an extreme subset of the cone. -/ |
| 79 | +theorem isExtreme (h : F.IsFaceOf C) : IsExtreme R (C : Set M) F := by |
| 80 | + refine ⟨h.1, ?_⟩ |
| 81 | + rintro _ xc _ yc _ zf ⟨_, _, a0, b0, -, rfl⟩ |
| 82 | + exact h.mem_of_smul_add_smul_mem_left xc yc a0 b0 zf |
| 83 | + |
| 84 | +/-- The intersection of two faces of two cones is a face of the intersection of the cones. -/ |
| 85 | +protected theorem inf (h₁ : F₁.IsFaceOf C₁) (h₂ : F₂.IsFaceOf C₂) : |
| 86 | + (F₁ ⊓ F₂).IsFaceOf (C₁ ⊓ C₂) := by |
| 87 | + use le_inf_iff.mpr ⟨Set.inter_subset_left.trans h₁.le, Set.inter_subset_right.trans h₂.le⟩ |
| 88 | + simp only [mem_inf, and_imp] |
| 89 | + refine fun xc₁ xc₂ yc₁ yc₂ a0 hz₁ hz₂ ↦ ⟨?_, ?_⟩ |
| 90 | + · exact h₁.mem_of_smul_add_mem xc₁ yc₁ a0 hz₁ |
| 91 | + · exact h₂.mem_of_smul_add_mem xc₂ yc₂ a0 hz₂ |
| 92 | + |
| 93 | +/-- The intersection of two faces of a cone is a face of the cone. -/ |
| 94 | +theorem inf_left (h₁ : F₁.IsFaceOf C) (h₂ : F₂.IsFaceOf C) : (F₁ ⊓ F₂).IsFaceOf C := |
| 95 | + inf_idem C ▸ IsFaceOf.inf h₁ h₂ |
| 96 | + |
| 97 | +/-- If a cone is a face of two cones simultaneously, then it's also a face of their intersection. -/ |
| 98 | +theorem inf_right (h₁ : F.IsFaceOf C₁) (h₂ : F.IsFaceOf C₂) : F.IsFaceOf (C₁ ⊓ C₂) := |
| 99 | + inf_idem F ▸ IsFaceOf.inf h₁ h₂ |
| 100 | + |
| 101 | +protected theorem sInf (F : Set (PointedCone R M)) (h : ∀ f ∈ F, f.IsFaceOf C) : |
| 102 | + (C ⊓ sInf F).IsFaceOf C where |
| 103 | + le _ sm := sm.1 |
| 104 | + mem_of_smul_add_mem := by |
| 105 | + simp only [mem_inf, mem_sInf, and_imp] |
| 106 | + intro _ _ a xc yc a0 _ h' |
| 107 | + simpa [xc] using fun F Fs ↦ (h F Fs).mem_of_smul_add_mem xc yc a0 (h' F Fs) |
| 108 | + |
| 109 | +theorem mem_of_add_mem_left (hF : F.IsFaceOf C) {x y : M} |
| 110 | + (hx : x ∈ C) (hy : y ∈ C) (hxy : x + y ∈ F) : x ∈ F := by |
| 111 | + nontriviality R using Module.subsingleton R M |
| 112 | + simpa [hxy] using hF.mem_of_smul_add_mem hx hy zero_lt_one |
| 113 | + |
| 114 | +theorem mem_of_add_mem_right (hF : F.IsFaceOf C) {x y : M} |
| 115 | + (hx : x ∈ C) (hy : y ∈ C) (hxy : x + y ∈ F) : y ∈ F := by |
| 116 | + rw [add_comm x y] at hxy; exact mem_of_add_mem_left hF hy hx hxy |
| 117 | + |
| 118 | +theorem add_mem_iff_mem (hF : F.IsFaceOf C) {x y : M} (hx : x ∈ C) (hy : y ∈ C) : |
| 119 | + x + y ∈ F ↔ x ∈ F ∧ y ∈ F := by |
| 120 | + refine ⟨?_, fun ⟨hx, hy⟩ ↦ F.add_mem hx hy⟩ |
| 121 | + exact fun h ↦ ⟨mem_of_add_mem_left hF hx hy h, mem_of_add_mem_right hF hx hy h⟩ |
| 122 | + |
| 123 | +/-- If the sum of points of a cone is in a face, then all the points are in the face. -/ |
| 124 | +theorem mem_of_sum_mem {ι : Type*} [Fintype ι] {f : ι → M} (hF : F.IsFaceOf C) |
| 125 | + (hsC : ∀ i : ι, f i ∈ C) (hs : ∑ i : ι, f i ∈ F) (i : ι) : f i ∈ F := by classical |
| 126 | + apply hF.mem_of_add_mem_left (hsC i) (sum_mem (fun j (_ : j ∈ Finset.univ.erase i) ↦ hsC j)) |
| 127 | + simp [hs] |
| 128 | + |
| 129 | +theorem sum_mem_iff_mem {ι : Type*} [Fintype ι] {f : ι → M} (hF : F.IsFaceOf C) |
| 130 | + (hsC : ∀ i, f i ∈ C) : ∑ i, f i ∈ F ↔ ∀ i, f i ∈ F := |
| 131 | + ⟨mem_of_sum_mem hF hsC, fun a ↦ Submodule.sum_mem F fun c _ ↦ a c⟩ |
| 132 | + |
| 133 | +/-- If the positive combination of points of a cone is in a face, then all the points are |
| 134 | +in the face. -/ |
| 135 | +theorem mem_of_sum_smul_mem {ι : Type*} [Fintype ι] {f : ι → M} {c : ι → R} |
| 136 | + (hF : F.IsFaceOf C) (hsC : ∀ i : ι, f i ∈ C) (hc : ∀ i, 0 ≤ c i) (hs : ∑ i : ι, c i • f i ∈ F) |
| 137 | + (i : ι) (hci : 0 < c i) : f i ∈ F := by classical |
| 138 | + rw [Finset.sum_eq_add_sum_sdiff_singleton i] at hs |
| 139 | + · refine hF.mem_of_smul_add_mem (hsC i) ?_ hci hs |
| 140 | + exact C.sum_mem fun i _ ↦ C.smul_mem (hc i) (hsC i) |
| 141 | + · simp |
| 142 | + |
| 143 | +/-- The face of a face of a cone is also a face of the cone. -/ |
| 144 | +@[trans] |
| 145 | +protected theorem trans (h₁ : F₂.IsFaceOf F₁) (h₂ : F₁.IsFaceOf C) : F₂.IsFaceOf C := by |
| 146 | + refine ⟨h₁.1.trans h₂.1, fun hx hy ha hxy ↦ h₁.2 (h₂.2 hx hy ha (h₁.le hxy)) ?_ ha hxy⟩ |
| 147 | + exact h₂.mem_of_add_mem_right (smul_mem _ ha.le hx) hy (h₁.le hxy) |
| 148 | + |
| 149 | +section Map |
| 150 | + |
| 151 | +variable [AddCommGroup N] [Module R N] |
| 152 | + |
| 153 | +/-- The image of a face of a cone under an injective linear map is a face of the |
| 154 | +image of the cone. -/ |
| 155 | +protected theorem map (f : M →ₗ[R] N) (hf : Function.Injective f) (hF : F.IsFaceOf C) : |
| 156 | + (F.map f).IsFaceOf (C.map f) where |
| 157 | + le := map_mono hF.le |
| 158 | + mem_of_smul_add_mem := by |
| 159 | + rintro _ _ a ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩ ha ⟨z, hz₁, hz₂⟩ |
| 160 | + dsimp at hz₂ |
| 161 | + rw [← map_smul, ← map_add] at hz₂ |
| 162 | + exact ⟨x, hF.mem_of_smul_add_mem hx hy ha (hf hz₂ ▸ hz₁), rfl⟩ |
| 163 | + |
| 164 | +/-- The image of a face of a cone under an equivalence is a face of the image of the cone. -/ |
| 165 | +theorem map_equiv (e : M ≃ₗ[R] N) (hF : F.IsFaceOf C) : |
| 166 | + (F.map (e : M →ₗ[R] N)).IsFaceOf (C.map e) := hF.map _ e.injective |
| 167 | + |
| 168 | +theorem of_map_injective {f : M →ₗ[R] N} (hf : Function.Injective f) |
| 169 | + (hc : (map f F).IsFaceOf (map f C)) : F.IsFaceOf C := by |
| 170 | + obtain ⟨sub, hF⟩ := hc |
| 171 | + refine ⟨fun x xf ↦ ?_, fun hx hy ha h ↦ ?_⟩ |
| 172 | + · obtain ⟨y, yC, hy⟩ := mem_map.mp <| sub (mem_map_of_mem xf) |
| 173 | + rwa [hf hy] at yC |
| 174 | + · simp only [mem_map, forall_exists_index, and_imp] at hF |
| 175 | + obtain ⟨_, ⟨hx', hhx'⟩⟩ := hF _ hx rfl _ hy rfl ha _ h (by simp) |
| 176 | + convert hx' |
| 177 | + exact hf hhx'.symm |
| 178 | + |
| 179 | +/-- The comap of a face of a cone under a linear map is a face of the comap of the cone. -/ |
| 180 | +protected theorem comap (f : N →ₗ[R] M) (hF : F.IsFaceOf C) : (F.comap f).IsFaceOf (C.comap f) := by |
| 181 | + refine ⟨comap_mono hF.le, ?_⟩ |
| 182 | + simp only [mem_comap, map_add, map_smul] |
| 183 | + exact hF.mem_of_smul_add_mem |
| 184 | + |
| 185 | +theorem of_comap_surjective {f : N →ₗ[R] M} (hf : Function.Surjective f) |
| 186 | + (hc : (F.comap f).IsFaceOf (C.comap f)) : F.IsFaceOf C := by |
| 187 | + refine ⟨fun x xF ↦ ?_, fun {x y _} xC yC a0 h ↦ ?_⟩ |
| 188 | + · rw [← (hf x).choose_spec] at xF ⊢ |
| 189 | + exact mem_comap.mp (hc.1 xF) |
| 190 | + · rw [← (hf x).choose_spec] at h ⊢ xC |
| 191 | + rw [← (hf y).choose_spec] at h yC |
| 192 | + exact hc.2 xC yC a0 (by simpa) |
| 193 | + |
| 194 | +end Map |
| 195 | + |
| 196 | +end IsFaceOf |
| 197 | + |
| 198 | +/-- The image of a cone `F` under an injective linear map is a face of the |
| 199 | +image of another cone `C` if and only if `F` is a face of `C`. -/ |
| 200 | +theorem isFaceOf_map_iff [AddCommGroup N] [Module R N] {f : M →ₗ[R] N} (hf : Function.Injective f) : |
| 201 | + (F.map f).IsFaceOf (C.map f) ↔ F.IsFaceOf C := |
| 202 | + ⟨IsFaceOf.of_map_injective hf, IsFaceOf.map _ hf⟩ |
| 203 | + |
| 204 | +/-- The comap of a cone `F` under a surjective linear map is a face of the |
| 205 | +comap of another cone `F` if and only if `F` is a face of `C`. -/ |
| 206 | +theorem isFaceOf_comap_iff [AddCommGroup N] [Module R N] {f : N →ₗ[R] M} |
| 207 | + (hf : Function.Surjective f) : (F.comap f).IsFaceOf (C.comap f) ↔ F.IsFaceOf C := |
| 208 | + ⟨IsFaceOf.of_comap_surjective hf, IsFaceOf.comap _⟩ |
| 209 | + |
| 210 | +end Semiring |
| 211 | + |
| 212 | +section DivisionRing |
| 213 | + |
| 214 | +variable [DivisionRing R] [LinearOrder R] [IsOrderedRing R] |
| 215 | +variable [AddCommGroup M] [Module R M] |
| 216 | +variable {C F F₁ F₂ : PointedCone R M} |
| 217 | + |
| 218 | +namespace IsFaceOf |
| 219 | + |
| 220 | +theorem of_mem_of_add_mem_left (h₁ : F ≤ C) (h₂ : ∀ {x y : M}, x ∈ C → y ∈ C → x + y ∈ F → x ∈ F) : |
| 221 | + F.IsFaceOf C := by |
| 222 | + refine ⟨h₁, fun hx hy ha haxy ↦ ?_⟩ |
| 223 | + simpa [← smul_assoc, inv_mul_cancel₀ (ne_of_gt ha)] using smul_mem _ |
| 224 | + (inv_nonneg.mpr (le_of_lt ha)) <| h₂ (smul_mem _ (le_of_lt ha) hx) hy haxy |
| 225 | + |
| 226 | +/-- The lineality space of a cone is a face. -/ |
| 227 | +lemma lineal (C : PointedCone R M) : IsFaceOf C.lineal C := by |
| 228 | + apply of_mem_of_add_mem_left (lineal_le C) |
| 229 | + intro _ _ xc yc xyf |
| 230 | + simp [neg_add_rev, xc, true_and] at xyf ⊢ |
| 231 | + simpa [neg_add_cancel_comm] using add_mem xyf.2 yc |
| 232 | + |
| 233 | +/-- The lineality space of a cone lies in every face. -/ |
| 234 | +lemma lineal_le (hF : F.IsFaceOf C) : C.lineal ≤ F := |
| 235 | + fun _ hx ↦ hF.mem_of_add_mem_left hx.1 hx.2 (by simp) |
| 236 | + |
| 237 | +/-- The lineality space of a face of a cone agrees with the lineality space of the cone. -/ |
| 238 | +lemma lineal_congr (hF : F.IsFaceOf C) : F.lineal = C.lineal := by |
| 239 | + ext |
| 240 | + refine ⟨fun ⟨hx, hx'⟩ ↦ ⟨hF.le hx, hF.le hx'⟩, fun ⟨hx, hx'⟩ ↦ ⟨?_, ?_⟩⟩ |
| 241 | + · exact hF.mem_of_add_mem_left hx hx' (by simp) |
| 242 | + · exact hF.mem_of_add_mem_left hx' hx (by simp) |
| 243 | + |
| 244 | +section Prod |
| 245 | + |
| 246 | +variable [AddCommGroup N] [Module R N] |
| 247 | + |
| 248 | +/-- The product of two faces of two cones is a face of the product of the cones. -/ |
| 249 | +protected theorem prod {C₁ F₁ : PointedCone R M} {C₂ F₂ : PointedCone R N} |
| 250 | + (hF₁ : F₁.IsFaceOf C₁) (hF₂ : F₂.IsFaceOf C₂) : IsFaceOf (F₁.prod F₂) (C₁.prod C₂) := by |
| 251 | + refine ⟨fun x hx ↦ by simpa [mem_prod] using ⟨hF₁.le hx.1, hF₂.le hx.2⟩, ?_⟩ |
| 252 | + simp only [mem_prod, Prod.fst_add, Prod.smul_fst, Prod.snd_add, |
| 253 | + Prod.smul_snd, and_imp, Prod.forall] |
| 254 | + intro _ _ _ _ _ xc₁ xc₂ yc₁ yc₂ a0 hab₁ hab₂ |
| 255 | + exact ⟨hF₁.mem_of_smul_add_mem xc₁ yc₁ a0 hab₁, hF₂.mem_of_smul_add_mem xc₂ yc₂ a0 hab₂⟩ |
| 256 | + |
| 257 | +/-- The projection of a face of a product cone onto the first component is a face of the |
| 258 | +projection of the product cone onto the first component. -/ |
| 259 | +protected theorem fst {C₁ : PointedCone R M} {C₂ : PointedCone R N} |
| 260 | + {F : PointedCone R (M × N)} |
| 261 | + (hF : F.IsFaceOf (C₁.prod C₂)) : (F.map (.fst R M N)).IsFaceOf C₁ := by |
| 262 | + constructor |
| 263 | + · intro x hx |
| 264 | + simp only [mem_map, LinearMap.fst_apply, Prod.exists, exists_and_right, exists_eq_right] at hx |
| 265 | + exact (Set.mem_prod.mp <| hF.le hx.choose_spec).1 |
| 266 | + · simp only [mem_map, LinearMap.fst_apply, Prod.exists, exists_and_right, exists_eq_right, |
| 267 | + forall_exists_index] |
| 268 | + intro x y a hx hy ha z h |
| 269 | + refine ⟨0, hF.mem_of_smul_add_mem (x := (x, 0)) (y := (y, z)) ?_ ?_ ha (by simpa)⟩ |
| 270 | + · exact mem_prod.mp ⟨hx, zero_mem C₂⟩ |
| 271 | + · exact mem_prod.mp ⟨hy, (hF.le h).2⟩ |
| 272 | + |
| 273 | +/-- The projection of a face of a product cone onto the second component is a face of the |
| 274 | +projection of the product cone onto the second component. -/ |
| 275 | +protected theorem snd {C₁ : PointedCone R M} {C₂ : PointedCone R N} {F : PointedCone R (M × N)} |
| 276 | + (hF : F.IsFaceOf (C₁.prod C₂)) : (F.map (.snd R M N)).IsFaceOf C₂ := by |
| 277 | + have := hF.map _ (LinearEquiv.prodComm R M N).injective |
| 278 | + convert IsFaceOf.fst (by simpa [PointedCone.map, Submodule.map]) |
| 279 | + ext; simp |
| 280 | + |
| 281 | +end Prod |
| 282 | + |
| 283 | +end IsFaceOf |
| 284 | + |
| 285 | +end DivisionRing |
| 286 | + |
| 287 | +end PointedCone |
0 commit comments