l3lab/ntp-mathlib huggingface dataset:
theorem add_singleton_eq_iff {s t : Multiset α} {a : α} : s + {a} = t ↔ a ∈ t ∧ s = t.erase a := by
  rw [add_comm, singleton_add]; constructor
  · rintro rfl
    exact ⟨s.mem_cons_self a, (s.erase_cons_head a).symm⟩
  · 

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ : Multiset α
a✝ b : α
s t : Multiset α
a : α
⊢ a ∈ t ∧ s = erase t a → a ::ₘ s = t

Next tactic:
rintro ⟨h, rfl⟩
theorem add_singleton_eq_iff {s t : Multiset α} {a : α} : s + {a} = t ↔ a ∈ t ∧ s = t.erase a := by
  rw [add_comm, singleton_add]; constructor
  · rintro rfl
    exact ⟨s.mem_cons_self a, (s.erase_cons_head a).symm⟩
  · rintro ⟨h, rfl⟩
    

Proof state:
case mpr.intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s t✝ : Multiset α
a✝ b : α
t : Multiset α
a : α
h : a ∈ t
⊢ a ::ₘ erase t a = t

Next tactic:
exact cons_erase h
theorem erase_add_right_pos {a : α} (s) {t : Multiset α} (h : a ∈ t) :
    (s + t).erase a = s + t.erase a := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ : Multiset α
a✝ b a : α
s t : Multiset α
h : a ∈ t
⊢ erase (s + t) a = s + erase t a

Next tactic:
rw [add_comm, erase_add_left_pos s h, add_comm]
theorem erase_add_left_neg {a : α} (s) {t : Multiset α} (h : a ∉ t) :
    (s + t).erase a = s.erase a + t := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ : Multiset α
a✝ b a : α
s t : Multiset α
h : a ∉ t
⊢ erase (s + t) a = erase s a + t

Next tactic:
rw [add_comm, erase_add_right_neg s h, add_comm]
@[simp]
theorem erase_lt {a : α} {s : Multiset α} : s.erase a < s ↔ a ∈ s :=
  ⟨fun h => not_imp_comm.1 erase_of_not_mem (ne_of_lt h), fun h => by
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t : Multiset α
a✝ b a : α
s : Multiset α
h : a ∈ s
⊢ erase s a < s

Next tactic:
simpa [h] using lt_cons_self (s.erase a) a
theorem erase_le_iff_le_cons {s t : Multiset α} {a : α} : s.erase a ≤ t ↔ s ≤ a ::ₘ t :=
  ⟨fun h => le_trans (le_cons_erase _ _) (cons_le_cons _ h), fun h =>
    if m : a ∈ s then by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ : Multiset α
a✝ b : α
s t : Multiset α
a : α
h : s ≤ a ::ₘ t
m : a ∈ s
⊢ erase s a ≤ t

Next tactic:
rw [← cons_erase m] at h
theorem erase_le_iff_le_cons {s t : Multiset α} {a : α} : s.erase a ≤ t ↔ s ≤ a ::ₘ t :=
  ⟨fun h => le_trans (le_cons_erase _ _) (cons_le_cons _ h), fun h =>
    if m : a ∈ s then by rw [← cons_erase m] at h; 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t✝ : Multiset α
a✝ b : α
s t : Multiset α
a : α
h : a ::ₘ erase s a ≤ a ::ₘ t
m : a ∈ s
⊢ erase s a ≤ t

Next tactic:
exact (cons_le_cons_iff _).1 h
theorem card_erase_eq_ite {a : α} {s : Multiset α} :
    card (s.erase a) = if a ∈ s then pred (card s) else card s := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t : Multiset α
a✝ b a : α
s : Multiset α
⊢ card (erase s a) = if a ∈ s then pred (card s) else card s

