Theorem: List.perm_of_mem_permutationsAux
File: Mathlib/Data/List/Perm.lean

tactic: show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is
state_before: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ {ts is l : List α}, l ∈ ts.permutationsAux is → l ~ ts ++ is
state_after: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (ts is l : List α), l ∈ ts.permutationsAux is → l ~ ts ++ is

tactic: refine permutationsAux.rec (by simp) ?_
state_before: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (ts is l : List α), l ∈ ts.permutationsAux is → l ~ ts ++ is
state_after: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (t : α) (ts is : List α),
    (∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is) →
      (∀ l ∈ is.permutationsAux [], l ~ is ++ []) → ∀ l ∈ (t :: ts).permutationsAux is, l ~ t :: ts ++ is

tactic: introv IH1 IH2 m
state_before: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (t : α) (ts is : List α),
    (∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is) →
      (∀ l ∈ is.permutationsAux [], l ~ is ++ []) → ∀ l ∈ (t :: ts).permutationsAux is, l ~ t :: ts ++ is
state_after: α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l : List α
m : l ∈ (t :: ts).permutationsAux is
⊢ l ~ t :: ts ++ is

tactic: rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m
state_before: α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l : List α
m : l ∈ (t :: ts).permutationsAux is
⊢ l ~ t :: ts ++ is
state_after: α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l : List α
m :
  l ∈ ts.permutationsAux (t :: is) ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ is :: is.permutationsAux [] ∧ l₂ ≠ [] ∧ l = l₁ ++ t :: l₂ ++ ts
⊢ l ~ t :: ts ++ is

tactic: rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩)
state_before: α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l : List α
m :
  l ∈ ts.permutationsAux (t :: is) ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ is :: is.permutationsAux [] ∧ l₂ ≠ [] ∧ l = l₁ ++ t :: l₂ ++ ts
⊢ l ~ t :: ts ++ is
state_after: case inl
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l : List α
m : l ∈ ts.permutationsAux (t :: is)
⊢ l ~ t :: ts ++ is

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

tactic: simp
state_before: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
⊢ ∀ (is l : List α), l ∈ [].permutationsAux is → l ~ [] ++ is
state_after: no goals

tactic: exact (IH1 _ m).trans perm_middle
state_before: case inl
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l : List α
m : l ∈ ts.permutationsAux (t :: is)
⊢ l ~ t :: ts ++ is
state_after: no goals

tactic: exact ((perm_middle.trans (p.cons _)).append_right _).trans (perm_append_comm.cons _)
state_before: case inr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
m : l₁ ++ l₂ ∈ is :: is.permutationsAux []
left✝ : l₂ ≠ []
p : l₁ ++ l₂ ~ is
⊢ l₁ ++ t :: l₂ ++ ts ~ t :: ts ++ is
state_after: no goals

tactic: simp only [mem_cons] at m
state_before: α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
m : l₁ ++ l₂ ∈ is :: is.permutationsAux []
left✝ : l₂ ≠ []
⊢ l₁ ++ l₂ ~ is
state_after: α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
m : l₁ ++ l₂ = is ∨ l₁ ++ l₂ ∈ is.permutationsAux []
⊢ l₁ ++ l₂ ~ is

tactic: cases' m with e m
state_before: α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
m : l₁ ++ l₂ = is ∨ l₁ ++ l₂ ∈ is.permutationsAux []
⊢ l₁ ++ l₂ ~ is
state_after: case inl
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
e : l₁ ++ l₂ = is
⊢ l₁ ++ l₂ ~ is

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

tactic: exact is.append_nil ▸ IH2 _ m
state_before: case inr
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
m : l₁ ++ l₂ ∈ is.permutationsAux []
⊢ l₁ ++ l₂ ~ is
state_after: no goals

tactic: simp [e]
state_before: case inl
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a t : α
ts is : List α
IH1 : ∀ l ∈ ts.permutationsAux (t :: is), l ~ ts ++ t :: is
IH2 : ∀ l ∈ is.permutationsAux [], l ~ is ++ []
l₁ l₂ : List α
left✝ : l₂ ≠ []
e : l₁ ++ l₂ = is
⊢ l₁ ++ l₂ ~ is
state_after: no goals