l3lab/ntp-mathlib huggingface dataset:
theorem comp_inj (B₁ B₂ : BilinForm R M') {l r : M →ₗ[R] M'} (hₗ : Function.Surjective l)
    (hᵣ : Function.Surjective r) : B₁.comp l r = B₂.comp l r ↔ B₁ = B₂ := by
  constructor <;> intro h
  · -- B₁.comp l r = B₂.comp l r → B₁ = B₂
    ext x y
    cases' hₗ x with x' hx
    subst hx
    cases' hᵣ y with y' hy
    

Proof state:
case mp.H.intro.intro
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₂
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
B₁ B₂ : BilinForm R M'
l r : M →ₗ[R] M'
hₗ : Function.Surjective ⇑l
hᵣ : Function.Surjective ⇑r
h : comp B₁ l r = comp B₂ l r
y : M'
x' y' : M
hy : r y' = y
⊢ bilin B₁ (l x') y = bilin B₂ (l x') y

Next tactic:
subst hy
theorem comp_inj (B₁ B₂ : BilinForm R M') {l r : M →ₗ[R] M'} (hₗ : Function.Surjective l)
    (hᵣ : Function.Surjective r) : B₁.comp l r = B₂.comp l r ↔ B₁ = B₂ := by
  constructor <;> intro h
  · -- B₁.comp l r = B₂.comp l r → B₁ = B₂
    ext x y
    cases' hₗ x with x' hx
    subst hx
    cases' hᵣ y with y' hy
    subst hy
    

Proof state:
case mp.H.intro.intro
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₂
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
B₁ B₂ : BilinForm R M'
l r : M →ₗ[R] M'
hₗ : Function.Surjective ⇑l
hᵣ : Function.Surjective ⇑r
h : comp B₁ l r = comp B₂ l r
x' y' : M
⊢ bilin B₁ (l x') (r y') = bilin B₂ (l x') (r y')

Next tactic:
rw [← comp_apply, ← comp_apply, h]
theorem comp_inj (B₁ B₂ : BilinForm R M') {l r : M →ₗ[R] M'} (hₗ : Function.Surjective l)
    (hᵣ : Function.Surjective r) : B₁.comp l r = B₂.comp l r ↔ B₁ = B₂ := by
  constructor <;> intro h
  · -- B₁.comp l r = B₂.comp l r → B₁ = B₂
    ext x y
    cases' hₗ x with x' hx
    subst hx
    cases' hᵣ y with y' hy
    subst hy
    rw [← comp_apply, ← comp_apply, h]
  · -- B₁ = B₂ → B₁.comp l r = B₂.comp l r
    

Proof state:
case mpr
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₂
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
B₁ B₂ : BilinForm R M'
l r : M →ₗ[R] M'
hₗ : Function.Surjective ⇑l
hᵣ : Function.Surjective ⇑r
h : B₁ = B₂
⊢ comp B₁ l r = comp B₂ l r

