l3lab/ntp-mathlib huggingface dataset:
/-- If `g, h ≤ f` and `g i + h i ≤ f i`, then the product of `f` over `s` is at least the
  sum of the products of `g` and `h`. This is the version for `CanonicallyOrderedCommSemiring`.
-/
theorem prod_add_prod_le' (hi : i ∈ s) (h2i : g i + h i ≤ f i) (hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j)
    (hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j) : ((∏ i in s, g i) + ∏ i in s, h i) ≤ ∏ i in s, f i := by
  classical
    simp_rw [prod_eq_mul_prod_diff_singleton hi]
    refine' le_trans _ (mul_le_mul_right' h2i _)
    rw [right_distrib]
    apply add_le_add <;> apply mul_le_mul_left' <;> apply prod_le_prod' <;>
            simp only [and_imp, mem_sdiff, mem_singleton] <;>
          intros <;>
        

Proof state:
case h₁.bc.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✝ : CanonicallyOrderedCommSemiring R
f g h : ι → R
s : Finset ι
i : ι
hi : i ∈ s
h2i : g i + h i ≤ f i
hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j
hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j
i✝ : ι
a✝¹ : i✝ ∈ s
a✝ : ¬i✝ = i
⊢ g i✝ ≤ f i✝

Next tactic:
apply_assumption
/-- If `g, h ≤ f` and `g i + h i ≤ f i`, then the product of `f` over `s` is at least the
  sum of the products of `g` and `h`. This is the version for `CanonicallyOrderedCommSemiring`.
-/
theorem prod_add_prod_le' (hi : i ∈ s) (h2i : g i + h i ≤ f i) (hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j)
    (hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j) : ((∏ i in s, g i) + ∏ i in s, h i) ≤ ∏ i in s, f i := by
  classical
    simp_rw [prod_eq_mul_prod_diff_singleton hi]
    refine' le_trans _ (mul_le_mul_right' h2i _)
    rw [right_distrib]
    apply add_le_add <;> apply mul_le_mul_left' <;> apply prod_le_prod' <;>
            simp only [and_imp, mem_sdiff, mem_singleton] <;>
          intros <;>
        

Proof state:
case h₂.bc.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✝ : CanonicallyOrderedCommSemiring R
f g h : ι → R
s : Finset ι
i : ι
hi : i ∈ s
h2i : g i + h i ≤ f i
hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j
hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j
i✝ : ι
a✝¹ : i✝ ∈ s
a✝ : ¬i✝ = i
⊢ h i✝ ≤ f i✝

Next tactic:
apply_assumption
/-- If `g, h ≤ f` and `g i + h i ≤ f i`, then the product of `f` over `s` is at least the
  sum of the products of `g` and `h`. This is the version for `CanonicallyOrderedCommSemiring`.
-/
theorem prod_add_prod_le' (hi : i ∈ s) (h2i : g i + h i ≤ f i) (hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j)
    (hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j) : ((∏ i in s, g i) + ∏ i in s, h i) ≤ ∏ i in s, f i := by
  classical
    simp_rw [prod_eq_mul_prod_diff_singleton hi]
    refine' le_trans _ (mul_le_mul_right' h2i _)
    rw [right_distrib]
    apply add_le_add <;> apply mul_le_mul_left' <;> apply prod_le_prod' <;>
            simp only [and_imp, mem_sdiff, mem_singleton] <;>
          intros <;>
        apply_assumption <;>
      

Proof state:
case h₁.bc.h.a
ι : 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✝ : CanonicallyOrderedCommSemiring R
f g h : ι → R
s : Finset ι
i : ι
hi : i ∈ s
h2i : g i + h i ≤ f i
hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j
hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j
i✝ : ι
a✝¹ : i✝ ∈ s
a✝ : ¬i✝ = i
⊢ i✝ ∈ s

Next tactic:
assumption
/-- If `g, h ≤ f` and `g i + h i ≤ f i`, then the product of `f` over `s` is at least the
  sum of the products of `g` and `h`. This is the version for `CanonicallyOrderedCommSemiring`.
