l3lab/ntp-mathlib huggingface dataset:
theorem bind_hcongr {β' : Type v} {m : Multiset α} {f : α → Multiset β} {f' : α → Multiset β'}
    (h : β = β') (hf : ∀ a ∈ m, HEq (f a) (f' a)) : HEq (bind m f) (bind m f') := by
  subst h
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
f f' : α → Multiset β
hf : ∀ a ∈ m, HEq (f a) (f' a)
⊢ HEq (bind m f) (bind m f')

Next tactic:
simp only [heq_eq_eq] at hf
theorem bind_hcongr {β' : Type v} {m : Multiset α} {f : α → Multiset β} {f' : α → Multiset β'}
    (h : β = β') (hf : ∀ a ∈ m, HEq (f a) (f' a)) : HEq (bind m f) (bind m f') := by
  subst h
  simp only [heq_eq_eq] at hf
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
f f' : α → Multiset β
hf : ∀ a ∈ m, f a = f' a
⊢ HEq (bind m f) (bind m f')

Next tactic:
simp [bind_congr hf]
theorem map_bind (m : Multiset α) (n : α → Multiset β) (f : β → γ) :
    map f (bind m n) = bind m fun a => map f (n a) :=
  Multiset.induction_on m (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : α → Multiset β
f : β → γ
⊢ map f (bind 0 n) = bind 0 fun a => map f (n a)

Next tactic:
simp
theorem map_bind (m : Multiset α) (n : α → Multiset β) (f : β → γ) :
    map f (bind m n) = bind m fun a => map f (n a) :=
  Multiset.induction_on m (by simp) (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : α → Multiset β
f : β → γ
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    (map f (bind s n) = bind s fun a => map f (n a)) → map f (bind (a ::ₘ s) n) = bind (a ::ₘ s) fun a => map f (n a)

Next tactic:
simp (config := { contextual := true })
theorem bind_map (m : Multiset α) (n : β → Multiset γ) (f : α → β) :
    bind (map f m) n = bind m fun a => n (f a) :=
  Multiset.induction_on m (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : β → Multiset γ
f : α → β
⊢ bind (map f 0) n = bind 0 fun a => n (f a)

Next tactic:
simp
theorem bind_map (m : Multiset α) (n : β → Multiset γ) (f : α → β) :
    bind (map f m) n = bind m fun a => n (f a) :=
  Multiset.induction_on m (by simp) (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : β → Multiset γ
f : α → β
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    (bind (map f s) n = bind s fun a => n (f a)) → bind (map f (a ::ₘ s)) n = bind (a ::ₘ s) fun a => n (f a)

Next tactic:
simp (config := { contextual := true })
theorem bind_assoc {s : Multiset α} {f : α → Multiset β} {g : β → Multiset γ} :
    (s.bind f).bind g = s.bind fun a => (f a).bind g :=
  Multiset.induction_on s (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s✝ t : Multiset α
f✝ g✝ : α → Multiset β
s : Multiset α
f : α → Multiset β
g : β → Multiset γ
⊢ bind (bind 0 f) g = bind 0 fun a => bind (f a) g

Next tactic:
simp
theorem bind_assoc {s : Multiset α} {f : α → Multiset β} {g : β → Multiset γ} :
    (s.bind f).bind g = s.bind fun a => (f a).bind g :=
  Multiset.induction_on s (by simp) (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s✝ t : Multiset α
f✝ g✝ : α → Multiset β
s : Multiset α
f : α → Multiset β
g : β → Multiset γ
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    (bind (bind s f) g = bind s fun a => bind (f a) g) →
      bind (bind (a ::ₘ s) f) g = bind (a ::ₘ s) fun a => bind (f a) g

Next tactic:
simp (config := { contextual := true })
theorem bind_bind (m : Multiset α) (n : Multiset β) {f : α → β → Multiset γ} :
    ((bind m) fun a => (bind n) fun b => f a b) = (bind n) fun b => (bind m) fun a => f a b :=
  Multiset.induction_on m (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : Multiset β
f : α → β → Multiset γ
⊢ (bind 0 fun a => bind n fun b => f a b) = bind n fun b => bind 0 fun a => f a b

Next tactic:
simp
theorem bind_bind (m : Multiset α) (n : Multiset β) {f : α → β → Multiset γ} :
    ((bind m) fun a => (bind n) fun b => f a b) = (bind n) fun b => (bind m) fun a => f a b :=
  Multiset.induction_on m (by simp) (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : Multiset β
f : α → β → Multiset γ
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    ((bind s fun a => bind n fun b => f a b) = bind n fun b => bind s fun a => f a b) →
      (bind (a ::ₘ s) fun a => bind n fun b => f a b) = bind n fun b => bind (a ::ₘ s) fun a => f a b

Next tactic:
simp (config := { contextual := true })
theorem bind_map_comm (m : Multiset α) (n : Multiset β) {f : α → β → γ} :
    ((bind m) fun a => n.map fun b => f a b) = (bind n) fun b => m.map fun a => f a b :=
  Multiset.induction_on m (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : Multiset β
f : α → β → γ
⊢ (bind 0 fun a => map (fun b => f a b) n) = bind n fun b => map (fun a => f a b) 0

Next tactic:
simp
theorem bind_map_comm (m : Multiset α) (n : Multiset β) {f : α → β → γ} :
    ((bind m) fun a => n.map fun b => f a b) = (bind n) fun b => m.map fun a => f a b :=
  Multiset.induction_on m (by simp) (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s t : Multiset α
f✝ g : α → Multiset β
m : Multiset α
n : Multiset β
f : α → β → γ
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    ((bind s fun a => map (fun b => f a b) n) = bind n fun b => map (fun a => f a b) s) →
      (bind (a ::ₘ s) fun a => map (fun b => f a b) n) = bind n fun b => map (fun a => f a b) (a ::ₘ s)

Next tactic:
simp (config := { contextual := true })
@[to_additive (attr := simp)]
theorem prod_bind [CommMonoid β] (s : Multiset α) (t : α → Multiset β) :
    (s.bind t).prod = (s.map fun a => (t a).prod).prod :=
  Multiset.induction_on s (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s✝ t✝ : Multiset α
f g : α → Multiset β
inst✝ : CommMonoid β
s : Multiset α
t : α → Multiset β
⊢ prod (bind 0 t) = prod (map (fun a => prod (t a)) 0)

Next tactic:
simp
@[to_additive (attr := simp)]
theorem prod_bind [CommMonoid β] (s : Multiset α) (t : α → Multiset β) :
    (s.bind t).prod = (s.map fun a => (t a).prod).prod :=
  Multiset.induction_on s (by simp) fun a s ih => by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a✝ : α
s✝¹ t✝ : Multiset α
f g : α → Multiset β
inst✝ : CommMonoid β
s✝ : Multiset α
t : α → Multiset β
a : α
s : Multiset α
ih : prod (bind s t) = prod (map (fun a => prod (t a)) s)
⊢ prod (bind (a ::ₘ s) t) = prod (map (fun a => prod (t a)) (a ::ₘ s))

Next tactic:
simp [ih, cons_bind]
theorem rel_bind {r : α → β → Prop} {p : γ → δ → Prop} {s t} {f : α → Multiset γ}
    {g : β → Multiset δ} (h : (r ⇒ Rel p) f g) (hst : Rel r s t) :
    Rel p (s.bind f) (t.bind g) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s✝ t✝ : Multiset α
f✝ g✝ : α → Multiset β
r : α → β → Prop
p : γ → δ → Prop
s : Multiset α
t : Multiset β
f : α → Multiset γ
g : β → Multiset δ
h : (r ⇒ Rel p) f g
hst : Rel r s t
⊢ Rel p (bind s f) (bind t g)

Next tactic:
apply rel_join
theorem rel_bind {r : α → β → Prop} {p : γ → δ → Prop} {s t} {f : α → Multiset γ}
    {g : β → Multiset δ} (h : (r ⇒ Rel p) f g) (hst : Rel r s t) :
    Rel p (s.bind f) (t.bind g) := by
  apply rel_join
  

Proof state:
case h
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s✝ t✝ : Multiset α
f✝ g✝ : α → Multiset β
r : α → β → Prop
p : γ → δ → Prop
s : Multiset α
t : Multiset β
f : α → Multiset γ
g : β → Multiset δ
h : (r ⇒ Rel p) f g
hst : Rel r s t
⊢ Rel (Rel p) (map f s) (map g t)

Next tactic:
rw [rel_map]
theorem rel_bind {r : α → β → Prop} {p : γ → δ → Prop} {s t} {f : α → Multiset γ}
    {g : β → Multiset δ} (h : (r ⇒ Rel p) f g) (hst : Rel r s t) :
    Rel p (s.bind f) (t.bind g) := by
  apply rel_join
  rw [rel_map]
  

Proof state:
case h
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
s✝ t✝ : Multiset α
f✝ g✝ : α → Multiset β
r : α → β → Prop
p : γ → δ → Prop
s : Multiset α
t : Multiset β
f : α → Multiset γ
g : β → Multiset δ
h : (r ⇒ Rel p) f g
hst : Rel r s t
⊢ Rel (fun a b => Rel p (f a) (g b)) s t

Next tactic:
exact hst.mono fun a _ b _ hr => h hr
theorem count_sum [DecidableEq α] {m : Multiset β} {f : β → Multiset α} {a : α} :
    count a (map f m).sum = sum (m.map fun b => count a <| f b) :=
  Multiset.induction_on m (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a✝ : α
s t : Multiset α
f✝ g : α → Multiset β
inst✝ : DecidableEq α
m : Multiset β
f : β → Multiset α
a : α
⊢ count a (sum (map f 0)) = sum (map (fun b => count a (f b)) 0)

Next tactic:
simp
theorem count_sum [DecidableEq α] {m : Multiset β} {f : β → Multiset α} {a : α} :
    count a (map f m).sum = sum (m.map fun b => count a <| f b) :=
  Multiset.induction_on m (by simp) (by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a✝ : α
s t : Multiset α
f✝ g : α → Multiset β
inst✝ : DecidableEq α
m : Multiset β
f : β → Multiset α
a : α
⊢ ∀ ⦃a_1 : β⦄ {s : Multiset β},
    count a (sum (map f s)) = sum (map (fun b => count a (f b)) s) →
      count a (sum (map f (a_1 ::ₘ s))) = sum (map (fun b => count a (f b)) (a_1 ::ₘ s))

Next tactic:
simp
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  

Proof state:
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
⊢ f x ≤ bind S f

Next tactic:
classical
    rw [le_iff_count]
    intro a
    rw [count_bind]
    apply le_sum_of_mem
    rw [mem_map]
    exact ⟨x, hx, rfl⟩
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  classical
    

Proof state:
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
⊢ f x ≤ bind S f

Next tactic:
rw [le_iff_count]
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  classical
    rw [le_iff_count]
    

Proof state:
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
⊢ ∀ (a : β), count a (f x) ≤ count a (bind S f)

Next tactic:
intro a
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  classical
    rw [le_iff_count]
    intro a
    

Proof state:
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a✝ : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
a : β
⊢ count a (f x) ≤ count a (bind S f)

Next tactic:
rw [count_bind]
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  classical
    rw [le_iff_count]
    intro a
    rw [count_bind]
    

Proof state:
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a✝ : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
a : β
⊢ count a (f x) ≤ sum (map (fun b => count a (f b)) S)

Next tactic:
apply le_sum_of_mem
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  classical
    rw [le_iff_count]
    intro a
    rw [count_bind]
    apply le_sum_of_mem
    

Proof state:
case h
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a✝ : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
a : β
⊢ count a (f x) ∈ map (fun b => count a (f b)) S

Next tactic:
rw [mem_map]
theorem le_bind {α β : Type*} {f : α → Multiset β} (S : Multiset α) {x : α} (hx : x ∈ S) :
    f x ≤ S.bind f := by
  classical
    rw [le_iff_count]
    intro a
    rw [count_bind]
    apply le_sum_of_mem
    rw [mem_map]
    

Proof state:
case h
α✝ : Type u_1
β✝ : Type v
γ : Type u_2
δ : Type u_3
a✝ : α✝
s t : Multiset α✝
f✝ g : α✝ → Multiset β✝
α : Type u_4
β : Type u_5
f : α → Multiset β
S : Multiset α
x : α
hx : x ∈ S
a : β
⊢ ∃ a_1 ∈ S, count a (f a_1) = count a (f x)

Next tactic:
exact ⟨x, hx, rfl⟩
@[simp]
theorem coe_product (l₁ : List α) (l₂ : List β) :
    (l₁ : Multiset α) ×ˢ (l₂ : Multiset β) = (l₁ ×ˢ l₂) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
l₁ : List α
l₂ : List β
⊢ ↑l₁ ×ˢ ↑l₂ = ↑(l₁ ×ˢ l₂)

Next tactic:
dsimp only [SProd.sprod]
@[simp]
theorem coe_product (l₁ : List α) (l₂ : List β) :
    (l₁ : Multiset α) ×ˢ (l₂ : Multiset β) = (l₁ ×ˢ l₂) := by
  dsimp only [SProd.sprod]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
l₁ : List α
l₂ : List β
⊢ product ↑l₁ ↑l₂ = ↑(List.product l₁ l₂)

Next tactic:
rw [product, List.product, ← coe_bind]
@[simp]
theorem coe_product (l₁ : List α) (l₂ : List β) :
    (l₁ : Multiset α) ×ˢ (l₂ : Multiset β) = (l₁ ×ˢ l₂) := by
  dsimp only [SProd.sprod]
  rw [product, List.product, ← coe_bind]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
l₁ : List α
l₂ : List β
⊢ (bind ↑l₁ fun a => map (Prod.mk a) ↑l₂) = bind ↑l₁ fun a => ↑(List.map (Prod.mk a) l₂)

Next tactic:
simp
@[simp]
theorem cons_product : (a ::ₘ s) ×ˢ t = map (Prod.mk a) t + s ×ˢ t := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
⊢ (a ::ₘ s) ×ˢ t = map (Prod.mk a) t + s ×ˢ t

Next tactic:
simp [SProd.sprod, product]
@[simp]
theorem product_zero : s ×ˢ (0 : Multiset β) = 0 := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
⊢ s ×ˢ 0 = 0

Next tactic:
simp [SProd.sprod, product]
@[simp]
theorem product_cons : s ×ˢ (b ::ₘ t) = (s.map fun a => (a, b)) + s ×ˢ t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
⊢ s ×ˢ (b ::ₘ t) = map (fun a => (a, b)) s + s ×ˢ t

Next tactic:
simp [SProd.sprod, product]
@[simp]
theorem product_singleton : ({a} : Multiset α) ×ˢ ({b} : Multiset β) = {(a, b)} := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
⊢ {a} ×ˢ {b} = {(a, b)}

Next tactic:
simp only [SProd.sprod, product, bind_singleton, map_singleton]
@[simp]
theorem add_product (s t : Multiset α) (u : Multiset β) : (s + t) ×ˢ u = s ×ˢ u + t ×ˢ u := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s✝ : Multiset α
t✝ : Multiset β
s t : Multiset α
u : Multiset β
⊢ (s + t) ×ˢ u = s ×ˢ u + t ×ˢ u

Next tactic:
simp [SProd.sprod, product]
@[simp]
theorem product_add (s : Multiset α) : ∀ t u : Multiset β, s ×ˢ (t + u) = s ×ˢ t + s ×ˢ u :=
  Multiset.induction_on s (fun t u => rfl) fun a s IH t u => by
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a✝ : α
b : β
s✝¹ : Multiset α
t✝ : Multiset β
s✝ : Multiset α
a : α
s : Multiset α
IH : ∀ (t u : Multiset β), s ×ˢ (t + u) = s ×ˢ t + s ×ˢ u
t u : Multiset β
⊢ (a ::ₘ s) ×ˢ (t + u) = (a ::ₘ s) ×ˢ t + (a ::ₘ s) ×ˢ u

Next tactic:
rw [cons_product, IH]
@[simp]
theorem product_add (s : Multiset α) : ∀ t u : Multiset β, s ×ˢ (t + u) = s ×ˢ t + s ×ˢ u :=
  Multiset.induction_on s (fun t u => rfl) fun a s IH t u => by
    rw [cons_product, IH]
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a✝ : α
b : β
s✝¹ : Multiset α
t✝ : Multiset β
s✝ : Multiset α
a : α
s : Multiset α
IH : ∀ (t u : Multiset β), s ×ˢ (t + u) = s ×ˢ t + s ×ˢ u
t u : Multiset β
⊢ map (Prod.mk a) (t + u) + (s ×ˢ t + s ×ˢ u) = (a ::ₘ s) ×ˢ t + (a ::ₘ s) ×ˢ u

Next tactic:
simp [add_comm, add_left_comm, add_assoc]
@[simp]
theorem mem_product {s t} : ∀ {p : α × β}, p ∈ @product α β s t ↔ p.1 ∈ s ∧ p.2 ∈ t
  | (a, b) => by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a✝ : α
b✝ : β
s✝ : Multiset α
t✝ : Multiset β
s : Multiset α
t : Multiset β
a : α
b : β
⊢ (a, b) ∈ product s t ↔ (a, b).1 ∈ s ∧ (a, b).2 ∈ t

Next tactic:
simp [product, and_left_comm]
@[simp]
theorem card_product : card (s ×ˢ t) = card s * card t := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
a : α
b : β
s : Multiset α
t : Multiset β
⊢ card (s ×ˢ t) = card s * card t

Next tactic:
simp [SProd.sprod, product]
@[simp]
theorem coe_sigma (l₁ : List α) (l₂ : ∀ a, List (σ a)) :
    (@Multiset.sigma α σ l₁ fun a => l₂ a) = l₁.sigma l₂ := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a : α
s : Multiset α
t : (a : α) → Multiset (σ a)
l₁ : List α
l₂ : (a : α) → List (σ a)
⊢ (Multiset.sigma ↑l₁ fun a => ↑(l₂ a)) = ↑(List.sigma l₁ l₂)

Next tactic:
rw [Multiset.sigma, List.sigma, ← coe_bind]
@[simp]
theorem coe_sigma (l₁ : List α) (l₂ : ∀ a, List (σ a)) :
    (@Multiset.sigma α σ l₁ fun a => l₂ a) = l₁.sigma l₂ := by
  rw [Multiset.sigma, List.sigma, ← coe_bind]
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a : α
s : Multiset α
t : (a : α) → Multiset (σ a)
l₁ : List α
l₂ : (a : α) → List (σ a)
⊢ (bind ↑l₁ fun a => map (Sigma.mk a) ↑(l₂ a)) = bind ↑l₁ fun a => ↑(List.map (Sigma.mk a) (l₂ a))

Next tactic:
simp
@[simp]
theorem cons_sigma : (a ::ₘ s).sigma t = (t a).map (Sigma.mk a) + s.sigma t := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a : α
s : Multiset α
t : (a : α) → Multiset (σ a)
⊢ Multiset.sigma (a ::ₘ s) t = map (Sigma.mk a) (t a) + Multiset.sigma s t

Next tactic:
simp [Multiset.sigma]
@[simp]
theorem add_sigma (s t : Multiset α) (u : ∀ a, Multiset (σ a)) :
    (s + t).sigma u = s.sigma u + t.sigma u := by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a : α
s✝ : Multiset α
t✝ : (a : α) → Multiset (σ a)
s t : Multiset α
u : (a : α) → Multiset (σ a)
⊢ Multiset.sigma (s + t) u = Multiset.sigma s u + Multiset.sigma t u

Next tactic:
simp [Multiset.sigma]
@[simp]
theorem sigma_add :
    ∀ t u : ∀ a, Multiset (σ a), (s.sigma fun a => t a + u a) = s.sigma t + s.sigma u :=
  Multiset.induction_on s (fun t u => rfl) fun a s IH t u => by
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a✝ : α
s✝ : Multiset α
t✝ : (a : α) → Multiset (σ a)
a : α
s : Multiset α
IH : ∀ (t u : (a : α) → Multiset (σ a)), (Multiset.sigma s fun a => t a + u a) = Multiset.sigma s t + Multiset.sigma s u
t u : (a : α) → Multiset (σ a)
⊢ (Multiset.sigma (a ::ₘ s) fun a => t a + u a) = Multiset.sigma (a ::ₘ s) t + Multiset.sigma (a ::ₘ s) u

Next tactic:
rw [cons_sigma, IH]
@[simp]
theorem sigma_add :
    ∀ t u : ∀ a, Multiset (σ a), (s.sigma fun a => t a + u a) = s.sigma t + s.sigma u :=
  Multiset.induction_on s (fun t u => rfl) fun a s IH t u => by
    rw [cons_sigma, IH]
    

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a✝ : α
s✝ : Multiset α
t✝ : (a : α) → Multiset (σ a)
a : α
s : Multiset α
IH : ∀ (t u : (a : α) → Multiset (σ a)), (Multiset.sigma s fun a => t a + u a) = Multiset.sigma s t + Multiset.sigma s u
t u : (a : α) → Multiset (σ a)
⊢ map (Sigma.mk a) (t a + u a) + ((Multiset.sigma s fun a => t a) + Multiset.sigma s fun a => u a) =
    Multiset.sigma (a ::ₘ s) t + Multiset.sigma (a ::ₘ s) u

Next tactic:
simp [add_comm, add_left_comm, add_assoc]
@[simp]
theorem mem_sigma {s t} : ∀ {p : Σa, σ a}, p ∈ @Multiset.sigma α σ s t ↔ p.1 ∈ s ∧ p.2 ∈ t p.1
  | ⟨a, b⟩ => by 

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a✝ : α
s✝ : Multiset α
t✝ : (a : α) → Multiset (σ a)
s : Multiset α
t : (a : α) → Multiset (σ a)
a : α
b : σ a
⊢ { fst := a, snd := b } ∈ Multiset.sigma s t ↔
    { fst := a, snd := b }.fst ∈ s ∧ { fst := a, snd := b }.snd ∈ t { fst := a, snd := b }.fst

Next tactic:
simp [Multiset.sigma, and_assoc, and_left_comm]
@[simp]
theorem card_sigma : card (s.sigma t) = sum (map (fun a => card (t a)) s) := by
  

Proof state:
α : Type u_1
β : Type v
γ : Type u_2
δ : Type u_3
σ : α → Type u_4
a : α
s : Multiset α
t : (a : α) → Multiset (σ a)
⊢ card (Multiset.sigma s t) = sum (map (fun a => card (t a)) s)

Next tactic:
simp [Multiset.sigma, (· ∘ ·)]
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        

Proof state:
C : Type u
X Y Z : F C
f : X ⟶ Y
g : Y ⟶ Z
⊢ ((fun x x_1 => x ≈ x_1) ⇒ (fun x x_1 => x ≈ x_1) ⇒ fun x x_1 => x ≈ x_1) Hom.comp Hom.comp

Next tactic:
intro f f' hf g g' hg
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        intro f f' hf g g' hg
        

Proof state:
C : Type u
X Y Z : F C
f✝ : X ⟶ Y
g✝ : Y ⟶ Z
f f' : X ⟶ᵐ Y
hf : f ≈ f'
g g' : Y ⟶ᵐ Z
hg : g ≈ g'
⊢ Hom.comp f g ≈ Hom.comp f' g'

Next tactic:
exact comp hf hg
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        intro f f' hf g g' hg
        exact comp hf hg)
      f g
  id_comp := by
    

Proof state:
C : Type u
⊢ ∀ {X Y : F C} (f : X ⟶ Y), 𝟙 X ≫ f = f

Next tactic:
rintro X Y ⟨f⟩
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        intro f f' hf g g' hg
        exact comp hf hg)
      f g
  id_comp := by
    rintro X Y ⟨f⟩
    

Proof state:
case mk
C : Type u
X Y : F C
f✝ : X ⟶ Y
f : X ⟶ᵐ Y
⊢ 𝟙 X ≫ Quot.mk Setoid.r f = Quot.mk Setoid.r f

Next tactic:
exact Quotient.sound (id_comp f)
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        intro f f' hf g g' hg
        exact comp hf hg)
      f g
  id_comp := by
    rintro X Y ⟨f⟩
    exact Quotient.sound (id_comp f)
  comp_id := by
    

Proof state:
C : Type u
⊢ ∀ {X Y : F C} (f : X ⟶ Y), f ≫ 𝟙 Y = f

Next tactic:
rintro X Y ⟨f⟩
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        intro f f' hf g g' hg
        exact comp hf hg)
      f g
  id_comp := by
    rintro X Y ⟨f⟩
    exact Quotient.sound (id_comp f)
  comp_id := by
    rintro X Y ⟨f⟩
    

Proof state:
case mk
C : Type u
X Y : F C
f✝ : X ⟶ Y
f : X ⟶ᵐ Y
⊢ Quot.mk Setoid.r f ≫ 𝟙 Y = Quot.mk Setoid.r f

Next tactic:
exact Quotient.sound (comp_id f)
instance categoryFreeMonoidalCategory : Category.{u} (F C) where
  Hom X Y := Quotient (FreeMonoidalCategory.setoidHom X Y)
  id X := ⟦FreeMonoidalCategory.Hom.id _⟧
  comp := @fun X Y Z f g =>
    Quotient.map₂ Hom.comp
      (by
        intro f f' hf g g' hg
        exact comp hf hg)
      f g
  id_comp := by
    rintro X Y ⟨f⟩
    exact Quotient.sound (id_comp f)
  comp_id := by
    rintro X Y ⟨f⟩
    exact Quotient.sound (comp_id f)
  assoc := by
    

Proof state:
C : Type u
⊢ ∀ {W X Y Z : F C} (f : W ⟶ X) (g : X ⟶ Y) (h : Y ⟶ Z), (f ≫ g) ≫ h = f ≫ g ≫ h

Next tactic:
rintro W X Y Z ⟨f⟩ ⟨g⟩ ⟨h⟩