l3lab/ntp-mathlib huggingface dataset:
@[to_additive sum_lt_sum_of_subset]
theorem prod_lt_prod_of_subset' (h : s ⊆ t) {i : ι} (ht : i ∈ t) (hs : i ∉ s) (hlt : 1 < f i)
    (hle : ∀ j ∈ t, j ∉ s → 1 ≤ f j) : ∏ j in s, f j < ∏ j in t, f j := by
  classical calc
    ∏ j in s, f j < ∏ j in insert i s, f j := by
      rw [prod_insert hs]
      exact lt_mul_of_one_lt_left' (∏ j in s, f j) hlt
    _ ≤ ∏ j in t, f j := by
      apply prod_le_prod_of_subset_of_one_le'
      · simp [Finset.insert_subset_iff, h, ht]
      · 

Proof state:
case hf
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
h : s ⊆ t
i : ι
ht : i ∈ t
hs : i ∉ s
hlt : 1 < f i
hle : ∀ j ∈ t, j ∉ s → 1 ≤ f j
⊢ ∀ i_1 ∈ t, i_1 ∉ insert i s → 1 ≤ f i_1

Next tactic:
intro x hx h'x
@[to_additive sum_lt_sum_of_subset]
theorem prod_lt_prod_of_subset' (h : s ⊆ t) {i : ι} (ht : i ∈ t) (hs : i ∉ s) (hlt : 1 < f i)
    (hle : ∀ j ∈ t, j ∉ s → 1 ≤ f j) : ∏ j in s, f j < ∏ j in t, f j := by
  classical calc
    ∏ j in s, f j < ∏ j in insert i s, f j := by
      rw [prod_insert hs]
      exact lt_mul_of_one_lt_left' (∏ j in s, f j) hlt
    _ ≤ ∏ j in t, f j := by
      apply prod_le_prod_of_subset_of_one_le'
      · simp [Finset.insert_subset_iff, h, ht]
      · intro x hx h'x
        

Proof state:
case hf
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
h : s ⊆ t
i : ι
ht : i ∈ t
hs : i ∉ s
hlt : 1 < f i
hle : ∀ j ∈ t, j ∉ s → 1 ≤ f j
x : ι
hx : x ∈ t
h'x : x ∉ insert i s
⊢ 1 ≤ f x

Next tactic:
simp only [mem_insert, not_or] at h'x
@[to_additive sum_lt_sum_of_subset]
theorem prod_lt_prod_of_subset' (h : s ⊆ t) {i : ι} (ht : i ∈ t) (hs : i ∉ s) (hlt : 1 < f i)
    (hle : ∀ j ∈ t, j ∉ s → 1 ≤ f j) : ∏ j in s, f j < ∏ j in t, f j := by
  classical calc
    ∏ j in s, f j < ∏ j in insert i s, f j := by
      rw [prod_insert hs]
      exact lt_mul_of_one_lt_left' (∏ j in s, f j) hlt
    _ ≤ ∏ j in t, f j := by
      apply prod_le_prod_of_subset_of_one_le'
      · simp [Finset.insert_subset_iff, h, ht]
      · intro x hx h'x
        simp only [mem_insert, not_or] at h'x
        

Proof state:
case hf
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
h : s ⊆ t
i : ι
ht : i ∈ t
hs : i ∉ s
hlt : 1 < f i
hle : ∀ j ∈ t, j ∉ s → 1 ≤ f j
x : ι
hx : x ∈ t
h'x : ¬x = i ∧ x ∉ s
⊢ 1 ≤ f x

Next tactic:
exact hle x hx h'x.2
@[to_additive single_lt_sum]
theorem single_lt_prod' {i j : ι} (hij : j ≠ i) (hi : i ∈ s) (hj : j ∈ s) (hlt : 1 < f j)
    (hle : ∀ k ∈ s, k ≠ i → 1 ≤ f k) : f i < ∏ k in s, f k :=
  calc
    f i = ∏ k in {i}, f k := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