-/
theorem prod_add_prod_le' (hi : i ∈ s) (h2i : g i + h i ≤ f i) (hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j)
    (hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j) : ((∏ i in s, g i) + ∏ i in s, h i) ≤ ∏ i in s, f i := by
  classical
    simp_rw [prod_eq_mul_prod_diff_singleton hi]
    refine' le_trans _ (mul_le_mul_right' h2i _)
    rw [right_distrib]
    apply add_le_add <;> apply mul_le_mul_left' <;> apply prod_le_prod' <;>
            simp only [and_imp, mem_sdiff, mem_singleton] <;>
          intros <;>
        apply_assumption <;>
      

Proof state:
case h₁.bc.h.a
ι : 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✝ : CanonicallyOrderedCommSemiring R
f g h : ι → R
s : Finset ι
i : ι
hi : i ∈ s
h2i : g i + h i ≤ f i
hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j
hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j
i✝ : ι
a✝¹ : i✝ ∈ s
a✝ : ¬i✝ = i
⊢ i✝ ≠ i

Next tactic:
assumption
/-- If `g, h ≤ f` and `g i + h i ≤ f i`, then the product of `f` over `s` is at least the
  sum of the products of `g` and `h`. This is the version for `CanonicallyOrderedCommSemiring`.
-/
theorem prod_add_prod_le' (hi : i ∈ s) (h2i : g i + h i ≤ f i) (hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j)
    (hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j) : ((∏ i in s, g i) + ∏ i in s, h i) ≤ ∏ i in s, f i := by
  classical
    simp_rw [prod_eq_mul_prod_diff_singleton hi]
    refine' le_trans _ (mul_le_mul_right' h2i _)
    rw [right_distrib]
    apply add_le_add <;> apply mul_le_mul_left' <;> apply prod_le_prod' <;>
            simp only [and_imp, mem_sdiff, mem_singleton] <;>
          intros <;>
        apply_assumption <;>
      

Proof state:
case h₂.bc.h.a
ι : 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✝ : CanonicallyOrderedCommSemiring R
f g h : ι → R
s : Finset ι
i : ι
hi : i ∈ s
h2i : g i + h i ≤ f i
hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j
hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j
i✝ : ι
a✝¹ : i✝ ∈ s
a✝ : ¬i✝ = i
⊢ i✝ ∈ s

Next tactic:
assumption
/-- If `g, h ≤ f` and `g i + h i ≤ f i`, then the product of `f` over `s` is at least the
  sum of the products of `g` and `h`. This is the version for `CanonicallyOrderedCommSemiring`.
-/
theorem prod_add_prod_le' (hi : i ∈ s) (h2i : g i + h i ≤ f i) (hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j)
    (hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j) : ((∏ i in s, g i) + ∏ i in s, h i) ≤ ∏ i in s, f i := by
  classical
    simp_rw [prod_eq_mul_prod_diff_singleton hi]
    refine' le_trans _ (mul_le_mul_right' h2i _)
    rw [right_distrib]
    apply add_le_add <;> apply mul_le_mul_left' <;> apply prod_le_prod' <;>
            simp only [and_imp, mem_sdiff, mem_singleton] <;>
          intros <;>
        apply_assumption <;>
      

Proof state:
case h₂.bc.h.a
ι : 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✝ : CanonicallyOrderedCommSemiring R
f g h : ι → R
s : Finset ι
i : ι
hi : i ∈ s
h2i : g i + h i ≤ f i
hgf : ∀ j ∈ s, j ≠ i → g j ≤ f j
hhf : ∀ j ∈ s, j ≠ i → h j ≤ f j
i✝ : ι
a✝¹ : i✝ ∈ s
a✝ : ¬i✝ = i
⊢ i✝ ≠ i

Next tactic:
assumption
@[to_additive sum_pos]
lemma one_lt_prod (hf : 1 < f) : 1 < ∏ i, f i :=
  Finset.one_lt_prod' (λ _ _ ↦ hf.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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf : 1 < f
⊢ ∃ i ∈ Finset.univ, 1 < f i

Next tactic:
simpa using (Pi.lt_def.1 hf).2
@[to_additive]
lemma prod_lt_one (hf : f < 1) : ∏ i, f i < 1 :=
  Finset.prod_lt_one' (λ _ _ ↦ hf.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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf : f < 1
