-- Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean
theorem det_mul (M N : Matrix n n R) : det (M * N) = det M * det N :=
  calc
    det (M * N) = ∑ p : n → n, ∑ σ : Perm n, ε σ * ∏ i, M (σ i) (p i) * N (p i) i

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * (↑↑(sign σ) * ↑↑(sign ((Equiv.mulRight σ⁻¹) τ))) * ∏ i : n, M (((Equiv.mulRight σ⁻¹) τ) i) i

Tactic:
have : (∏ j, M (τ j) (σ j)) = ∏ j, M ((τ * σ⁻¹) j) j := by
  rw [← (σ⁻¹ : _ ≃ _).prod_comp]
  simp only [Equiv.Perm.coe_mul, apply_inv_self, Function.comp_apply]

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * (↑↑(sign σ) * ↑↑(sign ((Equiv.mulRight σ⁻¹) τ))) * ∏ i : n, M (((Equiv.mulRight σ⁻¹) τ) i) i

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
⊢ ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j

Tactic:
rw [← (σ⁻¹ : _ ≃ _).prod_comp]

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
⊢ ∏ i : n, M (τ (σ⁻¹ i)) (σ (σ⁻¹ i)) = ∏ j : n, M ((τ * σ⁻¹) j) j

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
⊢ ↑↑(sign (τ * σ⁻¹ * σ)) = ↑↑(sign τ)

Tactic:
simp only [inv_mul_cancel_right]

Result:
no goals

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
⊢ ↑↑(sign σ) * ↑↑(sign (τ * σ⁻¹)) = ↑↑(sign (τ * σ⁻¹ * σ))

Tactic:
rw [mul_comm, sign_mul (τ * σ⁻¹)]

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
⊢ ↑↑(sign (τ * σ⁻¹)) * ↑↑(sign σ) = ↑↑(sign (τ * σ⁻¹) * sign σ)

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
⊢ ∑ x : Perm n, ∑ i : n → n, ↑↑(sign x) * ∏ i_1 : n, M (x i_1) (i i_1) * N (i i_1) i_1 =
    ∑ p : n → n, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M (σ i) (p i) * N (p i) i

Tactic:
rw [Finset.sum_comm]

Result:
no goals

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
⊢ ∑ τ : Perm n, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M (σ i) (τ i) * N (τ i) i =
    ∑ σ : Perm n, ∑ τ : Perm n, (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j)

Tactic:
simp only [mul_comm, mul_left_comm, prod_mul_distrib, mul_assoc]

Result:
no goals

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
h : ↑↑(sign σ) * ↑↑(sign (τ * σ⁻¹)) = ↑↑(sign τ)
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ x : n, M ((τ * σ⁻¹) x) x

Tactic:
simp only [this]

Result:
no goals

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
⊢ (M * N).det = ∑ p : n → n, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M (σ i) (p i) * N (p i) i

Tactic:
simp only [det_apply', mul_apply, prod_univ_sum, mul_sum, Fintype.piFinset_univ]

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
⊢ ∑ x : Perm n, ∑ i : n → n, ↑↑(sign x) * ∏ i_1 : n, M (x i_1) (i i_1) * N (i i_1) i_1 =
    ∑ p : n → n, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M (σ i) (p i) * N (p i) i

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * (↑↑(sign σ) * ↑↑(sign ((Equiv.mulRight σ⁻¹) τ))) * ∏ i : n, M (((Equiv.mulRight σ⁻¹) τ) i) i

Tactic:
have h : ε σ * ε (τ * σ⁻¹) = ε τ :=
  calc
    ε σ * ε (τ * σ⁻¹) = ε (τ * σ⁻¹ * σ) := by
      rw [mul_comm, sign_mul (τ * σ⁻¹)]
      simp only [Int.cast_mul, Units.val_mul]
    _ = ε τ := by simp only [inv_mul_cancel_right]

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
h : ↑↑(sign σ) * ↑↑(sign (τ * σ⁻¹)) = ↑↑(sign τ)
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * (↑↑(sign σ) * ↑↑(sign ((Equiv.mulRight σ⁻¹) τ))) * ∏ i : n, M (((Equiv.mulRight σ⁻¹) τ) i) i

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
⊢ ∑ p : n → n, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M (σ i) (p i) * N (p i) i =
    ∑ p ∈ filter (fun p => Bijective p) univ, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M (σ i) (p i) * N (p i) i

Tactic:
refine (sum_subset (filter_subset _ _) fun f _ hbij ↦ det_mul_aux ?_).symm

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
f : n → n
x✝ : f ∈ univ
hbij : f ∉ filter (fun p => Bijective p) univ
⊢ ¬Bijective f

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
⊢ ↑↑(sign (τ * σ⁻¹)) * ↑↑(sign σ) = ↑↑(sign (τ * σ⁻¹) * sign σ)

Tactic:
simp only [Int.cast_mul, Units.val_mul]

Result:
no goals

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
⊢ ∑ σ : Perm n, ∑ τ : Perm n, (∏ i : n, N (σ i) i) * (↑↑(sign σ) * ↑↑(sign τ)) * ∏ i : n, M (τ i) i = M.det * N.det

Tactic:
simp only [det_apply', Finset.mul_sum, mul_comm, mul_left_comm, mul_assoc]

Result:
no goals

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
h : ↑↑(sign σ) * ↑↑(sign (τ * σ⁻¹)) = ↑↑(sign τ)
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * (↑↑(sign σ) * ↑↑(sign ((Equiv.mulRight σ⁻¹) τ))) * ∏ i : n, M (((Equiv.mulRight σ⁻¹) τ) i) i

Tactic:
simp_rw [Equiv.coe_mulRight, h]

Result:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
σ : Perm n
x✝ : σ ∈ univ
τ : Perm n
this : ∏ j : n, M (τ j) (σ j) = ∏ j : n, M ((τ * σ⁻¹) j) j
h : ↑↑(sign σ) * ↑↑(sign (τ * σ⁻¹)) = ↑↑(sign τ)
⊢ (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ j : n, M (τ j) (σ j) =
    (∏ i : n, N (σ i) i) * ↑↑(sign τ) * ∏ x : n, M ((τ * σ⁻¹) x) x

Proof state:
n : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
R : Type v
inst✝ : CommRing R
M N : Matrix n n R
f : n → n
x✝ : f ∈ univ
hbij : f ∉ filter (fun p => Bijective p) univ
⊢ ¬Bijective f

Tactic:
simpa only [true_and, mem_filter, mem_univ] using hbij

Result:
no goals