l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; 

Proof state:
case pos.zero.x_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
h₁ : xs = []
⊢ False

Next tactic:
rw [h₁] at h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; 

Proof state:
case pos.zero.x_4
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length []
h₁ : xs = []
⊢ False

Next tactic:
contradiction
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · 

Proof state:
case pos.zero.x_5
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
⊢ ∀ (x : α) (xs_1 : List α) (n : ℕ), xs = x :: xs_1 → zero = succ n → False

Next tactic:
intros
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; 

Proof state:
case pos.zero.x_5
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : zero < length xs
x✝ : α
xs_1✝ : List α
n✝ : ℕ
x_1✝ : xs = x✝ :: xs_1✝
x_2✝ : zero = succ n✝
⊢ False

Next tactic:
contradiction
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      

Proof state:
case pos.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
xs : List α
acc : Array α
h : succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (Array.toList acc ++ take (succ n✝) xs, drop (succ n✝) xs)

Next tactic:
| succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        

Proof state:
case pos.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
xs : List α
acc : Array α
h : succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (Array.toList acc ++ take (succ n✝) xs, drop (succ n✝) xs)

Next tactic:
cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        

Proof state:
case pos.succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
h : succ n✝ < length []
⊢ splitAt.go l [] (succ n✝) acc = (Array.toList acc ++ take (succ n✝) [], drop (succ n✝) [])

Next tactic:
| nil => contradiction
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => 

Proof state:
case pos.succ.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
h : succ n✝ < length []
⊢ splitAt.go l [] (succ n✝) acc = (Array.toList acc ++ take (succ n✝) [], drop (succ n✝) [])

Next tactic:
contradiction
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        

Proof state:
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : succ n✝ < length (hd :: tl)
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (Array.toList acc ++ take (succ n✝) (hd :: tl), drop (succ n✝) (hd :: tl))

Next tactic:
| cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          

Proof state:
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : succ n✝ < length (hd :: tl)
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (Array.toList acc ++ take (succ n✝) (hd :: tl), drop (succ n✝) (hd :: tl))

Next tactic:
rw [length, succ_eq_add_one] at h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          

Proof state:
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : n✝ + 1 < length tl + 1
⊢ splitAt.go l (hd :: tl) (succ n✝) acc = (Array.toList acc ++ take (succ n✝) (hd :: tl), drop (succ n✝) (hd :: tl))

Next tactic:
rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          

Proof state:
case pos.succ.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih :
  ∀ (xs : List α) (acc : Array α),
    n✝ < length xs → splitAt.go l xs n✝ acc = (Array.toList acc ++ take n✝ xs, drop n✝ xs)
acc : Array α
hd : α
tl : List α
h : n✝ + 1 < length tl + 1
⊢ splitAt.go l tl n✝ (Array.push acc hd) = (Array.toList (Array.push acc hd) ++ take n✝ tl, drop n✝ tl)

Next tactic:
exact ih _ _ <| lt_of_add_lt_add_right h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
    · 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n✝ : ℕ
l✝ : List α
n : ℕ
l xs : List α
acc : Array α
h : ¬n < length xs
⊢ splitAt.go l xs n acc = (l, [])

Next tactic:
induction n generalizing xs acc with
      | zero =>
        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
        rw [eq_nil_of_length_eq_zero h, splitAt.go]
      | succ _ ih =>
        cases xs with
        | nil => rw [splitAt.go]
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go]
          exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
    · induction n generalizing xs acc with
      

Proof state:
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : ¬zero < length xs
⊢ splitAt.go l xs zero acc = (l, [])

Next tactic:
| zero =>
        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
        rw [eq_nil_of_length_eq_zero h, splitAt.go]
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
    · induction n generalizing xs acc with
      | zero =>
        

Proof state:
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : ¬zero < length xs
⊢ splitAt.go l xs zero acc = (l, [])

Next tactic:
rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
    · induction n generalizing xs acc with
      | zero =>
        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
        

Proof state:
case neg.zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l xs : List α
acc : Array α
h : length xs = 0
⊢ splitAt.go l xs zero acc = (l, [])

Next tactic:
rw [eq_nil_of_length_eq_zero h, splitAt.go]
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
    · induction n generalizing xs acc with
      | zero =>
        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
        rw [eq_nil_of_length_eq_zero h, splitAt.go]
      

Proof state:
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
xs : List α
acc : Array α
h : ¬succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (l, [])

Next tactic:
| succ _ ih =>
        cases xs with
        | nil => rw [splitAt.go]
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go]
          exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h
@[simp]
theorem splitAt_eq_take_drop (n : ℕ) (l : List α) : splitAt n l = (take n l, drop n l) := by
  by_cases h : n < l.length <;> rw [splitAt, go_eq_take_drop]
  · rw [if_pos h]; rfl
  · rw [if_neg h, take_all_of_le <| le_of_not_lt h, drop_eq_nil_of_le <| le_of_not_lt h]
where
  go_eq_take_drop (n : ℕ) (l xs : List α) (acc : Array α) : splitAt.go l xs n acc =
      if n < xs.length then (acc.toList ++ take n xs, drop n xs) else (l, []) := by
    split_ifs with h
    · induction n generalizing xs acc with
      | zero =>
        rw [splitAt.go, take, drop, append_nil]
        · intros h₁; rw [h₁] at h; contradiction
        · intros; contradiction
      | succ _ ih =>
        cases xs with
        | nil => contradiction
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go, take, drop, append_cons, Array.toList_eq, ← Array.push_data,
            ← Array.toList_eq]
          exact ih _ _ <| lt_of_add_lt_add_right h
    · induction n generalizing xs acc with
      | zero =>
        rw [zero_eq, not_lt, nonpos_iff_eq_zero] at h
        rw [eq_nil_of_length_eq_zero h, splitAt.go]
      | succ _ ih =>
        

Proof state:
case neg.succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs✝ ys : List α
ls : List (List α)
f : List α → List α
n : ℕ
l✝ l : List α
n✝ : ℕ
ih : ∀ (xs : List α) (acc : Array α), ¬n✝ < length xs → splitAt.go l xs n✝ acc = (l, [])
xs : List α
acc : Array α
h : ¬succ n✝ < length xs
⊢ splitAt.go l xs (succ n✝) acc = (l, [])

Next tactic:
cases xs with
        | nil => rw [splitAt.go]
        | cons hd tl =>
          rw [length, succ_eq_add_one] at h
          rw [splitAt.go]
          exact ih _ _ <| not_imp_not.mpr (Nat.add_lt_add_right · 1) h