l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem single_le_prod : (∀ x ∈ s, (1 : α) ≤ x) → ∀ x ∈ s, x ≤ s.prod :=
  Quotient.inductionOn s fun l hl x hx => by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
l : List α
hl : ∀ x ∈ ⟦l⟧, 1 ≤ x
x : α
hx : x ∈ ⟦l⟧
⊢ x ≤ prod ⟦l⟧

Next tactic:
simpa using List.single_le_prod hl x hx
@[to_additive sum_le_card_nsmul]
theorem prod_le_pow_card (s : Multiset α) (n : α) (h : ∀ x ∈ s, x ≤ n) : s.prod ≤ n ^ card s := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s✝ t : Multiset α
a : α
s : Multiset α
n : α
h : ∀ x ∈ s, x ≤ n
⊢ prod s ≤ n ^ card s

Next tactic:
induction s using Quotient.inductionOn
@[to_additive sum_le_card_nsmul]
theorem prod_le_pow_card (s : Multiset α) (n : α) (h : ∀ x ∈ s, x ≤ n) : s.prod ≤ n ^ card s := by
  induction s using Quotient.inductionOn
  

Proof state:
case h
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a n : α
a✝ : List α
h : ∀ x ∈ ⟦a✝⟧, x ≤ n
⊢ prod ⟦a✝⟧ ≤ n ^ card ⟦a✝⟧

