l3lab/ntp-mathlib huggingface dataset:
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is

Next tactic:
show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is

Next tactic:
refine' permutationsAux.rec (by simp) _
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by 

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (is l : List α), l ∈ permutationsAux [] is → l ~ [] ++ is

Next tactic:
simp
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (t : α) (ts is : List α),
    (∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is) →
      (∀ l ∈ permutationsAux is [], l ~ is ++ []) → ∀ l ∈ permutationsAux (t :: ts) is, l ~ t :: ts ++ is

Next tactic:
introv IH1 IH2 m
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l : List α
m : l ∈ permutationsAux (t :: ts) is
⊢ l ~ t :: ts ++ is

Next tactic:
rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l : List α
m :
  l ∈ permutationsAux ts (t :: is) ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ is :: permutationsAux is [] ∧ l₂ ≠ [] ∧ l = l₁ ++ t :: l₂ ++ ts
⊢ l ~ t :: ts ++ is

Next tactic:
rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · 

Proof state:
case inl
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l : List α
m : l ∈ permutationsAux ts (t :: is)
⊢ l ~ t :: ts ++ is

Next tactic:
exact (IH1 _ m).trans perm_middle
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · exact (IH1 _ m).trans perm_middle
  · 

Proof state:
case inr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l₁ l₂ : List α
m : l₁ ++ l₂ ∈ is :: permutationsAux is []
left✝ : l₂ ≠ []
⊢ l₁ ++ t :: l₂ ++ ts ~ t :: ts ++ is

Next tactic:
have p : l₁ ++ l₂ ~ is := by
      simp [permutations] at m
      cases' m with e m
      · simp [e]
      exact is.append_nil ▸ IH2 _ m
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · exact (IH1 _ m).trans perm_middle
  · have p : l₁ ++ l₂ ~ is := by
      

Proof state:
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l₁ l₂ : List α
m : l₁ ++ l₂ ∈ is :: permutationsAux is []
left✝ : l₂ ≠ []
⊢ l₁ ++ l₂ ~ is

Next tactic:
simp [permutations] at m
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · exact (IH1 _ m).trans perm_middle
  · have p : l₁ ++ l₂ ~ is := by
      simp [permutations] at m
      

Proof state:
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
m : l₁ ++ l₂ = is ∨ l₁ ++ l₂ ∈ permutationsAux is []
⊢ l₁ ++ l₂ ~ is

Next tactic:
cases' m with e m
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · exact (IH1 _ m).trans perm_middle
  · have p : l₁ ++ l₂ ~ is := by
      simp [permutations] at m
      cases' m with e m
      · 

Proof state:
case inl
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
e : l₁ ++ l₂ = is
⊢ l₁ ++ l₂ ~ is

Next tactic:
simp [e]
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · exact (IH1 _ m).trans perm_middle
  · have p : l₁ ++ l₂ ~ is := by
      simp [permutations] at m
      cases' m with e m
      · simp [e]
      

Proof state:
case inr
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
m : l₁ ++ l₂ ∈ permutationsAux is []
⊢ l₁ ++ l₂ ~ is

Next tactic:
exact is.append_nil ▸ IH2 _ m
theorem perm_of_mem_permutationsAux :
    ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by
  show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
  refine' permutationsAux.rec (by simp) _
  introv IH1 IH2 m
  rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
  rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
  · exact (IH1 _ m).trans perm_middle
  · have p : l₁ ++ l₂ ~ is := by
      simp [permutations] at m
      cases' m with e m
      · simp [e]
      exact is.append_nil ▸ IH2 _ m
    

Proof state:
case inr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ permutationsAux ts (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ permutationsAux is [], l ~ is ++ []
l₁ l₂ : List α
m : l₁ ++ l₂ ∈ is :: permutationsAux is []
left✝ : l₂ ≠ []
p : l₁ ++ l₂ ~ is
⊢ l₁ ++ t :: l₂ ++ ts ~ t :: ts ++ is

Next tactic:
exact ((perm_middle.trans (p.cons _)).append_right _).trans (perm_append_comm.cons _)
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (ts is : List α), length (permutationsAux ts is) + (length is)! = (length ts + length is)!

Next tactic:
refine' permutationsAux.rec (by simp) _
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by 

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (is : List α), length (permutationsAux [] is) + (length is)! = (length [] + length is)!

Next tactic:
simp
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by simp) _
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (t : α) (ts is : List α),
    length (permutationsAux ts (t :: is)) + (length (t :: is))! = (length ts + length (t :: is))! →
      length (permutationsAux is []) + (length [])! = (length is + length [])! →
        length (permutationsAux (t :: ts) is) + (length is)! = (length (t :: ts) + length is)!

