l3lab/ntp-mathlib huggingface dataset:
theorem ne_single_iff {n : ℕ} (hn : 0 < n) {c : Composition n} :
    c ≠ single n hn ↔ ∀ i, c.blocksFun i < n := by
  rw [← not_iff_not]
  push_neg
  constructor
  · rintro rfl
    exact ⟨⟨0, by simp⟩, by simp⟩
  · rintro ⟨i, hi⟩
    rw [eq_single_iff_length]
    have : ∀ j : Fin c.length, j = i := by
      intro j
      by_contra ji
      

Proof state:
n✝ : ℕ
c✝ : Composition n✝
n : ℕ
hn : 0 < n
c : Composition n
i : Fin (length c)
hi : n ≤ blocksFun c i
j : Fin (length c)
ji : ¬j = i
⊢ False

Next tactic:
apply lt_irrefl (∑ k, c.blocksFun k)
theorem ne_single_iff {n : ℕ} (hn : 0 < n) {c : Composition n} :
    c ≠ single n hn ↔ ∀ i, c.blocksFun i < n := by
  rw [← not_iff_not]
  push_neg
  constructor
  · rintro rfl
    exact ⟨⟨0, by simp⟩, by simp⟩
  · rintro ⟨i, hi⟩
    rw [eq_single_iff_length]
    have : ∀ j : Fin c.length, j = i := by
      intro j
      by_contra ji
      apply lt_irrefl (∑ k, c.blocksFun k)
      

Proof state:
n✝ : ℕ
c✝ : Composition n✝
n : ℕ
hn : 0 < n
c : Composition n
i : Fin (length c)
hi : n ≤ blocksFun c i
j : Fin (length c)
ji : ¬j = i
⊢ ∑ k : Fin (length c), blocksFun c k < ∑ k : Fin (length c), blocksFun c k

Next tactic:
calc
        ∑ k, c.blocksFun k ≤ c.blocksFun i := by simp only [c.sum_blocksFun, hi]
        _ < ∑ k, c.blocksFun k :=
          Finset.single_lt_sum ji (Finset.mem_univ _) (Finset.mem_univ _) (c.one_le_blocksFun j)
            fun _ _ _ => zero_le _
theorem ne_single_iff {n : ℕ} (hn : 0 < n) {c : Composition n} :
    c ≠ single n hn ↔ ∀ i, c.blocksFun i < n := by
  rw [← not_iff_not]
  push_neg
  constructor
  · rintro rfl
    exact ⟨⟨0, by simp⟩, by simp⟩
  · rintro ⟨i, hi⟩
    rw [eq_single_iff_length]
    have : ∀ j : Fin c.length, j = i := by
      intro j
      by_contra ji
      apply lt_irrefl (∑ k, c.blocksFun k)
      calc
        ∑ k, c.blocksFun k ≤ c.blocksFun i := by 

Proof state:
n✝ : ℕ
c✝ : Composition n✝
n : ℕ
hn : 0 < n
c : Composition n
i : Fin (length c)
hi : n ≤ blocksFun c i
j : Fin (length c)
ji : ¬j = i
⊢ ∑ k : Fin (length c), blocksFun c k ≤ blocksFun c i

Next tactic:
simp only [c.sum_blocksFun, hi]
theorem ne_single_iff {n : ℕ} (hn : 0 < n) {c : Composition n} :
    c ≠ single n hn ↔ ∀ i, c.blocksFun i < n := by
  rw [← not_iff_not]
  push_neg
  constructor
  · rintro rfl
    exact ⟨⟨0, by simp⟩, by simp⟩
  · rintro ⟨i, hi⟩
    rw [eq_single_iff_length]
    have : ∀ j : Fin c.length, j = i := by
      intro j
      by_contra ji
      apply lt_irrefl (∑ k, c.blocksFun k)
      calc
        ∑ k, c.blocksFun k ≤ c.blocksFun i := by simp only [c.sum_blocksFun, hi]
        _ < ∑ k, c.blocksFun k :=
          Finset.single_lt_sum ji (Finset.mem_univ _) (Finset.mem_univ _) (c.one_le_blocksFun j)
            fun _ _ _ => zero_le _

    