Next tactic:
simpa using List.prod_le_pow_card _ _ h
@[to_additive all_zero_of_le_zero_le_of_sum_eq_zero]
theorem all_one_of_le_one_le_of_prod_eq_one :
    (∀ x ∈ s, (1 : α) ≤ x) → s.prod = 1 → ∀ x ∈ s, x = (1 : α) :=
  Quotient.inductionOn s (by
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
⊢ ∀ (a : List α), (∀ x ∈ ⟦a⟧, 1 ≤ x) → prod ⟦a⟧ = 1 → ∀ x ∈ ⟦a⟧, x = 1

Next tactic:
simp only [quot_mk_to_coe, coe_prod, mem_coe]
@[to_additive all_zero_of_le_zero_le_of_sum_eq_zero]
theorem all_one_of_le_one_le_of_prod_eq_one :
    (∀ x ∈ s, (1 : α) ≤ x) → s.prod = 1 → ∀ x ∈ s, x = (1 : α) :=
  Quotient.inductionOn s (by
    simp only [quot_mk_to_coe, coe_prod, mem_coe]
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
⊢ ∀ (a : List α), (∀ x ∈ a, 1 ≤ x) → List.prod a = 1 → ∀ x ∈ a, x = 1

Next tactic:
exact fun l => List.all_one_of_le_one_le_of_prod_eq_one
@[to_additive]
theorem prod_le_prod_of_rel_le (h : s.Rel (· ≤ ·) t) : s.prod ≤ t.prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
h : Rel (fun x x_1 => x ≤ x_1) s t
⊢ prod s ≤ prod t

Next tactic:
induction' h with _ _ _ _ rh _ rt
@[to_additive]
theorem prod_le_prod_of_rel_le (h : s.Rel (· ≤ ·) t) : s.prod ≤ t.prod := by
  induction' h with _ _ _ _ rh _ rt
  · 

Proof state:
case zero
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
⊢ prod 0 ≤ prod 0

Next tactic:
rfl
@[to_additive]
theorem prod_le_prod_of_rel_le (h : s.Rel (· ≤ ·) t) : s.prod ≤ t.prod := by
  induction' h with _ _ _ _ rh _ rt
  · rfl
  · 

Proof state:
case cons
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a a✝¹ b✝ : α
as✝ bs✝ : Multiset α
rh : a✝¹ ≤ b✝
a✝ : Rel (fun x x_1 => x ≤ x_1) as✝ bs✝
rt : prod as✝ ≤ prod bs✝
⊢ prod (a✝¹ ::ₘ as✝) ≤ prod (b✝ ::ₘ bs✝)

Next tactic:
rw [prod_cons, prod_cons]
@[to_additive]
theorem prod_le_prod_of_rel_le (h : s.Rel (· ≤ ·) t) : s.prod ≤ t.prod := by
  induction' h with _ _ _ _ rh _ rt
  · rfl
  · rw [prod_cons, prod_cons]
    

Proof state:
case cons
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a a✝¹ b✝ : α
as✝ bs✝ : Multiset α
rh : a✝¹ ≤ b✝
a✝ : Rel (fun x x_1 => x ≤ x_1) as✝ bs✝
rt : prod as✝ ≤ prod bs✝
⊢ a✝¹ * prod as✝ ≤ b✝ * prod bs✝

Next tactic:
exact mul_le_mul' rh rt
@[to_additive card_nsmul_le_sum]
theorem pow_card_le_prod (h : ∀ x ∈ s, a ≤ x) : a ^ card s ≤ s.prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
h : ∀ x ∈ s, a ≤ x
⊢ a ^ card s ≤ prod s

Next tactic:
rw [← Multiset.prod_replicate, ← Multiset.map_const]
@[to_additive card_nsmul_le_sum]
theorem pow_card_le_prod (h : ∀ x ∈ s, a ≤ x) : a ^ card s ≤ s.prod := by
  rw [← Multiset.prod_replicate, ← Multiset.map_const]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommMonoid α
s t : Multiset α
a : α
h : ∀ x ∈ s, a ≤ x
⊢ prod (map (Function.const α a) s) ≤ prod s

Next tactic:
exact prod_map_le_prod _ h
@[to_additive sum_lt_sum]
theorem prod_lt_prod' (hle : ∀ i ∈ s, f i ≤ g i) (hlt : ∃ i ∈ s, f i < g i) :
    (s.map f).prod < (s.map g).prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCancelCommMonoid α
s : Multiset ι
f g : ι → α
hle : ∀ i ∈ s, f i ≤ g i
hlt : ∃ i ∈ s, f i < g i
⊢ prod (map f s) < prod (map g s)

Next tactic:
obtain ⟨l⟩ := s
@[to_additive sum_lt_sum]
theorem prod_lt_prod' (hle : ∀ i ∈ s, f i ≤ g i) (hlt : ∃ i ∈ s, f i < g i) :
    (s.map f).prod < (s.map g).prod := by
  obtain ⟨l⟩ := s
  

Proof state:
case mk
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCancelCommMonoid α
s : Multiset ι
f g : ι → α
l : List ι
hle : ∀ i ∈ Quot.mk Setoid.r l, f i ≤ g i
hlt : ∃ i ∈ Quot.mk Setoid.r l, f i < g i
⊢ prod (map f (Quot.mk Setoid.r l)) < prod (map g (Quot.mk Setoid.r l))

Next tactic:
simp only [Multiset.quot_mk_to_coe'', Multiset.coe_map, Multiset.coe_prod]
@[to_additive sum_lt_sum]
theorem prod_lt_prod' (hle : ∀ i ∈ s, f i ≤ g i) (hlt : ∃ i ∈ s, f i < g i) :
    (s.map f).prod < (s.map g).prod := by
  obtain ⟨l⟩ := s
  simp only [Multiset.quot_mk_to_coe'', Multiset.coe_map, Multiset.coe_prod]
  

Proof state:
case mk
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCancelCommMonoid α
s : Multiset ι
f g : ι → α
l : List ι
hle : ∀ i ∈ Quot.mk Setoid.r l, f i ≤ g i
hlt : ∃ i ∈ Quot.mk Setoid.r l, f i < g i
⊢ List.prod (List.map f l) < List.prod (List.map g l)

Next tactic:
exact List.prod_lt_prod' f g hle hlt
@[to_additive sum_lt_sum_of_nonempty]
theorem prod_lt_prod_of_nonempty' (hs : s ≠ ∅) (hfg : ∀ i ∈ s, f i < g i) :
    (s.map f).prod < (s.map g).prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCancelCommMonoid α
s : Multiset ι
f g : ι → α
hs : s ≠ ∅
hfg : ∀ i ∈ s, f i < g i
⊢ prod (map f s) < prod (map g s)

Next tactic:
obtain ⟨i, hi⟩ := exists_mem_of_ne_zero hs
@[to_additive sum_lt_sum_of_nonempty]
theorem prod_lt_prod_of_nonempty' (hs : s ≠ ∅) (hfg : ∀ i ∈ s, f i < g i) :
    (s.map f).prod < (s.map g).prod := by
  obtain ⟨i, hi⟩ := exists_mem_of_ne_zero hs
  

Proof state:
case intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCancelCommMonoid α
s : Multiset ι
f g : ι → α
hs : s ≠ ∅
hfg : ∀ i ∈ s, f i < g i
i : ι
hi : i ∈ s
⊢ prod (map f s) < prod (map g s)

Next tactic:
exact prod_lt_prod' (fun i hi => le_of_lt (hfg i hi)) ⟨i, hi, hfg i hi⟩
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
h : ∀ a ∈ m, 0 ≤ a
⊢ 0 ≤ prod m

Next tactic:
revert h
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
⊢ (∀ a ∈ m, 0 ≤ a) → 0 ≤ prod m

Next tactic:
refine' m.induction_on _ _
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  refine' m.induction_on _ _
  · 

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
⊢ (∀ a ∈ 0, 0 ≤ a) → 0 ≤ prod 0

Next tactic:
rintro -
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  refine' m.induction_on _ _
  · rintro -
    

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
⊢ 0 ≤ prod 0

Next tactic:
rw [prod_zero]
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  refine' m.induction_on _ _
  · rintro -
    rw [prod_zero]
    

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
⊢ 0 ≤ 1

Next tactic:
exact zero_le_one
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  refine' m.induction_on _ _
  · rintro -
    rw [prod_zero]
    exact zero_le_one
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
⊢ ∀ ⦃a : α⦄ {s : Multiset α}, ((∀ a ∈ s, 0 ≤ a) → 0 ≤ prod s) → (∀ a_2 ∈ a ::ₘ s, 0 ≤ a_2) → 0 ≤ prod (a ::ₘ s)

Next tactic:
intro a s hs ih
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  refine' m.induction_on _ _
  · rintro -
    rw [prod_zero]
    exact zero_le_one
  intro a s hs ih
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
a : α
s : Multiset α
hs : (∀ a ∈ s, 0 ≤ a) → 0 ≤ prod s
ih : ∀ a_1 ∈ a ::ₘ s, 0 ≤ a_1
⊢ 0 ≤ prod (a ::ₘ s)

Next tactic:
rw [prod_cons]
theorem prod_nonneg [OrderedCommSemiring α] {m : Multiset α} (h : ∀ a ∈ m, (0 : α) ≤ a) :
    0 ≤ m.prod := by
  revert h
  refine' m.induction_on _ _
  · rintro -
    rw [prod_zero]
    exact zero_le_one
  intro a s hs ih
  rw [prod_cons]
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : OrderedCommSemiring α
m : Multiset α
a : α
s : Multiset α
hs : (∀ a ∈ s, 0 ≤ a) → 0 ≤ prod s
ih : ∀ a_1 ∈ a ::ₘ s, 0 ≤ a_1
⊢ 0 ≤ a * prod s

Next tactic:
exact mul_nonneg (ih _ <| mem_cons_self _ _) (hs fun a ha => ih _ <| mem_cons_of_mem ha)
/-- Slightly more general version of `Multiset.prod_eq_one_iff` for a non-ordered `Monoid` -/
@[to_additive
      "Slightly more general version of `Multiset.sum_eq_zero_iff` for a non-ordered `AddMonoid`"]
theorem prod_eq_one [CommMonoid α] {m : Multiset α} (h : ∀ x ∈ m, x = (1 : α)) : m.prod = 1 := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : CommMonoid α
m : Multiset α
h : ∀ x ∈ m, x = 1
⊢ prod m = 1

Next tactic:
induction' m using Quotient.inductionOn with l
/-- Slightly more general version of `Multiset.prod_eq_one_iff` for a non-ordered `Monoid` -/
@[to_additive
      "Slightly more general version of `Multiset.sum_eq_zero_iff` for a non-ordered `AddMonoid`"]
theorem prod_eq_one [CommMonoid α] {m : Multiset α} (h : ∀ x ∈ m, x = (1 : α)) : m.prod = 1 := by
  induction' m using Quotient.inductionOn with l
  

Proof state:
case h
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : CommMonoid α
l : List α
h : ∀ x ∈ ⟦l⟧, x = 1
⊢ prod ⟦l⟧ = 1

Next tactic:
simp [List.prod_eq_one h]
@[to_additive]
theorem le_prod_of_mem [CanonicallyOrderedCommMonoid α] {m : Multiset α} {a : α} (h : a ∈ m) :
    a ≤ m.prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : CanonicallyOrderedCommMonoid α
m : Multiset α
a : α
h : a ∈ m
⊢ a ≤ prod m

Next tactic:
obtain ⟨m', rfl⟩ := exists_cons_of_mem h
@[to_additive]
theorem le_prod_of_mem [CanonicallyOrderedCommMonoid α] {m : Multiset α} {a : α} (h : a ∈ m) :
    a ≤ m.prod := by
  obtain ⟨m', rfl⟩ := exists_cons_of_mem h
  

Proof state:
case intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : CanonicallyOrderedCommMonoid α
a : α
m' : Multiset α
h : a ∈ a ::ₘ m'
⊢ a ≤ prod (a ::ₘ m')

Next tactic:
rw [prod_cons]
@[to_additive]
theorem le_prod_of_mem [CanonicallyOrderedCommMonoid α] {m : Multiset α} {a : α} (h : a ∈ m) :
    a ≤ m.prod := by
  obtain ⟨m', rfl⟩ := exists_cons_of_mem h
  rw [prod_cons]
  

Proof state:
case intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : CanonicallyOrderedCommMonoid α
a : α
m' : Multiset α
h : a ∈ a ::ₘ m'
⊢ a ≤ a * prod m'

Next tactic:
exact _root_.le_mul_right (le_refl a)
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
s : Multiset α
hps : ∀ a ∈ s, p a
⊢ f (prod s) ≤ prod (map f s)

Next tactic:
revert s
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
⊢ ∀ (s : Multiset α), (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)

Next tactic:
refine' Multiset.induction _ _
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · 

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
⊢ (∀ a ∈ 0, p a) → f (prod 0) ≤ prod (map f 0)

Next tactic:
simp [le_of_eq h_one]
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · simp [le_of_eq h_one]
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    ((∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)) →
      (∀ a_2 ∈ a ::ₘ s, p a_2) → f (prod (a ::ₘ s)) ≤ prod (map f (a ::ₘ s))

Next tactic:
intro a s hs hpsa
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · simp [le_of_eq h_one]
  intro a s hs hpsa
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hpsa : ∀ a_1 ∈ a ::ₘ s, p a_1
⊢ f (prod (a ::ₘ s)) ≤ prod (map f (a ::ₘ s))

Next tactic:
have hps : ∀ x, x ∈ s → p x := fun x hx => hpsa x (mem_cons_of_mem hx)
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · simp [le_of_eq h_one]
  intro a s hs hpsa
  have hps : ∀ x, x ∈ s → p x := fun x hx => hpsa x (mem_cons_of_mem hx)
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hpsa : ∀ a_1 ∈ a ::ₘ s, p a_1
hps : ∀ x ∈ s, p x
⊢ f (prod (a ::ₘ s)) ≤ prod (map f (a ::ₘ s))

Next tactic:
have hp_prod : p s.prod := prod_induction p s hp_mul hp_one hps
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · simp [le_of_eq h_one]
  intro a s hs hpsa
  have hps : ∀ x, x ∈ s → p x := fun x hx => hpsa x (mem_cons_of_mem hx)
  have hp_prod : p s.prod := prod_induction p s hp_mul hp_one hps
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hpsa : ∀ a_1 ∈ a ::ₘ s, p a_1
hps : ∀ x ∈ s, p x
hp_prod : p (prod s)
⊢ f (prod (a ::ₘ s)) ≤ prod (map f (a ::ₘ s))

Next tactic:
rw [prod_cons, map_cons, prod_cons]
@[to_additive le_sum_of_subadditive_on_pred]
theorem le_prod_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (p : α → Prop) (h_one : f 1 = 1) (hp_one : p 1)
    (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b) (hp_mul : ∀ a b, p a → p b → p (a * b))
    (s : Multiset α) (hps : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · simp [le_of_eq h_one]
  intro a s hs hpsa
  have hps : ∀ x, x ∈ s → p x := fun x hx => hpsa x (mem_cons_of_mem hx)
  have hp_prod : p s.prod := prod_induction p s hp_mul hp_one hps
  rw [prod_cons, map_cons, prod_cons]
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_one : f 1 = 1
hp_one : p 1
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hpsa : ∀ a_1 ∈ a ::ₘ s, p a_1
hps : ∀ x ∈ s, p x
hp_prod : p (prod s)
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
exact (h_mul a s.prod (hpsa a (mem_cons_self a s)) hp_prod).trans (mul_le_mul_left' (hs hps) _)
@[to_additive le_sum_of_subadditive]
theorem le_prod_of_submultiplicative [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (h_one : f 1 = 1) (h_mul : ∀ a b, f (a * b) ≤ f a * f b) (s : Multiset α) :
    f s.prod ≤ (s.map f).prod :=
  le_prod_of_submultiplicative_on_pred f (fun _ => True) h_one trivial (fun x y _ _ => h_mul x y)
    (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
h_one : f 1 = 1
h_mul : ∀ (a b : α), f (a * b) ≤ f a * f b
s : Multiset α
⊢ ∀ (a b : α), (fun x => True) a → (fun x => True) b → (fun x => True) (a * b)

Next tactic:
simp
@[to_additive le_sum_of_subadditive]
theorem le_prod_of_submultiplicative [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (h_one : f 1 = 1) (h_mul : ∀ a b, f (a * b) ≤ f a * f b) (s : Multiset α) :
    f s.prod ≤ (s.map f).prod :=
  le_prod_of_submultiplicative_on_pred f (fun _ => True) h_one trivial (fun x y _ _ => h_mul x y)
    (by simp) s (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
h_one : f 1 = 1
h_mul : ∀ (a b : α), f (a * b) ≤ f a * f b
s : Multiset α
⊢ ∀ a ∈ s, (fun x => True) a

Next tactic:
simp
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
s : Multiset α
hs_nonempty : s ≠ ∅
hs : ∀ a ∈ s, p a
⊢ f (prod s) ≤ prod (map f s)

Next tactic:
revert s
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
⊢ ∀ (s : Multiset α), s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)

Next tactic:
refine' Multiset.induction _ _
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · 

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
⊢ 0 ≠ ∅ → (∀ a ∈ 0, p a) → f (prod 0) ≤ prod (map f 0)

Next tactic:
intro h
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
h : 0 ≠ ∅
⊢ (∀ a ∈ 0, p a) → f (prod 0) ≤ prod (map f 0)

Next tactic:
exfalso