l3lab/ntp-mathlib huggingface dataset:
theorem mul_scalar_mul [Monoid α] (x : Holor α []) (y : Holor α ds) :
    x ⊗ y = x ⟨[], Forall₂.nil⟩ • y := by
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Monoid α
x : Holor α []
y : Holor α ds
⊢ x ⊗ y = x { val := [], property := (_ : Forall₂ (fun x x_1 => x < x_1) [] []) } • y

Next tactic:
simp (config := { unfoldPartialApp := true }) [mul, SMul.smul, HolorIndex.take, HolorIndex.drop,
    HSMul.hSMul]
theorem holor_index_cons_decomp (p : HolorIndex (d :: ds) → Prop) :
    ∀ t : HolorIndex (d :: ds),
      (∀ i is, ∀ h : t.1 = i :: is, p ⟨i :: is, by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
p : HolorIndex (d :: ds) → Prop
t : HolorIndex (d :: ds)
i : ℕ
is : List ℕ
h : ↑t = i :: is
⊢ Forall₂ (fun x x_1 => x < x_1) (i :: is) (d :: ds)

Next tactic:
rw [← h]
theorem holor_index_cons_decomp (p : HolorIndex (d :: ds) → Prop) :
    ∀ t : HolorIndex (d :: ds),
      (∀ i is, ∀ h : t.1 = i :: is, p ⟨i :: is, by rw [← h]; 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
p : HolorIndex (d :: ds) → Prop
t : HolorIndex (d :: ds)
i : ℕ
is : List ℕ
h : ↑t = i :: is
⊢ Forall₂ (fun x x_1 => x < x_1) (↑t) (d :: ds)

Next tactic:
exact t.2
/-- Two holors are equal if all their slices are equal. -/
theorem slice_eq (x : Holor α (d :: ds)) (y : Holor α (d :: ds)) (h : slice x = slice y) : x = y :=
  funext fun t : HolorIndex (d :: ds) =>
    holor_index_cons_decomp (fun t => x t = y t) t fun i is hiis =>
      have hiisdds : Forall₂ (· < ·) (i :: is) (d :: ds) := by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
x y : Holor α (d :: ds)
h : slice x = slice y
t : HolorIndex (d :: ds)
i : ℕ
is : List ℕ
hiis : ↑t = i :: is
⊢ Forall₂ (fun x x_1 => x < x_1) (i :: is) (d :: ds)

Next tactic:
rw [← hiis]
/-- Two holors are equal if all their slices are equal. -/
theorem slice_eq (x : Holor α (d :: ds)) (y : Holor α (d :: ds)) (h : slice x = slice y) : x = y :=
  funext fun t : HolorIndex (d :: ds) =>
    holor_index_cons_decomp (fun t => x t = y t) t fun i is hiis =>
      have hiisdds : Forall₂ (· < ·) (i :: is) (d :: ds) := by rw [← hiis]; 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
x y : Holor α (d :: ds)
h : slice x = slice y
t : HolorIndex (d :: ds)
i : ℕ
is : List ℕ
hiis : ↑t = i :: is
⊢ Forall₂ (fun x x_1 => x < x_1) (↑t) (d :: ds)

Next tactic:
exact t.2
/-- Two holors are equal if all their slices are equal. -/
theorem slice_eq (x : Holor α (d :: ds)) (y : Holor α (d :: ds)) (h : slice x = slice y) : x = y :=
  funext fun t : HolorIndex (d :: ds) =>
    holor_index_cons_decomp (fun t => x t = y t) t fun i is hiis =>
      have hiisdds : Forall₂ (· < ·) (i :: is) (d :: ds) := by rw [← hiis]; exact t.2
      have hid : i < d := (forall₂_cons.1 hiisdds).1
      have hisds : Forall₂ (· < ·) is ds := (forall₂_cons.1 hiisdds).2
      calc
        x ⟨i :: is, _⟩ = slice x i hid ⟨is, hisds⟩ := congr_arg (fun t => x t) (Subtype.eq rfl)
        _ = slice y i hid ⟨is, hisds⟩ := by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
x y : Holor α (d :: ds)
h : slice x = slice y
t : HolorIndex (d :: ds)
i : ℕ
is : List ℕ
hiis : ↑t = i :: is
hiisdds : Forall₂ (fun x x_1 => x < x_1) (i :: is) (d :: ds)
hid : i < d
hisds : Forall₂ (fun x x_1 => x < x_1) is ds
⊢ slice x i hid { val := is, property := hisds } = slice y i hid { val := is, property := hisds }

Next tactic:
rw [h]
theorem slice_unitVec_mul [Ring α] {i : ℕ} {j : ℕ} (hid : i < d) (x : Holor α ds) :
    slice (unitVec d j ⊗ x) i hid = if i = j then x else 0 :=
  funext fun t : HolorIndex ds =>
    if h : i = j then by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
i j : ℕ
hid : i < d
x : Holor α ds
t : HolorIndex ds
h : i = j
⊢ slice (unitVec d j ⊗ x) i hid t = ite (i = j) x 0 t

Next tactic:
simp [slice, mul, HolorIndex.take, unitVec, HolorIndex.drop, h]
theorem slice_unitVec_mul [Ring α] {i : ℕ} {j : ℕ} (hid : i < d) (x : Holor α ds) :
    slice (unitVec d j ⊗ x) i hid = if i = j then x else 0 :=
  funext fun t : HolorIndex ds =>
    if h : i = j then by simp [slice, mul, HolorIndex.take, unitVec, HolorIndex.drop, h]
    else by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
i j : ℕ
hid : i < d
x : Holor α ds
t : HolorIndex ds
h : ¬i = j
⊢ slice (unitVec d j ⊗ x) i hid t = ite (i = j) x 0 t

Next tactic:
simp [slice, mul, HolorIndex.take, unitVec, HolorIndex.drop, h]
theorem slice_unitVec_mul [Ring α] {i : ℕ} {j : ℕ} (hid : i < d) (x : Holor α ds) :
    slice (unitVec d j ⊗ x) i hid = if i = j then x else 0 :=
  funext fun t : HolorIndex ds =>
    if h : i = j then by simp [slice, mul, HolorIndex.take, unitVec, HolorIndex.drop, h]
    else by simp [slice, mul, HolorIndex.take, unitVec, HolorIndex.drop, h]; 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
i j : ℕ
hid : i < d
x : Holor α ds
t : HolorIndex ds
h : ¬i = j
⊢ 0 = OfNat.ofNat 0 t

Next tactic:
rfl
theorem slice_add [Add α] (i : ℕ) (hid : i < d) (x : Holor α (d :: ds)) (y : Holor α (d :: ds)) :
    slice x i hid + slice y i hid = slice (x + y) i hid :=
  funext fun t => by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Add α
i : ℕ
hid : i < d
x y : Holor α (d :: ds)
t : HolorIndex ds
⊢ (slice x i hid + slice y i hid) t = slice (x + y) i hid t

Next tactic:
simp [slice, (· + ·), Add.add]
theorem slice_sum [AddCommMonoid α] {β : Type} (i : ℕ) (hid : i < d) (s : Finset β)
    (f : β → Holor α (d :: ds)) : (∑ x in s, slice (f x) i hid) = slice (∑ x in s, f x) i hid := by
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : AddCommMonoid α
β : Type
i : ℕ
hid : i < d
s : Finset β
f : β → Holor α (d :: ds)
⊢ ∑ x in s, slice (f x) i hid = slice (∑ x in s, f x) i hid

Next tactic:
letI := Classical.decEq β
theorem slice_sum [AddCommMonoid α] {β : Type} (i : ℕ) (hid : i < d) (s : Finset β)
    (f : β → Holor α (d :: ds)) : (∑ x in s, slice (f x) i hid) = slice (∑ x in s, f x) i hid := by
  letI := Classical.decEq β
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : AddCommMonoid α
β : Type
i : ℕ
hid : i < d
s : Finset β
f : β → Holor α (d :: ds)
this : DecidableEq β := Classical.decEq β
⊢ ∑ x in s, slice (f x) i hid = slice (∑ x in s, f x) i hid

Next tactic:
refine' Finset.induction_on s _ _
theorem slice_sum [AddCommMonoid α] {β : Type} (i : ℕ) (hid : i < d) (s : Finset β)
    (f : β → Holor α (d :: ds)) : (∑ x in s, slice (f x) i hid) = slice (∑ x in s, f x) i hid := by
  letI := Classical.decEq β
  refine' Finset.induction_on s _ _
  · 

Proof state:
case refine'_1
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : AddCommMonoid α
β : Type
i : ℕ
hid : i < d
s : Finset β
f : β → Holor α (d :: ds)
this : DecidableEq β := Classical.decEq β
⊢ ∑ x in ∅, slice (f x) i hid = slice (∑ x in ∅, f x) i hid

Next tactic:
simp [slice_zero]
theorem slice_sum [AddCommMonoid α] {β : Type} (i : ℕ) (hid : i < d) (s : Finset β)
    (f : β → Holor α (d :: ds)) : (∑ x in s, slice (f x) i hid) = slice (∑ x in s, f x) i hid := by
  letI := Classical.decEq β
  refine' Finset.induction_on s _ _
  · simp [slice_zero]
  · 

Proof state:
case refine'_2
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : AddCommMonoid α
β : Type
i : ℕ
hid : i < d
s : Finset β
f : β → Holor α (d :: ds)
this : DecidableEq β := Classical.decEq β
⊢ ∀ ⦃a : β⦄ {s : Finset β},
    a ∉ s →
      ∑ x in s, slice (f x) i hid = slice (∑ x in s, f x) i hid →
        ∑ x in insert a s, slice (f x) i hid = slice (∑ x in insert a s, f x) i hid

Next tactic:
intro _ _ h_not_in ih
theorem slice_sum [AddCommMonoid α] {β : Type} (i : ℕ) (hid : i < d) (s : Finset β)
    (f : β → Holor α (d :: ds)) : (∑ x in s, slice (f x) i hid) = slice (∑ x in s, f x) i hid := by
  letI := Classical.decEq β
  refine' Finset.induction_on s _ _
  · simp [slice_zero]
  · intro _ _ h_not_in ih
    

Proof state:
case refine'_2
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : AddCommMonoid α
β : Type
i : ℕ
hid : i < d
s : Finset β
f : β → Holor α (d :: ds)
this : DecidableEq β := Classical.decEq β
a✝ : β
s✝ : Finset β
h_not_in : a✝ ∉ s✝
ih : ∑ x in s✝, slice (f x) i hid = slice (∑ x in s✝, f x) i hid
⊢ ∑ x in insert a✝ s✝, slice (f x) i hid = slice (∑ x in insert a✝ s✝, f x) i hid

Next tactic:
rw [Finset.sum_insert h_not_in, ih, slice_add, Finset.sum_insert h_not_in]
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
⊢ ∑ i in Finset.attach (Finset.range d), unitVec d ↑i ⊗ slice x ↑i (_ : Nat.succ ↑i ≤ d) = x

Next tactic:
apply slice_eq _ _ _
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
⊢ slice (∑ i in Finset.attach (Finset.range d), unitVec d ↑i ⊗ slice x ↑i (_ : Nat.succ ↑i ≤ d)) = slice x

Next tactic:
ext i hid
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  

Proof state:
case h.h
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
⊢ slice (∑ i in Finset.attach (Finset.range d), unitVec d ↑i ⊗ slice x ↑i (_ : Nat.succ ↑i ≤ d)) i hid = slice x i hid

Next tactic:
rw [← slice_sum]
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  

Proof state:
case h.h
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
⊢ ∑ x_1 in Finset.attach (Finset.range d), slice (unitVec d ↑x_1 ⊗ slice x ↑x_1 (_ : Nat.succ ↑x_1 ≤ d)) i hid =
    slice x i hid

Next tactic:
simp only [slice_unitVec_mul hid]
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  

Proof state:
case h.h
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
⊢ (∑ x_1 in Finset.attach (Finset.range d), if i = ↑x_1 then slice x ↑x_1 (_ : Nat.succ ↑x_1 ≤ d) else 0) =
    slice x i hid

Next tactic:
rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · 

Proof state:
case h.h
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
⊢ (if i = ↑{ val := i, property := (_ : i ∈ Finset.range d) } then
      slice x ↑{ val := i, property := (_ : i ∈ Finset.range d) }
        (_ : Nat.succ ↑{ val := i, property := (_ : i ∈ Finset.range d) } ≤ d)
    else 0) =
    slice x i hid

Next tactic:
simp
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · 

Proof state:
case h.h.h₀
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
⊢ ∀ b ∈ Finset.attach (Finset.range d),
    b ≠ { val := i, property := (_ : i ∈ Finset.range d) } →
      (if i = ↑b then slice x ↑b (_ : Nat.succ ↑b ≤ d) else 0) = 0

Next tactic:
intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
    

Proof state:
case h.h.h₀
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
b : { x // x ∈ Finset.range d }
x✝ : b ∈ Finset.attach (Finset.range d)
hbi : b ≠ { val := i, property := (_ : i ∈ Finset.range d) }
⊢ (if i = ↑b then slice x ↑b (_ : Nat.succ ↑b ≤ d) else 0) = 0

Next tactic:
have hbi' : i ≠ b := by simpa only [Ne.def, Subtype.ext_iff, Subtype.coe_mk] using hbi.symm
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
    have hbi' : i ≠ b := by 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
b : { x // x ∈ Finset.range d }
x✝ : b ∈ Finset.attach (Finset.range d)
hbi : b ≠ { val := i, property := (_ : i ∈ Finset.range d) }
⊢ i ≠ ↑b

Next tactic:
simpa only [Ne.def, Subtype.ext_iff, Subtype.coe_mk] using hbi.symm
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
    have hbi' : i ≠ b := by simpa only [Ne.def, Subtype.ext_iff, Subtype.coe_mk] using hbi.symm
    

Proof state:
case h.h.h₀
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
b : { x // x ∈ Finset.range d }
x✝ : b ∈ Finset.attach (Finset.range d)
hbi : b ≠ { val := i, property := (_ : i ∈ Finset.range d) }
hbi' : i ≠ ↑b
⊢ (if i = ↑b then slice x ↑b (_ : Nat.succ ↑b ≤ d) else 0) = 0

Next tactic:
simp [hbi']
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
    have hbi' : i ≠ b := by simpa only [Ne.def, Subtype.ext_iff, Subtype.coe_mk] using hbi.symm
    simp [hbi']
  · 

Proof state:
case h.h.h₁
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
⊢ { val := i, property := (_ : i ∈ Finset.range d) } ∉ Finset.attach (Finset.range d) →
    (if i = ↑{ val := i, property := (_ : i ∈ Finset.range d) } then
        slice x ↑{ val := i, property := (_ : i ∈ Finset.range d) }
          (_ : Nat.succ ↑{ val := i, property := (_ : i ∈ Finset.range d) } ≤ d)
      else 0) =
      0

Next tactic:
intro (hid' : Subtype.mk i _ ∉ Finset.attach (Finset.range d))
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
    have hbi' : i ≠ b := by simpa only [Ne.def, Subtype.ext_iff, Subtype.coe_mk] using hbi.symm
    simp [hbi']
  · intro (hid' : Subtype.mk i _ ∉ Finset.attach (Finset.range d))
    

Proof state:
case h.h.h₁
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
hid' : { val := i, property := (_ : i ∈ Finset.range d) } ∉ Finset.attach (Finset.range d)
⊢ (if i = ↑{ val := i, property := (_ : i ∈ Finset.range d) } then
      slice x ↑{ val := i, property := (_ : i ∈ Finset.range d) }
        (_ : Nat.succ ↑{ val := i, property := (_ : i ∈ Finset.range d) } ≤ d)
    else 0) =
    0

Next tactic:
exfalso
/-- The original holor can be recovered from its slices by multiplying with unit vectors and
summing up. -/
@[simp]
theorem sum_unitVec_mul_slice [Ring α] (x : Holor α (d :: ds)) :
    (∑ i in (Finset.range d).attach,
        unitVec d i ⊗ slice x i (Nat.succ_le_of_lt (Finset.mem_range.1 i.prop))) =
      x := by
  apply slice_eq _ _ _
  ext i hid
  rw [← slice_sum]
  simp only [slice_unitVec_mul hid]
  rw [Finset.sum_eq_single (Subtype.mk i <| Finset.mem_range.2 hid)]
  · simp
  · intro (b : { x // x ∈ Finset.range d }) (_ : b ∈ (Finset.range d).attach) (hbi : b ≠ ⟨i, _⟩)
    have hbi' : i ≠ b := by simpa only [Ne.def, Subtype.ext_iff, Subtype.coe_mk] using hbi.symm
    simp [hbi']
  · intro (hid' : Subtype.mk i _ ∉ Finset.attach (Finset.range d))
    exfalso
    

Proof state:
case h.h.h₁.h
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝ : Ring α
x : Holor α (d :: ds)
i : ℕ
hid : i < d
hid' : { val := i, property := (_ : i ∈ Finset.range d) } ∉ Finset.attach (Finset.range d)
⊢ False

Next tactic:
exact absurd (Finset.mem_attach _ _) hid'
theorem cprankMax_nil [Monoid α] [AddMonoid α] (x : Holor α nil) : CPRankMax 1 x := by
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
x : Holor α []
⊢ CPRankMax 1 x

Next tactic:
have h := CPRankMax.succ 0 x 0 (CPRankMax1.nil x) CPRankMax.zero
theorem cprankMax_nil [Monoid α] [AddMonoid α] (x : Holor α nil) : CPRankMax 1 x := by
  have h := CPRankMax.succ 0 x 0 (CPRankMax1.nil x) CPRankMax.zero
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
x : Holor α []
h : CPRankMax (0 + 1) (x + 0)
⊢ CPRankMax 1 x

Next tactic:
rwa [add_zero x, zero_add] at h
theorem cprankMax_1 [Monoid α] [AddMonoid α] {x : Holor α ds} (h : CPRankMax1 x) :
    CPRankMax 1 x := by
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
x : Holor α ds
h : CPRankMax1 x
⊢ CPRankMax 1 x

Next tactic:
have h' := CPRankMax.succ 0 x 0 h CPRankMax.zero
theorem cprankMax_1 [Monoid α] [AddMonoid α] {x : Holor α ds} (h : CPRankMax1 x) :
    CPRankMax 1 x := by
  have h' := CPRankMax.succ 0 x 0 h CPRankMax.zero
  

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
x : Holor α ds
h : CPRankMax1 x
h' : CPRankMax (0 + 1) (x + 0)
⊢ CPRankMax 1 x

Next tactic:
rwa [zero_add, add_zero] at h'
theorem cprankMax_add [Monoid α] [AddMonoid α] :
    ∀ {m : ℕ} {n : ℕ} {x : Holor α ds} {y : Holor α ds},
      CPRankMax m x → CPRankMax n y → CPRankMax (m + n) (x + y)
  | 0, n, x, y, hx, hy => by
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
n : ℕ
x y : Holor α ds
hx : CPRankMax 0 x
hy : CPRankMax n y
⊢ CPRankMax (0 + n) (x + y)

Next tactic:
match hx with
    | CPRankMax.zero => simp only [zero_add, hy]
theorem cprankMax_add [Monoid α] [AddMonoid α] :
    ∀ {m : ℕ} {n : ℕ} {x : Holor α ds} {y : Holor α ds},
      CPRankMax m x → CPRankMax n y → CPRankMax (m + n) (x + y)
  | 0, n, x, y, hx, hy => by
    match hx with
    | CPRankMax.zero => 

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
n : ℕ
x y : Holor α ds
hx : CPRankMax 0 x
hy : CPRankMax n y
⊢ CPRankMax (0 + n) (0 + y)

Next tactic:
simp only [zero_add, hy]
theorem cprankMax_add [Monoid α] [AddMonoid α] :
    ∀ {m : ℕ} {n : ℕ} {x : Holor α ds} {y : Holor α ds},
      CPRankMax m x → CPRankMax n y → CPRankMax (m + n) (x + y)
  | 0, n, x, y, hx, hy => by
    match hx with
    | CPRankMax.zero => simp only [zero_add, hy]
  | m + 1, n, _, y, CPRankMax.succ _ x₁ x₂ hx₁ hx₂, hy => by
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
m n : ℕ
y x₁ x₂ : Holor α ds
hx₁ : CPRankMax1 x₁
hx₂ : CPRankMax m x₂
hy : CPRankMax n y
⊢ CPRankMax (m + 1 + n) (x₁ + x₂ + y)

Next tactic:
simp only [add_comm, add_assoc]
theorem cprankMax_add [Monoid α] [AddMonoid α] :
    ∀ {m : ℕ} {n : ℕ} {x : Holor α ds} {y : Holor α ds},
      CPRankMax m x → CPRankMax n y → CPRankMax (m + n) (x + y)
  | 0, n, x, y, hx, hy => by
    match hx with
    | CPRankMax.zero => simp only [zero_add, hy]
  | m + 1, n, _, y, CPRankMax.succ _ x₁ x₂ hx₁ hx₂, hy => by
    simp only [add_comm, add_assoc]
    

Proof state:
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
m n : ℕ
y x₁ x₂ : Holor α ds
hx₁ : CPRankMax1 x₁
hx₂ : CPRankMax m x₂
hy : CPRankMax n y
⊢ CPRankMax (n + (m + 1)) (x₁ + (x₂ + y))

Next tactic:
apply CPRankMax.succ
theorem cprankMax_add [Monoid α] [AddMonoid α] :
    ∀ {m : ℕ} {n : ℕ} {x : Holor α ds} {y : Holor α ds},
      CPRankMax m x → CPRankMax n y → CPRankMax (m + n) (x + y)
  | 0, n, x, y, hx, hy => by
    match hx with
    | CPRankMax.zero => simp only [zero_add, hy]
  | m + 1, n, _, y, CPRankMax.succ _ x₁ x₂ hx₁ hx₂, hy => by
    simp only [add_comm, add_assoc]
    apply CPRankMax.succ
    · 

Proof state:
case a
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
m n : ℕ
y x₁ x₂ : Holor α ds
hx₁ : CPRankMax1 x₁
hx₂ : CPRankMax m x₂
hy : CPRankMax n y
⊢ CPRankMax1 x₁

Next tactic:
assumption
theorem cprankMax_add [Monoid α] [AddMonoid α] :
    ∀ {m : ℕ} {n : ℕ} {x : Holor α ds} {y : Holor α ds},
      CPRankMax m x → CPRankMax n y → CPRankMax (m + n) (x + y)
  | 0, n, x, y, hx, hy => by
    match hx with
    | CPRankMax.zero => simp only [zero_add, hy]
  | m + 1, n, _, y, CPRankMax.succ _ x₁ x₂ hx₁ hx₂, hy => by
    simp only [add_comm, add_assoc]
    apply CPRankMax.succ
    · assumption
    · -- Porting note: Single line is added.
      

Proof state:
case a
α : Type
d : ℕ
ds ds₁ ds₂ ds₃ : List ℕ
inst✝¹ : Monoid α
inst✝ : AddMonoid α
m n : ℕ
y x₁ x₂ : Holor α ds
hx₁ : CPRankMax1 x₁
hx₂ : CPRankMax m x₂
hy : CPRankMax n y
⊢ CPRankMax (Nat.add n (Nat.add m 0)) (x₂ + y)

Next tactic:
simp only [Nat.add_eq, add_zero, add_comm n m]