Theorem: List.perm_permutations'Aux_comm
File: Mathlib/Data/List/Perm.lean

Proof steps:
state_before: α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b : α
l : List α
⊢ (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
state_after: case nil
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a✝ a b : α
⊢ (permutations'Aux a []).bind (permutations'Aux b) ~ (permutations'Aux b []).bind (permutations'Aux a)

case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
⊢ (permutations'Aux a (c :: l)).bind (permutations'Aux b) ~ (permutations'Aux b (c :: l)).bind (permutations'Aux a)
tactic: induction' l with c l ih
state_before: case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
⊢ (permutations'Aux a (c :: l)).bind (permutations'Aux b) ~ (permutations'Aux b (c :: l)).bind (permutations'Aux a)
state_after: case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
⊢ (b :: a :: c :: l) ::
      (a :: b :: c :: l) ::
        (map (cons a ∘ cons c) (permutations'Aux b l) ++
          (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b)) ~
    (a :: b :: c :: l) ::
      (b :: a :: c :: l) ::
        (map (cons b ∘ cons c) (permutations'Aux a l) ++
          (map (cons c) (permutations'Aux b l)).bind (permutations'Aux a))
tactic: simp only [permutations'Aux, bind_cons, map_cons, map_map, cons_append]
state_before: case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
⊢ (b :: a :: c :: l) ::
      (a :: b :: c :: l) ::
        (map (cons a ∘ cons c) (permutations'Aux b l) ++
          (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b)) ~
    (a :: b :: c :: l) ::
      (b :: a :: c :: l) ::
        (map (cons b ∘ cons c) (permutations'Aux a l) ++
          (map (cons c) (permutations'Aux b l)).bind (permutations'Aux a))
state_after: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++ (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++ (map (cons c) (permutations'Aux b l)).bind (permutations'Aux a)
tactic: apply Perm.swap'
state_before: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++ (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++ (map (cons c) (permutations'Aux b l)).bind (permutations'Aux a)
state_after: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
this :
  ∀ (a b : α),
    (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
      map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++ (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++ (map (cons c) (permutations'Aux b l)).bind (permutations'Aux a)
tactic: have :
    ∀ a b,
      (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
        map (cons b ∘ cons c) (permutations'Aux a l) ++
          map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) := by
    intros a' b'
    simp only [bind_map, permutations'Aux]
    show List.bind (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++
      map (cons c) (permutations'Aux _ a))) ~ _
    refine (bind_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_
    rw [← map_eq_bind, ← map_bind]
    exact Perm.refl _
state_before: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
this :
  ∀ (a b : α),
    (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
      map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++ (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++ (map (cons c) (permutations'Aux b l)).bind (permutations'Aux a)
state_after: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
this :
  ∀ (a b : α),
    (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
      map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++
      (map (cons b ∘ cons c) (permutations'Aux a l) ++
        map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++
      (map (cons a ∘ cons c) (permutations'Aux b l) ++ map (cons c) ((permutations'Aux b l).bind (permutations'Aux a)))
tactic: refine (((this _ _).append_left _).trans ?_).trans ((this _ _).append_left _).symm
state_before: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
this :
  ∀ (a b : α),
    (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
      map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++
      (map (cons b ∘ cons c) (permutations'Aux a l) ++
        map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++
      (map (cons a ∘ cons c) (permutations'Aux b l) ++ map (cons c) ((permutations'Aux b l).bind (permutations'Aux a)))
state_after: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
this :
  ∀ (a b : α),
    (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
      map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++ map (cons b ∘ cons c) (permutations'Aux a l) ++
      map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons a ∘ cons c) (permutations'Aux b l) ++
      map (cons c) ((permutations'Aux b l).bind (permutations'Aux a))
tactic: rw [← append_assoc, ← append_assoc]
state_before: case cons.p
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ a b c : α
l : List α
ih : (permutations'Aux a l).bind (permutations'Aux b) ~ (permutations'Aux b l).bind (permutations'Aux a)
this :
  ∀ (a b : α),
    (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~
      map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons c) ((permutations'Aux a l).bind (permutations'Aux b))
⊢ map (cons a ∘ cons c) (permutations'Aux b l) ++ map (cons b ∘ cons c) (permutations'Aux a l) ++
      map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) ~
    map (cons b ∘ cons c) (permutations'Aux a l) ++ map (cons a ∘ cons c) (permutations'Aux b l) ++
      map (cons c) ((permutations'Aux b l).bind (permutations'Aux a))
state_after: no goals
tactic: exact perm_append_comm.append (ih.map _)