l3lab/ntp-mathlib huggingface dataset:
instance [IsEmpty α] : Unique (Multiset α) where
  default := 0
  uniq := by rintro ⟨_ | ⟨a, l⟩⟩; 

Proof state:
case mk.nil
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : IsEmpty α
a✝ : Multiset α
⊢ Quot.mk Setoid.r [] = default
case mk.cons
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : IsEmpty α
a✝ : Multiset α
a : α
l : List α
⊢ Quot.mk Setoid.r (a :: l) = default

Next tactic:
exacts [rfl, isEmptyElim a]
@[simp]
theorem cons_inj_right (a : α) : ∀ {s t : Multiset α}, a ::ₘ s = a ::ₘ t ↔ s = t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a : α
⊢ ∀ {s t : Multiset α}, a ::ₘ s = a ::ₘ t ↔ s = t

Next tactic:
rintro ⟨l₁⟩ ⟨l₂⟩
@[simp]
theorem cons_inj_right (a : α) : ∀ {s t : Multiset α}, a ::ₘ s = a ::ₘ t ↔ s = t := by
  rintro ⟨l₁⟩ ⟨l₂⟩; 

Proof state:
case mk.mk
α : Type u_1
β : Type v
γ : Type u_2
a : α
s✝ : Multiset α
l₁ : List α
t✝ : Multiset α
l₂ : List α
⊢ a ::ₘ Quot.mk Setoid.r l₁ = a ::ₘ Quot.mk Setoid.r l₂ ↔ Quot.mk Setoid.r l₁ = Quot.mk Setoid.r l₂

Next tactic:
simp
@[recursor 5]
protected theorem induction {p : Multiset α → Prop} (empty : p 0)
    (cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)) : ∀ s, p s := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
p : Multiset α → Prop
empty : p 0
cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)
⊢ ∀ (s : Multiset α), p s

Next tactic:
rintro ⟨l⟩
@[recursor 5]
protected theorem induction {p : Multiset α → Prop} (empty : p 0)
    (cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)) : ∀ s, p s := by
  rintro ⟨l⟩; 

Proof state:
case mk
α : Type u_1
β : Type v
γ : Type u_2
p : Multiset α → Prop
empty : p 0
cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)
s✝ : Multiset α
l : List α
⊢ p (Quot.mk Setoid.r l)

Next tactic:
induction' l with _ _ ih <;> [exact empty; exact cons ih]
@[recursor 5]
protected theorem induction {p : Multiset α → Prop} (empty : p 0)
    (cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)) : ∀ s, p s := by
  rintro ⟨l⟩; 

Proof state:
case mk
α : Type u_1
β : Type v
γ : Type u_2
p : Multiset α → Prop
empty : p 0
cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)
s✝ : Multiset α
l : List α
⊢ p (Quot.mk Setoid.r l)

Next tactic:
induction' l with _ _ ih
@[recursor 5]
protected theorem induction {p : Multiset α → Prop} (empty : p 0)
    (cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)) : ∀ s, p s := by
  rintro ⟨l⟩; induction' l with _ _ ih <;> [

Proof state:
case mk.nil
α : Type u_1
β : Type v
γ : Type u_2
p : Multiset α → Prop
empty : p 0
cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)
s✝ : Multiset α
⊢ p (Quot.mk Setoid.r [])

Next tactic:
exact empty
@[recursor 5]
protected theorem induction {p : Multiset α → Prop} (empty : p 0)
    (cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)) : ∀ s, p s := by
  rintro ⟨l⟩; induction' l with _ _ ih <;> [exact empty; 

Proof state:
case mk.cons
α : Type u_1
β : Type v
γ : Type u_2
p : Multiset α → Prop
empty : p 0
cons : ∀ ⦃a : α⦄ {s : Multiset α}, p s → p (a ::ₘ s)
s✝ : Multiset α
head✝ : α
tail✝ : List α
ih : p (Quot.mk Setoid.r tail✝)
⊢ p (Quot.mk Setoid.r (head✝ :: tail✝))

