l3lab/ntp-mathlib huggingface dataset:
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  

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 α
h : ∀ (x : α), x ∈ xs → ¬p x = true
⊢ splitOnP p xs = [xs]

Next tactic:
induction xs with
  | nil => rfl
  | cons hd tl ih =>
    simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
    rw [ih <| forall_mem_of_forall_mem_cons h]
    rfl
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  induction xs with
  

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p [] = [[]]

Next tactic:
| nil => rfl
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  induction xs with
  | nil => 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p [] = [[]]

Next tactic:
rfl
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  induction xs with
  | nil => rfl
  

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl) = [hd :: tl]

Next tactic:
| cons hd tl ih =>
    simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
    rw [ih <| forall_mem_of_forall_mem_cons h]
    rfl
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  induction xs with
  | nil => rfl
  | cons hd tl ih =>
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl) = [hd :: tl]

Next tactic:
simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  induction xs with
  | nil => rfl
  | cons hd tl ih =>
    simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ (if False then [] :: splitOnP p tl else modifyHead (cons hd) (splitOnP p tl)) = [hd :: tl]

Next tactic:
rw [ih <| forall_mem_of_forall_mem_cons h]
/-- If no element satisfies `p` in the list `xs`, then `xs.splitOnP p = [xs]` -/
theorem splitOnP_eq_single (h : ∀ x ∈ xs, ¬p x) : xs.splitOnP p = [xs] := by
  induction xs with
  | nil => rfl
  | cons hd tl ih =>
    simp only [splitOnP_cons, h hd (mem_cons_self hd tl), if_neg]
    rw [ih <| forall_mem_of_forall_mem_cons h]
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p tl = [tl]
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ (if False then [[], tl] else modifyHead (cons hd) [tl]) = [hd :: tl]

Next tactic:
rfl
/-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
  assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by
  

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 α
h : ∀ (x : α), x ∈ xs → ¬p x = true
sep : α
hsep : p sep = true
as : List α
⊢ splitOnP p (xs ++ sep :: as) = xs :: splitOnP p as

Next tactic:
induction xs with
  | nil => simp [hsep]
  | cons hd tl ih => simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
/-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
  assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by
  induction xs with
  

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p ([] ++ sep :: as) = [] :: splitOnP p as

Next tactic:
| nil => simp [hsep]
/-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
  assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by
  induction xs with
  | nil => 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
h : ∀ (x : α), x ∈ [] → ¬p x = true
⊢ splitOnP p ([] ++ sep :: as) = [] :: splitOnP p as

Next tactic:
simp [hsep]
/-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
  assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by
  induction xs with
  | nil => simp [hsep]
  

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p (tl ++ sep :: as) = tl :: splitOnP p as
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl ++ sep :: as) = (hd :: tl) :: splitOnP p as

Next tactic:
| cons hd tl ih => simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
/-- When a list of the form `[...xs, sep, ...as]` is split on `p`, the first element is `xs`,
  assuming no element in `xs` satisfies `p` but `sep` does satisfy `p` -/
theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : List α) :
    (xs ++ sep :: as).splitOnP p = xs :: as.splitOnP p := by
  induction xs with
  | nil => simp [hsep]
  | cons hd tl ih => 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
sep : α
hsep : p sep = true
as : List α
hd : α
tl : List α
ih : (∀ (x : α), x ∈ tl → ¬p x = true) → splitOnP p (tl ++ sep :: as) = tl :: splitOnP p as
h : ∀ (x : α), x ∈ hd :: tl → ¬p x = true
⊢ splitOnP p (hd :: tl ++ sep :: as) = (hd :: tl) :: splitOnP p as

Next tactic:
simp [h hd _, ih <| forall_mem_of_forall_mem_cons h]
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  

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 α
x : α
inst✝ : DecidableEq α
⊢ intercalate [x] (splitOn x xs) = xs

Next tactic:
simp only [intercalate, splitOn]
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  

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 α
x : α
inst✝ : DecidableEq α
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) xs)) = xs

Next tactic:
induction' xs with hd tl ih
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) [])) = []

Next tactic:
simp [join]
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl : List α
ih : join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) tl)) = tl
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl

Next tactic:
cases' h' : splitOnP (· == x) tl with hd' tl'
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · 

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 α
x : α
inst✝ : DecidableEq α
hd : α
tl : List α
ih : join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) tl)) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = []
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl

Next tactic:
exact (splitOnP_ne_nil _ tl h').elim
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  

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 α
x : α
inst✝ : DecidableEq α
hd : α
tl : List α
ih : join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) tl)) = tl
hd' : List α
tl' : List (List α)
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl

Next tactic:
rw [h'] at ih
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] 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 α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
⊢ join (intersperse [x] (splitOnP (fun x_1 => x_1 == x) (hd :: tl))) = hd :: tl