Next tactic:
rw [h]
/-- Apply a linear equivalence on the arguments of a bilinear form. -/
def congr (e : M₂ ≃ₗ[R₂] M₂') : BilinForm R₂ M₂ ≃ₗ[R₂] BilinForm R₂ M₂' where
  toFun B := B.comp e.symm e.symm
  invFun B := B.comp e e
  left_inv B := ext fun x y => by simp only [comp_apply, LinearEquiv.coe_coe, e.symm_apply_apply]
  right_inv B := ext fun x y => by simp only [comp_apply, LinearEquiv.coe_coe, e.apply_symm_apply]
  map_add' B B' := ext fun 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
B B' : BilinForm R₂ M₂
x y : M₂'
⊢ bilin ((fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B')) x y =
    bilin
      ((fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
        (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B')
      x y

Next tactic:
simp only [comp_apply, add_apply]
/-- Apply a linear equivalence on the arguments of a bilinear form. -/
def congr (e : M₂ ≃ₗ[R₂] M₂') : BilinForm R₂ M₂ ≃ₗ[R₂] BilinForm R₂ M₂' where
  toFun B := B.comp e.symm e.symm
  invFun B := B.comp e e
  left_inv B := ext fun x y => by simp only [comp_apply, LinearEquiv.coe_coe, e.symm_apply_apply]
  right_inv B := ext fun x y => by simp only [comp_apply, LinearEquiv.coe_coe, e.apply_symm_apply]
  map_add' B B' := ext fun x y => by simp only [comp_apply, add_apply]
  map_smul' B B' := ext fun 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
B : R₂
B' : BilinForm R₂ M₂
x y : M₂'
⊢ bilin
      (AddHom.toFun
        { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
          map_add' :=
            (_ :
              ∀ (B B' : BilinForm R₂ M₂),
                (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                  (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                    (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') }
        (B • B'))
      x y =
    bilin
      ((RingHom.id R₂) B •
        AddHom.toFun
          { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
            map_add' :=
              (_ :
                ∀ (B B' : BilinForm R₂ M₂),
                  (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                    (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                      (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') }
          B')
      x y

Next tactic:
simp [comp_apply, smul_apply]
/-- Apply a linear equivalence on the arguments of a bilinear form. -/
def congr (e : M₂ ≃ₗ[R₂] M₂') : BilinForm R₂ M₂ ≃ₗ[R₂] BilinForm R₂ M₂' where
  toFun B := B.comp e.symm e.symm
  invFun B := B.comp e e
  left_inv B := ext fun 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
B : BilinForm R₂ M₂
x y : M₂
⊢ bilin
      ((fun B => comp B ↑e ↑e)
        (AddHom.toFun
          {
              toAddHom :=
                { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
                  map_add' :=
                    (_ :
                      ∀ (B B' : BilinForm R₂ M₂),
                        (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                          (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                            (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') },
              map_smul' :=
                (_ :
                  ∀ (B : R₂) (B' : BilinForm R₂ M₂),
                    AddHom.toFun
                        { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
                          map_add' :=
                            (_ :
                              ∀ (B B' : BilinForm R₂ M₂),
                                (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                                  (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                                    (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') }
                        (B • B') =
                      (RingHom.id R₂) B •
                        AddHom.toFun
                          { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
                            map_add' :=
                              (_ :
                                ∀ (B B' : BilinForm R₂ M₂),
                                  (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                                    (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                                      (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') }
                          B') }.toAddHom
          B))
      x y =
    bilin B x y

Next tactic:
simp only [comp_apply, LinearEquiv.coe_coe, e.symm_apply_apply]
/-- Apply a linear equivalence on the arguments of a bilinear form. -/
def congr (e : M₂ ≃ₗ[R₂] M₂') : BilinForm R₂ M₂ ≃ₗ[R₂] BilinForm R₂ M₂' where
  toFun B := B.comp e.symm e.symm
  invFun B := B.comp e e
  left_inv B := ext fun x y => by simp only [comp_apply, LinearEquiv.coe_coe, e.symm_apply_apply]
  right_inv B := ext fun 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
B : BilinForm R₂ M₂'
x y : M₂'
⊢ bilin
      (AddHom.toFun
        {
            toAddHom :=
              { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
                map_add' :=
                  (_ :
                    ∀ (B B' : BilinForm R₂ M₂),
                      (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                        (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                          (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') },
            map_smul' :=
              (_ :
                ∀ (B : R₂) (B' : BilinForm R₂ M₂),
                  AddHom.toFun
                      { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
                        map_add' :=
                          (_ :
                            ∀ (B B' : BilinForm R₂ M₂),
                              (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                                (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                                  (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') }
                      (B • B') =
                    (RingHom.id R₂) B •
                      AddHom.toFun
                        { toFun := fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e),
                          map_add' :=
                            (_ :
                              ∀ (B B' : BilinForm R₂ M₂),
                                (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) (B + B') =
                                  (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B +
                                    (fun B => comp B ↑(LinearEquiv.symm e) ↑(LinearEquiv.symm e)) B') }
                        B') }.toAddHom
        ((fun B => comp B ↑e ↑e) B))
      x y =
    bilin B x y

Next tactic:
simp only [comp_apply, LinearEquiv.coe_coe, e.apply_symm_apply]
@[simp]
theorem congr_symm (e : M₂ ≃ₗ[R₂] M₂') : (congr e).symm = congr e.symm := 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
⊢ LinearEquiv.symm (congr e) = congr (LinearEquiv.symm e)

Next tactic:
ext
@[simp]
theorem congr_symm (e : M₂ ≃ₗ[R₂] M₂') : (congr e).symm = congr e.symm := 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
x✝¹ : BilinForm R₂ M₂'
x✝ y✝ : M₂
⊢ bilin ((LinearEquiv.symm (congr e)) x✝¹) x✝ y✝ = bilin ((congr (LinearEquiv.symm e)) x✝¹) x✝ y✝

Next tactic:
simp only [congr_apply, LinearEquiv.symm_symm]
@[simp]
theorem congr_symm (e : M₂ ≃ₗ[R₂] M₂') : (congr e).symm = congr e.symm := by
  ext
  simp only [congr_apply, LinearEquiv.symm_symm]
  

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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
e : M₂ ≃ₗ[R₂] M₂'
x✝¹ : BilinForm R₂ M₂'
x✝ y✝ : M₂
⊢ bilin ((LinearEquiv.symm (congr e)) x✝¹) x✝ y✝ = bilin x✝¹ (e x✝) (e y✝)

Next tactic:
rfl
/-- `linMulLin f g` is the bilinear form mapping `x` and `y` to `f x * g y` -/
def linMulLin (f g : M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x * g 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
f g : M₂ →ₗ[R₂] R₂
x y z : M₂
⊢ (fun x y => f x * g y) (x + y) z = (fun x y => f x * g y) x z + (fun x y => f x * g y) y z

Next tactic:
simp only [LinearMap.map_add, add_mul]
/-- `linMulLin f g` is the bilinear form mapping `x` and `y` to `f x * g y` -/
def linMulLin (f g : M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x * g y
  bilin_add_left x y z := by simp only [LinearMap.map_add, add_mul]
  bilin_smul_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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
f g : M₂ →ₗ[R₂] R₂
x : R₂
y z : M₂
⊢ (fun x y => f x * g y) (x • y) z = x * (fun x y => f x * g y) y z

Next tactic:
simp only [LinearMap.map_smul, smul_eq_mul, mul_assoc]
/-- `linMulLin f g` is the bilinear form mapping `x` and `y` to `f x * g y` -/
def linMulLin (f g : M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x * g y
  bilin_add_left x y z := by simp only [LinearMap.map_add, add_mul]
  bilin_smul_left x y z := by simp only [LinearMap.map_smul, smul_eq_mul, mul_assoc]
  bilin_add_right 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
f g : M₂ →ₗ[R₂] R₂
x y z : M₂
⊢ (fun x y => f x * g y) x (y + z) = (fun x y => f x * g y) x y + (fun x y => f x * g y) x z

Next tactic:
simp only [LinearMap.map_add, mul_add]
/-- `linMulLin f g` is the bilinear form mapping `x` and `y` to `f x * g y` -/
def linMulLin (f g : M₂ →ₗ[R₂] R₂) : BilinForm R₂ M₂ where
  bilin x y := f x * g y
  bilin_add_left x y z := by simp only [LinearMap.map_add, add_mul]
  bilin_smul_left x y z := by simp only [LinearMap.map_smul, smul_eq_mul, mul_assoc]
  bilin_add_right x y z := by simp only [LinearMap.map_add, mul_add]
  bilin_smul_right 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
f g : M₂ →ₗ[R₂] R₂
x : R₂
y z : M₂
⊢ (fun x y => f x * g y) y (x • z) = x * (fun x y => f x * g y) y z

Next tactic:
simp only [LinearMap.map_smul, smul_eq_mul, mul_left_comm]
/-- Write out `B x y` as a sum over `B (b i) (b j)` if `b` is a basis. -/
theorem sum_repr_mul_repr_mul (x y : M₂) :
    ((b.repr x).sum fun i xi => (b.repr y).sum fun j yj => xi • yj • B₂ (b i) (b j)) = B₂ 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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
F₂ : BilinForm R₂ M₂
ι : Type u_13
b : Basis ι R₂ M₂
x y : M₂
⊢ (Finsupp.sum (b.repr x) fun i xi => Finsupp.sum (b.repr y) fun j yj => xi • yj • bilin B₂ (b i) (b j)) = bilin B₂ x y

Next tactic:
conv_rhs => rw [← b.total_repr x, ← b.total_repr y]
/-- Write out `B x y` as a sum over `B (b i) (b j)` if `b` is a basis. -/
theorem sum_repr_mul_repr_mul (x y : M₂) :
    ((b.repr x).sum fun i xi => (b.repr y).sum fun j yj => xi • yj • B₂ (b i) (b j)) = B₂ x y := by
  conv_rhs => 

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₂
M₂' : Type u_11
M₂'' : Type u_12
inst✝³ : AddCommMonoid M₂'
inst✝² : AddCommMonoid M₂''
inst✝¹ : Module R₂ M₂'
inst✝ : Module R₂ M₂''
F₂ : BilinForm R₂ M₂
ι : Type u_13
b : Basis ι R₂ M₂
x y : M₂
| bilin B₂ x y

Next tactic:
rw [← b.total_repr x, ← b.total_repr y]