@@ -815,8 +815,77 @@ namespace AffineSubspace
815815
816816open 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
822891to all points. -/
0 commit comments