Proof state:
case mpr.intro
n✝ : ℕ
c✝ : Composition n✝
n : ℕ
hn : 0 < n
c : Composition n
i : Fin (length c)
hi : n ≤ blocksFun c i
this : ∀ (j : Fin (length c)), j = i
⊢ length c = 1

Next tactic:
simpa using Fintype.card_eq_one_of_forall_eq this
@[local simp]
theorem splitWrtCompositionAux_cons (l : List α) (n ns) :
    l.splitWrtCompositionAux (n::ns) = take n l::(drop n l).splitWrtCompositionAux ns := by
  

Proof state:
n✝ : ℕ
α : Type u_1
l : List α
n : ℕ
ns : List ℕ
⊢ splitWrtCompositionAux l (n :: ns) = take n l :: splitWrtCompositionAux (drop n l) ns

Next tactic:
simp [splitWrtCompositionAux]
theorem length_splitWrtCompositionAux (l : List α) (ns) :
    length (l.splitWrtCompositionAux ns) = ns.length := by
    

Proof state:
n : ℕ
α : Type u_1
l : List α
ns : List ℕ
⊢ length (splitWrtCompositionAux l ns) = length ns

Next tactic:
induction ns generalizing l
theorem length_splitWrtCompositionAux (l : List α) (ns) :
    length (l.splitWrtCompositionAux ns) = ns.length := by
    induction ns generalizing l
    · 

Proof state:
case nil
n : ℕ
α : Type u_1
l : List α
⊢ length (splitWrtCompositionAux l []) = length []

Next tactic:
simp [splitWrtCompositionAux, *]
theorem length_splitWrtCompositionAux (l : List α) (ns) :
    length (l.splitWrtCompositionAux ns) = ns.length := by
    induction ns generalizing l
    · simp [splitWrtCompositionAux, *]
    · 

Proof state:
case cons
n : ℕ
α : Type u_1
head✝ : ℕ
tail✝ : List ℕ
tail_ih✝ : ∀ (l : List α), length (splitWrtCompositionAux l tail✝) = length tail✝
l : List α
⊢ length (splitWrtCompositionAux l (head✝ :: tail✝)) = length (head✝ :: tail✝)

Next tactic:
simp [*]
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  

Proof state:
n : ℕ
α : Type u_1
ns : List ℕ
⊢ ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns

Next tactic:
induction' ns with n ns IH
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> 

Proof state:
case nil
n : ℕ
α : Type u_1
⊢ ∀ {l : List α}, sum [] ≤ length l → map length (splitWrtCompositionAux l []) = []

Next tactic:
intro l h
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
⊢ ∀ {l : List α}, sum (n :: ns) ≤ length l → map length (splitWrtCompositionAux l (n :: ns)) = n :: ns

Next tactic:
intro l h
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> 

Proof state:
case nil
n : ℕ
α : Type u_1
l : List α
h : sum [] ≤ length l
⊢ map length (splitWrtCompositionAux l []) = []

Next tactic:
simp at h
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : sum (n :: ns) ≤ length l
⊢ map length (splitWrtCompositionAux l (n :: ns)) = n :: ns

Next tactic:
simp at h
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · 

Proof state:
case nil
n : ℕ
α : Type u_1
l : List α
h : True
⊢ map length (splitWrtCompositionAux l []) = []

Next tactic:
simp [splitWrtCompositionAux]
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
⊢ map length (splitWrtCompositionAux l (n :: ns)) = n :: ns

Next tactic:
have := le_trans (Nat.le_add_right _ _) h
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ map length (splitWrtCompositionAux l (n :: ns)) = n :: ns

Next tactic:
simp only [splitWrtCompositionAux_cons, this]
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  simp only [splitWrtCompositionAux_cons, this]; 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ map length (take n l :: splitWrtCompositionAux (drop n l) ns) = n :: ns

Next tactic:
dsimp
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  simp only [splitWrtCompositionAux_cons, this]; dsimp
  

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ length (take n l) :: map length (splitWrtCompositionAux (drop n l) ns) = n :: ns

