l3lab/ntp-mathlib huggingface dataset:
theorem blockTriangular_blockDiagonal [DecidableEq α] (d : α → Matrix m m R) :
    BlockTriangular (blockDiagonal d) Prod.snd := by
  rintro ⟨i, i'⟩ ⟨j, j'⟩ h
  

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq α
d : α → Matrix m m R
i : m
i' : α
j : m
j' : α
h : (j, j').2 < (i, i').2
⊢ blockDiagonal d (i, i') (j, j') = 0

Next tactic:
rw [blockDiagonal'_eq_blockDiagonal, blockTriangular_blockDiagonal']
theorem blockTriangular_blockDiagonal [DecidableEq α] (d : α → Matrix m m R) :
    BlockTriangular (blockDiagonal d) Prod.snd := by
  rintro ⟨i, i'⟩ ⟨j, j'⟩ h
  rw [blockDiagonal'_eq_blockDiagonal, blockTriangular_blockDiagonal']
  

Proof state:
case mk.mk.a
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq α
d : α → Matrix m m R
i : m
i' : α
j : m
j' : α
h : (j, j').2 < (i, i').2
⊢ { fst := j', snd := j }.fst < { fst := i', snd := i }.fst

Next tactic:
exact h
theorem blockTriangular_stdBasisMatrix {i j : m} (hij : b i ≤ b j) (c : R) :
    BlockTriangular (stdBasisMatrix i j c) b := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq m
i j : m
hij : b i ≤ b j
c : R
⊢ BlockTriangular (stdBasisMatrix i j c) b

Next tactic:
intro r s hrs
theorem blockTriangular_stdBasisMatrix {i j : m} (hij : b i ≤ b j) (c : R) :
    BlockTriangular (stdBasisMatrix i j c) b := by
  intro r s hrs
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq m
i j : m
hij : b i ≤ b j
c : R
r s : m
hrs : b s < b r
⊢ stdBasisMatrix i j c r s = 0

Next tactic:
apply StdBasisMatrix.apply_of_ne
theorem blockTriangular_stdBasisMatrix {i j : m} (hij : b i ≤ b j) (c : R) :
    BlockTriangular (stdBasisMatrix i j c) b := by
  intro r s hrs
  apply StdBasisMatrix.apply_of_ne
  

Proof state:
case h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq m
i j : m
hij : b i ≤ b j
c : R
r s : m
hrs : b s < b r
⊢ ¬(i = r ∧ j = s)

Next tactic:
rintro ⟨rfl, rfl⟩
theorem blockTriangular_stdBasisMatrix {i j : m} (hij : b i ≤ b j) (c : R) :
    BlockTriangular (stdBasisMatrix i j c) b := by
  intro r s hrs
  apply StdBasisMatrix.apply_of_ne
  rintro ⟨rfl, rfl⟩
  

Proof state:
case h.intro
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq m
i j : m
hij : b i ≤ b j
c : R
hrs : b j < b i
⊢ False

