l3lab/ntp-mathlib huggingface dataset:
theorem cons_subperm_of_mem {a : α} {l₁ l₂ : List α} (d₁ : Nodup l₁) (h₁ : a ∉ l₁) (h₂ : a ∈ l₂)
    (s : l₁ <+~ l₂) : a :: l₁ <+~ l₂ := by
  rcases s with ⟨l, p, s⟩
  induction s generalizing l₁
  case slnil => cases h₂
  case cons r₁ r₂ b s' ih =>
    simp? at h₂ says simp only [Bool.not_eq_true, mem_cons] at h₂
    cases' h₂ with e m
    · subst b
      exact ⟨a :: r₁, p.cons a, s'.cons₂ _⟩
    · rcases ih d₁ h₁ m p with ⟨t, p', s'⟩
      exact ⟨t, p', s'.cons _⟩
  case cons₂ r₁ r₂ b _ ih =>
    have bm : b ∈ l₁ := p.subset <| mem_cons_self _ _
    have am : a ∈ r₂ := by
      simp only [find?, mem_cons] at h₂
      exact h₂.resolve_left fun e => h₁ <| e.symm ▸ bm
    rcases mem_split bm with ⟨t₁, t₂, rfl⟩
    

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
l✝ l₁ l₂✝ : List α
a✝¹ a : α
l₂ l r₁ r₂ : List α
b : α
a✝ : r₁ <+ r₂
ih : ∀ {l₁ : List α}, Nodup l₁ → a ∉ l₁ → a ∈ r₂ → r₁ ~ l₁ → a :: l₁ <+~ r₂
h₂ : a ∈ b :: r₂
am : a ∈ r₂
t₁ t₂ : List α
d₁ : Nodup (t₁ ++ b :: t₂)
h₁ : a ∉ t₁ ++ b :: t₂
p : b :: r₁ ~ t₁ ++ b :: t₂
bm : b ∈ t₁ ++ b :: t₂
⊢ a :: (t₁ ++ b :: t₂) <+~ b :: r₂

Next tactic:
have st : t₁ ++ t₂ <+ t₁ ++ b :: t₂ := by simp
theorem cons_subperm_of_mem {a : α} {l₁ l₂ : List α} (d₁ : Nodup l₁) (h₁ : a ∉ l₁) (h₂ : a ∈ l₂)
    (s : l₁ <+~ l₂) : a :: l₁ <+~ l₂ := by
  rcases s with ⟨l, p, s⟩
  induction s generalizing l₁
  case slnil => cases h₂
  case cons r₁ r₂ b s' ih =>
    simp? at h₂ says simp only [Bool.not_eq_true, mem_cons] at h₂
    cases' h₂ with e m
    · subst b
      exact ⟨a :: r₁, p.cons a, s'.cons₂ _⟩
    · rcases ih d₁ h₁ m p with ⟨t, p', s'⟩
      exact ⟨t, p', s'.cons _⟩
  case cons₂ r₁ r₂ b _ ih =>
    have bm : b ∈ l₁ := p.subset <| mem_cons_self _ _
    have am : a ∈ r₂ := by
      simp only [find?, mem_cons] at h₂
      exact h₂.resolve_left fun e => h₁ <| e.symm ▸ bm
    rcases mem_split bm with ⟨t₁, t₂, rfl⟩
    have st : t₁ ++ t₂ <+ t₁ ++ b :: t₂ := by 

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂✝ : List α
a✝¹ a : α
l₂ l r₁ r₂ : List α
b : α
a✝ : r₁ <+ r₂
ih : ∀ {l₁ : List α}, Nodup l₁ → a ∉ l₁ → a ∈ r₂ → r₁ ~ l₁ → a :: l₁ <+~ r₂
h₂ : a ∈ b :: r₂
am : a ∈ r₂
t₁ t₂ : List α
d₁ : Nodup (t₁ ++ b :: t₂)
h₁ : a ∉ t₁ ++ b :: t₂
p : b :: r₁ ~ t₁ ++ b :: t₂
bm : b ∈ t₁ ++ b :: t₂
⊢ t₁ ++ t₂ <+ t₁ ++ b :: t₂

