l3lab/ntp-mathlib huggingface dataset:
/-- Auxiliary definition to define `toLinHom`; see below. -/
def toLinHomAux₂ (A : BilinForm R M) : M →ₗ[R₂] M →ₗ[R] R where
  toFun := toLinHomAux₁ A
  map_add' x₁ x₂ :=
    LinearMap.ext fun x => by
      simp only [toLinHomAux₁, LinearMap.coe_mk, LinearMap.add_apply, add_left, AddHom.coe_mk]
  map_smul' c x :=
    LinearMap.ext <| by
      dsimp [toLinHomAux₁]
      intros
      -- Porting note: moved out of `simp only`
      

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
A : BilinForm R M
c : R₂
x x✝ : M
⊢ bilin A (c • x) x✝ = c • bilin A x x✝

Next tactic:
rw [← algebraMap_smul R c x]
/-- Auxiliary definition to define `toLinHom`; see below. -/
def toLinHomAux₂ (A : BilinForm R M) : M →ₗ[R₂] M →ₗ[R] R where
  toFun := toLinHomAux₁ A
  map_add' x₁ x₂ :=
    LinearMap.ext fun x => by
      simp only [toLinHomAux₁, LinearMap.coe_mk, LinearMap.add_apply, add_left, AddHom.coe_mk]
  map_smul' c x :=
    LinearMap.ext <| by
      dsimp [toLinHomAux₁]
      intros
      -- Porting note: moved out of `simp only`
      rw [← algebraMap_smul R c x]
      

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
A : BilinForm R M
c : R₂
x x✝ : M
⊢ bilin A ((algebraMap R₂ R) c • x) x✝ = c • bilin A x x✝

Next tactic:
simp only [Algebra.smul_def, LinearMap.coe_mk, LinearMap.smul_apply, smul_left]
/-- The linear map obtained from a `BilinForm` by fixing the left co-ordinate and evaluating in
the right.
This is the most general version of the construction; it is `R₂`-linear for some distinguished
commutative subsemiring `R₂` of the scalar ring.  Over a semiring with no particular distinguished
such subsemiring, use `toLin'`, which is `ℕ`-linear.  Over a commutative semiring, use `toLin`,
which is linear. -/
def toLinHom : BilinForm R M →ₗ[R₂] M →ₗ[R₂] M →ₗ[R] R where
  toFun := toLinHomAux₂
  map_add' A₁ A₂ :=
    LinearMap.ext fun x => by
      

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
A₁ A₂ : BilinForm R M
x : M
⊢ (toLinHomAux₂ (A₁ + A₂)) x = (toLinHomAux₂ A₁ + toLinHomAux₂ A₂) x