Next tactic:
exact cons ih
/-- Dependent recursor on multisets.
TODO: should be @[recursor 6], but then the definition of `Multiset.pi` fails with a stack
overflow in `whnf`.
-/
protected
def rec (C_0 : C 0) (C_cons : ∀ a m, C m → C (a ::ₘ m))
    (C_cons_heq :
      ∀ a a' m b, HEq (C_cons a (a' ::ₘ m) (C_cons a' m b)) (C_cons a' (a ::ₘ m) (C_cons a m b)))
    (m : Multiset α) : C m :=
  Quotient.hrecOn m (@List.rec α (fun l => C ⟦l⟧) C_0 fun a l b => C_cons a ⟦l⟧ b) fun l l' h =>
    h.rec_heq
      (fun hl _ ↦ by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
C : Multiset α → Sort u_3
C_0 : C 0
C_cons : (a : α) → (m : Multiset α) → C m → C (a ::ₘ m)
C_cons_heq :
  ∀ (a a' : α) (m : Multiset α) (b : C m),
    HEq (C_cons a (a' ::ₘ m) (C_cons a' m b)) (C_cons a' (a ::ₘ m) (C_cons a m b))
m : Multiset α
l l' : List α
h : l ≈ l'
a✝ : α
l✝ l'✝ : List α
b✝ : C ⟦l✝⟧
b'✝ : C ⟦l'✝⟧
hl : l✝ ~ l'✝
x✝ : HEq b✝ b'✝
⊢ HEq (C_cons a✝ ⟦l✝⟧ b✝) (C_cons a✝ ⟦l'✝⟧ b'✝)

Next tactic:
congr 1
/-- Dependent recursor on multisets.
TODO: should be @[recursor 6], but then the definition of `Multiset.pi` fails with a stack
overflow in `whnf`.
-/
protected
def rec (C_0 : C 0) (C_cons : ∀ a m, C m → C (a ::ₘ m))
    (C_cons_heq :
      ∀ a a' m b, HEq (C_cons a (a' ::ₘ m) (C_cons a' m b)) (C_cons a' (a ::ₘ m) (C_cons a m b)))
    (m : Multiset α) : C m :=
  Quotient.hrecOn m (@List.rec α (fun l => C ⟦l⟧) C_0 fun a l b => C_cons a ⟦l⟧ b) fun l l' h =>
    h.rec_heq
      (fun hl _ ↦ by congr 1; 

Proof state:
case e_2
α : Type u_1
β : Type v
γ : Type u_2
C : Multiset α → Sort u_3
C_0 : C 0
C_cons : (a : α) → (m : Multiset α) → C m → C (a ::ₘ m)
C_cons_heq :
  ∀ (a a' : α) (m : Multiset α) (b : C m),
    HEq (C_cons a (a' ::ₘ m) (C_cons a' m b)) (C_cons a' (a ::ₘ m) (C_cons a m b))
m : Multiset α
l l' : List α
h : l ≈ l'
a✝ : α
l✝ l'✝ : List α
b✝ : C ⟦l✝⟧
b'✝ : C ⟦l'✝⟧
hl : l✝ ~ l'✝
x✝ : HEq b✝ b'✝
⊢ ⟦l✝⟧ = ⟦l'✝⟧

Next tactic:
exact Quot.sound hl
theorem eq_zero_of_forall_not_mem {s : Multiset α} : (∀ x, x ∉ s) → s = 0 :=
  Quot.inductionOn s fun l H => by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
l : List α
H : ∀ (x : α), x ∉ Quot.mk Setoid.r l
⊢ Quot.mk Setoid.r l = 0

Next tactic:
rw [eq_nil_iff_forall_not_mem.mpr H]
theorem eq_zero_of_forall_not_mem {s : Multiset α} : (∀ x, x ∉ s) → s = 0 :=
  Quot.inductionOn s fun l H => by rw [eq_nil_iff_forall_not_mem.mpr H]; 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
l : List α
H : ∀ (x : α), x ∉ Quot.mk Setoid.r l
⊢ Quot.mk Setoid.r [] = 0

Next tactic:
rfl
theorem exists_mem_of_ne_zero {s : Multiset α} : s ≠ 0 → ∃ a : α, a ∈ s :=
  Quot.inductionOn s fun l hl =>
    match l, hl with
    | [], h => False.elim <| h rfl
    | a :: l, _ => ⟨a, by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
l✝ : List α
hl : Quot.mk Setoid.r l✝ ≠ 0
a : α
l : List α
x✝ : Quot.mk Setoid.r (a :: l) ≠ 0
⊢ a ∈ Quot.mk Setoid.r (a :: l)

Next tactic:
simp
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
⊢ a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
haveI : DecidableEq α := Classical.decEq α
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
⊢ a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
constructor
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
⊢ a ::ₘ as = b ::ₘ bs → a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
intro eq
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    

Proof state:
case mp
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
⊢ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
by_cases h : a = b
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : a = b
⊢ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
subst h
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
a : α
as bs : Multiset α
this : DecidableEq α
eq : a ::ₘ as = a ::ₘ bs
⊢ a = a ∧ as = bs ∨ a ≠ a ∧ ∃ cs, as = a ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
simp_all
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · 

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
⊢ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this : a ∈ b ::ₘ bs
⊢ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
have : a ∈ bs := by simpa [h]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this : a ∈ b ::ₘ bs
⊢ a ∈ bs

Next tactic:
simpa [h]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝¹ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝ : a ∈ b ::ₘ bs
this : a ∈ bs
⊢ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
rcases exists_cons_of_mem this with ⟨cs, hcs⟩
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      

Proof state:
case neg.intro
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝¹ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝ : a ∈ b ::ₘ bs
this : a ∈ bs
cs : Multiset α
hcs : bs = a ::ₘ cs
⊢ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs

Next tactic:
simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      

Proof state:
case neg.intro
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝¹ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝ : a ∈ b ::ₘ bs
this : a ∈ bs
cs : Multiset α
hcs : bs = a ::ₘ cs
⊢ as = b ::ₘ cs

Next tactic:
have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝¹ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝ : a ∈ b ::ₘ bs
this : a ∈ bs
cs : Multiset α
hcs : bs = a ::ₘ cs
⊢ a ::ₘ as = b ::ₘ a ::ₘ cs

Next tactic:
simp [eq, hcs]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      

Proof state:
case neg.intro
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝² : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝¹ : a ∈ b ::ₘ bs
this✝ : a ∈ bs
cs : Multiset α
hcs : bs = a ::ₘ cs
this : a ::ₘ as = b ::ₘ a ::ₘ cs
⊢ as = b ::ₘ cs

Next tactic:
have : a ::ₘ as = a ::ₘ b ::ₘ cs := by rwa [cons_swap]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      have : a ::ₘ as = a ::ₘ b ::ₘ cs := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝² : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝¹ : a ∈ b ::ₘ bs
this✝ : a ∈ bs
cs : Multiset α
hcs : bs = a ::ₘ cs
this : a ::ₘ as = b ::ₘ a ::ₘ cs
⊢ a ::ₘ as = a ::ₘ b ::ₘ cs

Next tactic:
rwa [cons_swap]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      have : a ::ₘ as = a ::ₘ b ::ₘ cs := by rwa [cons_swap]
      

Proof state:
case neg.intro
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this✝³ : DecidableEq α
eq : a ::ₘ as = b ::ₘ bs
h : ¬a = b
this✝² : a ∈ b ::ₘ bs
this✝¹ : a ∈ bs
cs : Multiset α
hcs : bs = a ::ₘ cs
this✝ : a ::ₘ as = b ::ₘ a ::ₘ cs
this : a ::ₘ as = a ::ₘ b ::ₘ cs
⊢ as = b ::ₘ cs

Next tactic:
simpa using this
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      have : a ::ₘ as = a ::ₘ b ::ₘ cs := by rwa [cons_swap]
      simpa using this
  · 

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
⊢ (a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs) → a ::ₘ as = b ::ₘ bs

Next tactic:
intro h
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      have : a ::ₘ as = a ::ₘ b ::ₘ cs := by rwa [cons_swap]
      simpa using this
  · intro h
    

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
h : a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs
⊢ a ::ₘ as = b ::ₘ bs

Next tactic:
rcases h with (⟨eq₁, eq₂⟩ | ⟨_, cs, eq₁, eq₂⟩)
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      have : a ::ₘ as = a ::ₘ b ::ₘ cs := by rwa [cons_swap]
      simpa using this
  · intro h
    rcases h with (⟨eq₁, eq₂⟩ | ⟨_, cs, eq₁, eq₂⟩)
    · 

Proof state:
case mpr.inl.intro
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
eq₁ : a = b
eq₂ : as = bs
⊢ a ::ₘ as = b ::ₘ bs

Next tactic:
simp [*]
theorem cons_eq_cons {a b : α} {as bs : Multiset α} :
    a ::ₘ as = b ::ₘ bs ↔ a = b ∧ as = bs ∨ a ≠ b ∧ ∃ cs, as = b ::ₘ cs ∧ bs = a ::ₘ cs := by
  haveI : DecidableEq α := Classical.decEq α
  constructor
  · intro eq
    by_cases h : a = b
    · subst h
      simp_all
    · have : a ∈ b ::ₘ bs := eq ▸ mem_cons_self _ _
      have : a ∈ bs := by simpa [h]
      rcases exists_cons_of_mem this with ⟨cs, hcs⟩
      simp only [h, hcs, false_and, ne_eq, not_false_eq_true, cons_inj_right, exists_eq_right',
        true_and, false_or]
      have : a ::ₘ as = b ::ₘ a ::ₘ cs := by simp [eq, hcs]
      have : a ::ₘ as = a ::ₘ b ::ₘ cs := by rwa [cons_swap]
      simpa using this
  · intro h
    rcases h with (⟨eq₁, eq₂⟩ | ⟨_, cs, eq₁, eq₂⟩)
    · simp [*]
    · 

Proof state:
case mpr.inr.intro.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
a b : α
as bs : Multiset α
this : DecidableEq α
left✝ : a ≠ b
cs : Multiset α
eq₁ : as = b ::ₘ cs
eq₂ : bs = a ::ₘ cs
⊢ a ::ₘ as = b ::ₘ bs

Next tactic:
simp [*, cons_swap a b]
@[simp]
theorem mem_singleton {a b : α} : b ∈ ({a} : Multiset α) ↔ b = a := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
⊢ b ∈ {a} ↔ b = a

Next tactic:
simp only [← cons_zero, mem_cons, iff_self_iff, or_false_iff, not_mem_zero]
theorem mem_singleton_self (a : α) : a ∈ ({a} : Multiset α) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a : α
⊢ a ∈ {a}

Next tactic:
rw [← cons_zero]
theorem mem_singleton_self (a : α) : a ∈ ({a} : Multiset α) := by
  rw [← cons_zero]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a : α
⊢ a ∈ a ::ₘ 0

Next tactic:
exact mem_cons_self _ _
@[simp]
theorem singleton_inj {a b : α} : ({a} : Multiset α) = {b} ↔ a = b := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
⊢ {a} = {b} ↔ a = b

Next tactic:
simp_rw [← cons_zero]
@[simp]
theorem singleton_inj {a b : α} : ({a} : Multiset α) = {b} ↔ a = b := by
  simp_rw [← cons_zero]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
⊢ a ::ₘ 0 = b ::ₘ 0 ↔ a = b

Next tactic:
exact cons_inj_left _
@[simp, norm_cast]
theorem coe_eq_singleton {l : List α} {a : α} : (l : Multiset α) = {a} ↔ l = [a] := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
l : List α
a : α
⊢ ↑l = {a} ↔ l = [a]

Next tactic:
rw [← coe_singleton, coe_eq_coe, List.perm_singleton]
@[simp]
theorem singleton_eq_cons_iff {a b : α} (m : Multiset α) : {a} = b ::ₘ m ↔ a = b ∧ m = 0 := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
m : Multiset α
⊢ {a} = b ::ₘ m ↔ a = b ∧ m = 0

Next tactic:
rw [← cons_zero, cons_eq_cons]
@[simp]
theorem singleton_eq_cons_iff {a b : α} (m : Multiset α) : {a} = b ::ₘ m ↔ a = b ∧ m = 0 := by
  rw [← cons_zero, cons_eq_cons]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a b : α
m : Multiset α
⊢ (a = b ∧ 0 = m ∨ a ≠ b ∧ ∃ cs, 0 = b ::ₘ cs ∧ m = a ::ₘ cs) ↔ a = b ∧ m = 0

Next tactic:
simp [eq_comm]
@[simp]
theorem cons_subset {a : α} {s t : Multiset α} : a ::ₘ s ⊆ t ↔ a ∈ t ∧ s ⊆ t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s✝ : Multiset α
a✝ a : α
s t : Multiset α
⊢ a ::ₘ s ⊆ t ↔ a ∈ t ∧ s ⊆ t

Next tactic:
simp [subset_iff, or_imp, forall_and]
@[simp] lemma zero_ssubset : 0 ⊂ s ↔ s ≠ 0 := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
a : α
⊢ 0 ⊂ s ↔ s ≠ 0

Next tactic:
simp [ssubset_iff_subset_not_subset]
@[simp] lemma singleton_subset : {a} ⊆ s ↔ a ∈ s := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
a : α
⊢ {a} ⊆ s ↔ a ∈ s

Next tactic:
simp [subset_iff]
@[simp]
theorem toList_eq_nil {s : Multiset α} : s.toList = [] ↔ s = 0 := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
⊢ toList s = [] ↔ s = 0

Next tactic:
rw [← coe_eq_zero, coe_toList]
@[simp]
theorem mem_toList {a : α} {s : Multiset α} : a ∈ s.toList ↔ a ∈ s := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a : α
s : Multiset α
⊢ a ∈ toList s ↔ a ∈ s

Next tactic:
rw [← mem_coe, coe_toList]
@[simp]
theorem toList_eq_singleton_iff {a : α} {m : Multiset α} : m.toList = [a] ↔ m = {a} := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
a : α
m : Multiset α
⊢ toList m = [a] ↔ m = {a}

Next tactic:
rw [← perm_singleton, ← coe_eq_coe, coe_toList, coe_singleton]
instance : PartialOrder (Multiset α) where
  le := Multiset.Le
  le_refl := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
⊢ ∀ (a : Multiset α), a ≤ a

Next tactic:
rintro ⟨l⟩
instance : PartialOrder (Multiset α) where
  le := Multiset.Le
  le_refl := by rintro ⟨l⟩; 

Proof state:
case mk
α : Type u_1
β : Type v
γ : Type u_2
a✝ : Multiset α
l : List α
⊢ Quot.mk Setoid.r l ≤ Quot.mk Setoid.r l

Next tactic:
exact Subperm.refl _
instance : PartialOrder (Multiset α) where
  le := Multiset.Le
  le_refl := by rintro ⟨l⟩; exact Subperm.refl _
  le_trans := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
⊢ ∀ (a b c : Multiset α), a ≤ b → b ≤ c → a ≤ c

Next tactic:
rintro ⟨l₁⟩ ⟨l₂⟩ ⟨l₃⟩