l3lab/ntp-mathlib huggingface dataset:
/-- If `A : S.obj B ⟶ T` is a costructured arrow for `S : C ⥤ D` and `T : D`, then we can
    explicitly describe the quotients of `A` as the quotients `P` of `B` in `C` for which `A.hom`
    factors through the image of `P` under `S`. -/
def quotientEquiv [HasColimits C] [PreservesColimits S] (A : CostructuredArrow S T) :
    Subobject (op A) ≃o { P : Subobject (op A.left) // ∃ q, S.map P.arrow.unop ≫ q = A.hom } where
  toFun P := ⟨projectQuotient P, projectQuotient_factors P⟩
  invFun P := liftQuotient P.val P.prop.choose_spec
  left_inv P := lift_projectQuotient _ _
  right_inv P := Subtype.ext (by simp only [liftQuotient, Quiver.Hom.unop_op, homMk_left,
      Quiver.Hom.op_unop, projectQuotient_mk, Subobject.mk_arrow])
  map_rel_iff' := by
    apply Subobject.ind₂
    intro P Q f g hf hg
    refine' ⟨fun h => Subobject.mk_le_mk_of_comm _ _, fun h => _⟩
    · refine' (homMk (Subobject.ofMkLEMk _ _ h).unop ((cancel_epi (S.map g.unop.left)).1 _)).op
      dsimp
      simp only [← S.map_comp_assoc, unop_left_comp_ofMkLEMk_unop, unop_op, CommaMorphism.w,
        Functor.const_obj_obj, right_eq_id, Functor.const_obj_map, Category.comp_id]
    · apply Quiver.Hom.unop_inj
      ext
      exact unop_left_comp_ofMkLEMk_unop _
    · refine' Subobject.mk_le_mk_of_comm (Subobject.ofMkLEMk _ _ h).unop.left.op _
      

Proof state:
case h.refine'_3
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : C ⥤ D
T : D
inst✝¹ : HasColimits C
inst✝ : PreservesColimits S
A : CostructuredArrow S T
P Q : (CostructuredArrow S T)ᵒᵖ
f : P ⟶ op A
g : Q ⟶ op A
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ (Subobject.ofMkLEMk f g h).unop.left.op ≫ (MonoOver.arrow (MonoOver.mk' g)).unop.left.op =
    (MonoOver.arrow (MonoOver.mk' f)).unop.left.op

Next tactic:
refine' Quiver.Hom.unop_inj _
/-- If `A : S.obj B ⟶ T` is a costructured arrow for `S : C ⥤ D` and `T : D`, then we can
    explicitly describe the quotients of `A` as the quotients `P` of `B` in `C` for which `A.hom`
    factors through the image of `P` under `S`. -/
def quotientEquiv [HasColimits C] [PreservesColimits S] (A : CostructuredArrow S T) :
    Subobject (op A) ≃o { P : Subobject (op A.left) // ∃ q, S.map P.arrow.unop ≫ q = A.hom } where
  toFun P := ⟨projectQuotient P, projectQuotient_factors P⟩
  invFun P := liftQuotient P.val P.prop.choose_spec
  left_inv P := lift_projectQuotient _ _
  right_inv P := Subtype.ext (by simp only [liftQuotient, Quiver.Hom.unop_op, homMk_left,
      Quiver.Hom.op_unop, projectQuotient_mk, Subobject.mk_arrow])
  map_rel_iff' := by
    apply Subobject.ind₂
    intro P Q f g hf hg
    refine' ⟨fun h => Subobject.mk_le_mk_of_comm _ _, fun h => _⟩
    · refine' (homMk (Subobject.ofMkLEMk _ _ h).unop ((cancel_epi (S.map g.unop.left)).1 _)).op
      dsimp
      simp only [← S.map_comp_assoc, unop_left_comp_ofMkLEMk_unop, unop_op, CommaMorphism.w,
        Functor.const_obj_obj, right_eq_id, Functor.const_obj_map, Category.comp_id]
    · apply Quiver.Hom.unop_inj
      ext
      exact unop_left_comp_ofMkLEMk_unop _
    · refine' Subobject.mk_le_mk_of_comm (Subobject.ofMkLEMk _ _ h).unop.left.op _
      refine' Quiver.Hom.unop_inj _
      

Proof state:
case h.refine'_3
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : C ⥤ D
T : D
inst✝¹ : HasColimits C
inst✝ : PreservesColimits S
A : CostructuredArrow S T
P Q : (CostructuredArrow S T)ᵒᵖ
f : P ⟶ op A
g : Q ⟶ op A
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ ((Subobject.ofMkLEMk f g h).unop.left.op ≫ (MonoOver.arrow (MonoOver.mk' g)).unop.left.op).unop =
    (MonoOver.arrow (MonoOver.mk' f)).unop.left.op.unop

Next tactic:
have := congr_arg Quiver.Hom.unop (Subobject.ofMkLEMk_comp h)
/-- If `A : S.obj B ⟶ T` is a costructured arrow for `S : C ⥤ D` and `T : D`, then we can
    explicitly describe the quotients of `A` as the quotients `P` of `B` in `C` for which `A.hom`
    factors through the image of `P` under `S`. -/
def quotientEquiv [HasColimits C] [PreservesColimits S] (A : CostructuredArrow S T) :
    Subobject (op A) ≃o { P : Subobject (op A.left) // ∃ q, S.map P.arrow.unop ≫ q = A.hom } where
  toFun P := ⟨projectQuotient P, projectQuotient_factors P⟩
  invFun P := liftQuotient P.val P.prop.choose_spec
  left_inv P := lift_projectQuotient _ _
  right_inv P := Subtype.ext (by simp only [liftQuotient, Quiver.Hom.unop_op, homMk_left,
      Quiver.Hom.op_unop, projectQuotient_mk, Subobject.mk_arrow])
  map_rel_iff' := by
    apply Subobject.ind₂
    intro P Q f g hf hg
    refine' ⟨fun h => Subobject.mk_le_mk_of_comm _ _, fun h => _⟩
    · refine' (homMk (Subobject.ofMkLEMk _ _ h).unop ((cancel_epi (S.map g.unop.left)).1 _)).op
      dsimp
      simp only [← S.map_comp_assoc, unop_left_comp_ofMkLEMk_unop, unop_op, CommaMorphism.w,
        Functor.const_obj_obj, right_eq_id, Functor.const_obj_map, Category.comp_id]
    · apply Quiver.Hom.unop_inj
      ext
      exact unop_left_comp_ofMkLEMk_unop _
    · refine' Subobject.mk_le_mk_of_comm (Subobject.ofMkLEMk _ _ h).unop.left.op _
      refine' Quiver.Hom.unop_inj _
      have := congr_arg Quiver.Hom.unop (Subobject.ofMkLEMk_comp h)
      

Proof state:
case h.refine'_3
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : C ⥤ D
T : D
inst✝¹ : HasColimits C
inst✝ : PreservesColimits S
A : CostructuredArrow S T
P Q : (CostructuredArrow S T)ᵒᵖ
f : P ⟶ op A
g : Q ⟶ op A
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
this : (Subobject.ofMkLEMk f g h ≫ g).unop = f.unop
⊢ ((Subobject.ofMkLEMk f g h).unop.left.op ≫ (MonoOver.arrow (MonoOver.mk' g)).unop.left.op).unop =
    (MonoOver.arrow (MonoOver.mk' f)).unop.left.op.unop

Next tactic:
simpa only [unop_op, Functor.id_obj, Functor.const_obj_obj, MonoOver.mk'_obj, Over.mk_left,
        MonoOver.mk'_arrow, unop_comp, Quiver.Hom.unop_op, comp_left]
          using congr_arg CommaMorphism.left this
/-- `LinearMap.inl` as an isometry. -/
@[simps!]
def Isometry.inl (Q₁ : QuadraticForm R M₁) (Q₂ : QuadraticForm R M₂) : Q₁ →qᵢ (Q₁.prod Q₂) where
  toLinearMap := LinearMap.inl R _ _
  map_app' m₁ := by 

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M₁
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : AddCommMonoid N₁
inst✝⁴ : AddCommMonoid N₂
inst✝³ : Module R M₁
inst✝² : Module R M₂
inst✝¹ : Module R N₁
inst✝ : Module R N₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
m₁ : M₁
⊢ (prod Q₁ Q₂) (AddHom.toFun (LinearMap.inl R M₁ M₂).toAddHom m₁) = Q₁ m₁

Next tactic:
simp
/-- `LinearMap.inr` as an isometry. -/
@[simps!]
def Isometry.inr (Q₁ : QuadraticForm R M₁) (Q₂ : QuadraticForm R M₂) : Q₂ →qᵢ (Q₁.prod Q₂) where
  toLinearMap := LinearMap.inr R _ _
  map_app' m₁ := by 

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁸ : CommSemiring R
inst✝⁷ : AddCommMonoid M₁
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : AddCommMonoid N₁
inst✝⁴ : AddCommMonoid N₂
inst✝³ : Module R M₁
inst✝² : Module R M₂
inst✝¹ : Module R N₁
inst✝ : Module R N₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
m₁ : M₂
⊢ (prod Q₁ Q₂) (AddHom.toFun (LinearMap.inr R M₁ M₂).toAddHom m₁) = Q₂ m₁

Next tactic:
simp
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  

Proof state:
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : Anisotropic (prod Q₁ Q₂)
⊢ Anisotropic Q₁ ∧ Anisotropic Q₂

Next tactic:
simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  

Proof state:
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
⊢ Anisotropic Q₁ ∧ Anisotropic Q₂

Next tactic:
constructor
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  constructor
  · 

Proof state:
case left
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
⊢ Anisotropic Q₁

Next tactic:
intro x hx
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  constructor
  · intro x hx
    

Proof state:
case left
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
x : M₁
hx : Q₁ x = 0
⊢ x = 0

Next tactic:
refine' (h x 0 _).1
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  constructor
  · intro x hx
    refine' (h x 0 _).1
    

Proof state:
case left
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
x : M₁
hx : Q₁ x = 0
⊢ Q₁ x + Q₂ 0 = 0

Next tactic:
rw [hx, zero_add, map_zero]
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  constructor
  · intro x hx
    refine' (h x 0 _).1
    rw [hx, zero_add, map_zero]
  · 

Proof state:
case right
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
⊢ Anisotropic Q₂

Next tactic:
intro x hx
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  constructor
  · intro x hx
    refine' (h x 0 _).1
    rw [hx, zero_add, map_zero]
  · intro x hx
    

Proof state:
case right
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
x : M₂
hx : Q₂ x = 0
⊢ x = 0

Next tactic:
refine' (h 0 x _).2
/-- If a product is anisotropic then its components must be. The converse is not true. -/
theorem anisotropic_of_prod {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} (h : (Q₁.prod Q₂).Anisotropic) :
    Q₁.Anisotropic ∧ Q₂.Anisotropic := by
  simp_rw [Anisotropic, prod_apply, Prod.forall, Prod.mk_eq_zero] at h
  constructor
  · intro x hx
    refine' (h x 0 _).1
    rw [hx, zero_add, map_zero]
  · intro x hx
    refine' (h 0 x _).2
    

Proof state:
case right
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), Q₁ a + Q₂ b = 0 → a = 0 ∧ b = 0
x : M₂
hx : Q₂ x = 0
⊢ Q₁ 0 + Q₂ x = 0

Next tactic:
rw [hx, add_zero, map_zero]
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  

Proof state:
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
⊢ (∀ (x : M₁ × M₂), 0 ≤ (prod Q₁ Q₂) x) ↔ (∀ (x : M₁), 0 ≤ Q₁ x) ∧ ∀ (x : M₂), 0 ≤ Q₂ x

Next tactic:
simp_rw [Prod.forall, prod_apply]
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  

Proof state:
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
⊢ (∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b) ↔ (∀ (x : M₁), 0 ≤ Q₁ x) ∧ ∀ (x : M₂), 0 ≤ Q₂ x

Next tactic:
constructor
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · 

Proof state:
case mp
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
⊢ (∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b) → (∀ (x : M₁), 0 ≤ Q₁ x) ∧ ∀ (x : M₂), 0 ≤ Q₂ x

Next tactic:
intro h
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · intro h
    

Proof state:
case mp
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b
⊢ (∀ (x : M₁), 0 ≤ Q₁ x) ∧ ∀ (x : M₂), 0 ≤ Q₂ x

Next tactic:
constructor
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · intro h
    constructor
    · 

Proof state:
case mp.left
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b
⊢ ∀ (x : M₁), 0 ≤ Q₁ x

Next tactic:
intro x
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · intro h
    constructor
    · intro x; 

Proof state:
case mp.left
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b
x : M₁
⊢ 0 ≤ Q₁ x

Next tactic:
simpa only [add_zero, map_zero] using h x 0
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · intro h
    constructor
    · intro x; simpa only [add_zero, map_zero] using h x 0
    · 

Proof state:
case mp.right
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b
⊢ ∀ (x : M₂), 0 ≤ Q₂ x

Next tactic:
intro x
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · intro h
    constructor
    · intro x; simpa only [add_zero, map_zero] using h x 0
    · intro x; 

Proof state:
case mp.right
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
h : ∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b
x : M₂
⊢ 0 ≤ Q₂ x

Next tactic:
simpa only [zero_add, map_zero] using h 0 x
theorem nonneg_prod_iff {R} [OrderedCommRing R] [Module R M₁] [Module R M₂]
    {Q₁ : QuadraticForm R M₁} {Q₂ : QuadraticForm R M₂} :
    (∀ x, 0 ≤ (Q₁.prod Q₂) x) ↔ (∀ x, 0 ≤ Q₁ x) ∧ ∀ x, 0 ≤ Q₂ x := by
  simp_rw [Prod.forall, prod_apply]
  constructor
  · intro h
    constructor
    · intro x; simpa only [add_zero, map_zero] using h x 0
    · intro x; simpa only [zero_add, map_zero] using h 0 x
  · 

Proof state:
case mpr
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝¹¹ : CommSemiring R✝
inst✝¹⁰ : AddCommMonoid M₁
inst✝⁹ : AddCommMonoid M₂
inst✝⁸ : AddCommMonoid N₁
inst✝⁷ : AddCommMonoid N₂
inst✝⁶ : Module R✝ M₁
inst✝⁵ : Module R✝ M₂
inst✝⁴ : Module R✝ N₁
inst✝³ : Module R✝ N₂
R : Type u_9
inst✝² : OrderedCommRing R
inst✝¹ : Module R M₁
inst✝ : Module R M₂
Q₁ : QuadraticForm R M₁
Q₂ : QuadraticForm R M₂
⊢ ((∀ (x : M₁), 0 ≤ Q₁ x) ∧ ∀ (x : M₂), 0 ≤ Q₂ x) → ∀ (a : M₁) (b : M₂), 0 ≤ Q₁ a + Q₂ b

Next tactic:
rintro ⟨h₁, h₂⟩ x₁ x₂