Theorem: List.Perm.foldl_eq'
File: .lake/packages/batteries/Batteries/Data/List/Perm.lean

tactic: induction p using recOnSwap' generalizing init with
| nil => simp
| cons x _p IH =>
  simp only [foldl]
  apply IH; intros; apply comm <;> exact .tail _ ‹_›
| swap' x y _p IH =>
  simp only [foldl]
  rw [comm x (.tail _ <| .head _) y (.head _)]
  apply IH; intros; apply comm <;> exact .tail _ (.tail _ ‹_›)
| trans p₁ _p₂ IH₁ IH₂ =>
  refine (IH₁ comm init).trans (IH₂ ?_ _)
  intros; apply comm <;> apply p₁.symm.subset <;> assumption
state_before: β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
p : l₁ ~ l₂
comm : ∀ (x : α), x ∈ l₁ → ∀ (y : α), y ∈ l₁ → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
⊢ foldl f init l₁ = foldl f init l₂
state_after: no goals

tactic: simp
state_before: case nil
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
comm : ∀ (x : α), x ∈ [] → ∀ (y : α), y ∈ [] → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
⊢ foldl f init [] = foldl f init []
state_after: no goals

tactic: simp only [foldl]
state_before: case cons
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
⊢ foldl f init (x :: l₁✝) = foldl f init (x :: l₂✝)
state_after: case cons
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
⊢ foldl f (f init x) l₁✝ = foldl f (f init x) l₂✝

tactic: apply IH
state_before: case cons
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
⊢ foldl f (f init x) l₁✝ = foldl f (f init x) l₂✝
state_after: case cons.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
⊢ ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x

tactic: intros
state_before: case cons.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
⊢ ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
state_after: case cons.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
x✝ : α
a✝¹ : x✝ ∈ l₁✝
y✝ : α
a✝ : y✝ ∈ l₁✝
z✝ : β
⊢ f (f z✝ x✝) y✝ = f (f z✝ y✝) x✝

tactic: apply comm <;> exact .tail _ ‹_›
state_before: case cons.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm : ∀ (x_1 : α), x_1 ∈ x :: l₁✝ → ∀ (y : α), y ∈ x :: l₁✝ → ∀ (z : β), f (f z x_1) y = f (f z y) x_1
init : β
x✝ : α
a✝¹ : x✝ ∈ l₁✝
y✝ : α
a✝ : y✝ ∈ l₁✝
z✝ : β
⊢ f (f z✝ x✝) y✝ = f (f z✝ y✝) x✝
state_after: no goals

tactic: simp only [foldl]
state_before: case swap'
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ foldl f init (y :: x :: l₁✝) = foldl f init (x :: y :: l₂✝)
state_after: case swap'
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ foldl f (f (f init y) x) l₁✝ = foldl f (f (f init x) y) l₂✝

tactic: rw [comm x (.tail _ <| .head _) y (.head _)]
state_before: case swap'
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ foldl f (f (f init y) x) l₁✝ = foldl f (f (f init x) y) l₂✝
state_after: case swap'
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ foldl f (f (f init y) x) l₁✝ = foldl f (f (f init y) x) l₂✝

tactic: apply IH
state_before: case swap'
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ foldl f (f (f init y) x) l₁✝ = foldl f (f (f init y) x) l₂✝
state_after: case swap'.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x

tactic: intros
state_before: case swap'.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
⊢ ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
state_after: case swap'.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
x✝ : α
a✝¹ : x✝ ∈ l₁✝
y✝ : α
a✝ : y✝ ∈ l₁✝
z✝ : β
⊢ f (f z✝ x✝) y✝ = f (f z✝ y✝) x✝

tactic: apply comm <;> exact .tail _ (.tail _ ‹_›)
state_before: case swap'.comm
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ : List α
x y : α
l₁✝ l₂✝ : List α
_p : l₁✝ ~ l₂✝
IH :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
comm :
  ∀ (x_1 : α), x_1 ∈ y :: x :: l₁✝ → ∀ (y_1 : α), y_1 ∈ y :: x :: l₁✝ → ∀ (z : β), f (f z x_1) y_1 = f (f z y_1) x_1
init : β
x✝ : α
a✝¹ : x✝ ∈ l₁✝
y✝ : α
a✝ : y✝ ∈ l₁✝
z✝ : β
⊢ f (f z✝ x✝) y✝ = f (f z✝ y✝) x✝
state_after: no goals

tactic: refine (IH₁ comm init).trans (IH₂ ?_ _)
state_before: case trans
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ l₁✝ l₂✝ l₃✝ : List α
p₁ : l₁✝ ~ l₂✝
_p₂ : l₂✝ ~ l₃✝
IH₁ :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
IH₂ :
  (∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₂✝ = foldl f init l₃✝
comm : ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
⊢ foldl f init l₁✝ = foldl f init l₃✝
state_after: case trans
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ l₁✝ l₂✝ l₃✝ : List α
p₁ : l₁✝ ~ l₂✝
_p₂ : l₂✝ ~ l₃✝
IH₁ :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
IH₂ :
  (∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₂✝ = foldl f init l₃✝
comm : ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
⊢ ∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x

tactic: intros
state_before: case trans
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ l₁✝ l₂✝ l₃✝ : List α
p₁ : l₁✝ ~ l₂✝
_p₂ : l₂✝ ~ l₃✝
IH₁ :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
IH₂ :
  (∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₂✝ = foldl f init l₃✝
comm : ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
⊢ ∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x
state_after: case trans
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ l₁✝ l₂✝ l₃✝ : List α
p₁ : l₁✝ ~ l₂✝
_p₂ : l₂✝ ~ l₃✝
IH₁ :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
IH₂ :
  (∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₂✝ = foldl f init l₃✝
comm : ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
x✝ : α
a✝¹ : x✝ ∈ l₂✝
y✝ : α
a✝ : y✝ ∈ l₂✝
z✝ : β
⊢ f (f z✝ x✝) y✝ = f (f z✝ y✝) x✝

tactic: apply comm <;> apply p₁.symm.subset <;> assumption
state_before: case trans
β : Type u_1
α : Type u_2
f : β → α → β
l₁ l₂ l₁✝ l₂✝ l₃✝ : List α
p₁ : l₁✝ ~ l₂✝
_p₂ : l₂✝ ~ l₃✝
IH₁ :
  (∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₁✝ = foldl f init l₂✝
IH₂ :
  (∀ (x : α), x ∈ l₂✝ → ∀ (y : α), y ∈ l₂✝ → ∀ (z : β), f (f z x) y = f (f z y) x) →
    ∀ (init : β), foldl f init l₂✝ = foldl f init l₃✝
comm : ∀ (x : α), x ∈ l₁✝ → ∀ (y : α), y ∈ l₁✝ → ∀ (z : β), f (f z x) y = f (f z y) x
init : β
x✝ : α
a✝¹ : x✝ ∈ l₂✝
y✝ : α
a✝ : y✝ ∈ l₂✝
z✝ : β
⊢ f (f z✝ x✝) y✝ = f (f z✝ y✝) x✝
state_after: no goals