Next tactic:
dsimp only [toLinHomAux₁, toLinHomAux₂]
/-- The linear map obtained from a `BilinForm` by fixing the left co-ordinate and evaluating in
the right.
This is the most general version of the construction; it is `R₂`-linear for some distinguished
commutative subsemiring `R₂` of the scalar ring.  Over a semiring with no particular distinguished
such subsemiring, use `toLin'`, which is `ℕ`-linear.  Over a commutative semiring, use `toLin`,
which is linear. -/
def toLinHom : BilinForm R M →ₗ[R₂] M →ₗ[R₂] M →ₗ[R] R where
  toFun := toLinHomAux₂
  map_add' A₁ A₂ :=
    LinearMap.ext fun x => by
      dsimp only [toLinHomAux₁, toLinHomAux₂]
      apply LinearMap.ext
      intro y
      simp only [toLinHomAux₂, toLinHomAux₁, LinearMap.coe_mk, LinearMap.add_apply, add_apply,
        AddHom.coe_mk]
  map_smul' c A := by
    

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
c : R₂
A : BilinForm R M
⊢ AddHom.toFun
      { toFun := toLinHomAux₂,
        map_add' := (_ : ∀ (A₁ A₂ : BilinForm R M), toLinHomAux₂ (A₁ + A₂) = toLinHomAux₂ A₁ + toLinHomAux₂ A₂) }
      (c • A) =
    (RingHom.id R₂) c •
      AddHom.toFun
        { toFun := toLinHomAux₂,
          map_add' := (_ : ∀ (A₁ A₂ : BilinForm R M), toLinHomAux₂ (A₁ + A₂) = toLinHomAux₂ A₁ + toLinHomAux₂ A₂) }
        A

Next tactic:
dsimp [toLinHomAux₁, toLinHomAux₂]
/-- The linear map obtained from a `BilinForm` by fixing the left co-ordinate and evaluating in
the right.
This is the most general version of the construction; it is `R₂`-linear for some distinguished
commutative subsemiring `R₂` of the scalar ring.  Over a semiring with no particular distinguished
such subsemiring, use `toLin'`, which is `ℕ`-linear.  Over a commutative semiring, use `toLin`,
which is linear. -/
def toLinHom : BilinForm R M →ₗ[R₂] M →ₗ[R₂] M →ₗ[R] R where
  toFun := toLinHomAux₂
  map_add' A₁ A₂ :=
    LinearMap.ext fun x => by
      dsimp only [toLinHomAux₁, toLinHomAux₂]
      apply LinearMap.ext
      intro y
      simp only [toLinHomAux₂, toLinHomAux₁, LinearMap.coe_mk, LinearMap.add_apply, add_apply,
        AddHom.coe_mk]
  map_smul' c A := by
    dsimp [toLinHomAux₁, toLinHomAux₂]
    

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
c : R₂
A : BilinForm R M
⊢ {
      toAddHom :=
        { toFun := toLinHomAux₁ (c • A),
          map_add' :=
            (_ : ∀ (x₁ x₂ : M), toLinHomAux₁ (c • A) (x₁ + x₂) = toLinHomAux₁ (c • A) x₁ + toLinHomAux₁ (c • A) x₂) },
      map_smul' :=
        (_ :
          ∀ (c_1 : R₂) (x : M),
            AddHom.toFun
                { toFun := toLinHomAux₁ (c • A),
                  map_add' :=
                    (_ :
                      ∀ (x₁ x₂ : M),
                        toLinHomAux₁ (c • A) (x₁ + x₂) = toLinHomAux₁ (c • A) x₁ + toLinHomAux₁ (c • A) x₂) }
                (c_1 • x) =
              (RingHom.id R₂) c_1 •
                AddHom.toFun
                  { toFun := toLinHomAux₁ (c • A),
                    map_add' :=
                      (_ :
                        ∀ (x₁ x₂ : M),
                          toLinHomAux₁ (c • A) (x₁ + x₂) = toLinHomAux₁ (c • A) x₁ + toLinHomAux₁ (c • A) x₂) }
                  x) } =
    c •
      {
        toAddHom :=
          { toFun := toLinHomAux₁ A,
            map_add' := (_ : ∀ (x₁ x₂ : M), toLinHomAux₁ A (x₁ + x₂) = toLinHomAux₁ A x₁ + toLinHomAux₁ A x₂) },
        map_smul' :=
          (_ :
            ∀ (c : R₂) (x : M),
              AddHom.toFun
                  { toFun := toLinHomAux₁ A,
                    map_add' := (_ : ∀ (x₁ x₂ : M), toLinHomAux₁ A (x₁ + x₂) = toLinHomAux₁ A x₁ + toLinHomAux₁ A x₂) }
                  (c • x) =
                (RingHom.id R₂) c •
                  AddHom.toFun
                    { toFun := toLinHomAux₁ A,
                      map_add' :=
                        (_ : ∀ (x₁ x₂ : M), toLinHomAux₁ A (x₁ + x₂) = toLinHomAux₁ A x₁ + toLinHomAux₁ A x₂) }
                    x) }

Next tactic:
apply LinearMap.ext
@[simp]
theorem sum_apply {α} (t : Finset α) (B : α → BilinForm R M) (v w : M) :
    (∑ i in t, B i) v w = ∑ i in t, B i v w := by
  

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
α : Type u_11
t : Finset α
B : α → BilinForm R M
v w : M
⊢ bilin (∑ i in t, B i) v w = ∑ i in t, bilin (B i) v w

Next tactic:
show coeFnAddMonoidHom (∑ i in t, B i) v w = _
@[simp]
theorem sum_apply {α} (t : Finset α) (B : α → BilinForm R M) (v w : M) :
    (∑ i in t, B i) v w = ∑ i in t, B i v w := by
  show coeFnAddMonoidHom (∑ i in t, B i) v w = _
  

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
α : Type u_11
t : Finset α
B : α → BilinForm R M
v w : M
⊢ coeFnAddMonoidHom (∑ i in t, B i) v w = ∑ i in t, bilin (B i) v w

Next tactic:
rw [map_sum, Finset.sum_apply, Finset.sum_apply]
@[simp]
theorem sum_apply {α} (t : Finset α) (B : α → BilinForm R M) (v w : M) :
    (∑ i in t, B i) v w = ∑ i in t, B i v w := by
  show coeFnAddMonoidHom (∑ i in t, B i) v w = _
  rw [map_sum, Finset.sum_apply, Finset.sum_apply]
  

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁷ : Semiring R
inst✝¹⁶ : AddCommMonoid M
inst✝¹⁵ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁴ : Ring R₁
inst✝¹³ : AddCommGroup M₁
inst✝¹² : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹¹ : CommSemiring R₂
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁸ : CommRing R₃
inst✝⁷ : AddCommGroup M₃
inst✝⁶ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁵ : Field K
inst✝⁴ : AddCommGroup V
inst✝³ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
inst✝² : Algebra R₂ R
inst✝¹ : Module R₂ M
inst✝ : IsScalarTower R₂ R M
α : Type u_11
t : Finset α
B : α → BilinForm R M
v w : M
⊢ ∑ c in t, coeFnAddMonoidHom (B c) v w = ∑ i in t, bilin (B i) v w

Next tactic:
rfl
/-- A map with two arguments that is linear in both is a bilinear form.

This is an auxiliary definition for the full linear equivalence `LinearMap.toBilin`.
-/
def LinearMap.toBilinAux (f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x y
  bilin_add_left x y z := by
    

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂
x y z : M₂
⊢ (fun x y => (f x) y) (x + y) z = (fun x y => (f x) y) x z + (fun x y => (f x) y) y z

Next tactic:
simp only
/-- A map with two arguments that is linear in both is a bilinear form.

This is an auxiliary definition for the full linear equivalence `LinearMap.toBilin`.
-/
def LinearMap.toBilinAux (f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x y
  bilin_add_left x y z := by
    simp only
    

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂
x y z : M₂
⊢ (f (x + y)) z = (f x) z + (f y) z

Next tactic:
exact (LinearMap.map_add f x y).symm ▸ LinearMap.add_apply (f x) (f y) z
/-- A map with two arguments that is linear in both is a bilinear form.

This is an auxiliary definition for the full linear equivalence `LinearMap.toBilin`.
-/
def LinearMap.toBilinAux (f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x y
  bilin_add_left x y z := by
    simp only
    exact (LinearMap.map_add f x y).symm ▸ LinearMap.add_apply (f x) (f y) z
  bilin_smul_left a x y := by 

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂
a : R₂
x y : M₂
⊢ (fun x y => (f x) y) (a • x) y = a * (fun x y => (f x) y) x y

Next tactic:
simp only [LinearMap.map_smul, LinearMap.smul_apply, smul_eq_mul]
/-- Bilinear forms are linearly equivalent to maps with two arguments that are linear in both. -/
def BilinForm.toLin : BilinForm R₂ M₂ ≃ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ :=
  { BilinForm.toLinHom R₂ with
    invFun := LinearMap.toBilinAux
    left_inv := fun B => by
      

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
src✝ : BilinForm R₂ M₂ →ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ := toLinHom R₂
B : BilinForm R₂ M₂
⊢ LinearMap.toBilinAux
      (AddHom.toFun
        { toAddHom := src✝.toAddHom,
            map_smul' :=
              (_ :
                ∀ (r : R₂) (x : BilinForm R₂ M₂),
                  AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R₂) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
        B) =
    B

Next tactic:
ext
/-- Bilinear forms are linearly equivalent to maps with two arguments that are linear in both. -/
def BilinForm.toLin : BilinForm R₂ M₂ ≃ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ :=
  { BilinForm.toLinHom R₂ with
    invFun := LinearMap.toBilinAux
    left_inv := fun B => by
      ext
      

Proof state:
case H
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
src✝ : BilinForm R₂ M₂ →ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ := toLinHom R₂
B : BilinForm R₂ M₂
x✝ y✝ : M₂
⊢ bilin
      (LinearMap.toBilinAux
        (AddHom.toFun
          { toAddHom := src✝.toAddHom,
              map_smul' :=
                (_ :
                  ∀ (r : R₂) (x : BilinForm R₂ M₂),
                    AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R₂) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
          B))
      x✝ y✝ =
    bilin B x✝ y✝

Next tactic:
simp [LinearMap.toBilinAux]
/-- Bilinear forms are linearly equivalent to maps with two arguments that are linear in both. -/
def BilinForm.toLin : BilinForm R₂ M₂ ≃ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ :=
  { BilinForm.toLinHom R₂ with
    invFun := LinearMap.toBilinAux
    left_inv := fun B => by
      ext
      simp [LinearMap.toBilinAux]
    right_inv := fun B => by
      

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
src✝ : BilinForm R₂ M₂ →ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ := toLinHom R₂
B : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂
⊢ AddHom.toFun
      { toAddHom := src✝.toAddHom,
          map_smul' :=
            (_ :
              ∀ (r : R₂) (x : BilinForm R₂ M₂),
                AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R₂) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
      (LinearMap.toBilinAux B) =
    B

Next tactic:
ext
/-- Bilinear forms are linearly equivalent to maps with two arguments that are linear in both. -/
def BilinForm.toLin : BilinForm R₂ M₂ ≃ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ :=
  { BilinForm.toLinHom R₂ with
    invFun := LinearMap.toBilinAux
    left_inv := fun B => by
      ext
      simp [LinearMap.toBilinAux]
    right_inv := fun B => by
      ext
      

Proof state:
case h.h
R : Type u_1
M : Type u_2
inst✝¹⁴ : Semiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹¹ : Ring R₁
inst✝¹⁰ : AddCommGroup M₁
inst✝⁹ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝⁸ : CommSemiring R₂
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁵ : CommRing R₃
inst✝⁴ : AddCommGroup M₃
inst✝³ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝² : Field K
inst✝¹ : AddCommGroup V
inst✝ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
src✝ : BilinForm R₂ M₂ →ₗ[R₂] M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂ := toLinHom R₂
B : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂
x✝¹ x✝ : M₂
⊢ ((AddHom.toFun
          { toAddHom := src✝.toAddHom,
              map_smul' :=
                (_ :
                  ∀ (r : R₂) (x : BilinForm R₂ M₂),
                    AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R₂) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
          (LinearMap.toBilinAux B))
        x✝¹)
      x✝ =
    (B x✝¹) x✝

Next tactic:
simp [LinearMap.toBilinAux]
/-- Apply a linear map on the output of a bilinear form. -/
@[simps]
def compBilinForm (f : R →ₗ[R'] R') (B : BilinForm R M) : BilinForm R' M where
  bilin x y := f (B x y)
  bilin_add_left x y z := by 

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁸ : Semiring R
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁵ : Ring R₁
inst✝¹⁴ : AddCommGroup M₁
inst✝¹³ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹² : CommSemiring R₂
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁹ : CommRing R₃
inst✝⁸ : AddCommGroup M₃
inst✝⁷ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁶ : Field K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
R' : Type u_11
inst✝³ : CommSemiring R'
inst✝² : Algebra R' R
inst✝¹ : Module R' M
inst✝ : IsScalarTower R' R M
f : R →ₗ[R'] R'
B : BilinForm R M
x y z : M
⊢ (fun x y => f (BilinForm.bilin B x y)) (x + y) z =
    (fun x y => f (BilinForm.bilin B x y)) x z + (fun x y => f (BilinForm.bilin B x y)) y z

Next tactic:
simp only [BilinForm.add_left, map_add]
/-- Apply a linear map on the output of a bilinear form. -/
@[simps]
def compBilinForm (f : R →ₗ[R'] R') (B : BilinForm R M) : BilinForm R' M where
  bilin x y := f (B x y)
  bilin_add_left x y z := by simp only [BilinForm.add_left, map_add]
  bilin_smul_left r x y := by
    

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁸ : Semiring R
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁵ : Ring R₁
inst✝¹⁴ : AddCommGroup M₁
inst✝¹³ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹² : CommSemiring R₂
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁹ : CommRing R₃
inst✝⁸ : AddCommGroup M₃
inst✝⁷ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁶ : Field K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
R' : Type u_11
inst✝³ : CommSemiring R'
inst✝² : Algebra R' R
inst✝¹ : Module R' M
inst✝ : IsScalarTower R' R M
f : R →ₗ[R'] R'
B : BilinForm R M
r : R'
x y : M
⊢ (fun x y => f (BilinForm.bilin B x y)) (r • x) y = r * (fun x y => f (BilinForm.bilin B x y)) x y

Next tactic:
simp only
/-- Apply a linear map on the output of a bilinear form. -/
@[simps]
def compBilinForm (f : R →ₗ[R'] R') (B : BilinForm R M) : BilinForm R' M where
  bilin x y := f (B x y)
  bilin_add_left x y z := by simp only [BilinForm.add_left, map_add]
  bilin_smul_left r x y := by
    simp only
    

Proof state:
R : Type u_1
M : Type u_2
inst✝¹⁸ : Semiring R
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : Module R M
R₁ : Type u_3
M₁ : Type u_4
inst✝¹⁵ : Ring R₁
inst✝¹⁴ : AddCommGroup M₁
inst✝¹³ : Module R₁ M₁
R₂ : Type u_5
M₂ : Type u_6
inst✝¹² : CommSemiring R₂
inst✝¹¹ : AddCommMonoid M₂
inst✝¹⁰ : Module R₂ M₂
R₃ : Type u_7
M₃ : Type u_8
inst✝⁹ : CommRing R₃
inst✝⁸ : AddCommGroup M₃
inst✝⁷ : Module R₃ M₃
V : Type u_9
K : Type u_10
inst✝⁶ : Field K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
B✝ : BilinForm R M
B₁ : BilinForm R₁ M₁
B₂ : BilinForm R₂ M₂
R' : Type u_11
inst✝³ : CommSemiring R'
inst✝² : Algebra R' R
inst✝¹ : Module R' M
inst✝ : IsScalarTower R' R M
f : R →ₗ[R'] R'
B : BilinForm R M
r : R'
x y : M
⊢ f (BilinForm.bilin B (r • x) y) = r * f (BilinForm.bilin B x y)

Next tactic:
rw [← smul_one_smul R r (_ : M), BilinForm.smul_left, smul_one_mul r (_ : R), map_smul,
      smul_eq_mul]