l3lab/ntp-mathlib huggingface dataset:
theorem mem_of_subset' {a} : ∀ {l₁ l₂ : Lists' α true} (_ : l₁ ⊆ l₂) (_ : a ∈ l₁.toList), a ∈ l₂
  | nil, _, Lists'.Subset.nil, h => by cases h
  | cons' a0 l0, l₂, s, h => by
    cases' s with _ _ _ _ _ e m s
    simp only [toList, Sigma.eta, List.find?, List.mem_cons] at h
    rcases h with (rfl | h)
    · 

Proof state:
case cons.inl
α : Type u_1
a : Lists α
l0 l₂ : Lists' α true
a'✝ : Lists α
m : a'✝ ∈ toList l₂
s : Subset l0 l₂
e : a ~ a'✝
⊢ a ∈ l₂

Next tactic:
exact ⟨_, m, e⟩
theorem mem_of_subset' {a} : ∀ {l₁ l₂ : Lists' α true} (_ : l₁ ⊆ l₂) (_ : a ∈ l₁.toList), a ∈ l₂
  | nil, _, Lists'.Subset.nil, h => by cases h
  | cons' a0 l0, l₂, s, h => by
    cases' s with _ _ _ _ _ e m s
    simp only [toList, Sigma.eta, List.find?, List.mem_cons] at h
    rcases h with (rfl | h)
    · exact ⟨_, m, e⟩
    · 

Proof state:
case cons.inr
α : Type u_1
a : Lists α
l0 l₂ : Lists' α true
a✝ a'✝ : Lists α
e : a✝ ~ a'✝
m : a'✝ ∈ toList l₂
s : Subset l0 l₂
h : a ∈ toList l0
⊢ a ∈ l₂

Next tactic:
exact mem_of_subset' s h
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    

Proof state:
α : Type u_1
l₁ l₂ : Lists' α true
H : ∀ (a : Lists α), a ∈ toList l₁ → a ∈ l₂
⊢ l₁ ⊆ l₂

Next tactic:
rw [← of_toList l₁]
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    

Proof state:
α : Type u_1
l₁ l₂ : Lists' α true
H : ∀ (a : Lists α), a ∈ toList l₁ → a ∈ l₂
⊢ ofList (toList l₁) ⊆ l₂

Next tactic:
revert H
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    revert H; 

Proof state:
α : Type u_1
l₁ l₂ : Lists' α true
⊢ (∀ (a : Lists α), a ∈ toList l₁ → a ∈ l₂) → ofList (toList l₁) ⊆ l₂

Next tactic:
induction' toList l₁ with h t t_ih
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    revert H; induction' toList l₁ with h t t_ih <;> 

Proof state:
case nil
α : Type u_1
l₁ l₂ : Lists' α true
⊢ (∀ (a : Lists α), a ∈ [] → a ∈ l₂) → ofList [] ⊆ l₂

Next tactic:
intro H
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    revert H; induction' toList l₁ with h t t_ih <;> 

Proof state:
case cons
α : Type u_1
l₁ l₂ : Lists' α true
h : Lists α
t : List (Lists α)
t_ih : (∀ (a : Lists α), a ∈ t → a ∈ l₂) → ofList t ⊆ l₂
⊢ (∀ (a : Lists α), a ∈ h :: t → a ∈ l₂) → ofList (h :: t) ⊆ l₂

Next tactic:
intro H
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    revert H; induction' toList l₁ with h t t_ih <;> intro H
    · 

Proof state:
case nil
α : Type u_1
l₁ l₂ : Lists' α true
H : ∀ (a : Lists α), a ∈ [] → a ∈ l₂
⊢ ofList [] ⊆ l₂

Next tactic:
exact Subset.nil
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    revert H; induction' toList l₁ with h t t_ih <;> intro H
    · exact Subset.nil
    · 

Proof state:
case cons
α : Type u_1
l₁ l₂ : Lists' α true
h : Lists α
t : List (Lists α)
t_ih : (∀ (a : Lists α), a ∈ t → a ∈ l₂) → ofList t ⊆ l₂
H : ∀ (a : Lists α), a ∈ h :: t → a ∈ l₂
⊢ ofList (h :: t) ⊆ l₂