Next tactic:
simp
theorem cons_subperm_of_mem {a : α} {l₁ l₂ : List α} (d₁ : Nodup l₁) (h₁ : a ∉ l₁) (h₂ : a ∈ l₂)
    (s : l₁ <+~ l₂) : a :: l₁ <+~ l₂ := by
  rcases s with ⟨l, p, s⟩
  induction s generalizing l₁
  case slnil => cases h₂
  case cons r₁ r₂ b s' ih =>
    simp? at h₂ says simp only [Bool.not_eq_true, mem_cons] at h₂
    cases' h₂ with e m
    · subst b
      exact ⟨a :: r₁, p.cons a, s'.cons₂ _⟩
    · rcases ih d₁ h₁ m p with ⟨t, p', s'⟩
      exact ⟨t, p', s'.cons _⟩
  case cons₂ r₁ r₂ b _ ih =>
    have bm : b ∈ l₁ := p.subset <| mem_cons_self _ _
    have am : a ∈ r₂ := by
      simp only [find?, mem_cons] at h₂
      exact h₂.resolve_left fun e => h₁ <| e.symm ▸ bm
    rcases mem_split bm with ⟨t₁, t₂, rfl⟩
    have st : t₁ ++ t₂ <+ t₁ ++ b :: t₂ := by simp
    

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
l✝ l₁ l₂✝ : List α
a✝¹ a : α
l₂ l r₁ r₂ : List α
b : α
a✝ : r₁ <+ r₂
ih : ∀ {l₁ : List α}, Nodup l₁ → a ∉ l₁ → a ∈ r₂ → r₁ ~ l₁ → a :: l₁ <+~ r₂
h₂ : a ∈ b :: r₂
am : a ∈ r₂
t₁ t₂ : List α
d₁ : Nodup (t₁ ++ b :: t₂)
h₁ : a ∉ t₁ ++ b :: t₂
p : b :: r₁ ~ t₁ ++ b :: t₂
bm : b ∈ t₁ ++ b :: t₂
st : t₁ ++ t₂ <+ t₁ ++ b :: t₂
⊢ a :: (t₁ ++ b :: t₂) <+~ b :: r₂

Next tactic:
rcases ih (d₁.sublist st) (mt (fun x => st.subset x) h₁) am
        (Perm.cons_inv <| p.trans perm_middle) with
      ⟨t, p', s'⟩
theorem cons_subperm_of_mem {a : α} {l₁ l₂ : List α} (d₁ : Nodup l₁) (h₁ : a ∉ l₁) (h₂ : a ∈ l₂)
    (s : l₁ <+~ l₂) : a :: l₁ <+~ l₂ := by
  rcases s with ⟨l, p, s⟩
  induction s generalizing l₁
  case slnil => cases h₂
  case cons r₁ r₂ b s' ih =>
    simp? at h₂ says simp only [Bool.not_eq_true, mem_cons] at h₂
    cases' h₂ with e m
    · subst b
      exact ⟨a :: r₁, p.cons a, s'.cons₂ _⟩
    · rcases ih d₁ h₁ m p with ⟨t, p', s'⟩
      exact ⟨t, p', s'.cons _⟩
  case cons₂ r₁ r₂ b _ ih =>
    have bm : b ∈ l₁ := p.subset <| mem_cons_self _ _
    have am : a ∈ r₂ := by
      simp only [find?, mem_cons] at h₂
      exact h₂.resolve_left fun e => h₁ <| e.symm ▸ bm
    rcases mem_split bm with ⟨t₁, t₂, rfl⟩
    have st : t₁ ++ t₂ <+ t₁ ++ b :: t₂ := by simp
    rcases ih (d₁.sublist st) (mt (fun x => st.subset x) h₁) am
        (Perm.cons_inv <| p.trans perm_middle) with
      ⟨t, p', s'⟩
    

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
l✝ l₁ l₂✝ : List α
a✝¹ a : α
l₂ l r₁ r₂ : List α
b : α
a✝ : r₁ <+ r₂
ih : ∀ {l₁ : List α}, Nodup l₁ → a ∉ l₁ → a ∈ r₂ → r₁ ~ l₁ → a :: l₁ <+~ r₂
h₂ : a ∈ b :: r₂
am : a ∈ r₂
t₁ t₂ : List α
d₁ : Nodup (t₁ ++ b :: t₂)
h₁ : a ∉ t₁ ++ b :: t₂
p : b :: r₁ ~ t₁ ++ b :: t₂
bm : b ∈ t₁ ++ b :: t₂
st : t₁ ++ t₂ <+ t₁ ++ b :: t₂
t : List α
p' : t ~ a :: (t₁ ++ t₂)
s' : t <+ r₂
⊢ a :: (t₁ ++ b :: t₂) <+~ b :: r₂