Next tactic:
rw [splitOnP_cons]
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  

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 α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
⊢ join
      (intersperse [x]
        (if (hd == x) = true then [] :: splitOnP (fun x_1 => x_1 == x) tl
        else modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) =
    hd :: tl

Next tactic:
split_ifs with h
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  split_ifs with h
  · 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
h : (hd == x) = true
⊢ join (intersperse [x] ([] :: splitOnP (fun x_1 => x_1 == x) tl)) = hd :: tl

Next tactic:
rw [beq_iff_eq] at h
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  split_ifs with h
  · rw [beq_iff_eq] at h
    

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
h : hd = x
⊢ join (intersperse [x] ([] :: splitOnP (fun x_1 => x_1 == x) tl)) = hd :: tl

Next tactic:
subst h
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  split_ifs with h
  · rw [beq_iff_eq] at h
    subst h
    

Proof state:
case pos
ι : 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 α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [hd] (hd' :: tl')) = tl
h' : splitOnP (fun x => x == hd) tl = hd' :: tl'
⊢ join (intersperse [hd] ([] :: splitOnP (fun x => x == hd) tl)) = hd :: tl

Next tactic:
simp [ih, join, h']
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  split_ifs with h
  · rw [beq_iff_eq] at h
    subst h
    simp [ih, join, 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 α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
tl' : List (List α)
ih : join (intersperse [x] (hd' :: tl')) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: tl'
h : ¬(hd == x) = true
⊢ join (intersperse [x] (modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) = hd :: tl

Next tactic:
cases tl'
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  split_ifs with h
  · rw [beq_iff_eq] at h
    subst h
    simp [ih, join, h']
  cases tl' <;> 

Proof state:
case neg.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
h : ¬(hd == x) = true
ih : join (intersperse [x] [hd']) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = [hd']
⊢ join (intersperse [x] (modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) = hd :: tl

Next tactic:
simpa [join, h'] using ih
/-- `intercalate [x]` is the left inverse of `splitOn x`  -/
theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by
  simp only [intercalate, splitOn]
  induction' xs with hd tl ih; · simp [join]
  cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim
  rw [h'] at ih
  rw [splitOnP_cons]
  split_ifs with h
  · rw [beq_iff_eq] at h
    subst h
    simp [ih, join, h']
  cases tl' <;> 

Proof state:
case neg.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Bool
xs ys : List α
ls : List (List α)
f : List α → List α
x : α
inst✝ : DecidableEq α
hd : α
tl hd' : List α
h : ¬(hd == x) = true
head✝ : List α
tail✝ : List (List α)
ih : join (intersperse [x] (hd' :: head✝ :: tail✝)) = tl
h' : splitOnP (fun x_1 => x_1 == x) tl = hd' :: head✝ :: tail✝
⊢ join (intersperse [x] (modifyHead (cons hd) (splitOnP (fun x_1 => x_1 == x) tl))) = hd :: tl

Next tactic:
simpa [join, h'] using 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
  

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 : α
hx : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls : ls ≠ []
⊢ splitOn x (intercalate [x] ls) = ls

Next tactic:
simp only [intercalate]
/-- `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]
  

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 : α
hx : ∀ (l : List α), l ∈ ls → ¬x ∈ l
hls : ls ≠ []
⊢ splitOn x (join (intersperse [x] ls)) = ls

Next tactic:
induction' ls with hd tl 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; · 

Proof state:
case 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 : α
hx : ∀ (l : List α), l ∈ [] → ¬x ∈ l
hls : [] ≠ []
⊢ splitOn x (join (intersperse [x] [])) = []

Next tactic:
contradiction
/-- `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
  

Proof state:
case 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 : List α
tl : List (List α)
ih : (∀ (l : List α), l ∈ tl → ¬x ∈ l) → tl ≠ [] → splitOn x (join (intersperse [x] tl)) = tl
hx : ∀ (l : List α), l ∈ hd :: tl → ¬x ∈ l
hls : hd :: tl ≠ []
⊢ splitOn x (join (intersperse [x] (hd :: tl))) = hd :: tl

Next tactic:
cases tl
/-- `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
  · 

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] ≠ []
⊢ splitOn x (join (intersperse [x] [hd])) = [hd]

Next tactic:
suffices hd.splitOn x = [hd] by simpa [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 

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 : List α
ih : (∀ (l : List α), l ∈ [] → ¬x ∈ l) → [] ≠ [] → splitOn x (join (intersperse [x] [])) = []
hx : ∀ (l : List α), l ∈ [hd] → ¬x ∈ l
hls : [hd] ≠ []
this : splitOn x hd = [hd]
⊢ splitOn x (join (intersperse [x] [hd])) = [hd]

Next tactic:
simpa [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]
    

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] ≠ []
⊢ splitOn x hd = [hd]

Next tactic:
refine' splitOnP_eq_single _ _ _