Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit f6f6f8a

Browse files
committed
feat(linear_algebra/affine_space): more affine subspace lemmas (#3552)
Add more lemmas on affine subspaces that came up in the course of proving existence and uniqueness of the circumcenter of a simplex in a Euclidean space.
1 parent 7848f28 commit f6f6f8a

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/algebra/add_torsor.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,18 @@ begin
228228
exact hp
229229
end
230230

231+
/-- `vsub_set` of a single point. -/
232+
@[simp] lemma vsub_set_singleton (p : P) : vsub_set G ({p} : set P) = {0} :=
233+
begin
234+
ext g,
235+
rw set.mem_singleton_iff,
236+
split,
237+
{ rintros ⟨p1, hp1, p2, hp2, rfl⟩,
238+
rw set.mem_singleton_iff at hp1 hp2,
239+
simp [hp1, hp2] },
240+
{ exact λ h, h.symm ▸ ⟨p, set.mem_singleton p, p, set.mem_singleton p, (vsub_self G p).symm⟩ }
241+
end
242+
231243
/-- Each pairwise difference is in the `vsub_set`. -/
232244
lemma vsub_mem_vsub_set {p1 p2 : P} {s : set P} (hp1 : p1 ∈ s) (hp2 : p2 ∈ s) :
233245
(p1 -ᵥ p2) ∈ vsub_set G s :=

src/linear_algebra/affine_space.lean

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ by rw [vector_span_def, vsub_set_empty, submodule.span_empty]
6868

6969
variables {P}
7070

71+
/-- The `vector_span` of a single point is `⊥`. -/
72+
@[simp] lemma vector_span_singleton (p : P) : vector_span k V ({p} : set P) = ⊥ :=
73+
by simp [vector_span_def]
74+
7175
/-- The `vsub_set` lies within the `vector_span`. -/
7276
lemma vsub_set_subset_vector_span (s : set P) : vsub_set V s ⊆ vector_span k V s :=
7377
submodule.subset_span
@@ -842,6 +846,16 @@ eq_top_iff.2 $ subset_span_points k V _
842846

843847
variables {P}
844848

849+
/-- The affine span of a single point, coerced to a set, contains just
850+
that point. -/
851+
@[simp] lemma coe_affine_span_singleton (p : P) : (affine_span k V ({p} : set P) : set P) = {p} :=
852+
begin
853+
ext x,
854+
rw [mem_coe, ←vsub_right_mem_direction_iff_mem (mem_affine_span k V (set.mem_singleton p)) _,
855+
direction_affine_span],
856+
simp
857+
end
858+
845859
/-- The span of a union of sets is the sup of their spans. -/
846860
lemma span_union (s t : set P) : affine_span k V (s ∪ t) = affine_span k V s ⊔ affine_span k V t :=
847861
(affine_subspace.gi k V P).gc.l_sup
@@ -1217,6 +1231,84 @@ end
12171231

12181232
end affine_space
12191233

1234+
namespace affine_subspace
1235+
1236+
variables {k : Type*} {V : Type*} {P : Type*} [ring k] [add_comm_group V] [module k V]
1237+
[affine_space k V P]
1238+
1239+
open affine_space
1240+
1241+
/-- The direction of the sup of two nonempty affine subspaces is the
1242+
sup of the two directions and of any one difference between points in
1243+
the two subspaces. -/
1244+
lemma direction_sup {s1 s2 : affine_subspace k V P} {p1 p2 : P} (hp1 : p1 ∈ s1) (hp2 : p2 ∈ s2) :
1245+
(s1 ⊔ s2).direction = s1.direction ⊔ s2.direction ⊔ submodule.span k {p2 -ᵥ p1} :=
1246+
begin
1247+
refine le_antisymm _ _,
1248+
{ change (affine_span k V ((s1 : set P) ∪ s2)).direction ≤ _,
1249+
rw ←mem_coe at hp1,
1250+
rw [direction_affine_span, vector_span_eq_span_vsub_set_right k V (set.mem_union_left _ hp1),
1251+
submodule.span_le],
1252+
rintros v ⟨p3, hp3, rfl⟩,
1253+
cases hp3,
1254+
{ rw [sup_assoc, sup_comm, submodule.mem_coe, submodule.mem_sup],
1255+
use [0, submodule.zero_mem _, p3 -ᵥ p1, vsub_mem_direction hp3 hp1],
1256+
rw zero_add },
1257+
{ rw [sup_assoc, submodule.mem_coe, submodule.mem_sup],
1258+
use [0, submodule.zero_mem _, p3 -ᵥ p1],
1259+
rw [and_comm, zero_add],
1260+
use rfl,
1261+
rw [←vsub_add_vsub_cancel V p3 p2 p1, submodule.mem_sup],
1262+
use [p3 -ᵥ p2, vsub_mem_direction hp3 hp2, p2 -ᵥ p1,
1263+
submodule.mem_span_singleton_self _] } },
1264+
{ refine sup_le (sup_direction_le _ _) _,
1265+
rw [direction_eq_vector_span, vector_span_def],
1266+
exact Inf_le_Inf (λ p hp, set.subset.trans
1267+
(set.singleton_subset_iff.2
1268+
(vsub_mem_vsub_set V (mem_span_points k V p2 _ (set.mem_union_right _ hp2))
1269+
(mem_span_points k V p1 _ (set.mem_union_left _ hp1))))
1270+
hp) }
1271+
end
1272+
1273+
/-- The direction of the span of the result of adding a point to a
1274+
nonempty affine subspace is the sup of the direction of that subspace
1275+
and of any one difference between that point and a point in the
1276+
subspace. -/
1277+
lemma direction_affine_span_insert {s : affine_subspace k V P} {p1 p2 : P} (hp1 : p1 ∈ s) :
1278+
(affine_span k V (insert p2 (s : set P))).direction = submodule.span k {p2 -ᵥ p1} ⊔ s.direction :=
1279+
begin
1280+
rw [sup_comm, ←set.union_singleton, ←coe_affine_span_singleton k V p2],
1281+
change (s ⊔ affine_span k V {p2}).direction = _,
1282+
rw [direction_sup hp1 (mem_affine_span k V (set.mem_singleton _)), direction_affine_span],
1283+
simp
1284+
end
1285+
1286+
/-- Given a point `p1` in an affine subspace `s`, and a point `p2`, a
1287+
point `p` is in the span of `s` with `p2` added if and only if it is a
1288+
multiple of `p2 -ᵥ p1` added to a point in `s`. -/
1289+
lemma mem_affine_span_insert_iff {s : affine_subspace k V P} {p1 : P} (hp1 : p1 ∈ s) (p2 p : P) :
1290+
p ∈ affine_span k V (insert p2 (s : set P)) ↔
1291+
∃ (r : k) (p0 : P) (hp0 : p0 ∈ s), p = r • (p2 -ᵥ p1 : V) +ᵥ p0 :=
1292+
begin
1293+
rw ←mem_coe at hp1,
1294+
rw [←vsub_right_mem_direction_iff_mem (mem_affine_span k V (set.mem_insert_of_mem _ hp1)),
1295+
direction_affine_span_insert hp1, submodule.mem_sup],
1296+
split,
1297+
{ rintros ⟨v1, hv1, v2, hv2, hp⟩,
1298+
rw submodule.mem_span_singleton at hv1,
1299+
rcases hv1 with ⟨r, rfl⟩,
1300+
use [r, v2 +ᵥ p1, vadd_mem_of_mem_direction hv2 hp1],
1301+
symmetry' at hp,
1302+
rw [←sub_eq_zero_iff_eq, ←vsub_vadd_eq_vsub_sub, vsub_eq_zero_iff_eq] at hp,
1303+
rw [hp, vadd_assoc] },
1304+
{ rintros ⟨r, p3, hp3, rfl⟩,
1305+
use [r • (p2 -ᵥ p1), submodule.mem_span_singleton.2 ⟨r, rfl⟩, p3 -ᵥ p1,
1306+
vsub_mem_direction hp3 hp1],
1307+
rw [vadd_vsub_assoc, add_comm] }
1308+
end
1309+
1310+
end affine_subspace
1311+
12201312
/-- An `affine_map k V1 P1 V2 P2` is a map from `P1` to `P2` that
12211313
induces a corresponding linear map from `V1` to `V2`. -/
12221314
structure affine_map (k : Type*) (V1 : Type*) (P1 : Type*) (V2 : Type*) (P2 : Type*)

0 commit comments

Comments
 (0)