Next tactic:
rw [length_take, IH]
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  simp only [splitWrtCompositionAux_cons, this]; dsimp
  rw [length_take, IH] <;> 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ min n (length l) :: ns = n :: ns

Next tactic:
simp [length_drop]
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  simp only [splitWrtCompositionAux_cons, this]; dsimp
  rw [length_take, IH] <;> 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ sum ns ≤ length (drop n l)

Next tactic:
simp [length_drop]
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  simp only [splitWrtCompositionAux_cons, this]; dsimp
  rw [length_take, IH] <;> simp [length_drop]
  · 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ n ≤ length l

Next tactic:
assumption
theorem map_length_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum ≤ l.length → map length (l.splitWrtCompositionAux ns) = ns := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · simp [splitWrtCompositionAux]
  have := le_trans (Nat.le_add_right _ _) h
  simp only [splitWrtCompositionAux_cons, this]; dsimp
  rw [length_take, IH] <;> simp [length_drop]
  · assumption
  · 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns ≤ length l → map length (splitWrtCompositionAux l ns) = ns
l : List α
h : n + sum ns ≤ length l
this : n ≤ length l
⊢ sum ns ≤ length l - n

Next tactic:
exact le_tsub_of_add_le_left h
theorem length_pos_of_mem_splitWrtComposition {l l' : List α} {c : Composition l.length}
    (h : l' ∈ l.splitWrtComposition c) : 0 < length l' := by
  

Proof state:
n : ℕ
α : Type u_1
l l' : List α
c : Composition (length l)
h : l' ∈ splitWrtComposition l c
⊢ 0 < length l'

Next tactic:
have : l'.length ∈ (l.splitWrtComposition c).map List.length :=
    List.mem_map_of_mem List.length h
theorem length_pos_of_mem_splitWrtComposition {l l' : List α} {c : Composition l.length}
    (h : l' ∈ l.splitWrtComposition c) : 0 < length l' := by
  have : l'.length ∈ (l.splitWrtComposition c).map List.length :=
    List.mem_map_of_mem List.length h
  

Proof state:
n : ℕ
α : Type u_1
l l' : List α
c : Composition (length l)
h : l' ∈ splitWrtComposition l c
this : length l' ∈ map length (splitWrtComposition l c)
⊢ 0 < length l'

Next tactic:
rw [map_length_splitWrtComposition] at this
theorem length_pos_of_mem_splitWrtComposition {l l' : List α} {c : Composition l.length}
    (h : l' ∈ l.splitWrtComposition c) : 0 < length l' := by
  have : l'.length ∈ (l.splitWrtComposition c).map List.length :=
    List.mem_map_of_mem List.length h
  rw [map_length_splitWrtComposition] at this
  

Proof state:
n : ℕ
α : Type u_1
l l' : List α
c : Composition (length l)
h : l' ∈ splitWrtComposition l c
this : length l' ∈ c.blocks
⊢ 0 < length l'

Next tactic:
exact c.blocks_pos this
theorem sum_take_map_length_splitWrtComposition (l : List α) (c : Composition l.length) (i : ℕ) :
    (((l.splitWrtComposition c).map length).take i).sum = c.sizeUpTo i := by
  

Proof state:
n : ℕ
α : Type u_1
l : List α
c : Composition (length l)
i : ℕ
⊢ sum (take i (map length (splitWrtComposition l c))) = Composition.sizeUpTo c i

Next tactic:
congr
theorem sum_take_map_length_splitWrtComposition (l : List α) (c : Composition l.length) (i : ℕ) :
    (((l.splitWrtComposition c).map length).take i).sum = c.sizeUpTo i := by
  congr
  

Proof state:
case e_a.e_a
n : ℕ
α : Type u_1
l : List α
c : Composition (length l)
i : ℕ
⊢ map length (splitWrtComposition l c) = c.blocks

Next tactic:
exact map_length_splitWrtComposition l c
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  

Proof state:
n : ℕ
α : Type u_1
l : List α
ns : List ℕ
i : ℕ
hi : i < length (splitWrtCompositionAux l ns)
⊢ get (splitWrtCompositionAux l ns) { val := i, isLt := hi } = drop (sum (take i ns)) (take (sum (take (i + 1) ns)) l)

Next tactic:
induction' ns with n ns IH generalizing l i
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  induction' ns with n ns IH generalizing l i
  · 

Proof state:
case nil
n : ℕ
α : Type u_1
l : List α
i : ℕ
hi : i < length (splitWrtCompositionAux l [])
⊢ get (splitWrtCompositionAux l []) { val := i, isLt := hi } = drop (sum (take i [])) (take (sum (take (i + 1) [])) l)

Next tactic:
cases hi
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  induction' ns with n ns IH generalizing l i
  · cases hi
  

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH :
  ∀ (l : List α) {i : ℕ} (hi : i < length (splitWrtCompositionAux l ns)),
    get (splitWrtCompositionAux l ns) { val := i, isLt := hi } = drop (sum (take i ns)) (take (sum (take (i + 1) ns)) l)
l : List α
i : ℕ
hi : i < length (splitWrtCompositionAux l (n :: ns))
⊢ get (splitWrtCompositionAux l (n :: ns)) { val := i, isLt := hi } =
    drop (sum (take i (n :: ns))) (take (sum (take (i + 1) (n :: ns))) l)

Next tactic:
cases' i with i
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  induction' ns with n ns IH generalizing l i
  · cases hi
  cases' i with i
  · 

Proof state:
case cons.zero
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH :
  ∀ (l : List α) {i : ℕ} (hi : i < length (splitWrtCompositionAux l ns)),
    get (splitWrtCompositionAux l ns) { val := i, isLt := hi } = drop (sum (take i ns)) (take (sum (take (i + 1) ns)) l)
l : List α
hi : Nat.zero < length (splitWrtCompositionAux l (n :: ns))
⊢ get (splitWrtCompositionAux l (n :: ns)) { val := Nat.zero, isLt := hi } =
    drop (sum (take Nat.zero (n :: ns))) (take (sum (take (Nat.zero + 1) (n :: ns))) l)

Next tactic:
rw [Nat.add_zero, List.take_zero, sum_nil]
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  induction' ns with n ns IH generalizing l i
  · cases hi
  cases' i with i
  · rw [Nat.add_zero, List.take_zero, sum_nil]
    

Proof state:
case cons.zero
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH :
  ∀ (l : List α) {i : ℕ} (hi : i < length (splitWrtCompositionAux l ns)),
    get (splitWrtCompositionAux l ns) { val := i, isLt := hi } = drop (sum (take i ns)) (take (sum (take (i + 1) ns)) l)
l : List α
hi : Nat.zero < length (splitWrtCompositionAux l (n :: ns))
⊢ get (splitWrtCompositionAux l (n :: ns)) { val := Nat.zero, isLt := hi } = drop 0 (take (sum (take 1 (n :: ns))) l)

Next tactic:
simpa using get_zero hi
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  induction' ns with n ns IH generalizing l i
  · cases hi
  cases' i with i
  · rw [Nat.add_zero, List.take_zero, sum_nil]
    simpa using get_zero hi
  · 

Proof state:
case cons.succ
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH :
  ∀ (l : List α) {i : ℕ} (hi : i < length (splitWrtCompositionAux l ns)),
    get (splitWrtCompositionAux l ns) { val := i, isLt := hi } = drop (sum (take i ns)) (take (sum (take (i + 1) ns)) l)
l : List α
i : ℕ
hi : Nat.succ i < length (splitWrtCompositionAux l (n :: ns))
⊢ get (splitWrtCompositionAux l (n :: ns)) { val := Nat.succ i, isLt := hi } =
    drop (sum (take (Nat.succ i) (n :: ns))) (take (sum (take (Nat.succ i + 1) (n :: ns))) l)

Next tactic:
simp only [splitWrtCompositionAux._eq_2, get_cons_succ, IH, take,
        sum_cons, Nat.add_eq, add_zero, splitAt_eq_take_drop, ← drop_take, drop_drop]
theorem get_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} (hi) :
    (l.splitWrtCompositionAux ns).get ⟨i, hi⟩  =
      (l.take (ns.take (i + 1)).sum).drop (ns.take i).sum := by
  induction' ns with n ns IH generalizing l i
  · cases hi
  cases' i with i
  · rw [Nat.add_zero, List.take_zero, sum_nil]
    simpa using get_zero hi
  · simp only [splitWrtCompositionAux._eq_2, get_cons_succ, IH, take,
        sum_cons, Nat.add_eq, add_zero, splitAt_eq_take_drop, ← drop_take, drop_drop]
    

Proof state:
case cons.succ
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH :
  ∀ (l : List α) {i : ℕ} (hi : i < length (splitWrtCompositionAux l ns)),
    get (splitWrtCompositionAux l ns) { val := i, isLt := hi } = drop (sum (take i ns)) (take (sum (take (i + 1) ns)) l)
l : List α
i : ℕ
hi : Nat.succ i < length (splitWrtCompositionAux l (n :: ns))
⊢ drop (sum (take i ns) + n) (take (n + sum (take (i + 1) ns)) l) =
    drop (n + sum (take i ns)) (take (n + sum (take (Nat.succ i) ns)) l)

Next tactic:
rw [Nat.succ_eq_add_one, add_comm i 1, add_comm]
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  

Proof state:
n : ℕ
α : Type u_1
ns : List ℕ
⊢ ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l

Next tactic:
induction' ns with n ns IH
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> 

Proof state:
case nil
n : ℕ
α : Type u_1
⊢ ∀ {l : List α}, sum [] = length l → join (splitWrtCompositionAux l []) = l

Next tactic:
intro l h
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
⊢ ∀ {l : List α}, sum (n :: ns) = length l → join (splitWrtCompositionAux l (n :: ns)) = l

Next tactic:
intro l h
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> 

Proof state:
case nil
n : ℕ
α : Type u_1
l : List α
h : sum [] = length l
⊢ join (splitWrtCompositionAux l []) = l

Next tactic:
simp at h
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
l : List α
h : sum (n :: ns) = length l
⊢ join (splitWrtCompositionAux l (n :: ns)) = l

Next tactic:
simp at h
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · 

Proof state:
case nil
n : ℕ
α : Type u_1
l : List α
h : 0 = length l
⊢ join (splitWrtCompositionAux l []) = l

Next tactic:
exact (length_eq_zero.1 h.symm).symm
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · exact (length_eq_zero.1 h.symm).symm
  

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
l : List α
h : n + sum ns = length l
⊢ join (splitWrtCompositionAux l (n :: ns)) = l

Next tactic:
simp only [splitWrtCompositionAux_cons]
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · exact (length_eq_zero.1 h.symm).symm
  simp only [splitWrtCompositionAux_cons]; 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
l : List α
h : n + sum ns = length l
⊢ join (take n l :: splitWrtCompositionAux (drop n l) ns) = l

Next tactic:
dsimp
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · exact (length_eq_zero.1 h.symm).symm
  simp only [splitWrtCompositionAux_cons]; dsimp
  

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
l : List α
h : n + sum ns = length l
⊢ take n l ++ join (splitWrtCompositionAux (drop n l) ns) = l

Next tactic:
rw [IH]
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · exact (length_eq_zero.1 h.symm).symm
  simp only [splitWrtCompositionAux_cons]; dsimp
  rw [IH]
  · 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
l : List α
h : n + sum ns = length l
⊢ take n l ++ drop n l = l

Next tactic:
simp
theorem join_splitWrtCompositionAux {ns : List ℕ} :
    ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by
  induction' ns with n ns IH <;> intro l h <;> simp at h
  · exact (length_eq_zero.1 h.symm).symm
  simp only [splitWrtCompositionAux_cons]; dsimp
  rw [IH]
  · simp
  · 

Proof state:
case cons
n✝ : ℕ
α : Type u_1
n : ℕ
ns : List ℕ
IH : ∀ {l : List α}, sum ns = length l → join (splitWrtCompositionAux l ns) = l
l : List α
h : n + sum ns = length l
⊢ sum ns = length (drop n l)

Next tactic:
rw [length_drop, ← h, add_tsub_cancel_left]