l3lab/ntp-mathlib huggingface dataset:
theorem fromBlocks_add [Add α] (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (A' : Matrix n l α) (B' : Matrix n m α) (C' : Matrix o l α)
    (D' : Matrix o m α) :
    fromBlocks A B C D + fromBlocks A' B' C' D' = fromBlocks (A + A') (B + B') (C + C') (D + D') :=
  by ext i j; rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inl.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝ : Add α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix n l α
B' : Matrix n m α
C' : Matrix o l α
D' : Matrix o m α
val✝¹ : n
val✝ : l
⊢ (fromBlocks A B C D + fromBlocks A' B' C' D') (Sum.inl val✝¹) (Sum.inl val✝) =
    fromBlocks (A + A') (B + B') (C + C') (D + D') (Sum.inl val✝¹) (Sum.inl val✝)

Next tactic:
rfl
theorem fromBlocks_add [Add α] (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (A' : Matrix n l α) (B' : Matrix n m α) (C' : Matrix o l α)
    (D' : Matrix o m α) :
    fromBlocks A B C D + fromBlocks A' B' C' D' = fromBlocks (A + A') (B + B') (C + C') (D + D') :=
  by ext i j; rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inl.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝ : Add α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix n l α
B' : Matrix n m α
C' : Matrix o l α
D' : Matrix o m α
val✝¹ : n
val✝ : m
⊢ (fromBlocks A B C D + fromBlocks A' B' C' D') (Sum.inl val✝¹) (Sum.inr val✝) =
    fromBlocks (A + A') (B + B') (C + C') (D + D') (Sum.inl val✝¹) (Sum.inr val✝)

Next tactic:
rfl
theorem fromBlocks_add [Add α] (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (A' : Matrix n l α) (B' : Matrix n m α) (C' : Matrix o l α)
    (D' : Matrix o m α) :
    fromBlocks A B C D + fromBlocks A' B' C' D' = fromBlocks (A + A') (B + B') (C + C') (D + D') :=
  by ext i j; rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inr.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝ : Add α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix n l α
B' : Matrix n m α
C' : Matrix o l α
D' : Matrix o m α
val✝¹ : o
val✝ : l
⊢ (fromBlocks A B C D + fromBlocks A' B' C' D') (Sum.inr val✝¹) (Sum.inl val✝) =
    fromBlocks (A + A') (B + B') (C + C') (D + D') (Sum.inr val✝¹) (Sum.inl val✝)

Next tactic:
rfl
theorem fromBlocks_add [Add α] (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (A' : Matrix n l α) (B' : Matrix n m α) (C' : Matrix o l α)
    (D' : Matrix o m α) :
    fromBlocks A B C D + fromBlocks A' B' C' D' = fromBlocks (A + A') (B + B') (C + C') (D + D') :=
  by ext i j; rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inr.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝ : Add α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix n l α
B' : Matrix n m α
C' : Matrix o l α
D' : Matrix o m α
val✝¹ : o
val✝ : m
⊢ (fromBlocks A B C D + fromBlocks A' B' C' D') (Sum.inr val✝¹) (Sum.inr val✝) =
    fromBlocks (A + A') (B + B') (C + C') (D + D') (Sum.inr val✝¹) (Sum.inr val✝)

Next tactic:
rfl
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
⊢ fromBlocks A B C D * fromBlocks A' B' C' D' =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D')

Next tactic:
ext i j
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  

Proof state:
case a.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
i : n ⊕ o
j : p ⊕ q
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') i j =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') i j

Next tactic:
rcases i with ⟨⟩
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  rcases i with ⟨⟩ <;> 

Proof state:
case a.h.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
j : p ⊕ q
val✝ : n
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') (Sum.inl val✝) j =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') (Sum.inl val✝) j

Next tactic:
rcases j with ⟨⟩
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  rcases i with ⟨⟩ <;> 

Proof state:
case a.h.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
j : p ⊕ q
val✝ : o
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') (Sum.inr val✝) j =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') (Sum.inr val✝) j

Next tactic:
rcases j with ⟨⟩
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inl.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
val✝¹ : n
val✝ : p
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') (Sum.inl val✝¹) (Sum.inl val✝) =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') (Sum.inl val✝¹) (Sum.inl val✝)

Next tactic:
simp only [fromBlocks, mul_apply, of_apply,
      Sum.elim_inr, Fintype.sum_sum_type, Sum.elim_inl, add_apply]
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inl.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
val✝¹ : n
val✝ : q
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') (Sum.inl val✝¹) (Sum.inr val✝) =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') (Sum.inl val✝¹) (Sum.inr val✝)

Next tactic:
simp only [fromBlocks, mul_apply, of_apply,
      Sum.elim_inr, Fintype.sum_sum_type, Sum.elim_inl, add_apply]
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inr.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
val✝¹ : o
val✝ : p
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') (Sum.inr val✝¹) (Sum.inl val✝) =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') (Sum.inr val✝¹) (Sum.inl val✝)

Next tactic:
simp only [fromBlocks, mul_apply, of_apply,
      Sum.elim_inr, Fintype.sum_sum_type, Sum.elim_inl, add_apply]
theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') := by
  ext i j
  rcases i with ⟨⟩ <;> rcases j with ⟨⟩ <;> 

Proof state:
case a.h.inr.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
A' : Matrix l p α
B' : Matrix l q α
C' : Matrix m p α
D' : Matrix m q α
val✝¹ : o
val✝ : q
⊢ (fromBlocks A B C D * fromBlocks A' B' C' D') (Sum.inr val✝¹) (Sum.inr val✝) =
    fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') (Sum.inr val✝¹) (Sum.inr val✝)

Next tactic:
simp only [fromBlocks, mul_apply, of_apply,
      Sum.elim_inr, Fintype.sum_sum_type, Sum.elim_inl, add_apply]
theorem fromBlocks_mulVec [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum l m → α) :
    mulVec (fromBlocks A B C D) x =
      Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr))
        (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr)) := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : l ⊕ m → α
⊢ mulVec (fromBlocks A B C D) x =
    Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr)) (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr))