Next tactic:
simp only [ofList, List.find?, List.mem_cons, forall_eq_or_imp] at *
theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ :=
  ⟨fun H a => mem_of_subset' H, fun H => by
    rw [← of_toList l₁]
    revert H; induction' toList l₁ with h t t_ih <;> intro H
    · exact Subset.nil
    · simp only [ofList, List.find?, List.mem_cons, forall_eq_or_imp] at *
      

Proof state:
case cons
α : Type u_1
l₁ l₂ : Lists' α true
h : Lists α
t : List (Lists α)
t_ih : (∀ (a : Lists α), a ∈ t → a ∈ l₂) → ofList t ⊆ l₂
H : h ∈ l₂ ∧ ∀ (a : Lists α), a ∈ t → a ∈ l₂
⊢ cons h (ofList t) ⊆ l₂

Next tactic:
exact cons_subset.2 ⟨H.1, t_ih H.2⟩
theorem to_ofList (l : List (Lists α)) : toList (ofList l) = l := by 

Proof state:
α : Type u_1
l : List (Lists α)
⊢ toList (ofList l) = l

Next tactic:
simp [ofList, of']
theorem of_toList : ∀ {l : Lists α}, IsList l → ofList (toList l) = l
  | ⟨true, l⟩, _ => by 

Proof state:
α : Type u_1
l : Lists' α true
x✝ : IsList { fst := true, snd := l }
⊢ ofList (toList { fst := true, snd := l }) = { fst := true, snd := l }

Next tactic:
simp_all [ofList, of']
instance [DecidableEq α] : DecidableEq (Lists α) := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
⊢ DecidableEq (Lists α)

Next tactic:
unfold Lists
instance [DecidableEq α] : DecidableEq (Lists α) := by unfold Lists; 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
⊢ DecidableEq ((b : Bool) × Lists' α b)

Next tactic:
infer_instance
instance [SizeOf α] : SizeOf (Lists α) := by 

Proof state:
α : Type u_1
inst✝ : SizeOf α
⊢ SizeOf (Lists α)

Next tactic:
unfold Lists
instance [SizeOf α] : SizeOf (Lists α) := by unfold Lists; 

Proof state:
α : Type u_1
inst✝ : SizeOf α
⊢ SizeOf ((b : Bool) × Lists' α b)

Next tactic:
infer_instance
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  

Proof state:
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
⊢ PProd ((l : Lists α) → C l) ((l : Lists' α true) → D l)

Next tactic:
suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by 

Proof state:
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
this :
  {b : Bool} →
    (l : Lists' α b) →
      PProd (C { fst := b, snd := l })
        (match b, l with
        | true, l => D l
        | false, x => PUnit.{u_3})
⊢ PProd ((l : Lists α) → C l) ((l : Lists' α true) → D l)

Next tactic:
exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
  

Proof state:
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
⊢ {b : Bool} →
    (l : Lists' α b) →
      PProd (C { fst := b, snd := l })
        (match b, l with
        | true, l => D l
        | false, x => PUnit.{u_3})

Next tactic:
intros b l
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
  intros b l
  

Proof state:
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
b : Bool
l : Lists' α b
⊢ PProd (C { fst := b, snd := l })
    (match b, l with
    | true, l => D l
    | false, x => PUnit.{u_3})

Next tactic:
induction' l with a b a l IH₁ IH
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
  intros b l
  induction' l with a b a l IH₁ IH
  · 

Proof state:
case atom
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
b : Bool
a : α
⊢ PProd (C { fst := false, snd := Lists'.atom a })
    (match false, Lists'.atom a with
    | true, l => D l
    | false, x => PUnit.{u_3})

Next tactic:
exact ⟨C0 _, ⟨⟩⟩
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
  intros b l
  induction' l with a b a l IH₁ IH
  · exact ⟨C0 _, ⟨⟩⟩
  · 

Proof state:
case nil
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
b : Bool
⊢ PProd (C { fst := true, snd := Lists'.nil })
    (match true, Lists'.nil with
    | true, l => D l
    | false, x => PUnit.{u_3})

Next tactic:
exact ⟨C1 _ D0, D0⟩
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
  intros b l
  induction' l with a b a l IH₁ IH
  · exact ⟨C0 _, ⟨⟩⟩
  · exact ⟨C1 _ D0, D0⟩
  · 

Proof state:
case cons'
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
b✝ b : Bool
a : Lists' α b
l : Lists' α true
IH₁ :
  PProd (C { fst := b, snd := a })
    (match b, a with
    | true, l => D l
    | false, x => PUnit.{u_3})
IH :
  PProd (C { fst := true, snd := l })
    (match true, l with
    | true, l => D l
    | false, x => PUnit.{u_3})
⊢ PProd (C { fst := true, snd := Lists'.cons' a l })
    (match true, Lists'.cons' a l with
    | true, l => D l
    | false, x => PUnit.{u_3})

Next tactic:
have : D (Lists'.cons' a l) := D1 ⟨_, _⟩ _ IH₁.1 IH.2
/-- A recursion principle for pairs of ZFA lists and proper ZFA prelists. -/
def inductionMut (C : Lists α → Sort*) (D : Lists' α true → Sort*)
    (C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
    (D0 : D Lists'.nil) (D1 : ∀ a l, C a → D l → D (Lists'.cons a l)) :
    PProd (∀ l, C l) (∀ l, D l) := by
  suffices
    ∀ {b} (l : Lists' α b),
      PProd (C ⟨_, l⟩)
        (match b, l with
        | true, l => D l
        | false, _ => PUnit)
    by exact ⟨fun ⟨b, l⟩ => (this _).1, fun l => (this l).2⟩
  intros b l
  induction' l with a b a l IH₁ IH
  · exact ⟨C0 _, ⟨⟩⟩
  · exact ⟨C1 _ D0, D0⟩
  · have : D (Lists'.cons' a l) := D1 ⟨_, _⟩ _ IH₁.1 IH.2
    

Proof state:
case cons'
α : Type u_1
C : Lists α → Sort u_2
D : Lists' α true → Sort u_3
C0 : (a : α) → C (atom a)
C1 : (l : Lists' α true) → D l → C (of' l)
D0 : D Lists'.nil
D1 : (a : Lists α) → (l : Lists' α true) → C a → D l → D (Lists'.cons a l)
b✝ b : Bool
a : Lists' α b
l : Lists' α true
IH₁ :
  PProd (C { fst := b, snd := a })
    (match b, a with
    | true, l => D l
    | false, x => PUnit.{u_3})
IH :
  PProd (C { fst := true, snd := l })
    (match true, l with
    | true, l => D l
    | false, x => PUnit.{u_3})
this : D (Lists'.cons' a l)
⊢ PProd (C { fst := true, snd := Lists'.cons' a l })
    (match true, Lists'.cons' a l with
    | true, l => D l
    | false, x => PUnit.{u_3})

Next tactic:
exact ⟨C1 _ this, this⟩
theorem Equiv.antisymm_iff {l₁ l₂ : Lists' α true} : of' l₁ ~ of' l₂ ↔ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁ := by
  

Proof state:
α : Type u_1
l₁ l₂ : Lists' α true
⊢ of' l₁ ~ of' l₂ ↔ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁

Next tactic:
refine' ⟨fun h => _, fun ⟨h₁, h₂⟩ => Equiv.antisymm h₁ h₂⟩
theorem Equiv.antisymm_iff {l₁ l₂ : Lists' α true} : of' l₁ ~ of' l₂ ↔ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁ := by
  refine' ⟨fun h => _, fun ⟨h₁, h₂⟩ => Equiv.antisymm h₁ h₂⟩
  

Proof state:
α : Type u_1
l₁ l₂ : Lists' α true
h : of' l₁ ~ of' l₂
⊢ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁

Next tactic:
cases' h with _ _ _ h₁ h₂
theorem Equiv.antisymm_iff {l₁ l₂ : Lists' α true} : of' l₁ ~ of' l₂ ↔ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁ := by
  refine' ⟨fun h => _, fun ⟨h₁, h₂⟩ => Equiv.antisymm h₁ h₂⟩
  cases' h with _ _ _ h₁ h₂
  · 

Proof state:
case refl
α : Type u_1
l₁ : Lists' α true
⊢ l₁ ⊆ l₁ ∧ l₁ ⊆ l₁

Next tactic:
simp [Lists'.Subset.refl]
theorem Equiv.antisymm_iff {l₁ l₂ : Lists' α true} : of' l₁ ~ of' l₂ ↔ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁ := by
  refine' ⟨fun h => _, fun ⟨h₁, h₂⟩ => Equiv.antisymm h₁ h₂⟩
  cases' h with _ _ _ h₁ h₂
  · simp [Lists'.Subset.refl]
  · 

Proof state:
case antisymm
α : Type u_1
l₁ l₂ : Lists' α true
h₁ : Lists'.Subset l₁ l₂
h₂ : Lists'.Subset l₂ l₁
⊢ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁

Next tactic:
exact ⟨h₁, h₂⟩
theorem equiv_atom {a} {l : Lists α} : atom a ~ l ↔ atom a = l :=
  ⟨fun h => by 

Proof state:
α : Type u_1
a : α
l : Lists α
h : atom a ~ l
⊢ atom a = l

Next tactic:
cases h
theorem equiv_atom {a} {l : Lists α} : atom a ~ l ↔ atom a = l :=
  ⟨fun h => by cases h; 

Proof state:
case refl
α : Type u_1
a : α
⊢ atom a = atom a

Next tactic:
rfl
@[symm]
theorem Equiv.symm {l₁ l₂ : Lists α} (h : l₁ ~ l₂) : l₂ ~ l₁ := by
  

Proof state:
α : Type u_1
l₁ l₂ : Lists α
h : l₁ ~ l₂
⊢ l₂ ~ l₁

Next tactic:
cases' h with _ _ _ h₁ h₂ <;> [rfl; exact Equiv.antisymm h₂ h₁]
@[symm]
theorem Equiv.symm {l₁ l₂ : Lists α} (h : l₁ ~ l₂) : l₂ ~ l₁ := by
  

Proof state:
α : Type u_1
l₁ l₂ : Lists α
h : l₁ ~ l₂
⊢ l₂ ~ l₁

Next tactic:
cases' h with _ _ _ h₁ h₂
@[symm]
theorem Equiv.symm {l₁ l₂ : Lists α} (h : l₁ ~ l₂) : l₂ ~ l₁ := by
  cases' h with _ _ _ h₁ h₂ <;> [

Proof state:
case refl
α : Type u_1
l₁ : Lists α
⊢ l₁ ~ l₁

Next tactic:
rfl
@[symm]
theorem Equiv.symm {l₁ l₂ : Lists α} (h : l₁ ~ l₂) : l₂ ~ l₁ := by
  cases' h with _ _ _ h₁ h₂ <;> [rfl; 

Proof state:
case antisymm
α : Type u_1
l₁✝ l₂✝ : Lists' α true
h₁ : Lists'.Subset l₁✝ l₂✝
h₂ : Lists'.Subset l₂✝ l₁✝
⊢ { fst := true, snd := l₂✝ } ~ { fst := true, snd := l₁✝ }

Next tactic:
exact Equiv.antisymm h₂ h₁
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  

Proof state:
α : Type u_1
⊢ ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃

Next tactic:
let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  

Proof state:
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
⊢ ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃

Next tactic:
suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by 

Proof state:
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
this : PProd (∀ (l₁ : Lists α), trans l₁) (∀ (l : Lists' α true) (l' : Lists α), l' ∈ Lists'.toList l → trans l')
⊢ ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃

Next tactic:
exact this.1
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  

Proof state:
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
⊢ PProd (∀ (l₁ : Lists α), trans l₁) (∀ (l : Lists' α true) (l' : Lists α), l' ∈ Lists'.toList l → trans l')

Next tactic:
apply inductionMut
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · 

Proof state:
case C0
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
⊢ ∀ (a : α), trans (atom a)

Next tactic:
intro a l₂ l₃ h₁ h₂
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    

Proof state:
case C0
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
a : α
l₂ l₃ : Lists α
h₁ : atom a ~ l₂
h₂ : l₂ ~ l₃
⊢ atom a ~ l₃

Next tactic:
rwa [← equiv_atom.1 h₁] at h₂
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    rwa [← equiv_atom.1 h₁] at h₂
  · 

Proof state:
case C1
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
⊢ ∀ (l : Lists' α true), (∀ (l' : Lists α), l' ∈ Lists'.toList l → trans l') → trans (of' l)

Next tactic:
intro l₁ IH l₂ l₃ h₁ h₂
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    rwa [← equiv_atom.1 h₁] at h₂
  · intro l₁ IH l₂ l₃ h₁ h₂
    -- Porting note: Two 'have's are for saving the state.
    

Proof state:
case C1
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
l₁ : Lists' α true
IH : ∀ (l' : Lists α), l' ∈ Lists'.toList l₁ → trans l'
l₂ l₃ : Lists α
h₁ : of' l₁ ~ l₂
h₂ : l₂ ~ l₃
⊢ of' l₁ ~ l₃

Next tactic:
have h₁' := h₁
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    rwa [← equiv_atom.1 h₁] at h₂
  · intro l₁ IH l₂ l₃ h₁ h₂
    -- Porting note: Two 'have's are for saving the state.
    have h₁' := h₁
    

Proof state:
case C1
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
l₁ : Lists' α true
IH : ∀ (l' : Lists α), l' ∈ Lists'.toList l₁ → trans l'
l₂ l₃ : Lists α
h₁ : of' l₁ ~ l₂
h₂ : l₂ ~ l₃
h₁' : of' l₁ ~ l₂
⊢ of' l₁ ~ l₃

Next tactic:
have h₂' := h₂
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    rwa [← equiv_atom.1 h₁] at h₂
  · intro l₁ IH l₂ l₃ h₁ h₂
    -- Porting note: Two 'have's are for saving the state.
    have h₁' := h₁
    have h₂' := h₂
    

Proof state:
case C1
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
l₁ : Lists' α true
IH : ∀ (l' : Lists α), l' ∈ Lists'.toList l₁ → trans l'
l₂ l₃ : Lists α
h₁ : of' l₁ ~ l₂
h₂ : l₂ ~ l₃
h₁' : of' l₁ ~ l₂
h₂' : l₂ ~ l₃
⊢ of' l₁ ~ l₃

Next tactic:
cases' h₁ with _ _ l₂
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    rwa [← equiv_atom.1 h₁] at h₂
  · intro l₁ IH l₂ l₃ h₁ h₂
    -- Porting note: Two 'have's are for saving the state.
    have h₁' := h₁
    have h₂' := h₂
    cases' h₁ with _ _ l₂
    · 

Proof state:
case C1.refl
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
l₁ : Lists' α true
IH : ∀ (l' : Lists α), l' ∈ Lists'.toList l₁ → trans l'
l₃ : Lists α
h₂ : of' l₁ ~ l₃
h₁' : of' l₁ ~ of' l₁
h₂' : of' l₁ ~ l₃
⊢ of' l₁ ~ l₃

Next tactic:
exact h₂
theorem Equiv.trans : ∀ {l₁ l₂ l₃ : Lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ := by
  let trans := fun l₁ : Lists α => ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
  suffices PProd (∀ l₁, trans l₁) (∀ (l : Lists' α true), ∀ l' ∈ l.toList, trans l') by exact this.1
  apply inductionMut
  · intro a l₂ l₃ h₁ h₂
    rwa [← equiv_atom.1 h₁] at h₂
  · intro l₁ IH l₂ l₃ h₁ h₂
    -- Porting note: Two 'have's are for saving the state.
    have h₁' := h₁
    have h₂' := h₂
    cases' h₁ with _ _ l₂
    · exact h₂
    

Proof state:
case C1.antisymm
α : Type u_1
trans : Lists α → Prop := fun l₁ => ∀ ⦃l₂ l₃ : Lists α⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃
l₁ : Lists' α true
IH : ∀ (l' : Lists α), l' ∈ Lists'.toList l₁ → trans l'
l₃ : Lists α
l₂ : Lists' α true
a✝¹ : Lists'.Subset l₁ l₂
a✝ : Lists'.Subset l₂ l₁
h₂ : { fst := true, snd := l₂ } ~ l₃
h₁' : of' l₁ ~ { fst := true, snd := l₂ }
h₂' : { fst := true, snd := l₂ } ~ l₃
⊢ of' l₁ ~ l₃

Next tactic:
cases' h₂ with _ _ l₃