Skip to content

Commit 39aa723

Browse files
YaelDilliesb-mehta
andcommitted
feat(Convex): visibility through a set (#17928)
Define the relation of visibility with respect to a set, and lower bound how many elements of a set a point sees in terms of the dimension of that set. This will be used to prove a sort of strengthening of Freiman's lemma in additive combinatorics. From LeanCamCombi Co-authored-by: Bhavik Mehta <bm489@cam.ac.uk> Co-authored-by: Bhavik Mehta <bhavikmehta8@gmail.com>
1 parent d8b8344 commit 39aa723

File tree

2 files changed

+206
-0
lines changed

2 files changed

+206
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,7 @@ import Mathlib.Analysis.Convex.Strong
12221222
import Mathlib.Analysis.Convex.Topology
12231223
import Mathlib.Analysis.Convex.TotallyBounded
12241224
import Mathlib.Analysis.Convex.Uniform
1225+
import Mathlib.Analysis.Convex.Visible
12251226
import Mathlib.Analysis.Convolution
12261227
import Mathlib.Analysis.Distribution.AEEqOfIntegralContDiff
12271228
import Mathlib.Analysis.Distribution.FourierSchwartz
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/-
2+
Copyright (c) 2024 Yaël Dillies. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yaël Dillies
5+
-/
6+
import Mathlib.Algebra.Group.Pointwise.Set.Card
7+
import Mathlib.Analysis.Convex.Between
8+
import Mathlib.Analysis.Convex.Combination
9+
import Mathlib.Topology.Algebra.Affine
10+
import Mathlib.Topology.MetricSpace.Pseudo.Lemmas
11+
import Mathlib.Topology.Order.Monotone
12+
13+
/-!
14+
# Points in sight
15+
16+
This file defines the relation of visibility with respect to a set, and lower bounds how many
17+
elements of a set a point sees in terms of the dimension of that set.
18+
19+
## TODO
20+
21+
The art gallery problem can be stated using the visibility predicate: A set `A` (the art gallery) is
22+
guarded by a finite set `G` (the guards) iff `∀ a ∈ A, ∃ g ∈ G, IsVisible ℝ sᶜ a g`.
23+
-/
24+
25+
open AffineMap Filter Finset Set
26+
open scoped Cardinal Pointwise Topology
27+
28+
variable {𝕜 V P : Type*}
29+
30+
section AddTorsor
31+
variable [LinearOrderedField 𝕜] [AddCommGroup V] [Module 𝕜 V] [AddTorsor V P]
32+
{s t : Set P} {x y z : P}
33+
34+
variable (𝕜) in
35+
/-- Two points are visible to each other through a set if no point of that set lies strictly
36+
between them.
37+
38+
By convention, a point `x` sees itself through any set `s`, even when `x ∈ s`. -/
39+
def IsVisible (s : Set P) (x y : P) : Prop := ∀ ⦃z⦄, z ∈ s → ¬ Sbtw 𝕜 x z y
40+
41+
@[simp, refl] lemma IsVisible.rfl : IsVisible 𝕜 s x x := by simp [IsVisible]
42+
43+
lemma isVisible_comm : IsVisible 𝕜 s x y ↔ IsVisible 𝕜 s y x := by simp [IsVisible, sbtw_comm]
44+
45+
@[symm] alias ⟨IsVisible.symm, _⟩ := isVisible_comm
46+
47+
lemma IsVisible.mono (hst : s ⊆ t) (ht : IsVisible 𝕜 t x y) : IsVisible 𝕜 s x y :=
48+
fun _z hz ↦ ht <| hst hz
49+
50+
lemma isVisible_iff_lineMap (hxy : x ≠ y) :
51+
IsVisible 𝕜 s x y ↔ ∀ δ ∈ Set.Ioo (0 : 𝕜) 1, lineMap x y δ ∉ s := by
52+
simp [IsVisible, sbtw_iff_mem_image_Ioo_and_ne, hxy]
53+
aesop
54+
55+
end AddTorsor
56+
57+
section Module
58+
variable [LinearOrderedField 𝕜] [AddCommGroup V] [Module 𝕜 V] {s : Set V} {x y z : V}
59+
60+
/-- If a point `x` sees a convex combination of points of a set `s` through `convexHull ℝ s ∌ x`,
61+
then it sees all terms of that combination.
62+
63+
Note that the converse does not hold. -/
64+
lemma IsVisible.of_convexHull_of_pos {ι : Type*} {t : Finset ι} {a : ι → V} {w : ι → 𝕜}
65+
(hw₀ : ∀ i ∈ t, 0 ≤ w i) (hw₁ : ∑ i ∈ t, w i = 1) (ha : ∀ i ∈ t, a i ∈ s)
66+
(hx : x ∉ convexHull 𝕜 s) (hw : IsVisible 𝕜 (convexHull 𝕜 s) x (∑ i ∈ t, w i • a i)) {i : ι}
67+
(hi : i ∈ t) (hwi : 0 < w i) : IsVisible 𝕜 (convexHull 𝕜 s) x (a i) := by
68+
classical
69+
obtain hwi | hwi : w i = 1 ∨ w i < 1 := eq_or_lt_of_le <| (single_le_sum hw₀ hi).trans_eq hw₁
70+
· convert hw
71+
rw [← one_smul 𝕜 (a i), ← hwi, eq_comm]
72+
rw [← hwi, ← sub_eq_zero, ← sum_erase_eq_sub hi,
73+
sum_eq_zero_iff_of_nonneg fun j hj ↦ hw₀ _ <| erase_subset _ _ hj] at hw₁
74+
refine sum_eq_single _ (fun j hj hji ↦ ?_) (by simp [hi])
75+
rw [hw₁ _ <| mem_erase.2 ⟨hji, hj⟩, zero_smul]
76+
rintro _ hε ⟨⟨ε, ⟨hε₀, hε₁⟩, rfl⟩, h⟩
77+
replace hε₀ : 0 < ε := hε₀.lt_of_ne <| by rintro rfl; simp at h
78+
replace hε₁ : ε < 1 := hε₁.lt_of_ne <| by rintro rfl; simp at h
79+
have : 0 < 1 - ε := by linarith
80+
have hwi : 0 < 1 - w i := by linarith
81+
refine hw (z := lineMap x (∑ j ∈ t, w j • a j) ((w i)⁻¹ / ((1 - ε) / ε + (w i)⁻¹)))
82+
?_ <| sbtw_lineMap_iff.2 ⟨(ne_of_mem_of_not_mem ((convex_convexHull ..).sum_mem hw₀ hw₁
83+
fun i hi ↦ subset_convexHull _ _ <| ha _ hi) hx).symm, by positivity,
84+
(div_lt_one <| by positivity).2 ?_⟩
85+
· have : Wbtw 𝕜
86+
(lineMap x (a i) ε)
87+
(lineMap x (∑ j ∈ t, w j • a j) ((w i)⁻¹ / ((1 - ε) / ε + (w i)⁻¹)))
88+
(∑ j ∈ t.erase i, (w j / (1 - w i)) • a j) := by
89+
refine ⟨((1 - w i) / w i) / ((1 - ε) / ε + (1 - w i) / w i + 1), ⟨by positivity, ?_⟩, ?_⟩
90+
· refine (div_le_one <| by positivity).2 ?_
91+
calc
92+
(1 - w i) / w i = 0 + (1 - w i) / w i + 0 := by simp
93+
_ ≤ (1 - ε) / ε + (1 - w i) / w i + 1 := by gcongr <;> positivity
94+
have :
95+
w i • a i + (1 - w i) • ∑ j ∈ t.erase i, (w j / (1 - w i)) • a j = ∑ j ∈ t, w j • a j := by
96+
rw [smul_sum]
97+
simp_rw [smul_smul, mul_div_cancel₀ _ hwi.ne']
98+
exact add_sum_erase _ (fun i ↦ w i • a i) hi
99+
simp_rw [lineMap_apply_module, ← this, smul_add, smul_smul]
100+
match_scalars <;> field_simp <;> ring
101+
refine (convex_convexHull _ _).mem_of_wbtw this hε <| (convex_convexHull _ _).sum_mem ?_ ?_ ?_
102+
· intros j hj
103+
have := hw₀ j <| erase_subset _ _ hj
104+
positivity
105+
· rw [← sum_div, sum_erase_eq_sub hi, hw₁, div_self hwi.ne']
106+
· exact fun j hj ↦ subset_convexHull _ _ <| ha _ <| erase_subset _ _ hj
107+
· exact lt_add_of_pos_left _ <| by positivity
108+
109+
variable [TopologicalSpace 𝕜] [OrderTopology 𝕜] [TopologicalSpace V] [TopologicalAddGroup V]
110+
[ContinuousSMul 𝕜 V]
111+
112+
/-- One cannot see any point in the interior of a set. -/
113+
lemma IsVisible.eq_of_mem_interior (hsxy : IsVisible 𝕜 s x y) (hy : y ∈ interior s) :
114+
x = y := by
115+
by_contra! hxy
116+
suffices h : ∀ᶠ (_δ : 𝕜) in 𝓝[>] 0, False by obtain ⟨_, ⟨⟩⟩ := h.exists
117+
have hmem : ∀ᶠ (δ : 𝕜) in 𝓝[>] 0, lineMap y x δ ∈ s :=
118+
lineMap_continuous.continuousWithinAt.eventually_mem
119+
(by simpa using mem_interior_iff_mem_nhds.1 hy)
120+
filter_upwards [hmem, Ioo_mem_nhdsWithin_Ioi' zero_lt_one] with δ hmem hsbt
121+
using hsxy.symm hmem (by aesop)
122+
123+
/-- One cannot see any point of an open set. -/
124+
lemma IsOpen.eq_of_isVisible_of_left_mem (hs : IsOpen s) (hsxy : IsVisible 𝕜 s x y) (hy : y ∈ s) :
125+
x = y :=
126+
hsxy.eq_of_mem_interior (by simpa [hs.interior_eq])
127+
128+
end Module
129+
130+
section Real
131+
variable [AddCommGroup V] [Module ℝ V] {s : Set V} {x y z : V}
132+
133+
/-- All points of the convex hull of a set `s` visible from a point `x ∉ convexHull ℝ s` lie in the
134+
convex hull of such points that actually lie in `s`.
135+
136+
Note that the converse does not hold. -/
137+
lemma IsVisible.mem_convexHull_isVisible (hx : x ∉ convexHull ℝ s) (hy : y ∈ convexHull ℝ s)
138+
(hxy : IsVisible ℝ (convexHull ℝ s) x y) :
139+
y ∈ convexHull ℝ {z ∈ s | IsVisible ℝ (convexHull ℝ s) x z} := by
140+
classical
141+
obtain ⟨ι, _, w, a, hw₀, hw₁, ha, rfl⟩ := mem_convexHull_iff_exists_fintype.1 hy
142+
rw [← Fintype.sum_subset (s := {i | w i ≠ 0})
143+
fun i hi ↦ mem_filter.2 ⟨mem_univ _, left_ne_zero_of_smul hi⟩]
144+
exact (convex_convexHull ..).sum_mem (fun i _ ↦ hw₀ _) (by rwa [sum_filter_ne_zero])
145+
fun i hi ↦ subset_convexHull _ _ ⟨ha _, IsVisible.of_convexHull_of_pos (fun _ _ ↦ hw₀ _) hw₁
146+
(by simpa) hx hxy (mem_univ _) <| (hw₀ _).lt_of_ne' (mem_filter.1 hi).2
147+
148+
variable [TopologicalSpace V] [TopologicalAddGroup V] [ContinuousSMul ℝ V]
149+
150+
/-- If `s` is a closed set, then any point `x` sees some point of `s` in any direction where there
151+
is something to see. -/
152+
lemma IsClosed.exists_wbtw_isVisible (hs : IsClosed s) (hy : y ∈ s) (x : V) :
153+
∃ z ∈ s, Wbtw ℝ x z y ∧ IsVisible ℝ s x z := by
154+
let t : Set ℝ := Ici 0 ∩ lineMap x y ⁻¹' s
155+
have ht₁ : 1 ∈ t := by simpa [t]
156+
have ht : BddBelow t := bddBelow_Ici.inter_of_left
157+
let δ : ℝ := sInf t
158+
have hδ₁ : δ ≤ 1 := csInf_le ht ht₁
159+
obtain ⟨hδ₀, hδ⟩ : 0 ≤ δ ∧ lineMap x y δ ∈ s :=
160+
(isClosed_Ici.inter <| hs.preimage lineMap_continuous).csInf_mem ⟨1, ht₁⟩ ht
161+
refine ⟨lineMap x y δ, hδ, wbtw_lineMap_iff.2 <| .inr ⟨hδ₀, hδ₁⟩, ?_⟩
162+
rintro _ hε ⟨⟨ε, ⟨hε₀, hε₁⟩, rfl⟩, -, h⟩
163+
replace hδ₀ : 0 < δ := hδ₀.lt_of_ne' <| by rintro hδ₀; simp [hδ₀] at h
164+
replace hε₁ : ε < 1 := hε₁.lt_of_ne <| by rintro rfl; simp at h
165+
rw [lineMap_lineMap_right] at hε
166+
exact (csInf_le ht ⟨mul_nonneg hε₀ hδ₀.le, hε⟩).not_lt <| mul_lt_of_lt_one_left hδ₀ hε₁
167+
168+
-- TODO: Once we have cone hulls, the RHS can be strengthened to
169+
-- `coneHull ℝ x {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}`
170+
/-- A set whose convex hull is closed lies in the cone based at a point `x` generated by its points
171+
visible from `x` through its convex hull. -/
172+
lemma IsClosed.convexHull_subset_affineSpan_isVisible (hs : IsClosed (convexHull ℝ s))
173+
(hx : x ∉ convexHull ℝ s) :
174+
convexHull ℝ s ⊆ affineSpan ℝ ({x} ∪ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) := by
175+
rintro y hy
176+
obtain ⟨z, hz, hxzy, hxz⟩ := hs.exists_wbtw_isVisible hy x
177+
-- TODO: `calc` doesn't work with `∈` :(
178+
exact AffineSubspace.right_mem_of_wbtw hxzy (subset_affineSpan _ _ <| subset_union_left rfl)
179+
(affineSpan_mono _ subset_union_right <| convexHull_subset_affineSpan _ <|
180+
hxz.mem_convexHull_isVisible hx hz) (ne_of_mem_of_not_mem hz hx).symm
181+
182+
open Submodule in
183+
/-- If `s` is a closed set of dimension `d` and `x` is a point outside of its convex hull,
184+
then `x` sees at least `d` points of the convex hull of `s` that actually lie in `s`. -/
185+
lemma rank_le_card_isVisible (hs : IsClosed (convexHull ℝ s)) (hx : x ∉ convexHull ℝ s) :
186+
Module.rank ℝ (span ℝ (-x +ᵥ s)) ≤ #{y ∈ s | IsVisible ℝ (convexHull ℝ s) x y} := by
187+
calc
188+
Module.rank ℝ (span ℝ (-x +ᵥ s)) ≤
189+
Module.rank ℝ (span ℝ
190+
(-x +ᵥ affineSpan ℝ ({x} ∪ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) : Set V)) := by
191+
push_cast
192+
refine Submodule.rank_mono ?_
193+
gcongr
194+
exact (subset_convexHull ..).trans <| hs.convexHull_subset_affineSpan_isVisible hx
195+
_ = Module.rank ℝ (span ℝ (-x +ᵥ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y})) := by
196+
suffices h :
197+
-x +ᵥ (affineSpan ℝ ({x} ∪ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) : Set V) =
198+
span ℝ (-x +ᵥ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) by
199+
rw [AffineSubspace.coe_pointwise_vadd, h, span_span]
200+
simp [← AffineSubspace.coe_pointwise_vadd, AffineSubspace.pointwise_vadd_span,
201+
vadd_set_insert, -coe_affineSpan, affineSpan_insert_zero]
202+
_ ≤ #(-x +ᵥ {y ∈ s | IsVisible ℝ (convexHull ℝ s) x y}) := rank_span_le _
203+
_ = #{y ∈ s | IsVisible ℝ (convexHull ℝ s) x y} := by simp
204+
205+
end Real

0 commit comments

Comments
 (0)