i j : ι
hij : j ≠ i
hi : i ∈ s
hj : j ∈ s
hlt : 1 < f j
hle : ∀ k ∈ s, k ≠ i → 1 ≤ f k
⊢ f i = ∏ k in {i}, f k

Next tactic:
rw [prod_singleton]
@[to_additive sum_pos]
theorem one_lt_prod (h : ∀ i ∈ s, 1 < f i) (hs : s.Nonempty) : 1 < ∏ i in s, f i :=
  lt_of_le_of_lt (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
h : ∀ i ∈ s, 1 < f i
hs : Finset.Nonempty s
⊢ 1 ≤ ∏ i in s, 1

Next tactic:
rw [prod_const_one]
@[to_additive]
theorem prod_lt_one (h : ∀ i ∈ s, f i < 1) (hs : s.Nonempty) : ∏ i in s, f i < 1 :=
  (prod_lt_prod_of_nonempty' hs h).trans_le (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
h : ∀ i ∈ s, f i < 1
hs : Finset.Nonempty s
⊢ ∏ i in s, 1 ≤ 1

Next tactic:
rw [prod_const_one]
@[to_additive]
theorem prod_eq_prod_iff_of_le {f g : ι → M} (h : ∀ i ∈ s, f i ≤ g i) :
    ((∏ i in s, f i) = ∏ i in s, g i) ↔ ∀ i ∈ s, f i = g i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f✝ g✝ : ι → M
s t : Finset ι
f g : ι → M
h : ∀ i ∈ s, f i ≤ g i
⊢ ∏ i in s, f i = ∏ i in s, g i ↔ ∀ i ∈ s, f i = g i

Next tactic:
classical
    revert h
    refine Finset.induction_on s (fun _ ↦ ⟨fun _ _ h ↦ False.elim (Finset.not_mem_empty _ h),
      fun _ ↦ rfl⟩) fun a s ha ih H ↦ ?_
    specialize ih fun i ↦ H i ∘ Finset.mem_insert_of_mem
    rw [Finset.prod_insert ha, Finset.prod_insert ha, Finset.forall_mem_insert, ← ih]
    exact
      mul_eq_mul_iff_eq_and_eq (H a (s.mem_insert_self a))
        (Finset.prod_le_prod' fun i ↦ H i ∘ Finset.mem_insert_of_mem)
@[to_additive]
theorem prod_eq_prod_iff_of_le {f g : ι → M} (h : ∀ i ∈ s, f i ≤ g i) :
    ((∏ i in s, f i) = ∏ i in s, g i) ↔ ∀ i ∈ s, f i = g i := by
  classical
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f✝ g✝ : ι → M
s t : Finset ι
f g : ι → M
h : ∀ i ∈ s, f i ≤ g i
⊢ ∏ i in s, f i = ∏ i in s, g i ↔ ∀ i ∈ s, f i = g i

Next tactic:
revert h
@[to_additive]
theorem prod_eq_prod_iff_of_le {f g : ι → M} (h : ∀ i ∈ s, f i ≤ g i) :
    ((∏ i in s, f i) = ∏ i in s, g i) ↔ ∀ i ∈ s, f i = g i := by
  classical
    revert h
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f✝ g✝ : ι → M
s t : Finset ι
f g : ι → M
⊢ (∀ i ∈ s, f i ≤ g i) → (∏ i in s, f i = ∏ i in s, g i ↔ ∀ i ∈ s, f i = g i)

Next tactic:
refine Finset.induction_on s (fun _ ↦ ⟨fun _ _ h ↦ False.elim (Finset.not_mem_empty _ h),
      fun _ ↦ rfl⟩) fun a s ha ih H ↦ ?_
@[to_additive]
theorem prod_eq_prod_iff_of_le {f g : ι → M} (h : ∀ i ∈ s, f i ≤ g i) :
    ((∏ i in s, f i) = ∏ i in s, g i) ↔ ∀ i ∈ s, f i = g i := by
  classical
    revert h
    refine Finset.induction_on s (fun _ ↦ ⟨fun _ _ h ↦ False.elim (Finset.not_mem_empty _ h),
      fun _ ↦ rfl⟩) fun a s ha ih H ↦ ?_
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f✝ g✝ : ι → M
s✝ t : Finset ι
f g : ι → M
a : ι
s : Finset ι
ha : a ∉ s
ih : (∀ i ∈ s, f i ≤ g i) → (∏ i in s, f i = ∏ i in s, g i ↔ ∀ i ∈ s, f i = g i)
H : ∀ i ∈ insert a s, f i ≤ g i
⊢ ∏ i in insert a s, f i = ∏ i in insert a s, g i ↔ ∀ i ∈ insert a s, f i = g i

Next tactic:
specialize ih fun i ↦ H i ∘ Finset.mem_insert_of_mem
@[to_additive]
theorem prod_eq_prod_iff_of_le {f g : ι → M} (h : ∀ i ∈ s, f i ≤ g i) :
    ((∏ i in s, f i) = ∏ i in s, g i) ↔ ∀ i ∈ s, f i = g i := by
  classical
    revert h
    refine Finset.induction_on s (fun _ ↦ ⟨fun _ _ h ↦ False.elim (Finset.not_mem_empty _ h),
      fun _ ↦ rfl⟩) fun a s ha ih H ↦ ?_
    specialize ih fun i ↦ H i ∘ Finset.mem_insert_of_mem
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f✝ g✝ : ι → M
s✝ t : Finset ι
f g : ι → M
a : ι
s : Finset ι
ha : a ∉ s
H : ∀ i ∈ insert a s, f i ≤ g i
ih : ∏ i in s, f i = ∏ i in s, g i ↔ ∀ i ∈ s, f i = g i
⊢ ∏ i in insert a s, f i = ∏ i in insert a s, g i ↔ ∀ i ∈ insert a s, f i = g i

Next tactic:
rw [Finset.prod_insert ha, Finset.prod_insert ha, Finset.forall_mem_insert, ← ih]
@[to_additive]
theorem prod_eq_prod_iff_of_le {f g : ι → M} (h : ∀ i ∈ s, f i ≤ g i) :
    ((∏ i in s, f i) = ∏ i in s, g i) ↔ ∀ i ∈ s, f i = g i := by
  classical
    revert h
    refine Finset.induction_on s (fun _ ↦ ⟨fun _ _ h ↦ False.elim (Finset.not_mem_empty _ h),
      fun _ ↦ rfl⟩) fun a s ha ih H ↦ ?_
    specialize ih fun i ↦ H i ∘ Finset.mem_insert_of_mem
    rw [Finset.prod_insert ha, Finset.prod_insert ha, Finset.forall_mem_insert, ← ih]
    

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCancelCommMonoid M
f✝ g✝ : ι → M
s✝ t : Finset ι
f g : ι → M
a : ι
s : Finset ι
ha : a ∉ s
H : ∀ i ∈ insert a s, f i ≤ g i
ih : ∏ i in s, f i = ∏ i in s, g i ↔ ∀ i ∈ s, f i = g i
⊢ f a * ∏ x in s, f x = g a * ∏ x in s, g x ↔ f a = g a ∧ ∏ i in s, f i = ∏ i in s, g i

Next tactic:
exact
      mul_eq_mul_iff_eq_and_eq (H a (s.mem_insert_self a))
        (Finset.prod_le_prod' fun i ↦ H i ∘ Finset.mem_insert_of_mem)
@[to_additive] lemma prod_sdiff_le_prod_sdiff :
    ∏ i in s \ t, f i ≤ ∏ i in t \ s, f i ↔ ∏ i in s, f i ≤ ∏ i in t, f i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝¹ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
inst✝ : DecidableEq ι
⊢ ∏ i in s \ t, f i ≤ ∏ i in t \ s, f i ↔ ∏ i in s, f i ≤ ∏ i in t, f i

Next tactic:
rw [← mul_le_mul_iff_right, ← prod_union (disjoint_sdiff_inter _ _), sdiff_union_inter,
    ← prod_union, inter_comm, sdiff_union_inter]
@[to_additive] lemma prod_sdiff_le_prod_sdiff :
    ∏ i in s \ t, f i ≤ ∏ i in t \ s, f i ↔ ∏ i in s, f i ≤ ∏ i in t, f i := by
  rw [← mul_le_mul_iff_right, ← prod_union (disjoint_sdiff_inter _ _), sdiff_union_inter,
    ← prod_union, inter_comm, sdiff_union_inter];
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝¹ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
inst✝ : DecidableEq ι
⊢ Disjoint (t \ s) (s ∩ t)

Next tactic:
simpa only [inter_comm] using disjoint_sdiff_inter t s
@[to_additive] lemma prod_sdiff_lt_prod_sdiff :
    ∏ i in s \ t, f i < ∏ i in t \ s, f i ↔ ∏ i in s, f i < ∏ i in t, f i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝¹ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
inst✝ : DecidableEq ι
⊢ ∏ i in s \ t, f i < ∏ i in t \ s, f i ↔ ∏ i in s, f i < ∏ i in t, f i

Next tactic:
rw [← mul_lt_mul_iff_right, ← prod_union (disjoint_sdiff_inter _ _), sdiff_union_inter,
    ← prod_union, inter_comm, sdiff_union_inter]
@[to_additive] lemma prod_sdiff_lt_prod_sdiff :
    ∏ i in s \ t, f i < ∏ i in t \ s, f i ↔ ∏ i in s, f i < ∏ i in t, f i := by
  rw [← mul_lt_mul_iff_right, ← prod_union (disjoint_sdiff_inter _ _), sdiff_union_inter,
    ← prod_union, inter_comm, sdiff_union_inter];
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝¹ : OrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
inst✝ : DecidableEq ι
⊢ Disjoint (t \ s) (s ∩ t)

Next tactic:
simpa only [inter_comm] using disjoint_sdiff_inter t s
@[to_additive exists_lt_of_sum_lt]
theorem exists_lt_of_prod_lt' (Hlt : ∏ i in s, f i < ∏ i in s, g i) : ∃ i ∈ s, f i < g i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
Hlt : ∏ i in s, f i < ∏ i in s, g i
⊢ ∃ i ∈ s, f i < g i

Next tactic:
contrapose! Hlt with Hle
@[to_additive exists_lt_of_sum_lt]
theorem exists_lt_of_prod_lt' (Hlt : ∏ i in s, f i < ∏ i in s, g i) : ∃ i ∈ s, f i < g i := by
  contrapose! Hlt with Hle
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
Hle : ∀ i ∈ s, g i ≤ f i
⊢ ∏ i in s, g i ≤ ∏ i in s, f i

Next tactic:
exact prod_le_prod' Hle
@[to_additive exists_le_of_sum_le]
theorem exists_le_of_prod_le' (hs : s.Nonempty) (Hle : ∏ i in s, f i ≤ ∏ i in s, g i) :
    ∃ i ∈ s, f i ≤ g i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
hs : Finset.Nonempty s
Hle : ∏ i in s, f i ≤ ∏ i in s, g i
⊢ ∃ i ∈ s, f i ≤ g i

Next tactic:
contrapose! Hle with Hlt
@[to_additive exists_le_of_sum_le]
theorem exists_le_of_prod_le' (hs : s.Nonempty) (Hle : ∏ i in s, f i ≤ ∏ i in s, g i) :
    ∃ i ∈ s, f i ≤ g i := by
  contrapose! Hle with Hlt
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f g : ι → M
s t : Finset ι
hs : Finset.Nonempty s
Hlt : ∀ i ∈ s, g i < f i
⊢ ∏ i in s, g i < ∏ i in s, f i

Next tactic:
exact prod_lt_prod_of_nonempty' hs Hlt
@[to_additive exists_pos_of_sum_zero_of_exists_nonzero]
theorem exists_one_lt_of_prod_one_of_exists_ne_one' (f : ι → M) (h₁ : ∏ i in s, f i = 1)
    (h₂ : ∃ i ∈ s, f i ≠ 1) : ∃ i ∈ s, 1 < f i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f✝ g : ι → M
s t : Finset ι
f : ι → M
h₁ : ∏ i in s, f i = 1
h₂ : ∃ i ∈ s, f i ≠ 1
⊢ ∃ i ∈ s, 1 < f i

Next tactic:
contrapose! h₁
@[to_additive exists_pos_of_sum_zero_of_exists_nonzero]
theorem exists_one_lt_of_prod_one_of_exists_ne_one' (f : ι → M) (h₁ : ∏ i in s, f i = 1)
    (h₂ : ∃ i ∈ s, f i ≠ 1) : ∃ i ∈ s, 1 < f i := by
  contrapose! h₁
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f✝ g : ι → M
s t : Finset ι
f : ι → M
h₂ : ∃ i ∈ s, f i ≠ 1
h₁ : ∀ i ∈ s, f i ≤ 1
⊢ ∏ i in s, f i ≠ 1

Next tactic:
obtain ⟨i, m, i_ne⟩ : ∃ i ∈ s, f i ≠ 1 := h₂
@[to_additive exists_pos_of_sum_zero_of_exists_nonzero]
theorem exists_one_lt_of_prod_one_of_exists_ne_one' (f : ι → M) (h₁ : ∏ i in s, f i = 1)
    (h₂ : ∃ i ∈ s, f i ≠ 1) : ∃ i ∈ s, 1 < f i := by
  contrapose! h₁
  obtain ⟨i, m, i_ne⟩ : ∃ i ∈ s, f i ≠ 1 := h₂
  

Proof state:
case intro.intro
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f✝ g : ι → M
s t : Finset ι
f : ι → M
h₁ : ∀ i ∈ s, f i ≤ 1
i : ι
m : i ∈ s
i_ne : f i ≠ 1
⊢ ∏ i in s, f i ≠ 1

Next tactic:
apply ne_of_lt
@[to_additive exists_pos_of_sum_zero_of_exists_nonzero]
theorem exists_one_lt_of_prod_one_of_exists_ne_one' (f : ι → M) (h₁ : ∏ i in s, f i = 1)
    (h₂ : ∃ i ∈ s, f i ≠ 1) : ∃ i ∈ s, 1 < f i := by
  contrapose! h₁
  obtain ⟨i, m, i_ne⟩ : ∃ i ∈ s, f i ≠ 1 := h₂
  apply ne_of_lt
  

Proof state:
case intro.intro.h
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : LinearOrderedCancelCommMonoid M
f✝ g : ι → M
s t : Finset ι
f : ι → M
h₁ : ∀ i ∈ s, f i ≤ 1
i : ι
m : i ∈ s
i_ne : f i ≠ 1
⊢ ∏ i in s, f i < 1

Next tactic:
calc
    ∏ j in s, f j < ∏ j in s, 1 := prod_lt_prod' h₁ ⟨i, m, (h₁ i m).lt_of_ne i_ne⟩
    _ = 1 := prod_const_one
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s t : Finset ι
h0 : ∀ i ∈ s, 0 ≤ f i
h1 : ∀ i ∈ s, f i ≤ g i
⊢ ∏ i in s, f i ≤ ∏ i in s, g i

Next tactic:
induction' s using Finset.induction with a s has ih h
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · 

Proof state:
case empty
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s t : Finset ι
h0 : ∀ i ∈ ∅, 0 ≤ f i
h1 : ∀ i ∈ ∅, f i ≤ g i
⊢ ∏ i in ∅, f i ≤ ∏ i in ∅, g i

Next tactic:
simp
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · 

Proof state:
case insert
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
⊢ ∏ i in insert a s, f i ≤ ∏ i in insert a s, g i

Next tactic:
simp only [prod_insert has]
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    

Proof state:
case insert
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
⊢ f a * ∏ i in s, f i ≤ g a * ∏ i in s, g i

Next tactic:
apply mul_le_mul
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    apply mul_le_mul
    · 

Proof state:
case insert.h₁
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
⊢ f a ≤ g a

Next tactic:
exact h1 a (mem_insert_self a s)
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    apply mul_le_mul
    · exact h1 a (mem_insert_self a s)
    · 

Proof state:
case insert.h₂
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
⊢ ∏ i in s, f i ≤ ∏ i in s, g i

Next tactic:
refine ih (fun x H ↦ h0 _ ?_) (fun x H ↦ h1 _ ?_)
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    apply mul_le_mul
    · exact h1 a (mem_insert_self a s)
    · refine ih (fun x H ↦ h0 _ ?_) (fun x H ↦ h1 _ ?_) <;> 

Proof state:
case insert.h₂.refine_1
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
x : ι
H : x ∈ s
⊢ x ∈ insert a s

Next tactic:
exact mem_insert_of_mem H
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    apply mul_le_mul
    · exact h1 a (mem_insert_self a s)
    · refine ih (fun x H ↦ h0 _ ?_) (fun x H ↦ h1 _ ?_) <;> 

Proof state:
case insert.h₂.refine_2
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
x : ι
H : x ∈ s
⊢ x ∈ insert a s

Next tactic:
exact mem_insert_of_mem H
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    apply mul_le_mul
    · exact h1 a (mem_insert_self a s)
    · refine ih (fun x H ↦ h0 _ ?_) (fun x H ↦ h1 _ ?_) <;> exact mem_insert_of_mem H
    · 

Proof state:
case insert.c0
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
⊢ 0 ≤ ∏ i in s, f i

Next tactic:
apply prod_nonneg fun x H ↦ h0 x (mem_insert_of_mem H)
/-- If all `f i`, `i ∈ s`, are nonnegative and each `f i` is less than or equal to `g i`, then the
product of `f i` is less than or equal to the product of `g i`. See also `Finset.prod_le_prod'` for
the case of an ordered commutative multiplicative monoid. -/
theorem prod_le_prod (h0 : ∀ i ∈ s, 0 ≤ f i) (h1 : ∀ i ∈ s, f i ≤ g i) :
    ∏ i in s, f i ≤ ∏ i in s, g i := by
  induction' s using Finset.induction with a s has ih h
  · simp
  · simp only [prod_insert has]
    apply mul_le_mul
    · exact h1 a (mem_insert_self a s)
    · refine ih (fun x H ↦ h0 _ ?_) (fun x H ↦ h1 _ ?_) <;> exact mem_insert_of_mem H
    · apply prod_nonneg fun x H ↦ h0 x (mem_insert_of_mem H)
    · 

Proof state:
case insert.b0
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
G : Type u_6
k : Type u_7
R : Type u_8
inst✝ : OrderedCommSemiring R
f g : ι → R
s✝ t : Finset ι
a : ι
s : Finset ι
has : a ∉ s
ih : (∀ i ∈ s, 0 ≤ f i) → (∀ i ∈ s, f i ≤ g i) → ∏ i in s, f i ≤ ∏ i in s, g i
h0 : ∀ i ∈ insert a s, 0 ≤ f i
h1 : ∀ i ∈ insert a s, f i ≤ g i
⊢ 0 ≤ g a

Next tactic:
apply le_trans (h0 a (mem_insert_self a s)) (h1 a (mem_insert_self a s))