⊢ ∃ i ∈ Finset.univ, f i < 1

Next tactic:
simpa using (Pi.lt_def.1 hf).2
@[to_additive sum_pos_iff_of_nonneg]
lemma one_lt_prod_iff_of_one_le (hf : 1 ≤ f) : 1 < ∏ i, f i ↔ 1 < f := 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf : 1 ≤ f
⊢ 1 < ∏ i : ι, f i ↔ 1 < f

Next tactic:
obtain rfl | hf := hf.eq_or_lt
@[to_additive sum_pos_iff_of_nonneg]
lemma one_lt_prod_iff_of_one_le (hf : 1 ≤ f) : 1 < ∏ i, f i ↔ 1 < f := by
  obtain rfl | hf := hf.eq_or_lt <;> 

Proof state:
case inl
ι : 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
hf : 1 ≤ 1
⊢ 1 < ∏ i : ι, OfNat.ofNat 1 i ↔ 1 < 1

Next tactic:
simp [*, one_lt_prod]
@[to_additive sum_pos_iff_of_nonneg]
lemma one_lt_prod_iff_of_one_le (hf : 1 ≤ f) : 1 < ∏ i, f i ↔ 1 < f := by
  obtain rfl | hf := hf.eq_or_lt <;> 

Proof state:
case inr
ι : 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf✝ : 1 ≤ f
hf : 1 < f
⊢ 1 < ∏ i : ι, f i ↔ 1 < f

Next tactic:
simp [*, one_lt_prod]
@[to_additive]
lemma prod_lt_one_iff_of_le_one (hf : f ≤ 1) : ∏ i, f i < 1 ↔ f < 1 := 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf : f ≤ 1
⊢ ∏ i : ι, f i < 1 ↔ f < 1

Next tactic:
obtain rfl | hf := hf.eq_or_lt
@[to_additive]
lemma prod_lt_one_iff_of_le_one (hf : f ≤ 1) : ∏ i, f i < 1 ↔ f < 1 := by
  obtain rfl | hf := hf.eq_or_lt <;> 

Proof state:
case inl
ι : 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
hf : 1 ≤ 1
⊢ ∏ i : ι, OfNat.ofNat 1 i < 1 ↔ 1 < 1

Next tactic:
simp [*, prod_lt_one]
@[to_additive]
lemma prod_lt_one_iff_of_le_one (hf : f ≤ 1) : ∏ i, f i < 1 ↔ f < 1 := by
  obtain rfl | hf := hf.eq_or_lt <;> 

Proof state:
case inr
ι : 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf✝ : f ≤ 1
hf : f < 1
⊢ ∏ i : ι, f i < 1 ↔ f < 1

Next tactic:
simp [*, prod_lt_one]
@[to_additive]
lemma prod_eq_one_iff_of_one_le (hf : 1 ≤ f) : ∏ i, f i = 1 ↔ f = 1 := 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf : 1 ≤ f
⊢ ∏ i : ι, f i = 1 ↔ f = 1

Next tactic:
simpa only [(one_le_prod hf).not_gt_iff_eq, hf.not_gt_iff_eq]
    using (one_lt_prod_iff_of_one_le hf).not
@[to_additive]
lemma prod_eq_one_iff_of_le_one (hf : f ≤ 1) : ∏ i, f i = 1 ↔ f = 1 := 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✝¹ : Fintype ι
inst✝ : OrderedCancelCommMonoid M
f : ι → M
hf : f ≤ 1
⊢ ∏ i : ι, f i = 1 ↔ f = 1

Next tactic:
simpa only [(prod_le_one hf).not_gt_iff_eq, hf.not_gt_iff_eq, eq_comm]
    using (prod_lt_one_iff_of_le_one hf).not
/-- A sum of numbers is infinite iff one of them is infinite -/
theorem sum_eq_top_iff [AddCommMonoid M] {s : Finset ι} {f : ι → WithTop M} :
    ∑ i in s, f i = ⊤ ↔ ∃ i ∈ s, 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✝ : AddCommMonoid M