Next tactic:
ext i
theorem fromBlocks_mulVec [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum l m → α) :
    mulVec (fromBlocks A B C D) x =
      Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr))
        (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr)) := by
  ext i
  

Proof state:
case h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : l ⊕ m → α
i : n ⊕ o
⊢ mulVec (fromBlocks A B C D) x i =
    Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr)) (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr)) i

Next tactic:
cases i
theorem fromBlocks_mulVec [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum l m → α) :
    mulVec (fromBlocks A B C D) x =
      Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr))
        (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr)) := by
  ext i
  cases i <;> 

Proof state:
case h.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : l ⊕ m → α
val✝ : n
⊢ mulVec (fromBlocks A B C D) x (Sum.inl val✝) =
    Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr)) (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr))
      (Sum.inl val✝)

Next tactic:
simp [mulVec, dotProduct]
theorem fromBlocks_mulVec [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum l m → α) :
    mulVec (fromBlocks A B C D) x =
      Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr))
        (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr)) := by
  ext i
  cases i <;> 

Proof state:
case h.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype l
inst✝¹ : Fintype m
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : l ⊕ m → α
val✝ : o
⊢ mulVec (fromBlocks A B C D) x (Sum.inr val✝) =
    Sum.elim (mulVec A (x ∘ Sum.inl) + mulVec B (x ∘ Sum.inr)) (mulVec C (x ∘ Sum.inl) + mulVec D (x ∘ Sum.inr))
      (Sum.inr val✝)

Next tactic:
simp [mulVec, dotProduct]
theorem vecMul_fromBlocks [Fintype n] [Fintype o] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum n o → α) :
    vecMul x (fromBlocks A B C D) =
      Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C)
        (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D) := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype n
inst✝¹ : Fintype o
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : n ⊕ o → α
⊢ vecMul x (fromBlocks A B C D) =
    Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C) (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D)

Next tactic:
ext i
theorem vecMul_fromBlocks [Fintype n] [Fintype o] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum n o → α) :
    vecMul x (fromBlocks A B C D) =
      Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C)
        (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D) := by
  ext i
  

Proof state:
case h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype n
inst✝¹ : Fintype o
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : n ⊕ o → α
i : l ⊕ m
⊢ vecMul x (fromBlocks A B C D) i =
    Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C) (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D) i

Next tactic:
cases i
theorem vecMul_fromBlocks [Fintype n] [Fintype o] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum n o → α) :
    vecMul x (fromBlocks A B C D) =
      Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C)
        (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D) := by
  ext i
  cases i <;> 

Proof state:
case h.inl
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype n
inst✝¹ : Fintype o
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : n ⊕ o → α
val✝ : l
⊢ vecMul x (fromBlocks A B C D) (Sum.inl val✝) =
    Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C) (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D)
      (Sum.inl val✝)

Next tactic:
simp [vecMul, dotProduct]
theorem vecMul_fromBlocks [Fintype n] [Fintype o] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : Sum n o → α) :
    vecMul x (fromBlocks A B C D) =
      Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C)
        (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D) := by
  ext i
  cases i <;> 

