Theorem: Multiset.powersetLenAux_perm
File: Mathlib/Data/Multiset/Powerset.lean

tactic: induction' n with n IHn generalizing l₁ l₂
state_before: α : Type u_1
n : ℕ
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ powersetLenAux n l₁ ~ powersetLenAux n l₂

tactic: induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
state_before: case succ
α : Type u_1
l₁✝ l₂✝ : List α
p✝ : l₁✝ ~ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ powersetLenAux (Nat.succ n) l₁ ~ powersetLenAux (Nat.succ n) l₂

tactic: simp
state_before: case zero
α : Type u_1
l₁✝ l₂✝ : List α
p✝ : l₁✝ ~ l₂✝
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ powersetLenAux Nat.zero l₁ ~ powersetLenAux Nat.zero l₂

tactic: rfl
state_before: case succ.nil
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁ l₂ : List α
⊢ powersetLenAux (Nat.succ n) [] ~ powersetLenAux (Nat.succ n) []

tactic: simp only [powersetLenAux_cons]
state_before: case succ.cons
α : Type u_1
l₁✝¹ l₂✝¹ : List α
p✝ : l₁✝¹ ~ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
p : l₁ ~ l₂
IH : powersetLenAux (Nat.succ n) l₁ ~ powersetLenAux (Nat.succ n) l₂
⊢ powersetLenAux (Nat.succ n) (a :: l₁) ~ powersetLenAux (Nat.succ n) (a :: l₂)

tactic: exact IH.append ((IHn p).map _)
state_before: case succ.cons
α : Type u_1
l₁✝¹ l₂✝¹ : List α
p✝ : l₁✝¹ ~ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
p : l₁ ~ l₂
IH : powersetLenAux (Nat.succ n) l₁ ~ powersetLenAux (Nat.succ n) l₂
⊢ powersetLenAux (n + 1) l₁ ++ List.map (cons a) (powersetLenAux n l₁) ~
    powersetLenAux (n + 1) l₂ ++ List.map (cons a) (powersetLenAux n l₂)

tactic: simp only [powersetLenAux_cons, append_assoc]
state_before: case succ.swap
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁ l₂ : List α
a b : α
l : List α
⊢ powersetLenAux (Nat.succ n) (b :: a :: l) ~ powersetLenAux (Nat.succ n) (a :: b :: l)

tactic: apply Perm.append_left
state_before: case succ.swap
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁ l₂ : List α
a b : α
l : List α
⊢ powersetLenAux (n + 1) l ++
      (List.map (cons a) (powersetLenAux n l) ++ List.map (cons b) (powersetLenAux n (a :: l))) ~
    powersetLenAux (n + 1) l ++
      (List.map (cons b) (powersetLenAux n l) ++ List.map (cons a) (powersetLenAux n (b :: l)))

tactic: cases n
state_before: case succ.swap.a
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁ l₂ : List α
a b : α
l : List α
⊢ List.map (cons a) (powersetLenAux n l) ++ List.map (cons b) (powersetLenAux n (a :: l)) ~
    List.map (cons b) (powersetLenAux n l) ++ List.map (cons a) (powersetLenAux n (b :: l))

tactic: simp only [powersetLenAux_cons, map_append, List.map_map]
state_before: case succ.swap.a.succ
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux (Nat.succ n✝) l₁ ~ powersetLenAux (Nat.succ n✝) l₂
⊢ List.map (cons a) (powersetLenAux (Nat.succ n✝) l) ++ List.map (cons b) (powersetLenAux (Nat.succ n✝) (a :: l)) ~
    List.map (cons b) (powersetLenAux (Nat.succ n✝) l) ++ List.map (cons a) (powersetLenAux (Nat.succ n✝) (b :: l))

tactic: rw [← append_assoc, ← append_assoc,
  (by funext s; simp [cons_swap] : cons b ∘ cons a = cons a ∘ cons b)]
state_before: case succ.swap.a.succ
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux (Nat.succ n✝) l₁ ~ powersetLenAux (Nat.succ n✝) l₂
⊢ List.map (cons a) (powersetLenAux (Nat.succ n✝) l) ++
      (List.map (cons b) (powersetLenAux (n✝ + 1) l) ++ List.map (cons b ∘ cons a) (powersetLenAux n✝ l)) ~
    List.map (cons b) (powersetLenAux (Nat.succ n✝) l) ++
      (List.map (cons a) (powersetLenAux (n✝ + 1) l) ++ List.map (cons a ∘ cons b) (powersetLenAux n✝ l))

tactic: exact perm_append_comm.append_right _
state_before: case succ.swap.a.succ
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux (Nat.succ n✝) l₁ ~ powersetLenAux (Nat.succ n✝) l₂
⊢ List.map (cons a) (powersetLenAux (Nat.succ n✝) l) ++ List.map (cons b) (powersetLenAux (n✝ + 1) l) ++
      List.map (cons a ∘ cons b) (powersetLenAux n✝ l) ~
    List.map (cons b) (powersetLenAux (Nat.succ n✝) l) ++ List.map (cons a) (powersetLenAux (n✝ + 1) l) ++
      List.map (cons a ∘ cons b) (powersetLenAux n✝ l)

tactic: simp [Perm.swap]
state_before: case succ.swap.a.zero
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
l₁ l₂ : List α
a b : α
l : List α
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux Nat.zero l₁ ~ powersetLenAux Nat.zero l₂
⊢ List.map (cons a) (powersetLenAux Nat.zero l) ++ List.map (cons b) (powersetLenAux Nat.zero (a :: l)) ~
    List.map (cons b) (powersetLenAux Nat.zero l) ++ List.map (cons a) (powersetLenAux Nat.zero (b :: l))

tactic: funext s
state_before: α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux (Nat.succ n✝) l₁ ~ powersetLenAux (Nat.succ n✝) l₂
⊢ cons b ∘ cons a = cons a ∘ cons b

tactic: simp [cons_swap]
state_before: case h
α : Type u_1
l₁✝ l₂✝ : List α
p : l₁✝ ~ l₂✝
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux (Nat.succ n✝) l₁ ~ powersetLenAux (Nat.succ n✝) l₂
s : Multiset α
⊢ (cons b ∘ cons a) s = (cons a ∘ cons b) s

tactic: exact IH₁.trans IH₂
state_before: case succ.trans
α : Type u_1
l₁✝¹ l₂✝¹ : List α
p : l₁✝¹ ~ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetLenAux n l₁ ~ powersetLenAux n l₂
l₁✝ l₂✝ l₁ l₂ l₃ : List α
a✝¹ : l₁ ~ l₂
a✝ : l₂ ~ l₃
IH₁ : powersetLenAux (Nat.succ n) l₁ ~ powersetLenAux (Nat.succ n) l₂
IH₂ : powersetLenAux (Nat.succ n) l₂ ~ powersetLenAux (Nat.succ n) l₃
⊢ powersetLenAux (Nat.succ n) l₁ ~ powersetLenAux (Nat.succ n) l₃