s : Finset ι
f : ι → WithTop M
⊢ ∑ i in s, f i = ⊤ ↔ ∃ i ∈ s, f i = ⊤

Next tactic:
induction s using Finset.cons_induction
/-- A sum of numbers is infinite iff one of them is infinite -/
theorem sum_eq_top_iff [AddCommMonoid M] {s : Finset ι} {f : ι → WithTop M} :
    ∑ i in s, f i = ⊤ ↔ ∃ i ∈ s, f i = ⊤ := by
  induction s using Finset.cons_induction <;> 

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✝ : AddCommMonoid M
f : ι → WithTop M
⊢ ∑ i in ∅, f i = ⊤ ↔ ∃ i ∈ ∅, f i = ⊤

Next tactic:
simp [*]
/-- A sum of numbers is infinite iff one of them is infinite -/
theorem sum_eq_top_iff [AddCommMonoid M] {s : Finset ι} {f : ι → WithTop M} :
    ∑ i in s, f i = ⊤ ↔ ∃ i ∈ s, f i = ⊤ := by
  induction s using Finset.cons_induction <;> 

Proof state:
case cons
ι : 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✝ : AddCommMonoid M
f : ι → WithTop M
a✝¹ : ι
s✝ : Finset ι
h✝ : a✝¹ ∉ s✝
a✝ : ∑ i in s✝, f i = ⊤ ↔ ∃ i ∈ s✝, f i = ⊤
⊢ ∑ i in cons a✝¹ s✝ h✝, f i = ⊤ ↔ ∃ i ∈ cons a✝¹ s✝ h✝, f i = ⊤

Next tactic:
simp [*]
/-- A sum of finite numbers is still finite -/
theorem sum_lt_top_iff [AddCommMonoid M] [LT M] {s : Finset ι} {f : ι → WithTop M} :
    ∑ i in s, f i < ⊤ ↔ ∀ i ∈ s, 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✝¹ : AddCommMonoid M
inst✝ : LT M
s : Finset ι
f : ι → WithTop M
⊢ ∑ i in s, f i < ⊤ ↔ ∀ i ∈ s, f i < ⊤

Next tactic:
simp only [WithTop.lt_top_iff_ne_top, ne_eq, sum_eq_top_iff, not_exists, not_and]
@[simp]
theorem logb_zero : logb b 0 = 0 := by 

Proof state:
b x y : ℝ
⊢ logb b 0 = 0

Next tactic:
simp [logb]
@[simp]
theorem logb_one : logb b 1 = 0 := by 

Proof state:
b x y : ℝ
⊢ logb b 1 = 0

Next tactic:
simp [logb]
lemma logb_self_eq_one_iff : logb b b = 1 ↔ b ≠ 0 ∧ b ≠ 1 ∧ b ≠ -1 :=
  Iff.trans ⟨fun h h' => by 

Proof state:
b x y : ℝ
h : logb b b = 1
h' : log b = 0
⊢ False