Next tactic:
exact
      ⟨b :: t, (p'.cons b).trans <| (swap _ _ _).trans (perm_middle.symm.cons a), s'.cons₂ _⟩
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  

Proof state:
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ t : List α
h : l₁ ~ l₂
⊢ List.bagInter l₁ t ~ List.bagInter l₂ t

Next tactic:
induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · 

Proof state:
case nil
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ t : List α
⊢ List.bagInter [] t ~ List.bagInter [] t

Next tactic:
simp
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
l l₁✝¹ l₂✝¹ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
a✝ : l₁✝ ~ l₂✝
a_ih✝ : ∀ (t : List α), List.bagInter l₁✝ t ~ List.bagInter l₂✝ t
t : List α
⊢ List.bagInter (x :: l₁✝) t ~ List.bagInter (x :: l₂✝) t

Next tactic:
by_cases x ∈ t
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
l l₁✝¹ l₂✝¹ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
a✝ : l₁✝ ~ l₂✝
a_ih✝ : ∀ (t : List α), List.bagInter l₁✝ t ~ List.bagInter l₂✝ t
t : List α
h✝ : x ∈ t
⊢ List.bagInter (x :: l₁✝) t ~ List.bagInter (x :: l₂✝) t

Next tactic:
simp [*, Perm.cons]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
l l₁✝¹ l₂✝¹ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x : α
l₁✝ l₂✝ : List α
a✝ : l₁✝ ~ l₂✝
a_ih✝ : ∀ (t : List α), List.bagInter l₁✝ t ~ List.bagInter l₂✝ t
t : List α
h✝ : x ∉ t
⊢ List.bagInter (x :: l₁✝) t ~ List.bagInter (x :: l₂✝) t

Next tactic:
simp [*, Perm.cons]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · 

Proof state:
case swap
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
by_cases h : x = y
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : x = y
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
simp [h]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    

Proof state:
case neg
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
by_cases xt : x ∈ t
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
xt : x ∈ t
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
by_cases yt : y ∈ t
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
xt : x ∉ t
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
by_cases yt : y ∈ t
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> by_cases yt : y ∈ t
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
xt : x ∈ t
yt : y ∈ t
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
simp [xt, yt, mem_erase_of_ne h, mem_erase_of_ne (Ne.symm h), erase_comm, swap]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> by_cases yt : y ∈ t
    · simp [xt, yt, mem_erase_of_ne h, mem_erase_of_ne (Ne.symm h), erase_comm, swap]
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
xt : x ∈ t
yt : y ∉ t
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> by_cases yt : y ∈ t
    · simp [xt, yt, mem_erase_of_ne h, mem_erase_of_ne (Ne.symm h), erase_comm, swap]
    · simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
xt : x ∉ t
yt : y ∈ t
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> by_cases yt : y ∈ t
    · simp [xt, yt, mem_erase_of_ne h, mem_erase_of_ne (Ne.symm h), erase_comm, swap]
    · simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
    · simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ : List α
x y : α
l✝ t : List α
h : ¬x = y
xt : x ∉ t
yt : y ∉ t
⊢ List.bagInter (y :: x :: l✝) t ~ List.bagInter (x :: y :: l✝) t

Next tactic:
simp [xt, yt]
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
    l₁.bagInter t ~ l₂.bagInter t := by
  induction' h with x _ _ _ _ x y _ _ _ _ _ _ ih_1 ih_2 generalizing t; · simp
  · by_cases x ∈ t <;> simp [*, Perm.cons]
  · by_cases h : x = y
    · simp [h]
    by_cases xt : x ∈ t <;> by_cases yt : y ∈ t
    · simp [xt, yt, mem_erase_of_ne h, mem_erase_of_ne (Ne.symm h), erase_comm, swap]
    · simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
    · simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
    · simp [xt, yt]
  · 

Proof state:
case trans
α : Type u_1
β : Type u_2
l l₁✝¹ l₂✝¹ : List α
a : α
inst✝ : DecidableEq α
l₁ l₂ l₁✝ l₂✝ l₃✝ : List α
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
ih_1 : ∀ (t : List α), List.bagInter l₁✝ t ~ List.bagInter l₂✝ t
ih_2 : ∀ (t : List α), List.bagInter l₂✝ t ~ List.bagInter l₃✝ t
t : List α
⊢ List.bagInter l₁✝ t ~ List.bagInter l₃✝ t

Next tactic:
exact (ih_1 _).trans (ih_2 _)
theorem Perm.bagInter_left (l : List α) {t₁ t₂ : List α} (p : t₁ ~ t₂) :
    l.bagInter t₁ = l.bagInter t₂ := by
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
l t₁ t₂ : List α
p : t₁ ~ t₂
⊢ List.bagInter l t₁ = List.bagInter l t₂

Next tactic:
induction' l with a l IH generalizing t₁ t₂ p
theorem Perm.bagInter_left (l : List α) {t₁ t₂ : List α} (p : t₁ ~ t₂) :
    l.bagInter t₁ = l.bagInter t₂ := by
  induction' l with a l IH generalizing t₁ t₂ p; · 

Proof state:
case nil
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
p : t₁ ~ t₂
⊢ List.bagInter [] t₁ = List.bagInter [] t₂

Next tactic:
simp
theorem Perm.bagInter_left (l : List α) {t₁ t₂ : List α} (p : t₁ ~ t₂) :
    l.bagInter t₁ = l.bagInter t₂ := by
  induction' l with a l IH generalizing t₁ t₂ p; · simp
  

Proof state:
case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
a : α
l : List α
IH : ∀ {t₁ t₂ : List α}, t₁ ~ t₂ → List.bagInter l t₁ = List.bagInter l t₂
t₁ t₂ : List α
p : t₁ ~ t₂
⊢ List.bagInter (a :: l) t₁ = List.bagInter (a :: l) t₂

Next tactic:
by_cases h : a ∈ t₁
theorem Perm.bagInter_left (l : List α) {t₁ t₂ : List α} (p : t₁ ~ t₂) :
    l.bagInter t₁ = l.bagInter t₂ := by
  induction' l with a l IH generalizing t₁ t₂ p; · simp
  by_cases h : a ∈ t₁
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
a : α
l : List α
IH : ∀ {t₁ t₂ : List α}, t₁ ~ t₂ → List.bagInter l t₁ = List.bagInter l t₂
t₁ t₂ : List α
p : t₁ ~ t₂
h : a ∈ t₁
⊢ List.bagInter (a :: l) t₁ = List.bagInter (a :: l) t₂

Next tactic:
simp [h, p.subset h, IH (p.erase _)]
theorem Perm.bagInter_left (l : List α) {t₁ t₂ : List α} (p : t₁ ~ t₂) :
    l.bagInter t₁ = l.bagInter t₂ := by
  induction' l with a l IH generalizing t₁ t₂ p; · simp
  by_cases h : a ∈ t₁
  · simp [h, p.subset h, IH (p.erase _)]
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
a : α
l : List α
IH : ∀ {t₁ t₂ : List α}, t₁ ~ t₂ → List.bagInter l t₁ = List.bagInter l t₂
t₁ t₂ : List α
p : t₁ ~ t₂
h : a ∉ t₁
⊢ List.bagInter (a :: l) t₁ = List.bagInter (a :: l) t₂

Next tactic:
simp [h, mt p.mem_iff.2 h, IH p]
theorem perm_replicate_append_replicate {l : List α} {a b : α} {m n : ℕ} (h : a ≠ b) :
    l ~ replicate m a ++ replicate n b ↔ count a l = m ∧ count b l = n ∧ l ⊆ [a, b] := by
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
l : List α
a b : α
m n : ℕ
h : a ≠ b
⊢ l ~ replicate m a ++ replicate n b ↔ count a l = m ∧ count b l = n ∧ l ⊆ [a, b]

Next tactic:
rw [perm_iff_count, ← Decidable.and_forall_ne a, ← Decidable.and_forall_ne b]
theorem perm_replicate_append_replicate {l : List α} {a b : α} {m n : ℕ} (h : a ≠ b) :
    l ~ replicate m a ++ replicate n b ↔ count a l = m ∧ count b l = n ∧ l ⊆ [a, b] := by
  rw [perm_iff_count, ← Decidable.and_forall_ne a, ← Decidable.and_forall_ne b]
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
l : List α
a b : α
m n : ℕ
h : a ≠ b
⊢ (count a l = count a (replicate m a ++ replicate n b) ∧
      (b ≠ a → count b l = count b (replicate m a ++ replicate n b)) ∧
        ∀ (b_1 : α), b_1 ≠ b → b_1 ≠ a → count b_1 l = count b_1 (replicate m a ++ replicate n b)) ↔
    count a l = m ∧ count b l = n ∧ l ⊆ [a, b]

Next tactic:
suffices l ⊆ [a, b] ↔ ∀ c, c ≠ b → c ≠ a → c ∉ l by
    simp (config := { contextual := true }) [count_replicate, h, h.symm, this, count_eq_zero]
theorem perm_replicate_append_replicate {l : List α} {a b : α} {m n : ℕ} (h : a ≠ b) :
    l ~ replicate m a ++ replicate n b ↔ count a l = m ∧ count b l = n ∧ l ⊆ [a, b] := by
  rw [perm_iff_count, ← Decidable.and_forall_ne a, ← Decidable.and_forall_ne b]
  suffices l ⊆ [a, b] ↔ ∀ c, c ≠ b → c ≠ a → c ∉ l by
    

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
l : List α
a b : α
m n : ℕ
h : a ≠ b
this : l ⊆ [a, b] ↔ ∀ (c : α), c ≠ b → c ≠ a → c ∉ l
⊢ (count a l = count a (replicate m a ++ replicate n b) ∧
      (b ≠ a → count b l = count b (replicate m a ++ replicate n b)) ∧
        ∀ (b_1 : α), b_1 ≠ b → b_1 ≠ a → count b_1 l = count b_1 (replicate m a ++ replicate n b)) ↔
    count a l = m ∧ count b l = n ∧ l ⊆ [a, b]

Next tactic:
simp (config := { contextual := true }) [count_replicate, h, h.symm, this, count_eq_zero]
theorem perm_replicate_append_replicate {l : List α} {a b : α} {m n : ℕ} (h : a ≠ b) :
    l ~ replicate m a ++ replicate n b ↔ count a l = m ∧ count b l = n ∧ l ⊆ [a, b] := by
  rw [perm_iff_count, ← Decidable.and_forall_ne a, ← Decidable.and_forall_ne b]
  suffices l ⊆ [a, b] ↔ ∀ c, c ≠ b → c ≠ a → c ∉ l by
    simp (config := { contextual := true }) [count_replicate, h, h.symm, this, count_eq_zero]
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
inst✝ : DecidableEq α
l : List α
a b : α
m n : ℕ
h : a ≠ b
⊢ l ⊆ [a, b] ↔ ∀ (c : α), c ≠ b → c ≠ a → c ∉ l

Next tactic:
simp_rw [Ne.def, ← and_imp, ← not_or, Decidable.not_imp_not, subset_def, mem_cons,
    not_mem_nil, or_false, or_comm]
theorem Perm.dedup {l₁ l₂ : List α} (p : l₁ ~ l₂) : dedup l₁ ~ dedup l₂ :=
  perm_iff_count.2 fun a =>
    if h : a ∈ l₁ then by 

Proof state:
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a✝ : α
inst✝ : DecidableEq α
l₁ l₂ : List α
p : l₁ ~ l₂
a : α
h : a ∈ l₁
⊢ count a (List.dedup l₁) = count a (List.dedup l₂)

Next tactic:
simp [nodup_dedup, h, p.subset h]
theorem Perm.dedup {l₁ l₂ : List α} (p : l₁ ~ l₂) : dedup l₁ ~ dedup l₂ :=
  perm_iff_count.2 fun a =>
    if h : a ∈ l₁ then by simp [nodup_dedup, h, p.subset h] else by 

Proof state:
α : Type u_1
β : Type u_2
l l₁✝ l₂✝ : List α
a✝ : α
inst✝ : DecidableEq α
l₁ l₂ : List α
p : l₁ ~ l₂
a : α
h : a ∉ l₁
⊢ count a (List.dedup l₁) = count a (List.dedup l₂)

Next tactic:
simp [h, mt p.mem_iff.2 h]
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
l t₁ t₂ : List α
h : Disjoint t₁ t₂
⊢ l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂

Next tactic:
induction l
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  

Proof state:
case nil
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
⊢ [] ∩ (t₁ ++ t₂) ~ [] ∩ t₁ ++ [] ∩ t₂
case cons
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
head✝ : α
tail✝ : List α
tail_ih✝ : tail✝ ∩ (t₁ ++ t₂) ~ tail✝ ∩ t₁ ++ tail✝ ∩ t₂
⊢ (head✝ :: tail✝) ∩ (t₁ ++ t₂) ~ (head✝ :: tail✝) ∩ t₁ ++ (head✝ :: tail✝) ∩ t₂

Next tactic:
case nil => simp
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
⊢ [] ∩ (t₁ ++ t₂) ~ [] ∩ t₁ ++ [] ∩ t₂

Next tactic:
case nil => simp
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  case nil => 

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
⊢ [] ∩ (t₁ ++ t₂) ~ [] ∩ t₁ ++ [] ∩ t₂

Next tactic:
simp
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  case nil => simp
  

Proof state:
case cons
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
head✝ : α
tail✝ : List α
tail_ih✝ : tail✝ ∩ (t₁ ++ t₂) ~ tail✝ ∩ t₁ ++ tail✝ ∩ t₂
⊢ (head✝ :: tail✝) ∩ (t₁ ++ t₂) ~ (head✝ :: tail✝) ∩ t₁ ++ (head✝ :: tail✝) ∩ t₂

Next tactic:
case cons x xs l_ih =>
    by_cases h₁ : x ∈ t₁
    · have h₂ : x ∉ t₂ := h h₁
      simp [*]
    by_cases h₂ : x ∈ t₂
    · simp only [*, inter_cons_of_not_mem, false_or_iff, mem_append, inter_cons_of_mem,
        not_false_iff]
      refine' Perm.trans (Perm.cons _ l_ih) _
      change [x] ++ xs ∩ t₁ ++ xs ∩ t₂ ~ xs ∩ t₁ ++ ([x] ++ xs ∩ t₂)
      rw [← List.append_assoc]
      solve_by_elim [Perm.append_right, perm_append_comm]
    · simp [*]
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  case nil => simp
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
x : α
xs : List α
l_ih : xs ∩ (t₁ ++ t₂) ~ xs ∩ t₁ ++ xs ∩ t₂
⊢ (x :: xs) ∩ (t₁ ++ t₂) ~ (x :: xs) ∩ t₁ ++ (x :: xs) ∩ t₂

Next tactic:
case cons x xs l_ih =>
    by_cases h₁ : x ∈ t₁
    · have h₂ : x ∉ t₂ := h h₁
      simp [*]
    by_cases h₂ : x ∈ t₂
    · simp only [*, inter_cons_of_not_mem, false_or_iff, mem_append, inter_cons_of_mem,
        not_false_iff]
      refine' Perm.trans (Perm.cons _ l_ih) _
      change [x] ++ xs ∩ t₁ ++ xs ∩ t₂ ~ xs ∩ t₁ ++ ([x] ++ xs ∩ t₂)
      rw [← List.append_assoc]
      solve_by_elim [Perm.append_right, perm_append_comm]
    · simp [*]
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  case nil => simp
  case cons x xs l_ih =>
    

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
x : α
xs : List α
l_ih : xs ∩ (t₁ ++ t₂) ~ xs ∩ t₁ ++ xs ∩ t₂
⊢ (x :: xs) ∩ (t₁ ++ t₂) ~ (x :: xs) ∩ t₁ ++ (x :: xs) ∩ t₂

Next tactic:
by_cases h₁ : x ∈ t₁
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
    l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
  induction l
  case nil => simp
  case cons x xs l_ih =>
    by_cases h₁ : x ∈ t₁
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
inst✝ : DecidableEq α
t₁ t₂ : List α
h : Disjoint t₁ t₂
x : α
xs : List α
l_ih : xs ∩ (t₁ ++ t₂) ~ xs ∩ t₁ ++ xs ∩ t₂
h₁ : x ∈ t₁
⊢ (x :: xs) ∩ (t₁ ++ t₂) ~ (x :: xs) ∩ t₁ ++ (x :: xs) ∩ t₂

Next tactic:
have h₂ : x ∉ t₂ := h h₁