Skip to content

Commit 812b9b6

Browse files
TTony2019imathwy
andcommitted
feat(Analysis/Convex/Intrinsic): add product theorems for affine spans and intrinsic interiors (leanprover-community#38551)
Add API for products of affine subspaces and proves product theorems for affine spans and intrinsic interiors. Co-authored-by: Zichen Wang <imathwy@users.noreply.github.com>
1 parent ec463ea commit 812b9b6

5 files changed

Lines changed: 112 additions & 2 deletions

File tree

Mathlib/Algebra/Group/Pointwise/Set/Basic.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,10 @@ theorem inter_div_union_subset_union : s₁ ∩ s₂ / (t₁ ∪ t₂) ⊆ s₁
536536
theorem union_div_inter_subset_union : (s₁ ∪ s₂) / (t₁ ∩ t₂) ⊆ s₁ / t₁ ∪ s₂ / t₂ :=
537537
image2_union_inter_subset_union
538538

539+
@[to_additive (attr := simp) prod_sub_prod_comm]
540+
lemma prod_div_prod_comm [Div β] (s₁ s₂ : Set α) (t₁ t₂ : Set β) :
541+
(s₁ ×ˢ t₁) / (s₂ ×ˢ t₂) = (s₁ / s₂) ×ˢ (t₁ / t₂) := by aesop (add simp mem_div)
542+
539543
end Div
540544

541545
-- TODO: rename `NPow` to `npow` and `ZPow` to `zpow`.

Mathlib/Algebra/Torsor/Basic.lean

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ namespace Set
3333
theorem singleton_sdiv_self (p : P) : ({p} : Set P) /ₛ {p} = {(1 : G)} := by
3434
rw [Set.singleton_sdiv_singleton, sdiv_self]
3535

36+
@[to_additive (attr := simp)]
37+
theorem one_mem_sdiv_iff {s t : Set P} : (1 : G) ∈ s /ₛ t ↔ ¬Disjoint s t := by
38+
simp [not_disjoint_iff_nonempty_inter, mem_sdiv, Set.Nonempty]
39+
40+
@[to_additive]
41+
theorem Nonempty.one_mem_sdiv_self {s : Set P} (h : s.Nonempty) : (1 : G) ∈ s /ₛ s :=
42+
let ⟨p, hp⟩ := h
43+
⟨p, hp, p, hp, sdiv_self _⟩
44+
3645
end Set
3746
/-- If dividing two points by the same point produces equal results, those points are equal. -/
3847
@[to_additive /-- If the same point subtracted from two points produces equal
@@ -160,6 +169,17 @@ theorem mk_sdiv_mk (p₁ p₂ : P) (p₁' p₂' : P') :
160169

161170
end Prod
162171

172+
namespace Set
173+
174+
variable {G G' P P' : Type*} [Group G] [Group G'] [Torsor G P] [Torsor G' P']
175+
176+
@[to_additive prod_vsub_prod_comm]
177+
theorem prod_sdiv_prod_comm (s₁ s₂ : Set P) (t₁ t₂ : Set P') :
178+
(s₁ ×ˢ t₁) /ₛ (s₂ ×ˢ t₂) = (s₁ /ₛ s₂) ×ˢ (t₁ /ₛ t₂) := by
179+
aesop (add norm simp [mem_sdiv, mem_prod])
180+
181+
end Set
182+
163183
namespace Pi
164184

165185
universe u v w

Mathlib/Analysis/Convex/Intrinsic.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ theorem intrinsicClosure_eq_closure_inter_affineSpan (s : Set P) :
217217
rw [Subtype.range_coe]
218218
apply subset_affineSpan
219219

220+
theorem intrinsicInterior_prod_eq [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace Q]
221+
[AddTorsor W Q] (s : Set P) (t : Set Q) :
222+
intrinsicInterior 𝕜 (s ×ˢ t) = intrinsicInterior 𝕜 s ×ˢ intrinsicInterior 𝕜 t := by
223+
let e : affineSpan 𝕜 (s ×ˢ t) ≃ₜ affineSpan 𝕜 s × affineSpan 𝕜 t :=
224+
(Homeomorph.setCongr (by simp [affineSpan_prod_eq])).trans (Homeomorph.Set.prod _ _)
225+
have : Subtype.val ∘ e.symm = fun p ↦ (p.1, p.2) := rfl
226+
have h : ((↑) ⁻¹' (s ×ˢ t) : Set _) = e ⁻¹' (((↑) ⁻¹' s) ×ˢ ((↑) ⁻¹' t)) := rfl
227+
simp_rw [intrinsicInterior, h, ← e.preimage_interior, interior_prod_eq, ← e.image_symm,
228+
← image_comp, prod_image_image_eq, this]
229+
220230
section ImageOfHomeomorphAffineSpan
221231

222232
variable [AddCommGroup W] [Module 𝕜 W] [TopologicalSpace Q] [AddTorsor W Q]

Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Basic.lean

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,8 +815,77 @@ namespace AffineSubspace
815815

816816
open AffineEquiv
817817

818-
variable {k : Type*} {V : Type*} {P : Type*} [Ring k] [AddCommGroup V] [Module k V]
819-
variable [AffineSpace V P]
818+
variable {k V W P Q : Type*} [Ring k] [AddCommGroup V] [Module k V] [AffineSpace V P]
819+
[AddCommGroup W] [Module k W] [AffineSpace W Q]
820+
821+
/-- The product of two affine subspaces as an affine subspace. -/
822+
def prod (s : AffineSubspace k P) (t : AffineSubspace k Q) : AffineSubspace k (P × Q) where
823+
carrier := (s : Set P) ×ˢ (t : Set Q)
824+
smul_vsub_vadd_mem' c _ _ _ hp₁ hp₂ hp₃ :=
825+
⟨s.smul_vsub_vadd_mem' c hp₁.1 hp₂.1 hp₃.1, t.smul_vsub_vadd_mem' c hp₁.2 hp₂.2 hp₃.2
826+
827+
@[simp]
828+
theorem coe_prod (s : AffineSubspace k P) (t : AffineSubspace k Q) :
829+
(s.prod t : Set (P × Q)) = (s : Set P) ×ˢ (t : Set Q) :=
830+
rfl
831+
832+
@[simp]
833+
theorem mem_prod (s : AffineSubspace k P) (t : AffineSubspace k Q) (x : P × Q) :
834+
x ∈ s.prod t ↔ x.1 ∈ s ∧ x.2 ∈ t :=
835+
Set.mem_prod
836+
837+
@[gcongr]
838+
theorem prod_mono {s₁ s₂ : AffineSubspace k P} {t₁ t₂ : AffineSubspace k Q}
839+
(hs : s₁ ≤ s₂) (ht : t₁ ≤ t₂) : s₁.prod t₁ ≤ s₂.prod t₂ :=
840+
Set.prod_mono hs ht
841+
842+
@[simp]
843+
theorem prod_top_top : (⊤ : AffineSubspace k P).prod (⊤ : AffineSubspace k Q) = ⊤ := by
844+
ext; simp
845+
846+
@[simp]
847+
theorem prod_bot_right (s : AffineSubspace k P) : s.prod (⊥ : AffineSubspace k Q) = ⊥ := by
848+
simp [AffineSubspace.ext_iff]
849+
850+
@[simp]
851+
theorem prod_bot_left (t : AffineSubspace k P) : (⊥ : AffineSubspace k Q).prod t = ⊥ := by
852+
simp [AffineSubspace.ext_iff]
853+
854+
theorem prod_inf_prod (s₁ s₂ : AffineSubspace k P) (t₁ t₂ : AffineSubspace k Q) :
855+
s₁.prod t₁ ⊓ s₂.prod t₂ = (s₁ ⊓ s₂).prod (t₁ ⊓ t₂) :=
856+
SetLike.coe_injective Set.prod_inter_prod
857+
858+
theorem _root_.vectorSpan_prod_le (s : Set P) (t : Set Q) :
859+
vectorSpan k (s ×ˢ t) ≤ (vectorSpan k s).prod (vectorSpan k t) := by
860+
simpa [vectorSpan_def, Set.prod_vsub_prod_comm] using Submodule.span_prod_le (s -ᵥ s) (t -ᵥ t)
861+
862+
theorem direction_prod_le (s : AffineSubspace k P) (t : AffineSubspace k Q) :
863+
(s.prod t).direction ≤ s.direction.prod t.direction := by
864+
simpa [direction_eq_vectorSpan, coe_prod] using vectorSpan_prod_le (s : Set P) (t : Set Q)
865+
866+
theorem _root_.vectorSpan_prod_eq {s : Set P} {t : Set Q} (hs : s.Nonempty) (ht : t.Nonempty) :
867+
vectorSpan k (s ×ˢ t) = (vectorSpan k s).prod (vectorSpan k t) := by
868+
rw [vectorSpan_def, Set.prod_vsub_prod_comm]
869+
exact Submodule.span_prod_eq k hs.zero_mem_vsub_self ht.zero_mem_vsub_self
870+
871+
theorem direction_prod_eq {s : AffineSubspace k P} {t : AffineSubspace k Q}
872+
(hs : s ≠ ⊥) (ht : t ≠ ⊥) :
873+
(s.prod t).direction = s.direction.prod t.direction := by
874+
simp [direction_eq_vectorSpan, vectorSpan_prod_eq, nonempty_iff_ne_bot, ht, hs]
875+
876+
theorem _root_.affineSpan_prod_eq (s : Set P) (t : Set Q) :
877+
affineSpan k (s ×ˢ t) = (affineSpan k s).prod (affineSpan k t) := by
878+
rcases s.eq_empty_or_nonempty with rfl | hs
879+
· simp
880+
rcases t.eq_empty_or_nonempty with rfl | ht
881+
· simp
882+
apply AffineSubspace.ext_of_direction_eq
883+
· simp [direction_prod_eq, Set.nonempty_iff_ne_empty.mp, hs, ht, direction_affineSpan,
884+
vectorSpan_prod_eq]
885+
· obtain ⟨x, hx⟩ := hs
886+
obtain ⟨y, hy⟩ := ht
887+
use ⟨x, y⟩
888+
simp [mem_affineSpan, hx, hy]
820889

821890
/-- Two affine subspaces are parallel if one is related to the other by adding the same vector
822891
to all points. -/

Mathlib/LinearAlgebra/Prod.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,13 @@ theorem prod_eq_top_iff {p₁ : Submodule R M} {p₂ : Submodule R M₂} :
640640
p₁.prod p₂ = ⊤ ↔ p₁ = ⊤ ∧ p₂ = ⊤ := by
641641
simp only [eq_top_iff, le_prod_iff, map_top, range_fst, range_snd]
642642

643+
variable {M M₂} in
644+
theorem span_prod_eq {s : Set M} {t : Set M₂} (hs : 0 ∈ s) (ht : 0 ∈ t) :
645+
span R (s ×ˢ t) = (span R s).prod (span R t) := by
646+
refine le_antisymm (span_prod_le s t) ?_
647+
simp [Submodule.prod_le_iff, map_span]
648+
grind [span_mono]
649+
643650
end Submodule
644651

645652
namespace LinearEquiv

0 commit comments

Comments
 (0)