Proof state:
case h.inr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : Fintype n
inst✝¹ : Fintype o
inst✝ : NonUnitalNonAssocSemiring α
A : Matrix n l α
B : Matrix n m α
C : Matrix o l α
D : Matrix o m α
x : n ⊕ o → α
val✝ : m
⊢ vecMul x (fromBlocks A B C D) (Sum.inr val✝) =
    Sum.elim (vecMul (x ∘ Sum.inl) A + vecMul (x ∘ Sum.inr) C) (vecMul (x ∘ Sum.inl) B + vecMul (x ∘ Sum.inr) D)
      (Sum.inr val✝)

Next tactic:
simp [vecMul, dotProduct]
theorem toBlock_diagonal_self (d : m → α) (p : m → Prop) :
    Matrix.toBlock (diagonal d) p p = diagonal fun i : Subtype p => d ↑i := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p✝ : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : DecidableEq l
inst✝¹ : DecidableEq m
inst✝ : Zero α
d : m → α
p : m → Prop
⊢ toBlock (diagonal d) p p = diagonal fun i => d ↑i

Next tactic:
ext i j
theorem toBlock_diagonal_self (d : m → α) (p : m → Prop) :
    Matrix.toBlock (diagonal d) p p = diagonal fun i : Subtype p => d ↑i := by
  ext i j
  

Proof state:
case a.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p✝ : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : DecidableEq l
inst✝¹ : DecidableEq m
inst✝ : Zero α
d : m → α
p : m → Prop
i j : { a // p a }
⊢ toBlock (diagonal d) p p i j = diagonal (fun i => d ↑i) i j

Next tactic:
by_cases h : i = j
theorem toBlock_diagonal_self (d : m → α) (p : m → Prop) :
    Matrix.toBlock (diagonal d) p p = diagonal fun i : Subtype p => d ↑i := by
  ext i j
  by_cases h : i = j
  · 

Proof state:
case pos
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p✝ : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : DecidableEq l
inst✝¹ : DecidableEq m
inst✝ : Zero α
d : m → α
p : m → Prop
i j : { a // p a }
h : i = j
⊢ toBlock (diagonal d) p p i j = diagonal (fun i => d ↑i) i j

Next tactic:
simp [h]
theorem toBlock_diagonal_self (d : m → α) (p : m → Prop) :
    Matrix.toBlock (diagonal d) p p = diagonal fun i : Subtype p => d ↑i := by
  ext i j
  by_cases h : i = j
  · simp [h]
  · 

Proof state:
case neg
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p✝ : Type u_5
q : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : DecidableEq l
inst✝¹ : DecidableEq m
inst✝ : Zero α
d : m → α
p : m → Prop
i j : { a // p a }
h : ¬i = j
⊢ toBlock (diagonal d) p p i j = diagonal (fun i => d ↑i) i j

Next tactic:
simp [One.one, h, Subtype.val_injective.ne h]
theorem toBlock_diagonal_disjoint (d : m → α) {p q : m → Prop} (hpq : Disjoint p q) :
    Matrix.toBlock (diagonal d) p q = 0 := by
  

Proof state:
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p✝ : Type u_5
q✝ : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : DecidableEq l
inst✝¹ : DecidableEq m
inst✝ : Zero α
d : m → α
p q : m → Prop
hpq : Disjoint p q
⊢ toBlock (diagonal d) p q = 0

Next tactic:
ext ⟨i, hi⟩ ⟨j, hj⟩
theorem toBlock_diagonal_disjoint (d : m → α) {p q : m → Prop} (hpq : Disjoint p q) :
    Matrix.toBlock (diagonal d) p q = 0 := by
  ext ⟨i, hi⟩ ⟨j, hj⟩
  

Proof state:
case a.mk.h.mk
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
p✝ : Type u_5
q✝ : Type u_6
m' : o → Type u_7
n' : o → Type u_8
p' : o → Type u_9
R : Type u_10
S : Type u_11
α : Type u_12
β : Type u_13
inst✝² : DecidableEq l
inst✝¹ : DecidableEq m
inst✝ : Zero α
d : m → α
p q : m → Prop
hpq : Disjoint p q
i : m
hi : p i
j : m
hj : q j
⊢ toBlock (diagonal d) p q { val := i, property := hi } { val := j, property := hj } =
    OfNat.ofNat 0 { val := i, property := hi } { val := j, property := hj }

Next tactic:
have : i ≠ j := fun heq => hpq.le_bot i ⟨hi, heq.symm ▸ hj⟩