Next tactic:
intro t ts is IH1 IH2
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a t : α
ts is : List α
IH1 : length (permutationsAux ts (t :: is)) + (length (t :: is))! = (length ts + length (t :: is))!
IH2 : length (permutationsAux is []) + (length [])! = (length is + length [])!
⊢ length (permutationsAux (t :: ts) is) + (length is)! = (length (t :: ts) + length is)!

Next tactic:
have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by simpa using IH2
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2
  have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by 

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a t : α
ts is : List α
IH1 : length (permutationsAux ts (t :: is)) + (length (t :: is))! = (length ts + length (t :: is))!
IH2 : length (permutationsAux is []) + (length [])! = (length is + length [])!
⊢ length (permutationsAux is []) + 1 = (length is)!

Next tactic:
simpa using IH2
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2
  have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by simpa using IH2
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a t : α
ts is : List α
IH1 : length (permutationsAux ts (t :: is)) + (length (t :: is))! = (length ts + length (t :: is))!
IH2✝ : length (permutationsAux is []) + (length [])! = (length is + length [])!
IH2 : length (permutationsAux is []) + 1 = (length is)!
⊢ length (permutationsAux (t :: ts) is) + (length is)! = (length (t :: ts) + length is)!

Next tactic:
simp? [Nat.factorial, Nat.add_succ, mul_comm] at IH1 says
    simp only [factorial, add_eq, add_zero, mul_comm] at IH1
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2
  have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by simpa using IH2
  simp? [Nat.factorial, Nat.add_succ, mul_comm] at IH1 says
    

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a t : α
ts is : List α
IH1 : length (permutationsAux ts (t :: is)) + (length (t :: is))! = (length ts + length (t :: is))!
IH2✝ : length (permutationsAux is []) + (length [])! = (length is + length [])!
IH2 : length (permutationsAux is []) + 1 = (length is)!
⊢ length (permutationsAux (t :: ts) is) + (length is)! = (length (t :: ts) + length is)!

Next tactic:
simp only [factorial, add_eq, add_zero, mul_comm] at IH1
theorem length_permutationsAux :
    ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2
  have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by simpa using IH2
  simp? [Nat.factorial, Nat.add_succ, mul_comm] at IH1 says
    simp only [factorial, add_eq, add_zero, mul_comm] at IH1
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a t : α
ts is : List α
IH2✝ : length (permutationsAux is []) + (length [])! = (length is + length [])!
IH2 : length (permutationsAux is []) + 1 = (length is)!
IH1 :
  length (permutationsAux ts (t :: is)) + (length is)! * succ (length is) =
    (length ts + length is)! * succ (length ts + length is)
⊢ length (permutationsAux (t :: ts) is) + (length is)! = (length (t :: ts) + length is)!

Next tactic:
rw [permutationsAux_cons,
    length_foldr_permutationsAux2' _ _ _ _ _ fun l m => (perm_of_mem_permutations m).length_eq,
    permutations, length, length, IH2, Nat.succ_add, Nat.factorial_succ, mul_comm (_ + 1),
    ← Nat.succ_eq_add_one, ← IH1, add_comm (_ * _), add_assoc, Nat.mul_succ, mul_comm]
theorem mem_permutations_of_perm_lemma {is l : List α}
    (H : l ~ [] ++ is → (∃ (ts' : _) (_ : ts' ~ []), l = ts' ++ is) ∨ l ∈ permutationsAux is []) :
    l ~ is → l ∈ permutations is := by 

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
is l : List α
H : l ~ [] ++ is → (∃ ts', ∃ (_ : ts' ~ []), l = ts' ++ is) ∨ l ∈ permutationsAux is []
⊢ l ~ is → l ∈ permutations is

Next tactic:
simpa [permutations, perm_nil] using H
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ {ts is l : List α}, l ~ is ++ ts → (∃ is', ∃ (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is

Next tactic:
show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (ts is l : List α), l ~ is ++ ts → (∃ is', ∃ (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is

Next tactic:
refine' permutationsAux.rec (by simp) _
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by 

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (is l : List α), l ~ is ++ [] → (∃ is', ∃ (_ : is' ~ is), l = is' ++ []) ∨ l ∈ permutationsAux [] is

Next tactic:
simp
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (t : α) (ts is : List α),
    (∀ (l : List α),
        l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)) →
      (∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []) →
        ∀ (l : List α),
          l ~ is ++ t :: ts → (∃ is', ∃ (_ : is' ~ is), l = is' ++ t :: ts) ∨ l ∈ permutationsAux (t :: ts) is

Next tactic:
intro t ts is IH1 IH2 l p
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
l : List α
p : l ~ is ++ t :: ts
⊢ (∃ is', ∃ (_ : is' ~ is), l = is' ++ t :: ts) ∨ l ∈ permutationsAux (t :: ts) is

Next tactic:
rw [permutationsAux_cons, mem_foldr_permutationsAux2]
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  rw [permutationsAux_cons, mem_foldr_permutationsAux2]
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
l : List α
p : l ~ is ++ t :: ts
⊢ (∃ is', ∃ (_ : is' ~ is), l = is' ++ t :: ts) ∨
    l ∈ permutationsAux ts (t :: is) ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ permutations is ∧ l₂ ≠ [] ∧ l = l₁ ++ t :: l₂ ++ ts

Next tactic:
rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m)
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  rw [permutationsAux_cons, mem_foldr_permutationsAux2]
  rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m)
  · 

Proof state:
case inl.intro.intro
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
l : List α
p : l ~ is ++ t :: ts
is' : List α
p' : is' ~ t :: is
e : l = is' ++ ts
⊢ (∃ is', ∃ (_ : is' ~ is), l = is' ++ t :: ts) ∨
    l ∈ permutationsAux ts (t :: is) ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ permutations is ∧ l₂ ≠ [] ∧ l = l₁ ++ t :: l₂ ++ ts

Next tactic:
clear p
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  rw [permutationsAux_cons, mem_foldr_permutationsAux2]
  rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m)
  · clear p
    