Next tactic:
exact (hij.trans_lt hrs).false
theorem blockTriangular_stdBasisMatrix' {i j : m} (hij : b j ≤ b i) (c : R) :
    BlockTriangular (stdBasisMatrix i j c) (toDual ∘ b) :=
  blockTriangular_stdBasisMatrix (by 

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M N : Matrix m m R
b : m → α
inst✝¹ : Preorder α
inst✝ : DecidableEq m
i j : m
hij : b j ≤ b i
c : R
⊢ (⇑toDual ∘ b) i ≤ (⇑toDual ∘ b) j

Next tactic:
exact toDual_le_toDual.mpr hij
theorem BlockTriangular.mul [Fintype m] {M N : Matrix m m R} (hM : BlockTriangular M b)
    (hN : BlockTriangular N b) : BlockTriangular (M * N) b := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M✝ N✝ : Matrix m m R
b : m → α
inst✝¹ : LinearOrder α
inst✝ : Fintype m
M N : Matrix m m R
hM : BlockTriangular M b
hN : BlockTriangular N b
⊢ BlockTriangular (M * N) b

Next tactic:
intro i j hij
theorem BlockTriangular.mul [Fintype m] {M N : Matrix m m R} (hM : BlockTriangular M b)
    (hN : BlockTriangular N b) : BlockTriangular (M * N) b := by
  intro i j hij
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M✝ N✝ : Matrix m m R
b : m → α
inst✝¹ : LinearOrder α
inst✝ : Fintype m
M N : Matrix m m R
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
hij : b j < b i
⊢ (M * N) i j = 0

Next tactic:
apply Finset.sum_eq_zero
theorem BlockTriangular.mul [Fintype m] {M N : Matrix m m R} (hM : BlockTriangular M b)
    (hN : BlockTriangular N b) : BlockTriangular (M * N) b := by
  intro i j hij
  apply Finset.sum_eq_zero
  

Proof state:
case h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M✝ N✝ : Matrix m m R
b : m → α
inst✝¹ : LinearOrder α
inst✝ : Fintype m
M N : Matrix m m R
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
hij : b j < b i
⊢ ∀ x ∈ univ, (fun j => M i j) x * (fun j_1 => N j_1 j) x = 0

Next tactic:
intro k _
theorem BlockTriangular.mul [Fintype m] {M N : Matrix m m R} (hM : BlockTriangular M b)
    (hN : BlockTriangular N b) : BlockTriangular (M * N) b := by
  intro i j hij
  apply Finset.sum_eq_zero
  intro k _
  

Proof state:
case h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M✝ N✝ : Matrix m m R
b : m → α
inst✝¹ : LinearOrder α
inst✝ : Fintype m
M N : Matrix m m R
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
hij : b j < b i
k : m
a✝ : k ∈ univ
⊢ (fun j => M i j) k * (fun j_1 => N j_1 j) k = 0

Next tactic:
by_cases hki : b k < b i
theorem BlockTriangular.mul [Fintype m] {M N : Matrix m m R} (hM : BlockTriangular M b)
    (hN : BlockTriangular N b) : BlockTriangular (M * N) b := by
  intro i j hij
  apply Finset.sum_eq_zero
  intro k _
  by_cases hki : b k < b i
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M✝ N✝ : Matrix m m R
b : m → α
inst✝¹ : LinearOrder α
inst✝ : Fintype m
M N : Matrix m m R
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
hij : b j < b i
k : m
a✝ : k ∈ univ
hki : b k < b i
⊢ (fun j => M i j) k * (fun j_1 => N j_1 j) k = 0

Next tactic:
simp_rw [hM hki, zero_mul]
theorem BlockTriangular.mul [Fintype m] {M N : Matrix m m R} (hM : BlockTriangular M b)
    (hN : BlockTriangular N b) : BlockTriangular (M * N) b := by
  intro i j hij
  apply Finset.sum_eq_zero
  intro k _
  by_cases hki : b k < b i
  · simp_rw [hM hki, zero_mul]
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝² : CommRing R
M✝ N✝ : Matrix m m R
b : m → α
inst✝¹ : LinearOrder α
inst✝ : Fintype m
M N : Matrix m m R
hM : BlockTriangular M b
hN : BlockTriangular N b
i j : m
hij : b j < b i
k : m
a✝ : k ∈ univ
hki : ¬b k < b i
⊢ (fun j => M i j) k * (fun j_1 => N j_1 j) k = 0

Next tactic:
simp_rw [hN (lt_of_lt_of_le hij (le_of_not_lt hki)), mul_zero]
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
⊢ BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun x => a) fun x => b)

Next tactic:
rintro (c | c) (d | d) hcd
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> 