Next tactic:
by_cases h : a ∈ s
theorem card_erase_eq_ite {a : α} {s : Multiset α} :
    card (s.erase a) = if a ∈ s then pred (card s) else card s := by
  by_cases h : a ∈ s
  · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t : Multiset α
a✝ b a : α
s : Multiset α
h : a ∈ s
⊢ card (erase s a) = if a ∈ s then pred (card s) else card s

Next tactic:
rwa [card_erase_of_mem h, if_pos]
theorem card_erase_eq_ite {a : α} {s : Multiset α} :
    card (s.erase a) = if a ∈ s then pred (card s) else card s := by
  by_cases h : a ∈ s
  · rwa [card_erase_of_mem h, if_pos]
  · 

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
s✝ t : Multiset α
a✝ b a : α
s : Multiset α
h : a ∉ s
⊢ card (erase s a) = if a ∈ s then pred (card s) else card s

Next tactic:
rwa [erase_of_not_mem h, if_neg]
@[congr]
theorem map_congr {f g : α → β} {s t : Multiset α} :
    s = t → (∀ x ∈ t, f x = g x) → map f s = map g t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f g : α → β
s t : Multiset α
⊢ s = t → (∀ x ∈ t, f x = g x) → map f s = map g t

Next tactic:
rintro rfl h
@[congr]
theorem map_congr {f g : α → β} {s t : Multiset α} :
    s = t → (∀ x ∈ t, f x = g x) → map f s = map g t := by
  rintro rfl h
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f g : α → β
s : Multiset α
h : ∀ x ∈ s, f x = g x
⊢ map f s = map g s

Next tactic:
induction s using Quot.inductionOn
@[congr]
theorem map_congr {f g : α → β} {s t : Multiset α} :
    s = t → (∀ x ∈ t, f x = g x) → map f s = map g t := by
  rintro rfl h
  induction s using Quot.inductionOn
  

Proof state:
case h
α : Type u_1
β : Type v
γ : Type u_2
f g : α → β
a✝ : List α
h : ∀ x ∈ Quot.mk Setoid.r a✝, f x = g x
⊢ map f (Quot.mk Setoid.r a✝) = map g (Quot.mk Setoid.r a✝)