Next tactic:
simp [logb, h'] at h
@[simp]
theorem logb_abs (x : ℝ) : logb b |x| = logb b x := by 

Proof state:
b x✝ y x : ℝ
⊢ logb b |x| = logb b x

Next tactic:
rw [logb, logb, log_abs]
@[simp]
theorem logb_neg_eq_logb (x : ℝ) : logb b (-x) = logb b x := by
  

Proof state:
b x✝ y x : ℝ
⊢ logb b (-x) = logb b x

Next tactic:
rw [← logb_abs x, ← logb_abs (-x), abs_neg]
theorem logb_mul (hx : x ≠ 0) (hy : y ≠ 0) : logb b (x * y) = logb b x + logb b y := by
  

Proof state:
b x y : ℝ
hx : x ≠ 0
hy : y ≠ 0
⊢ logb b (x * y) = logb b x + logb b y

Next tactic:
simp_rw [logb, log_mul hx hy, add_div]
theorem logb_div (hx : x ≠ 0) (hy : y ≠ 0) : logb b (x / y) = logb b x - logb b y := by
  

Proof state:
b x y : ℝ
hx : x ≠ 0
hy : y ≠ 0
⊢ logb b (x / y) = logb b x - logb b y

Next tactic:
simp_rw [logb, log_div hx hy, sub_div]
@[simp]
theorem logb_inv (x : ℝ) : logb b x⁻¹ = -logb b x := by 

Proof state:
b x✝ y x : ℝ
⊢ logb b x⁻¹ = -logb b x

Next tactic:
simp [logb, neg_div]
theorem inv_logb (a b : ℝ) : (logb a b)⁻¹ = logb b a := by 

Proof state:
b✝ x y a b : ℝ
⊢ (logb a b)⁻¹ = logb b a

Next tactic:
simp_rw [logb, inv_div]
theorem inv_logb_mul_base {a b : ℝ} (h₁ : a ≠ 0) (h₂ : b ≠ 0) (c : ℝ) :
    (logb (a * b) c)⁻¹ = (logb a c)⁻¹ + (logb b c)⁻¹ := by
  

Proof state:
b✝ x y a b : ℝ
h₁ : a ≠ 0
h₂ : b ≠ 0
c : ℝ
⊢ (logb (a * b) c)⁻¹ = (logb a c)⁻¹ + (logb b c)⁻¹

Next tactic:
simp_rw [inv_logb]
theorem inv_logb_mul_base {a b : ℝ} (h₁ : a ≠ 0) (h₂ : b ≠ 0) (c : ℝ) :
    (logb (a * b) c)⁻¹ = (logb a c)⁻¹ + (logb b c)⁻¹ := by
  simp_rw [inv_logb]; 

Proof state:
b✝ x y a b : ℝ
h₁ : a ≠ 0
h₂ : b ≠ 0
c : ℝ
⊢ logb c (a * b) = logb c a + logb c b

Next tactic:
exact logb_mul h₁ h₂
theorem inv_logb_div_base {a b : ℝ} (h₁ : a ≠ 0) (h₂ : b ≠ 0) (c : ℝ) :
    (logb (a / b) c)⁻¹ = (logb a c)⁻¹ - (logb b c)⁻¹ := by
  

Proof state:
b✝ x y a b : ℝ
h₁ : a ≠ 0
h₂ : b ≠ 0
c : ℝ
⊢ (logb (a / b) c)⁻¹ = (logb a c)⁻¹ - (logb b c)⁻¹

Next tactic:
simp_rw [inv_logb]
theorem inv_logb_div_base {a b : ℝ} (h₁ : a ≠ 0) (h₂ : b ≠ 0) (c : ℝ) :
    (logb (a / b) c)⁻¹ = (logb a c)⁻¹ - (logb b c)⁻¹ := by
  simp_rw [inv_logb]; 

Proof state:
b✝ x y a b : ℝ
h₁ : a ≠ 0
h₂ : b ≠ 0
c : ℝ
⊢ logb c (a / b) = logb c a - logb c b

Next tactic:
exact logb_div h₁ h₂
theorem logb_mul_base {a b : ℝ} (h₁ : a ≠ 0) (h₂ : b ≠ 0) (c : ℝ) :
    logb (a * b) c = ((logb a c)⁻¹ + (logb b c)⁻¹)⁻¹ := by 

Proof state:
b✝ x y a b : ℝ
h₁ : a ≠ 0
h₂ : b ≠ 0
c : ℝ
⊢ logb (a * b) c = ((logb a c)⁻¹ + (logb b c)⁻¹)⁻¹

Next tactic:
rw [← inv_logb_mul_base h₁ h₂ c, inv_inv]
theorem logb_div_base {a b : ℝ} (h₁ : a ≠ 0) (h₂ : b ≠ 0) (c : ℝ) :
    logb (a / b) c = ((logb a c)⁻¹ - (logb b c)⁻¹)⁻¹ := by 

Proof state:
b✝ x y a b : ℝ
h₁ : a ≠ 0
h₂ : b ≠ 0
c : ℝ
⊢ logb (a / b) c = ((logb a c)⁻¹ - (logb b c)⁻¹)⁻¹

Next tactic:
rw [← inv_logb_div_base h₁ h₂ c, inv_inv]
theorem mul_logb {a b c : ℝ} (h₁ : b ≠ 0) (h₂ : b ≠ 1) (h₃ : b ≠ -1) :
    logb a b * logb b c = logb a c := by
  

Proof state:
b✝ x y a b c : ℝ
h₁ : b ≠ 0
h₂ : b ≠ 1
h₃ : b ≠ -1
⊢ logb a b * logb b c = logb a c

Next tactic:
unfold logb
theorem mul_logb {a b c : ℝ} (h₁ : b ≠ 0) (h₂ : b ≠ 1) (h₃ : b ≠ -1) :
    logb a b * logb b c = logb a c := by
  unfold logb
  

Proof state:
b✝ x y a b c : ℝ
h₁ : b ≠ 0
h₂ : b ≠ 1
h₃ : b ≠ -1
⊢ log b / log a * (log c / log b) = log c / log a

Next tactic:
rw [mul_comm, div_mul_div_cancel _ (log_ne_zero.mpr ⟨h₁, h₂, h₃⟩)]
private theorem log_b_ne_zero : log b ≠ 0 := by
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
⊢ log b ≠ 0

Next tactic:
have b_ne_zero : b ≠ 0
private theorem log_b_ne_zero : log b ≠ 0 := by
  have b_ne_zero : b ≠ 0; 

Proof state:
case b_ne_zero
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
⊢ b ≠ 0
b x y : ℝ b_pos : 0 < b b_ne_one : b ≠ 1 b_ne_zero : b ≠ 0 ⊢ log b ≠ 0

Next tactic:
linarith
private theorem log_b_ne_zero : log b ≠ 0 := by
  have b_ne_zero : b ≠ 0; linarith
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
b_ne_zero : b ≠ 0
⊢ log b ≠ 0

Next tactic:
have b_ne_minus_one : b ≠ -1
private theorem log_b_ne_zero : log b ≠ 0 := by
  have b_ne_zero : b ≠ 0; linarith
  have b_ne_minus_one : b ≠ -1; 

Proof state:
case b_ne_minus_one
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
b_ne_zero : b ≠ 0
⊢ b ≠ -1
b x y : ℝ b_pos : 0 < b b_ne_one : b ≠ 1 b_ne_zero : b ≠ 0 b_ne_minus_one : b ≠ -1 ⊢ log b ≠ 0

Next tactic:
linarith
private theorem log_b_ne_zero : log b ≠ 0 := by
  have b_ne_zero : b ≠ 0; linarith
  have b_ne_minus_one : b ≠ -1; linarith
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
b_ne_zero : b ≠ 0
b_ne_minus_one : b ≠ -1
⊢ log b ≠ 0

Next tactic:
simp [b_ne_one, b_ne_zero, b_ne_minus_one]
@[simp]
theorem logb_rpow : logb b (b ^ x) = x := by
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
⊢ logb b (b ^ x) = x

Next tactic:
rw [logb, div_eq_iff, log_rpow b_pos]
@[simp]
theorem logb_rpow : logb b (b ^ x) = x := by
  rw [logb, div_eq_iff, log_rpow b_pos]
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
⊢ log b ≠ 0

Next tactic:
exact log_b_ne_zero b_pos b_ne_one
theorem rpow_logb_eq_abs (hx : x ≠ 0) : b ^ logb b x = |x| := by
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ b ^ logb b x = |x|

Next tactic:
apply log_injOn_pos
theorem rpow_logb_eq_abs (hx : x ≠ 0) : b ^ logb b x = |x| := by
  apply log_injOn_pos
  

Proof state:
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ b ^ logb b x ∈ Ioi 0
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ |x| ∈ Ioi 0
case a b x y : ℝ b_pos : 0 < b b_ne_one : b ≠ 1 hx : x ≠ 0 ⊢ log (b ^ logb b x) = log |x|

Next tactic:
simp only [Set.mem_Ioi]
theorem rpow_logb_eq_abs (hx : x ≠ 0) : b ^ logb b x = |x| := by
  apply log_injOn_pos
  simp only [Set.mem_Ioi]
  

Proof state:
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ 0 < b ^ logb b x
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ |x| ∈ Ioi 0
case a b x y : ℝ b_pos : 0 < b b_ne_one : b ≠ 1 hx : x ≠ 0 ⊢ log (b ^ logb b x) = log |x|

Next tactic:
apply rpow_pos_of_pos b_pos
theorem rpow_logb_eq_abs (hx : x ≠ 0) : b ^ logb b x = |x| := by
  apply log_injOn_pos
  simp only [Set.mem_Ioi]
  apply rpow_pos_of_pos b_pos
  

Proof state:
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ |x| ∈ Ioi 0
case a b x y : ℝ b_pos : 0 < b b_ne_one : b ≠ 1 hx : x ≠ 0 ⊢ log (b ^ logb b x) = log |x|

Next tactic:
simp only [abs_pos, mem_Ioi, Ne.def, hx, not_false_iff]
theorem rpow_logb_eq_abs (hx : x ≠ 0) : b ^ logb b x = |x| := by
  apply log_injOn_pos
  simp only [Set.mem_Ioi]
  apply rpow_pos_of_pos b_pos
  simp only [abs_pos, mem_Ioi, Ne.def, hx, not_false_iff]
  

Proof state:
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ log (b ^ logb b x) = log |x|

Next tactic:
rw [log_rpow b_pos, logb, log_abs]
theorem rpow_logb_eq_abs (hx : x ≠ 0) : b ^ logb b x = |x| := by
  apply log_injOn_pos
  simp only [Set.mem_Ioi]
  apply rpow_pos_of_pos b_pos
  simp only [abs_pos, mem_Ioi, Ne.def, hx, not_false_iff]
  rw [log_rpow b_pos, logb, log_abs]
  

Proof state:
case a
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x ≠ 0
⊢ log x / log b * log b = log x

Next tactic:
field_simp [log_b_ne_zero b_pos b_ne_one]
@[simp]
theorem rpow_logb (hx : 0 < x) : b ^ logb b x = x := by
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : 0 < x
⊢ b ^ logb b x = x

Next tactic:
rw [rpow_logb_eq_abs b_pos b_ne_one hx.ne']
@[simp]
theorem rpow_logb (hx : 0 < x) : b ^ logb b x = x := by
  rw [rpow_logb_eq_abs b_pos b_ne_one hx.ne']
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : 0 < x
⊢ |x| = x

Next tactic:
exact abs_of_pos hx
theorem rpow_logb_of_neg (hx : x < 0) : b ^ logb b x = -x := by
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x < 0
⊢ b ^ logb b x = -x

Next tactic:
rw [rpow_logb_eq_abs b_pos b_ne_one (ne_of_lt hx)]
theorem rpow_logb_of_neg (hx : x < 0) : b ^ logb b x = -x := by
  rw [rpow_logb_eq_abs b_pos b_ne_one (ne_of_lt hx)]
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
hx : x < 0
⊢ |x| = -x

Next tactic:
exact abs_of_neg hx
theorem surjOn_logb' : SurjOn (logb b) (Iio 0) univ := by
  

Proof state:
b x y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
⊢ SurjOn (logb b) (Iio 0) univ

Next tactic:
intro x _
theorem surjOn_logb' : SurjOn (logb b) (Iio 0) univ := by
  intro x _
  

Proof state:
b x✝ y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
x : ℝ
a✝ : x ∈ univ
⊢ x ∈ logb b '' Iio 0

Next tactic:
use -b ^ x
theorem surjOn_logb' : SurjOn (logb b) (Iio 0) univ := by
  intro x _
  use -b ^ x
  

Proof state:
case h
b x✝ y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
x : ℝ
a✝ : x ∈ univ
⊢ -b ^ x ∈ Iio 0 ∧ logb b (-b ^ x) = x

Next tactic:
constructor
theorem surjOn_logb' : SurjOn (logb b) (Iio 0) univ := by
  intro x _
  use -b ^ x
  constructor
  · 

Proof state:
case h.left
b x✝ y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
x : ℝ
a✝ : x ∈ univ
⊢ -b ^ x ∈ Iio 0

Next tactic:
simp only [Right.neg_neg_iff, Set.mem_Iio]
theorem surjOn_logb' : SurjOn (logb b) (Iio 0) univ := by
  intro x _
  use -b ^ x
  constructor
  · simp only [Right.neg_neg_iff, Set.mem_Iio]
    

Proof state:
case h.left
b x✝ y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
x : ℝ
a✝ : x ∈ univ
⊢ 0 < b ^ x

Next tactic:
apply rpow_pos_of_pos b_pos
theorem surjOn_logb' : SurjOn (logb b) (Iio 0) univ := by
  intro x _
  use -b ^ x
  constructor
  · simp only [Right.neg_neg_iff, Set.mem_Iio]
    apply rpow_pos_of_pos b_pos
  · 

Proof state:
case h.right
b x✝ y : ℝ
b_pos : 0 < b
b_ne_one : b ≠ 1
x : ℝ
a✝ : x ∈ univ
⊢ logb b (-b ^ x) = x

Next tactic:
rw [logb_neg_eq_logb, logb_rpow b_pos b_ne_one]
private theorem b_pos : 0 < b := by 

Proof state:
b x y : ℝ
hb : 1 < b
⊢ 0 < b

Next tactic:
linarith
private theorem b_ne_one' : b ≠ 1 := by 

Proof state:
b x y : ℝ
hb : 1 < b
⊢ b ≠ 1

Next tactic:
linarith
@[simp]
theorem logb_le_logb (h : 0 < x) (h₁ : 0 < y) : logb b x ≤ logb b y ↔ x ≤ y := by
  

Proof state:
b x y : ℝ
hb : 1 < b
h : 0 < x
h₁ : 0 < y
⊢ logb b x ≤ logb b y ↔ x ≤ y

Next tactic:
rw [logb, logb, div_le_div_right (log_pos hb), log_le_log_iff h h₁]
@[gcongr]
theorem logb_le_logb_of_le (h : 0 < x) (hxy : x ≤ y) : logb b x ≤ logb b y :=
  (logb_le_logb hb h (by 

Proof state:
b x y : ℝ
hb : 1 < b
h : 0 < x
hxy : x ≤ y
⊢ 0 < y

Next tactic:
linarith
@[gcongr]
theorem logb_lt_logb (hx : 0 < x) (hxy : x < y) : logb b x < logb b y := by
  

Proof state:
b x y : ℝ
hb : 1 < b
hx : 0 < x
hxy : x < y
⊢ logb b x < logb b y

Next tactic:
rw [logb, logb, div_lt_div_right (log_pos hb)]
@[gcongr]
theorem logb_lt_logb (hx : 0 < x) (hxy : x < y) : logb b x < logb b y := by
  rw [logb, logb, div_lt_div_right (log_pos hb)]
  

Proof state:
b x y : ℝ
hb : 1 < b
hx : 0 < x
hxy : x < y
⊢ log x < log y

Next tactic:
exact log_lt_log hx hxy
@[simp]
theorem logb_lt_logb_iff (hx : 0 < x) (hy : 0 < y) : logb b x < logb b y ↔ x < y := by
  

Proof state:
b x y : ℝ
hb : 1 < b
hx : 0 < x
hy : 0 < y
⊢ logb b x < logb b y ↔ x < y

Next tactic:
rw [logb, logb, div_lt_div_right (log_pos hb)]
@[simp]
theorem logb_lt_logb_iff (hx : 0 < x) (hy : 0 < y) : logb b x < logb b y ↔ x < y := by
  rw [logb, logb, div_lt_div_right (log_pos hb)]
  

Proof state:
b x y : ℝ
hb : 1 < b
hx : 0 < x
hy : 0 < y
⊢ log x < log y ↔ x < y

Next tactic:
exact log_lt_log_iff hx hy
theorem logb_le_iff_le_rpow (hx : 0 < x) : logb b x ≤ y ↔ x ≤ b ^ y := by
  

Proof state:
b x y : ℝ
hb : 1 < b
hx : 0 < x
⊢ logb b x ≤ y ↔ x ≤ b ^ y

Next tactic:
rw [← rpow_le_rpow_left_iff hb, rpow_logb (b_pos hb) (b_ne_one' hb) hx]