Proof state:
case inl.inl
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c d : m
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inl d) < Sum.elim (fun x => a) (fun x => b) (Sum.inl c)
⊢ fromBlocks A B 0 D (Sum.inl c) (Sum.inl d) = 0

Next tactic:
first | simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> first | 

Proof state:
case inl.inl
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c d : m
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inl d) < Sum.elim (fun x => a) (fun x => b) (Sum.inl c)
⊢ fromBlocks A B 0 D (Sum.inl c) (Sum.inl d) = 0

Next tactic:
simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> 

Proof state:
case inl.inr
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c : m
d : n
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inr d) < Sum.elim (fun x => a) (fun x => b) (Sum.inl c)
⊢ fromBlocks A B 0 D (Sum.inl c) (Sum.inr d) = 0

Next tactic:
first | simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> first | 

Proof state:
case inl.inr
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c : m
d : n
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inr d) < Sum.elim (fun x => a) (fun x => b) (Sum.inl c)
⊢ fromBlocks A B 0 D (Sum.inl c) (Sum.inr d) = 0

Next tactic:
simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> 

Proof state:
case inr.inl
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c : n
d : m
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inl d) < Sum.elim (fun x => a) (fun x => b) (Sum.inr c)
⊢ fromBlocks A B 0 D (Sum.inr c) (Sum.inl d) = 0

Next tactic:
first | simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> first | 

Proof state:
case inr.inl
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c : n
d : m
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inl d) < Sum.elim (fun x => a) (fun x => b) (Sum.inr c)
⊢ fromBlocks A B 0 D (Sum.inr c) (Sum.inl d) = 0

Next tactic:
simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> 

Proof state:
case inr.inr
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c d : n
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inr d) < Sum.elim (fun x => a) (fun x => b) (Sum.inr c)
⊢ fromBlocks A B 0 D (Sum.inr c) (Sum.inr d) = 0

Next tactic:
first | simp [hab.not_lt] at hcd ⊢
theorem upper_two_blockTriangular [Preorder α] (A : Matrix m m R) (B : Matrix m n R)
    (D : Matrix n n R) {a b : α} (hab : a < b) :
    BlockTriangular (fromBlocks A B 0 D) (Sum.elim (fun _ => a) fun _ => b) := by
  rintro (c | c) (d | d) hcd <;> first | 

Proof state:
case inr.inr
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝¹ : CommRing R
M N : Matrix m m R
b✝ : m → α
inst✝ : Preorder α
A : Matrix m m R
B : Matrix m n R
D : Matrix n n R
a b : α
hab : a < b
c d : n
hcd : Sum.elim (fun x => a) (fun x => b) (Sum.inr d) < Sum.elim (fun x => a) (fun x => b) (Sum.inr c)
⊢ fromBlocks A B 0 D (Sum.inr c) (Sum.inr d) = 0

Next tactic:
simp [hab.not_lt] at hcd ⊢
theorem equiv_block_det (M : Matrix m m R) {p q : m → Prop} [DecidablePred p] [DecidablePred q]
    (e : ∀ x, q x ↔ p x) : (toSquareBlockProp M p).det = (toSquareBlockProp M q).det := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁶ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁵ : DecidableEq m
inst✝⁴ : Fintype m
inst✝³ : DecidableEq n
inst✝² : Fintype n
M : Matrix m m R
p q : m → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
e : ∀ (x : m), q x ↔ p x
⊢ det (toSquareBlockProp M p) = det (toSquareBlockProp M q)

Next tactic:
convert Matrix.det_reindex_self (Equiv.subtypeEquivRight e) (toSquareBlockProp M q)
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
⊢ det M =
    det
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
        (toBlock M (fun j => ¬p j) fun j => ¬p j))

Next tactic:
rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
⊢ det ((reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M) =
    det
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
        (toBlock M (fun j => ¬p j) fun j => ¬p j))

Next tactic:
rw [det_apply', det_apply']
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  

