l3lab/ntp-mathlib huggingface dataset:
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    

Proof state:
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(x_1 == x) = true

Next tactic:
intro y hy H
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    

Proof state:
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
y : α
hy : y ∈ hd
H : (y == x) = true
⊢ False

Next tactic:
rw [eq_of_beq H] at hy
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    

Proof state:
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
y : α
hy : x ∈ hd
H : (y == x) = true
⊢ False

Next tactic:
refine' hx hd _ hy
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    

Proof state:
case cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
y : α
hy : x ∈ hd
H : (y == x) = true
⊢ hd ∈ [hd]

Next tactic:
simp
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · 

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ splitOn x (join (intersperse [x] (hd :: head✝ :: tail✝))) = hd :: head✝ :: tail✝

Next tactic:
simp only [intersperse_cons_cons, singleton_append, join]
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝

Next tactic:
specialize ih _ _
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · 

Proof state:
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ ∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l

Next tactic:
intro l hl
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      

Proof state:
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
l : List α
hl : l ∈ head✝ :: tail✝
⊢ ¬x ∈ l

Next tactic:
apply hx l
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      

Proof state:
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
l : List α
hl : l ∈ head✝ :: tail✝
⊢ l ∈ hd :: head✝ :: tail✝

Next tactic:
simp only [mem_cons] at hl ⊢
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      

Proof state:
case cons.cons.specialize_1
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
l : List α
hl : l = head✝ ∨ l ∈ tail✝
⊢ l = hd ∨ l = head✝ ∨ l ∈ tail✝

Next tactic:
exact Or.inr hl
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · 

Proof state:
case cons.cons.specialize_2
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
ih :
  (∀ (l : List α), l ∈ head✝ :: tail✝ → ¬x ∈ l) →
    head✝ :: tail✝ ≠ [] → splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
⊢ head✝ :: tail✝ ≠ []

Next tactic:
exact List.noConfusion
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝

Next tactic:
have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
this : ∀ (as : List α), splitOnP (fun x_1 => x_1 == x) (hd ++ x :: as) = hd :: splitOnP (fun x_1 => x_1 == x) as
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(fun x_2 => x_2 == x) x_1 = true

Next tactic:
case h =>
      intro y hy H
      rw [eq_of_beq H] at hy
      exact hx hd (.head _) hy
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(fun x_2 => x_2 == x) x_1 = true

Next tactic:
case h =>
      intro y hy H
      rw [eq_of_beq H] at hy
      exact hx hd (.head _) hy
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    case h =>
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
⊢ ∀ (x_1 : α), x_1 ∈ hd → ¬(fun x_2 => x_2 == x) x_1 = true

Next tactic:
intro y hy H
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    case h =>
      intro y hy H
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
y : α
hy : y ∈ hd
H : (fun x_1 => x_1 == x) y = true
⊢ False

Next tactic:
rw [eq_of_beq H] at hy
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    case h =>
      intro y hy H
      rw [eq_of_beq H] at hy
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
y : α
hy : x ∈ hd
H : (fun x_1 => x_1 == x) y = true
⊢ False

Next tactic:
exact hx hd (.head _) hy
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    case h =>
      intro y hy H
      rw [eq_of_beq H] at hy
      exact hx hd (.head _) hy
    

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOn x (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
this : ∀ (as : List α), splitOnP (fun x_1 => x_1 == x) (hd ++ x :: as) = hd :: splitOnP (fun x_1 => x_1 == x) as
⊢ splitOn x (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝

Next tactic:
simp only [splitOn] at ih ⊢
/-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain
  consisting of each nonempty list of lists `ls` whose elements do not contain `x`  -/
theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ l) (hls : ls ≠ []) :
    ([x].intercalate ls).splitOn x = ls := by
  simp only [intercalate]
  induction' ls with hd tl ih; · contradiction
  cases tl
  · suffices hd.splitOn x = [hd] by simpa [join]
    refine' splitOnP_eq_single _ _ _
    intro y hy H
    rw [eq_of_beq H] at hy
    refine' hx hd _ hy
    simp
  · simp only [intersperse_cons_cons, singleton_append, join]
    specialize ih _ _
    · intro l hl
      apply hx l
      simp only [mem_cons] at hl ⊢
      exact Or.inr hl
    · exact List.noConfusion
    have := splitOnP_first (· == x) hd ?h x (beq_self_eq_true _)
    case h =>
      intro y hy H
      rw [eq_of_beq H] at hy
      exact hx hd (.head _) hy
    simp only [splitOn] at ih ⊢
    

Proof state:
case cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
inst✝ : DecidableEq α
x : α
hd head✝ : List α
tail✝ : List (List α)
hx : ∀ (l : List α), l ∈ hd :: head✝ :: tail✝ → ¬x ∈ l
hls : hd :: head✝ :: tail✝ ≠ []
ih : splitOnP (fun x_1 => x_1 == x) (join (intersperse [x] (head✝ :: tail✝))) = head✝ :: tail✝
this : ∀ (as : List α), splitOnP (fun x_1 => x_1 == x) (hd ++ x :: as) = hd :: splitOnP (fun x_1 => x_1 == x) as
⊢ splitOnP (fun x_1 => x_1 == x) (hd ++ x :: join (intersperse [x] (head✝ :: tail✝))) = hd :: head✝ :: tail✝

Next tactic:
rw [this, ih]