-- Mathlib/LinearAlgebra/Matrix/Determinant/Basic.lean
theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Matrix n n R) :
    (blockDiagonal M).det = ∏ k, (M k).det

Proof state:
case refine_1
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
⊢ ∀ (a : (a : o) → a ∈ univ → Perm n) (ha : a ∈ univ), (fun σ x => prodCongrLeft fun k => σ k ⋯) a ha ∈ preserving_snd

Tactic:
intro σ _

Result:
case refine_1
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : (a : o) → a ∈ univ → Perm n
ha✝ : σ ∈ univ
⊢ (fun σ x => prodCongrLeft fun k => σ k ⋯) σ ha✝ ∈ preserving_snd

Proof state:
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ ∑ σ : Perm (n × o), ↑↑(sign σ) * ∏ i : n × o, blockDiagonal M (σ i) i =
    ∏ x : o, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M x (σ i) i

Tactic:
rw [Finset.prod_sum]

Result:
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ ∑ σ : Perm (n × o), ↑↑(sign σ) * ∏ i : n × o, blockDiagonal M (σ i) i =
    ∑ p ∈ univ.pi fun x => univ, ∏ x ∈ univ.attach, ↑↑(sign (p ↑x ⋯)) * ∏ i : n, M (↑x) ((p ↑x ⋯) i) i

Proof state:
case refine_4
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : (a : o) → a ∈ univ → Perm n
ha✝ : σ ∈ univ
⊢ (∏ x : o, ↑↑(sign (σ x ⋯))) * ∏ x : o, ∏ x_1 : n, M x ((σ x ⋯) x_1) x_1 =
    ↑↑(sign ((fun σ x => prodCongrLeft fun k => σ k ⋯) σ ha✝)) *
      ∏ y : o, ∏ x : n, blockDiagonal M (((fun σ x => prodCongrLeft fun k => σ k ⋯) σ ha✝) (x, y)) (x, y)

Tactic:
simp only [sign_prodCongrLeft, Units.coe_prod, Int.cast_prod, blockDiagonal_apply_eq,
  prodCongrLeft_apply]

Result:
no goals

Proof state:
case refine_1.mk
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : (a : o) → a ∈ univ → Perm n
ha✝ : σ ∈ univ
fst✝ : n
x : o
⊢ (((fun σ x => prodCongrLeft fun k => σ k ⋯) σ ha✝) (fst✝, x)).2 = (fst✝, x).2

Tactic:
simp only [prodCongrLeft_apply]

Result:
no goals

Proof state:
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ ∑ σ : Perm (n × o), ↑↑(sign σ) * ∏ i : n × o, blockDiagonal M (σ i) i =
    ∑ p ∈ univ.pi fun x => univ, ∏ x ∈ univ.attach, ↑↑(sign (p ↑x ⋯)) * ∏ i : n, M (↑x) ((p ↑x ⋯) i) i

Tactic:
simp_rw [Finset.prod_attach_univ, Finset.univ_pi_univ]

Result:
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ ∑ σ : Perm (n × o), ↑↑(sign σ) * ∏ i : n × o, blockDiagonal M (σ i) i =
    ∑ x : (a : o) → a ∈ univ → Perm n, ∏ x_1 : o, ↑↑(sign (x x_1 ⋯)) * ∏ x_2 : n, M x_1 ((x x_1 ⋯) x_2) x_2

Proof state:
case intro.mk
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : Perm (n × o)
a✝ : σ ∈ univ
hσ : ¬∀ (x : n × o), (σ x).2 = x.2
k : n
x : o
hkx : ¬(σ (k, x)).2 = (k, x).2
⊢ blockDiagonal M (σ (k, x)) (k, x) = 0

Tactic:
rw [blockDiagonal_apply_ne]

Result:
case intro.mk.h
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : Perm (n × o)
a✝ : σ ∈ univ
hσ : ¬∀ (x : n × o), (σ x).2 = x.2
k : n
x : o
hkx : ¬(σ (k, x)).2 = (k, x).2
⊢ (σ (k, x)).2 ≠ x

Proof state:
case refine_3.refine_3
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : n × o ≃ n × o
hσ : ∀ (x : n × o), (σ x).2 = x.2
hσ' : ∀ (x : n × o), (σ⁻¹ x).2 = x.2
mk_apply_eq : ∀ (k : o) (x : n), ((σ (x, k)).1, k) = σ (x, k)
mk_inv_apply_eq : ∀ (k : o) (x : n), ((σ⁻¹ (x, k)).1, k) = σ⁻¹ (x, k)
⊢ (fun k x => { toFun := fun x => (σ (x, k)).1, invFun := fun x => (σ⁻¹ (x, k)).1, left_inv := ⋯, right_inv := ⋯ }) ∈
    univ

Tactic:
apply Finset.mem_univ

Result:
no goals

Proof state:
case refine_3.refine_2
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : n × o ≃ n × o
hσ : ∀ (x : n × o), (σ x).2 = x.2
hσ' : ∀ (x : n × o), (σ⁻¹ x).2 = x.2
mk_apply_eq : ∀ (k : o) (x : n), ((σ (x, k)).1, k) = σ (x, k)
mk_inv_apply_eq : ∀ (k : o) (x : n), ((σ⁻¹ (x, k)).1, k) = σ⁻¹ (x, k)
k : o
x✝ : k ∈ univ
⊢ RightInverse (fun x => (σ⁻¹ (x, k)).1) fun x => (σ (x, k)).1

Tactic:
intro x

Result:
case refine_3.refine_2
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : n × o ≃ n × o
hσ : ∀ (x : n × o), (σ x).2 = x.2
hσ' : ∀ (x : n × o), (σ⁻¹ x).2 = x.2
mk_apply_eq : ∀ (k : o) (x : n), ((σ (x, k)).1, k) = σ (x, k)
mk_inv_apply_eq : ∀ (k : o) (x : n), ((σ⁻¹ (x, k)).1, k) = σ⁻¹ (x, k)
k : o
x✝ : k ∈ univ
x : n
⊢ (fun x => (σ (x, k)).1) ((fun x => (σ⁻¹ (x, k)).1) x) = x

Proof state:
case snd
n : Type u_2
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
preserving_snd : Finset (Perm (n × o)) := filter (fun σ => ∀ (x : n × o), (σ x).2 = x.2) univ
mem_preserving_snd : ∀ {σ : Perm (n × o)}, σ ∈ preserving_snd ↔ ∀ (x : n × o), (σ x).2 = x.2
σ : n × o ≃ n × o
hσ : ∀ (x : n × o), (σ x).2 = x.2
hσ' : ∀ (x : n × o), (σ⁻¹ x).2 = x.2
mk_apply_eq : ∀ (k : o) (x : n), ((σ (x, k)).1, k) = σ (x, k)
k : o
x : n
⊢ ((σ⁻¹ (σ (σ⁻¹ (x, k)))).1, k).2 = (σ⁻¹ (x, k)).2

Tactic:
simp only [hσ']

Result:
no goals