Proof state:
case inl.intro.intro
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
l is' : List α
p' : is' ~ t :: is
e : l = is' ++ ts
⊢ (∃ is', ∃ (_ : is' ~ is), l = is' ++ t :: ts) ∨
    l ∈ permutationsAux ts (t :: is) ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ permutations is ∧ l₂ ≠ [] ∧ l = l₁ ++ t :: l₂ ++ ts

Next tactic:
subst e
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  rw [permutationsAux_cons, mem_foldr_permutationsAux2]
  rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m)
  · clear p
    subst e
    

Proof state:
case inl.intro.intro
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
is' : List α
p' : is' ~ t :: is
⊢ (∃ is'_1, ∃ (_ : is'_1 ~ is), is' ++ ts = is'_1 ++ t :: ts) ∨
    is' ++ ts ∈ permutationsAux ts (t :: is) ∨
      ∃ l₁ l₂, l₁ ++ l₂ ∈ permutations is ∧ l₂ ≠ [] ∧ is' ++ ts = l₁ ++ t :: l₂ ++ ts

Next tactic:
rcases mem_split (p'.symm.subset (mem_cons_self _ _)) with ⟨l₁, l₂, e⟩
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  rw [permutationsAux_cons, mem_foldr_permutationsAux2]
  rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m)
  · clear p
    subst e
    rcases mem_split (p'.symm.subset (mem_cons_self _ _)) with ⟨l₁, l₂, e⟩
    

Proof state:
case inl.intro.intro.intro.intro
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
is' : List α
p' : is' ~ t :: is
l₁ l₂ : List α
e : is' = l₁ ++ t :: l₂
⊢ (∃ is'_1, ∃ (_ : is'_1 ~ is), is' ++ ts = is'_1 ++ t :: ts) ∨
    is' ++ ts ∈ permutationsAux ts (t :: is) ∨
      ∃ l₁ l₂, l₁ ++ l₂ ∈ permutations is ∧ l₂ ≠ [] ∧ is' ++ ts = l₁ ++ t :: l₂ ++ ts

Next tactic:
subst is'
theorem mem_permutationsAux_of_perm :
    ∀ {ts is l : List α},
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by
  show ∀ (ts is l : List α),
      l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is
  refine' permutationsAux.rec (by simp) _
  intro t ts is IH1 IH2 l p
  rw [permutationsAux_cons, mem_foldr_permutationsAux2]
  rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m)
  · clear p
    subst e
    rcases mem_split (p'.symm.subset (mem_cons_self _ _)) with ⟨l₁, l₂, e⟩
    subst is'
    

Proof state:
case inl.intro.intro.intro.intro
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 :
  ∀ (l : List α), l ~ t :: is ++ ts → (∃ is', ∃ (_ : is' ~ t :: is), l = is' ++ ts) ∨ l ∈ permutationsAux ts (t :: is)
IH2 : ∀ (l : List α), l ~ [] ++ is → (∃ is', ∃ (_ : is' ~ []), l = is' ++ is) ∨ l ∈ permutationsAux is []
l₁ l₂ : List α
p' : l₁ ++ t :: l₂ ~ t :: is
⊢ (∃ is', ∃ (_ : is' ~ is), l₁ ++ t :: l₂ ++ ts = is' ++ t :: ts) ∨
    l₁ ++ t :: l₂ ++ ts ∈ permutationsAux ts (t :: is) ∨
      ∃ l₁_1 l₂_1, l₁_1 ++ l₂_1 ∈ permutations is ∧ l₂_1 ≠ [] ∧ l₁ ++ t :: l₂ ++ ts = l₁_1 ++ t :: l₂_1 ++ ts

Next tactic:
have p := (perm_middle.symm.trans p').cons_inv