Next tactic:
exact congr_arg _ (List.map_congr h)
theorem map_hcongr {β' : Type v} {m : Multiset α} {f : α → β} {f' : α → β'} (h : β = β')
    (hf : ∀ a ∈ m, HEq (f a) (f' a)) : HEq (map f m) (map f' m) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
β' : Type v
m : Multiset α
f : α → β
f' : α → β'
h : β = β'
hf : ∀ a ∈ m, HEq (f a) (f' a)
⊢ HEq (map f m) (map f' m)

Next tactic:
subst h
theorem map_hcongr {β' : Type v} {m : Multiset α} {f : α → β} {f' : α → β'} (h : β = β')
    (hf : ∀ a ∈ m, HEq (f a) (f' a)) : HEq (map f m) (map f' m) := by
  subst h; 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
m : Multiset α
f f' : α → β
hf : ∀ a ∈ m, HEq (f a) (f' a)
⊢ HEq (map f m) (map f' m)

Next tactic:
simp at hf
theorem map_hcongr {β' : Type v} {m : Multiset α} {f : α → β} {f' : α → β'} (h : β = β')
    (hf : ∀ a ∈ m, HEq (f a) (f' a)) : HEq (map f m) (map f' m) := by
  subst h; simp at hf
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
m : Multiset α
f f' : α → β
hf : ∀ a ∈ m, f a = f' a
⊢ HEq (map f m) (map f' m)

Next tactic:
simp [map_congr rfl hf]
theorem map_comp_cons (f : α → β) (t) : map f ∘ cons t = cons (f t) ∘ map f := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
t : α
⊢ map f ∘ cons t = cons (f t) ∘ map f

Next tactic:
ext
theorem map_comp_cons (f : α → β) (t) : map f ∘ cons t = cons (f t) ∘ map f := by
  ext
  

Proof state:
case h
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
t : α
x✝ : Multiset α
⊢ (map f ∘ cons t) x✝ = (cons (f t) ∘ map f) x✝

Next tactic:
simp
@[simp]
theorem map_replicate (f : α → β) (k : ℕ) (a : α) : (replicate k a).map f = replicate k (f a) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
k : ℕ
a : α
⊢ map f (replicate k a) = replicate k (f a)

Next tactic:
simp only [← coe_replicate, coe_map, List.map_replicate]
/-- If each element of `s : Multiset α` can be lifted to `β`, then `s` can be lifted to
`Multiset β`. -/
instance canLift (c) (p) [CanLift α β c p] :
    CanLift (Multiset α) (Multiset β) (map c) fun s => ∀ x ∈ s, p x where
  prf := by
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
c : β → α
p : α → Prop
inst✝ : CanLift α β c p
⊢ ∀ (x : Multiset α), (∀ x_1 ∈ x, p x_1) → ∃ y, map c y = x

Next tactic:
rintro ⟨l⟩ hl
/-- If each element of `s : Multiset α` can be lifted to `β`, then `s` can be lifted to
`Multiset β`. -/
instance canLift (c) (p) [CanLift α β c p] :
    CanLift (Multiset α) (Multiset β) (map c) fun s => ∀ x ∈ s, p x where
  prf := by
    rintro ⟨l⟩ hl
    

Proof state:
case mk
α : Type u_1
β : Type v
γ : Type u_2
c : β → α
p : α → Prop
inst✝ : CanLift α β c p
x✝ : Multiset α
l : List α
hl : ∀ x ∈ Quot.mk Setoid.r l, p x
⊢ ∃ y, map c y = Quot.mk Setoid.r l

Next tactic:
lift l to List β using hl
/-- If each element of `s : Multiset α` can be lifted to `β`, then `s` can be lifted to
`Multiset β`. -/
instance canLift (c) (p) [CanLift α β c p] :
    CanLift (Multiset α) (Multiset β) (map c) fun s => ∀ x ∈ s, p x where
  prf := by
    rintro ⟨l⟩ hl
    lift l to List β using hl
    

Proof state:
case mk.intro
α : Type u_1
β : Type v
γ : Type u_2
c : β → α
p : α → Prop
inst✝ : CanLift α β c p
x✝ : Multiset α
l : List β
⊢ ∃ y, map c y = Quot.mk Setoid.r (List.map c l)

Next tactic:
exact ⟨l, coe_map _ _⟩
@[simp]
theorem map_eq_zero {s : Multiset α} {f : α → β} : s.map f = 0 ↔ s = 0 := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
s : Multiset α
f : α → β
⊢ map f s = 0 ↔ s = 0

Next tactic:
rw [← Multiset.card_eq_zero, Multiset.card_map, Multiset.card_eq_zero]
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
⊢ map f s = {b} ↔ ∃ a, s = {a} ∧ f a = b

Next tactic:
constructor
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
⊢ map f s = {b} → ∃ a, s = {a} ∧ f a = b

Next tactic:
intro h
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · intro h
    

Proof state:
case mp
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
h : map f s = {b}
⊢ ∃ a, s = {a} ∧ f a = b

Next tactic:
obtain ⟨a, ha⟩ : ∃ a, s = {a} := by rw [← card_eq_one, ← card_map, h, card_singleton]
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · intro h
    obtain ⟨a, ha⟩ : ∃ a, s = {a} := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
h : map f s = {b}
⊢ ∃ a, s = {a}

Next tactic:
rw [← card_eq_one, ← card_map, h, card_singleton]
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · intro h
    obtain ⟨a, ha⟩ : ∃ a, s = {a} := by rw [← card_eq_one, ← card_map, h, card_singleton]
    

Proof state:
case mp.intro
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
h : map f s = {b}
a : α
ha : s = {a}
⊢ ∃ a, s = {a} ∧ f a = b

Next tactic:
refine' ⟨a, ha, _⟩
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · intro h
    obtain ⟨a, ha⟩ : ∃ a, s = {a} := by rw [← card_eq_one, ← card_map, h, card_singleton]
    refine' ⟨a, ha, _⟩
    

Proof state:
case mp.intro
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
h : map f s = {b}
a : α
ha : s = {a}
⊢ f a = b

Next tactic:
rw [← mem_singleton, ← h, ha, map_singleton, mem_singleton]
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · intro h
    obtain ⟨a, ha⟩ : ∃ a, s = {a} := by rw [← card_eq_one, ← card_map, h, card_singleton]
    refine' ⟨a, ha, _⟩
    rw [← mem_singleton, ← h, ha, map_singleton, mem_singleton]
  · 

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s : Multiset α
b : β
⊢ (∃ a, s = {a} ∧ f a = b) → map f s = {b}

Next tactic:
rintro ⟨a, rfl, rfl⟩
theorem map_eq_singleton {f : α → β} {s : Multiset α} {b : β} :
    map f s = {b} ↔ ∃ a : α, s = {a} ∧ f a = b := by
  constructor
  · intro h
    obtain ⟨a, ha⟩ : ∃ a, s = {a} := by rw [← card_eq_one, ← card_map, h, card_singleton]
    refine' ⟨a, ha, _⟩
    rw [← mem_singleton, ← h, ha, map_singleton, mem_singleton]
  · rintro ⟨a, rfl, rfl⟩
    

Proof state:
case mpr.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
a : α
⊢ map f {a} = {f a}

Next tactic:
simp
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
⊢ (∃ a ∈ s, f a = b ∧ map f (erase s a) = t) ↔ map f s = b ::ₘ t

Next tactic:
constructor
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
⊢ (∃ a ∈ s, f a = b ∧ map f (erase s a) = t) → map f s = b ::ₘ t

Next tactic:
rintro ⟨a, ha, rfl, rfl⟩
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    

Proof state:
case mp.intro.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
a : α
ha : a ∈ s
⊢ map f s = f a ::ₘ map f (erase s a)

Next tactic:
rw [← map_cons, Multiset.cons_erase ha]
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · 

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
⊢ map f s = b ::ₘ t → ∃ a ∈ s, f a = b ∧ map f (erase s a) = t

Next tactic:
intro h
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
h : map f s = b ::ₘ t
⊢ ∃ a ∈ s, f a = b ∧ map f (erase s a) = t

Next tactic:
have : b ∈ s.map f := by
      rw [h]
      exact mem_cons_self _ _
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
h : map f s = b ::ₘ t
⊢ b ∈ map f s

Next tactic:
rw [h]
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      rw [h]
      

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
h : map f s = b ::ₘ t
⊢ b ∈ b ::ₘ t

Next tactic:
exact mem_cons_self _ _
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      rw [h]
      exact mem_cons_self _ _
    

Proof state:
case mpr
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
b : β
h : map f s = b ::ₘ t
this : b ∈ map f s
⊢ ∃ a ∈ s, f a = b ∧ map f (erase s a) = t

Next tactic:
obtain ⟨a, h1, rfl⟩ := mem_map.mp this
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      rw [h]
      exact mem_cons_self _ _
    obtain ⟨a, h1, rfl⟩ := mem_map.mp this
    

Proof state:
case mpr.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
s : Multiset α
t : Multiset β
a : α
h1 : a ∈ s
h : map f s = f a ::ₘ t
this : f a ∈ map f s
⊢ ∃ a_1 ∈ s, f a_1 = f a ∧ map f (erase s a_1) = t

Next tactic:
obtain ⟨u, rfl⟩ := exists_cons_of_mem h1
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      rw [h]
      exact mem_cons_self _ _
    obtain ⟨a, h1, rfl⟩ := mem_map.mp this
    obtain ⟨u, rfl⟩ := exists_cons_of_mem h1
    

Proof state:
case mpr.intro.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
t : Multiset β
a : α
u : Multiset α
h1 : a ∈ a ::ₘ u
h : map f (a ::ₘ u) = f a ::ₘ t
this : f a ∈ map f (a ::ₘ u)
⊢ ∃ a_1 ∈ a ::ₘ u, f a_1 = f a ∧ map f (erase (a ::ₘ u) a_1) = t

Next tactic:
rw [map_cons, cons_inj_right] at h
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      rw [h]
      exact mem_cons_self _ _
    obtain ⟨a, h1, rfl⟩ := mem_map.mp this
    obtain ⟨u, rfl⟩ := exists_cons_of_mem h1
    rw [map_cons, cons_inj_right] at h
    

Proof state:
case mpr.intro.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
t : Multiset β
a : α
u : Multiset α
h1 : a ∈ a ::ₘ u
h : map f u = t
this : f a ∈ map f (a ::ₘ u)
⊢ ∃ a_1 ∈ a ::ₘ u, f a_1 = f a ∧ map f (erase (a ::ₘ u) a_1) = t

Next tactic:
refine' ⟨a, mem_cons_self _ _, rfl, _⟩
theorem map_eq_cons [DecidableEq α] (f : α → β) (s : Multiset α) (t : Multiset β) (b : β) :
    (∃ a ∈ s, f a = b ∧ (s.erase a).map f = t) ↔ s.map f = b ::ₘ t := by
  constructor
  · rintro ⟨a, ha, rfl, rfl⟩
    rw [← map_cons, Multiset.cons_erase ha]
  · intro h
    have : b ∈ s.map f := by
      rw [h]
      exact mem_cons_self _ _
    obtain ⟨a, h1, rfl⟩ := mem_map.mp this
    obtain ⟨u, rfl⟩ := exists_cons_of_mem h1
    rw [map_cons, cons_inj_right] at h
    refine' ⟨a, mem_cons_self _ _, rfl, _⟩
    

Proof state:
case mpr.intro.intro.intro
α : Type u_1
β : Type v
γ : Type u_2
inst✝ : DecidableEq α
f : α → β
t : Multiset β
a : α
u : Multiset α
h1 : a ∈ a ::ₘ u
h : map f u = t
this : f a ∈ map f (a ::ₘ u)
⊢ map f (erase (a ::ₘ u) a) = t

Next tactic:
rw [Multiset.erase_cons_head, h]
theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (Function.const α b₂) l) :
    b₁ = b₂ :=
  eq_of_mem_replicate <| by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
b₁ b₂ : β
l : List α
h : b₁ ∈ map (const α b₂) ↑l
⊢ b₁ ∈ replicate (?m.126952 h) b₂

Next tactic:
rwa [map_const] at h
@[simp]
theorem map_lt_map {f : α → β} {s t : Multiset α} (h : s < t) : s.map f < t.map f := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s t : Multiset α
h : s < t
⊢ map f s < map f t

Next tactic:
refine' (map_le_map h.le).lt_of_not_le fun H => h.ne <| eq_of_le_of_card_le h.le _
@[simp]
theorem map_lt_map {f : α → β} {s t : Multiset α} (h : s < t) : s.map f < t.map f := by
  refine' (map_le_map h.le).lt_of_not_le fun H => h.ne <| eq_of_le_of_card_le h.le _
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s t : Multiset α
h : s < t
H : map f t ≤ map f s
⊢ card t ≤ card s

Next tactic:
rw [← s.card_map f, ← t.card_map f]
@[simp]
theorem map_lt_map {f : α → β} {s t : Multiset α} (h : s < t) : s.map f < t.map f := by
  refine' (map_le_map h.le).lt_of_not_le fun H => h.ne <| eq_of_le_of_card_le h.le _
  rw [← s.card_map f, ← t.card_map f]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
f : α → β
s t : Multiset α
h : s < t
H : map f t ≤ map f s
⊢ card (map f t) ≤ card (map f s)

Next tactic:
exact card_le_of_le H
theorem map_erase [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)
    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x : α
s : Multiset α
⊢ map f (erase s x) = erase (map f s) (f x)

Next tactic:
induction' s using Multiset.induction_on with y s ih
theorem map_erase [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)
    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) := by
  induction' s using Multiset.induction_on with y s ih
  · 

Proof state:
case empty
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x : α
⊢ map f (erase 0 x) = erase (map f 0) (f x)

Next tactic:
simp
theorem map_erase [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)
    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) := by
  induction' s using Multiset.induction_on with y s ih
  · simp
  

Proof state:
case cons
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y : α
s : Multiset α
ih : map f (erase s x) = erase (map f s) (f x)
⊢ map f (erase (y ::ₘ s) x) = erase (map f (y ::ₘ s)) (f x)

Next tactic:
by_cases hxy : y = x
theorem map_erase [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)
    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) := by
  induction' s using Multiset.induction_on with y s ih
  · simp
  by_cases hxy : y = x
  · 

Proof state:
case pos
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y : α
s : Multiset α
ih : map f (erase s x) = erase (map f s) (f x)
hxy : y = x
⊢ map f (erase (y ::ₘ s) x) = erase (map f (y ::ₘ s)) (f x)

Next tactic:
cases hxy
theorem map_erase [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)
    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) := by
  induction' s using Multiset.induction_on with y s ih
  · simp
  by_cases hxy : y = x
  · cases hxy
    

Proof state:
case pos.refl
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x : α
s : Multiset α
ih : map f (erase s x) = erase (map f s) (f x)
⊢ map f (erase (x ::ₘ s) x) = erase (map f (x ::ₘ s)) (f x)

Next tactic:
simp
theorem map_erase [DecidableEq α] [DecidableEq β] (f : α → β) (hf : Function.Injective f) (x : α)
    (s : Multiset α) : (s.erase x).map f = (s.map f).erase (f x) := by
  induction' s using Multiset.induction_on with y s ih
  · simp
  by_cases hxy : y = x
  · cases hxy
    simp
  · 

Proof state:
case neg
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y : α
s : Multiset α
ih : map f (erase s x) = erase (map f s) (f x)
hxy : ¬y = x
⊢ map f (erase (y ::ₘ s) x) = erase (map f (y ::ₘ s)) (f x)

Next tactic:
rw [s.erase_cons_tail hxy, map_cons, map_cons, (s.map f).erase_cons_tail (hf.ne hxy), ih]
theorem map_erase_of_mem [DecidableEq α] [DecidableEq β] (f : α → β)
    (s : Multiset α) {x : α} (h : x ∈ s) : (s.erase x).map f = (s.map f).erase (f x) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
s : Multiset α
x : α
h : x ∈ s
⊢ map f (erase s x) = erase (map f s) (f x)

Next tactic:
induction' s using Multiset.induction_on with y s ih
theorem map_erase_of_mem [DecidableEq α] [DecidableEq β] (f : α → β)
    (s : Multiset α) {x : α} (h : x ∈ s) : (s.erase x).map f = (s.map f).erase (f x) := by
  induction' s using Multiset.induction_on with y s ih; 

Proof state:
case empty
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
x : α
h : x ∈ 0
⊢ map f (erase 0 x) = erase (map f 0) (f x)
case cons
α : Type u_1
β : Type v
γ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
x y : α
s : Multiset α
ih : x ∈ s → map f (erase s x) = erase (map f s) (f x)
h : x ∈ y ::ₘ s
⊢ map f (erase (y ::ₘ s) x) = erase (map f (y ::ₘ s)) (f x)

Next tactic:
simp