Proof state:
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
⊢ ∑ σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a }),
      ↑↑(Equiv.Perm.sign σ) *
        ∏ i : { a // p a } ⊕ { a // ¬p a }, (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M (σ i) i =
    ∑ σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a }),
      ↑↑(Equiv.Perm.sign σ) *
        ∏ i : { a // p a } ⊕ { a // ¬p a },
          fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
            (toBlock M (fun j => ¬p j) fun j => ¬p j) (σ i) i

Next tactic:
congr
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  congr; 

Proof state:
case e_f
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
⊢ (fun σ =>
      ↑↑(Equiv.Perm.sign σ) *
        ∏ i : { a // p a } ⊕ { a // ¬p a }, (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M (σ i) i) =
    fun σ =>
    ↑↑(Equiv.Perm.sign σ) *
      ∏ i : { a // p a } ⊕ { a // ¬p a },
        fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
          (toBlock M (fun j => ¬p j) fun j => ¬p j) (σ i) i

Next tactic:
ext σ
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  congr; ext σ; 

Proof state:
case e_f.h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a })
⊢ ↑↑(Equiv.Perm.sign σ) *
      ∏ i : { a // p a } ⊕ { a // ¬p a }, (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M (σ i) i =
    ↑↑(Equiv.Perm.sign σ) *
      ∏ i : { a // p a } ⊕ { a // ¬p a },
        fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
          (toBlock M (fun j => ¬p j) fun j => ¬p j) (σ i) i

Next tactic:
congr
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  congr; ext σ; congr; 

Proof state:
case e_f.h.e_a.e_f
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a })
⊢ (fun i => (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M (σ i) i) = fun i =>
    fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
      (toBlock M (fun j => ¬p j) fun j => ¬p j) (σ i) i

Next tactic:
ext x
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  congr; ext σ; congr; ext x
  

Proof state:
case e_f.h.e_a.e_f.h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a })
x : { a // p a } ⊕ { a // ¬p a }
⊢ (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M (σ x) x =
    fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
      (toBlock M (fun j => ¬p j) fun j => ¬p j) (σ x) x

Next tactic:
generalize hy : σ x = y
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  congr; ext σ; congr; ext x
  generalize hy : σ x = y
  

Proof state:
case e_f.h.e_a.e_f.h
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a })
x y : { a // p a } ⊕ { a // ¬p a }
hy : σ x = y
⊢ (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M y x =
    fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
      (toBlock M (fun j => ¬p j) fun j => ¬p j) y x

Next tactic:
cases x
theorem det_toBlock (M : Matrix m m R) (p : m → Prop) [DecidablePred p] :
    M.det =
      (fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p) <|
          toBlock M (fun j => ¬p j) fun j => ¬p j).det := by
  rw [← Matrix.det_reindex_self (Equiv.sumCompl p).symm M]
  rw [det_apply', det_apply']
  congr; ext σ; congr; ext x
  generalize hy : σ x = y
  cases x <;> 

Proof state:
case e_f.h.e_a.e_f.h.inl
α : Type u_1
β : Type u_2
m : Type u_3
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁵ : CommRing R
M✝ N : Matrix m m R
b : m → α
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
inst✝² : DecidableEq n
inst✝¹ : Fintype n
M : Matrix m m R
p : m → Prop
inst✝ : DecidablePred p
σ : Equiv.Perm ({ a // p a } ⊕ { a // ¬p a })
y : { a // p a } ⊕ { a // ¬p a }
val✝ : { a // p a }
hy : σ (Sum.inl val✝) = y
⊢ (reindex (Equiv.sumCompl p).symm (Equiv.sumCompl p).symm) M y (Sum.inl val✝) =
    fromBlocks (toBlock M p p) (toBlock M p fun j => ¬p j) (toBlock M (fun j => ¬p j) p)
      (toBlock M (fun j => ¬p j) fun j => ¬p j) y (Sum.inl val✝)

Next tactic:
cases y