Theorem: List.permutations_perm_permutations'
File: Mathlib/Data/List/Perm.lean

tactic: obtain ⟨n, h⟩ : ∃ n, length ts < n := ⟨_, Nat.lt_succ_self _⟩
state_before: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
ts : List α
⊢ ts.permutations ~ ts.permutations'
state_after: case intro
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
ts : List α
n : ℕ
h : ts.length < n
⊢ ts.permutations ~ ts.permutations'

tactic: induction' n with n IH generalizing ts
state_before: case intro
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
ts : List α
n : ℕ
h : ts.length < n
⊢ ts.permutations ~ ts.permutations'
state_after: case intro.zero
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
ts : List α
h : ts.length < 0
⊢ ts.permutations ~ ts.permutations'

case intro.succ
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts : List α
h : ts.length < n + 1
⊢ ts.permutations ~ ts.permutations'

tactic: refine List.reverseRecOn ts (fun _ => ?_) (fun ts t _ h => ?_) h
state_before: case intro.succ
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts : List α
h : ts.length < n + 1
⊢ ts.permutations ~ ts.permutations'
state_after: case intro.succ.refine_1
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts : List α
h : ts.length < n + 1
x✝ : [].length < n + 1
⊢ [].permutations ~ [].permutations'

case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : (ts ++ [t]).length < n + 1
⊢ (ts ++ [t]).permutations ~ (ts ++ [t]).permutations'

tactic: rw [← concat_eq_append, length_concat, Nat.succ_lt_succ_iff] at h
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : (ts ++ [t]).length < n + 1
⊢ (ts ++ [t]).permutations ~ (ts ++ [t]).permutations'
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
⊢ (ts ++ [t]).permutations ~ (ts ++ [t]).permutations'

tactic: have IH₂ := (IH ts.reverse (by rwa [length_reverse])).trans (reverse_perm _).permutations'
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
⊢ (ts ++ [t]).permutations ~ (ts ++ [t]).permutations'
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts ++ [t]).permutations ~ (ts ++ [t]).permutations'

tactic: simp only [permutations_append, foldr_permutationsAux2, permutationsAux_nil,
  permutationsAux_cons, append_nil]
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts ++ [t]).permutations ~ (ts ++ [t]).permutations'
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (map (fun x => x ++ [t]) ts.permutations ++ ts.reverse.permutations.bind fun y => (permutationsAux2 t [] [] y id).2) ~
    (ts ++ [t]).permutations'

tactic: refine
  (perm_append_comm.trans ((IH₂.bind_right _).append ((IH _ h).map _))).trans
    (Perm.trans ?_ perm_append_comm.permutations')
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (map (fun x => x ++ [t]) ts.permutations ++ ts.reverse.permutations.bind fun y => (permutationsAux2 t [] [] y id).2) ~
    (ts ++ [t]).permutations'
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts.permutations'.bind fun y => (permutationsAux2 t [] [] y id).2) ++ map (fun x => x ++ [t]) ts.permutations' ~
    ([t] ++ ts).permutations'

tactic: rw [map_eq_bind, singleton_append, permutations']
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts.permutations'.bind fun y => (permutationsAux2 t [] [] y id).2) ++ map (fun x => x ++ [t]) ts.permutations' ~
    ([t] ++ ts).permutations'
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ ((ts.permutations'.bind fun y => (permutationsAux2 t [] [] y id).2) ++ ts.permutations'.bind fun x => [x ++ [t]]) ~
    ts.permutations'.bind (permutations'Aux t)

tactic: refine (bind_append_perm _ _ _).trans ?_
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ ((ts.permutations'.bind fun y => (permutationsAux2 t [] [] y id).2) ++ ts.permutations'.bind fun x => [x ++ [t]]) ~
    ts.permutations'.bind (permutations'Aux t)
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts.permutations'.bind fun x => (permutationsAux2 t [] [] x id).2 ++ [x ++ [t]]) ~
    ts.permutations'.bind (permutations'Aux t)

tactic: refine Perm.of_eq ?_
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts.permutations'.bind fun x => (permutationsAux2 t [] [] x id).2 ++ [x ++ [t]]) ~
    ts.permutations'.bind (permutations'Aux t)
state_after: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts.permutations'.bind fun x => (permutationsAux2 t [] [] x id).2 ++ [x ++ [t]]) =
    ts.permutations'.bind (permutations'Aux t)

tactic: congr
state_before: case intro.succ.refine_2
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (ts.permutations'.bind fun x => (permutationsAux2 t [] [] x id).2 ++ [x ++ [t]]) =
    ts.permutations'.bind (permutations'Aux t)
state_after: case intro.succ.refine_2.e_b
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (fun x => (permutationsAux2 t [] [] x id).2 ++ [x ++ [t]]) = permutations'Aux t

tactic: funext _
state_before: case intro.succ.refine_2.e_b
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
⊢ (fun x => (permutationsAux2 t [] [] x id).2 ++ [x ++ [t]]) = permutations'Aux t
state_after: case intro.succ.refine_2.e_b.h
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝¹ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
x✝ : List α
⊢ (permutationsAux2 t [] [] x✝ id).2 ++ [x✝ ++ [t]] = permutations'Aux t x✝

tactic: rw [permutations'Aux_eq_permutationsAux2, permutationsAux2_append]
state_before: case intro.succ.refine_2.e_b.h
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝¹ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
IH₂ : ts.reverse.permutations ~ ts.permutations'
x✝ : List α
⊢ (permutationsAux2 t [] [] x✝ id).2 ++ [x✝ ++ [t]] = permutations'Aux t x✝
state_after: no goals

tactic: cases h
state_before: case intro.zero
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
ts : List α
h : ts.length < 0
⊢ ts.permutations ~ ts.permutations'
state_after: no goals

tactic: simp [permutations]
state_before: case intro.succ.refine_1
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts : List α
h : ts.length < n + 1
x✝ : [].length < n + 1
⊢ [].permutations ~ [].permutations'
state_after: no goals

tactic: rwa [length_reverse]
state_before: α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
n : ℕ
IH : ∀ (ts : List α), ts.length < n → ts.permutations ~ ts.permutations'
ts✝ : List α
h✝ : ts✝.length < n + 1
ts : List α
t : α
x✝ : ts.length < n + 1 → ts.permutations ~ ts.permutations'
h : ts.length < n
⊢ ts.reverse.length < n
state_after: no goals