l3lab/ntp-mathlib huggingface dataset:
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      

Proof state:
case inr.inl
x y : ℝ
n : ℤ
hn : 0 = n
⊢ 0 ≤ log ↑n

Next tactic:
| inl hn => simp [hn.symm]
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => 

Proof state:
case inr.inl
x y : ℝ
n : ℤ
hn : 0 = n
⊢ 0 ≤ log ↑n

Next tactic:
simp [hn.symm]
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      

Proof state:
case inr.inr
x y : ℝ
n : ℤ
hn : n < 0
⊢ 0 ≤ log ↑n

Next tactic:
| inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          rw [← log_neg_eq_log]
          exact log_nonneg this
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          

Proof state:
case inr.inr
x y : ℝ
n : ℤ
hn : n < 0
⊢ 0 ≤ log ↑n

Next tactic:
have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by 

Proof state:
x y : ℝ
n : ℤ
hn : n < 0
⊢ 1 ≤ -↑n

Next tactic:
rw [← neg_zero, ← lt_neg] at hn
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; 

Proof state:
x y : ℝ
n : ℤ
hn : 0 < -n
⊢ 1 ≤ -↑n

Next tactic:
exact mod_cast hn
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          

Proof state:
case inr.inr
x y : ℝ
n : ℤ
hn : n < 0
this : 1 ≤ -↑n
⊢ 0 ≤ log ↑n

Next tactic:
rw [← log_neg_eq_log]
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          rw [← log_neg_eq_log]
          

Proof state:
case inr.inr
x y : ℝ
n : ℤ
hn : n < 0
this : 1 ≤ -↑n
⊢ 0 ≤ log (-↑n)

Next tactic:
exact log_nonneg this
theorem strictAntiOn_log : StrictAntiOn log (Set.Iio 0) := by
  

Proof state:
x y : ℝ
⊢ StrictAntiOn log (Iio 0)

Next tactic:
rintro x (hx : x < 0) y (hy : y < 0) hxy
theorem strictAntiOn_log : StrictAntiOn log (Set.Iio 0) := by
  rintro x (hx : x < 0) y (hy : y < 0) hxy
  

Proof state:
x✝ y✝ x : ℝ
hx : x < 0
y : ℝ
hy : y < 0
hxy : x < y
⊢ log y < log x

Next tactic:
rw [← log_abs y, ← log_abs x]
theorem strictAntiOn_log : StrictAntiOn log (Set.Iio 0) := by
  rintro x (hx : x < 0) y (hy : y < 0) hxy
  rw [← log_abs y, ← log_abs x]
  

Proof state:
x✝ y✝ x : ℝ
hx : x < 0
y : ℝ
hy : y < 0
hxy : x < y
⊢ log |y| < log |x|

Next tactic:
refine' log_lt_log (abs_pos.2 hy.ne) _
theorem strictAntiOn_log : StrictAntiOn log (Set.Iio 0) := by
  rintro x (hx : x < 0) y (hy : y < 0) hxy
  rw [← log_abs y, ← log_abs x]
  refine' log_lt_log (abs_pos.2 hy.ne) _
  

Proof state:
x✝ y✝ x : ℝ
hx : x < 0
y : ℝ
hy : y < 0
hxy : x < y
⊢ |y| < |x|

Next tactic:
rwa [abs_of_neg hy, abs_of_neg hx, neg_lt_neg_iff]
theorem log_lt_sub_one_of_pos (hx1 : 0 < x) (hx2 : x ≠ 1) : log x < x - 1 := by
  

Proof state:
x y : ℝ
hx1 : 0 < x
hx2 : x ≠ 1
⊢ log x < x - 1

Next tactic:
have h : log x ≠ 0
theorem log_lt_sub_one_of_pos (hx1 : 0 < x) (hx2 : x ≠ 1) : log x < x - 1 := by
  have h : log x ≠ 0
  · 

Proof state:
case h
x y : ℝ
hx1 : 0 < x
hx2 : x ≠ 1
⊢ log x ≠ 0

Next tactic:
rwa [← log_one, log_injOn_pos.ne_iff hx1]
theorem log_lt_sub_one_of_pos (hx1 : 0 < x) (hx2 : x ≠ 1) : log x < x - 1 := by
  have h : log x ≠ 0
  · rwa [← log_one, log_injOn_pos.ne_iff hx1]
    

Proof state:
case h
x y : ℝ
hx1 : 0 < x
hx2 : x ≠ 1
⊢ 1 ∈ Ioi 0

Next tactic:
exact mem_Ioi.mpr zero_lt_one
theorem log_lt_sub_one_of_pos (hx1 : 0 < x) (hx2 : x ≠ 1) : log x < x - 1 := by
  have h : log x ≠ 0
  · rwa [← log_one, log_injOn_pos.ne_iff hx1]
    exact mem_Ioi.mpr zero_lt_one
  

Proof state:
x y : ℝ
hx1 : 0 < x
hx2 : x ≠ 1
h : log x ≠ 0
⊢ log x < x - 1

Next tactic:
linarith [add_one_lt_exp h, exp_log hx1]
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  

Proof state:
x✝ y x : ℝ
⊢ log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1

Next tactic:
constructor
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · 

Proof state:
case mp
x✝ y x : ℝ
⊢ log x = 0 → x = 0 ∨ x = 1 ∨ x = -1

Next tactic:
intro h
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    

Proof state:
case mp
x✝ y x : ℝ
h : log x = 0
⊢ x = 0 ∨ x = 1 ∨ x = -1

Next tactic:
rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · 

Proof state:
case mp.inl
x✝ y x : ℝ
h : log x = 0
x_lt_zero : x < 0
⊢ x = 0 ∨ x = 1 ∨ x = -1

Next tactic:
refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      

Proof state:
case mp.inl
x✝ y x : ℝ
h : log x = 0
x_lt_zero : x < 0
⊢ -x = 1

Next tactic:
rw [← log_neg_eq_log x] at h
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      

Proof state:
case mp.inl
x✝ y x : ℝ
h : log (-x) = 0
x_lt_zero : x < 0
⊢ -x = 1

Next tactic:
exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
    · 

Proof state:
case mp.inr.inl
x y : ℝ
h : log 0 = 0
⊢ 0 = 0 ∨ 0 = 1 ∨ 0 = -1

Next tactic:
exact Or.inl rfl
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
    · exact Or.inl rfl
    · 

Proof state:
case mp.inr.inr
x✝ y x : ℝ
h : log x = 0
x_gt_zero : 0 < x
⊢ x = 0 ∨ x = 1 ∨ x = -1

Next tactic:
exact Or.inr (Or.inl (eq_one_of_pos_of_log_eq_zero x_gt_zero h))
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
    · exact Or.inl rfl
    · exact Or.inr (Or.inl (eq_one_of_pos_of_log_eq_zero x_gt_zero h))
  · 

Proof state:
case mpr
x✝ y x : ℝ
⊢ x = 0 ∨ x = 1 ∨ x = -1 → log x = 0

Next tactic:
rintro (rfl | rfl | rfl)
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
    · exact Or.inl rfl
    · exact Or.inr (Or.inl (eq_one_of_pos_of_log_eq_zero x_gt_zero h))
  · rintro (rfl | rfl | rfl) <;> 

Proof state:
case mpr.inl
x y : ℝ
⊢ log 0 = 0

Next tactic:
simp only [log_one, log_zero, log_neg_eq_log]
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
    · exact Or.inl rfl
    · exact Or.inr (Or.inl (eq_one_of_pos_of_log_eq_zero x_gt_zero h))
  · rintro (rfl | rfl | rfl) <;> 

Proof state:
case mpr.inr.inl
x y : ℝ
⊢ log 1 = 0

Next tactic:
simp only [log_one, log_zero, log_neg_eq_log]
@[simp]
theorem log_eq_zero {x : ℝ} : log x = 0 ↔ x = 0 ∨ x = 1 ∨ x = -1 := by
  constructor
  · intro h
    rcases lt_trichotomy x 0 with (x_lt_zero | rfl | x_gt_zero)
    · refine' Or.inr (Or.inr (neg_eq_iff_eq_neg.mp _))
      rw [← log_neg_eq_log x] at h
      exact eq_one_of_pos_of_log_eq_zero (neg_pos.mpr x_lt_zero) h
    · exact Or.inl rfl
    · exact Or.inr (Or.inl (eq_one_of_pos_of_log_eq_zero x_gt_zero h))
  · rintro (rfl | rfl | rfl) <;> 

Proof state:
case mpr.inr.inr
x y : ℝ
⊢ log (-1) = 0

Next tactic:
simp only [log_one, log_zero, log_neg_eq_log]
theorem log_ne_zero {x : ℝ} : log x ≠ 0 ↔ x ≠ 0 ∧ x ≠ 1 ∧ x ≠ -1 := by
  

Proof state:
x✝ y x : ℝ
⊢ log x ≠ 0 ↔ x ≠ 0 ∧ x ≠ 1 ∧ x ≠ -1

Next tactic:
simpa only [not_or] using log_eq_zero.not
@[simp]
theorem log_pow (x : ℝ) (n : ℕ) : log (x ^ n) = n * log x := by
  

Proof state:
x✝ y x : ℝ
n : ℕ
⊢ log (x ^ n) = ↑n * log x

Next tactic:
induction' n with n ih
@[simp]
theorem log_pow (x : ℝ) (n : ℕ) : log (x ^ n) = n * log x := by
  induction' n with n ih
  · 

Proof state:
case zero
x✝ y x : ℝ
⊢ log (x ^ Nat.zero) = ↑Nat.zero * log x

Next tactic:
simp
@[simp]
theorem log_pow (x : ℝ) (n : ℕ) : log (x ^ n) = n * log x := by
  induction' n with n ih
  · simp
  

Proof state:
case succ
x✝ y x : ℝ
n : ℕ
ih : log (x ^ n) = ↑n * log x
⊢ log (x ^ Nat.succ n) = ↑(Nat.succ n) * log x

Next tactic:
rcases eq_or_ne x 0 with (rfl | hx)
@[simp]
theorem log_pow (x : ℝ) (n : ℕ) : log (x ^ n) = n * log x := by
  induction' n with n ih
  · simp
  rcases eq_or_ne x 0 with (rfl | hx)
  · 

Proof state:
case succ.inl
x y : ℝ
n : ℕ
ih : log (0 ^ n) = ↑n * log 0
⊢ log (0 ^ Nat.succ n) = ↑(Nat.succ n) * log 0

Next tactic:
simp
@[simp]
theorem log_pow (x : ℝ) (n : ℕ) : log (x ^ n) = n * log x := by
  induction' n with n ih
  · simp
  rcases eq_or_ne x 0 with (rfl | hx)
  · simp
  

Proof state:
case succ.inr
x✝ y x : ℝ
n : ℕ
ih : log (x ^ n) = ↑n * log x
hx : x ≠ 0
⊢ log (x ^ Nat.succ n) = ↑(Nat.succ n) * log x

Next tactic:
rw [pow_succ', log_mul (pow_ne_zero _ hx) hx, ih, Nat.cast_succ, add_mul, one_mul]
@[simp]
theorem log_zpow (x : ℝ) (n : ℤ) : log (x ^ n) = n * log x := by
  

Proof state:
x✝ y x : ℝ
n : ℤ
⊢ log (x ^ n) = ↑n * log x

Next tactic:
induction n
@[simp]
theorem log_zpow (x : ℝ) (n : ℤ) : log (x ^ n) = n * log x := by
  induction n
  · 

Proof state:
case ofNat
x✝ y x : ℝ
a✝ : ℕ
⊢ log (x ^ Int.ofNat a✝) = ↑(Int.ofNat a✝) * log x

Next tactic:
rw [Int.ofNat_eq_coe, zpow_ofNat, log_pow, Int.cast_ofNat]
@[simp]
theorem log_zpow (x : ℝ) (n : ℤ) : log (x ^ n) = n * log x := by
  induction n
  · rw [Int.ofNat_eq_coe, zpow_ofNat, log_pow, Int.cast_ofNat]
  

Proof state:
case negSucc
x✝ y x : ℝ
a✝ : ℕ
⊢ log (x ^ Int.negSucc a✝) = ↑(Int.negSucc a✝) * log x

Next tactic:
rw [zpow_negSucc, log_inv, log_pow, Int.cast_negSucc, Nat.cast_add_one, neg_mul_eq_neg_mul]
theorem log_sqrt {x : ℝ} (hx : 0 ≤ x) : log (sqrt x) = log x / 2 := by
  

Proof state:
x✝ y x : ℝ
hx : 0 ≤ x
⊢ log (sqrt x) = log x / 2

Next tactic:
rw [eq_div_iff, mul_comm, ← Nat.cast_two, ← log_pow, sq_sqrt hx]
theorem log_sqrt {x : ℝ} (hx : 0 ≤ x) : log (sqrt x) = log x / 2 := by
  rw [eq_div_iff, mul_comm, ← Nat.cast_two, ← log_pow, sq_sqrt hx]
  

Proof state:
x✝ y x : ℝ
hx : 0 ≤ x
⊢ 2 ≠ 0

Next tactic:
exact two_ne_zero
theorem log_le_sub_one_of_pos {x : ℝ} (hx : 0 < x) : log x ≤ x - 1 := by
  

Proof state:
x✝ y x : ℝ
hx : 0 < x
⊢ log x ≤ x - 1

Next tactic:
rw [le_sub_iff_add_le]
theorem log_le_sub_one_of_pos {x : ℝ} (hx : 0 < x) : log x ≤ x - 1 := by
  rw [le_sub_iff_add_le]
  

Proof state:
x✝ y x : ℝ
hx : 0 < x
⊢ log x + 1 ≤ x

Next tactic:
convert add_one_le_exp (log x)
theorem log_le_sub_one_of_pos {x : ℝ} (hx : 0 < x) : log x ≤ x - 1 := by
  rw [le_sub_iff_add_le]
  convert add_one_le_exp (log x)
  

Proof state:
case h.e'_4
x✝ y x : ℝ
hx : 0 < x
⊢ x = rexp (log x)

Next tactic:
rw [exp_log hx]
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
⊢ |log x * x| < 1

Next tactic:
have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by 

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
⊢ 0 < 1 / x

Next tactic:
simpa only [one_div, inv_pos] using h1
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : 0 < 1 / x
⊢ |log x * x| < 1

Next tactic:
replace := log_le_sub_one_of_pos this
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : log (1 / x) ≤ 1 / x - 1
⊢ |log x * x| < 1

Next tactic:
replace : log (1 / x) < 1 / x := by linarith
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by 

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : log (1 / x) ≤ 1 / x - 1
⊢ log (1 / x) < 1 / x

Next tactic:
linarith
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : log (1 / x) < 1 / x
⊢ |log x * x| < 1

Next tactic:
rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
⊢ |log x * x| < 1

Next tactic:
have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    rw [← log_inv]
    apply log_nonneg
    rw [← le_inv h1 zero_lt_one, inv_one]
    exact h2
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
⊢ 0 ≤ -log x * x

Next tactic:
refine' mul_nonneg _ h1.le
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
⊢ 0 ≤ -log x

Next tactic:
rw [← log_inv]
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    rw [← log_inv]
    

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
⊢ 0 ≤ log x⁻¹

Next tactic:
apply log_nonneg
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    rw [← log_inv]
    apply log_nonneg
    

Proof state:
case hx
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
⊢ 1 ≤ x⁻¹

Next tactic:
rw [← le_inv h1 zero_lt_one, inv_one]
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    rw [← log_inv]
    apply log_nonneg
    rw [← le_inv h1 zero_lt_one, inv_one]
    

Proof state:
case hx
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
⊢ x ≤ 1

Next tactic:
exact h2
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    rw [← log_inv]
    apply log_nonneg
    rw [← le_inv h1 zero_lt_one, inv_one]
    exact h2
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : -log x * x < 1
aux : 0 ≤ -log x * x
⊢ |log x * x| < 1

Next tactic:
rw [← abs_of_nonneg aux, neg_mul, abs_neg] at this
/-- Bound for `|log x * x|` in the interval `(0, 1]`. -/
theorem abs_log_mul_self_lt (x : ℝ) (h1 : 0 < x) (h2 : x ≤ 1) : |log x * x| < 1 := by
  have : 0 < 1 / x := by simpa only [one_div, inv_pos] using h1
  replace := log_le_sub_one_of_pos this
  replace : log (1 / x) < 1 / x := by linarith
  rw [log_div one_ne_zero h1.ne', log_one, zero_sub, lt_div_iff h1] at this
  have aux : 0 ≤ -log x * x := by
    refine' mul_nonneg _ h1.le
    rw [← log_inv]
    apply log_nonneg
    rw [← le_inv h1 zero_lt_one, inv_one]
    exact h2
  rw [← abs_of_nonneg aux, neg_mul, abs_neg] at this
  

Proof state:
x✝ y x : ℝ
h1 : 0 < x
h2 : x ≤ 1
this : |log x * x| < 1
aux : 0 ≤ -log x * x
⊢ |log x * x| < 1

Next tactic:
exact this
/-- The real logarithm function tends to `+∞` at `+∞`. -/
theorem tendsto_log_atTop : Tendsto log atTop atTop :=
  tendsto_comp_exp_atTop.1 <| by 

Proof state:
x y : ℝ
⊢ Tendsto (fun x => log (rexp x)) atTop atTop

Next tactic:
simpa only [log_exp] using tendsto_id
theorem tendsto_log_nhdsWithin_zero : Tendsto log (𝓝[≠] 0) atBot := by
  

Proof state:
x y : ℝ
⊢ Tendsto log (𝓝[≠] 0) atBot

Next tactic:
rw [← show _ = log from funext log_abs]
theorem tendsto_log_nhdsWithin_zero : Tendsto log (𝓝[≠] 0) atBot := by
  rw [← show _ = log from funext log_abs]
  

Proof state:
x y : ℝ
⊢ Tendsto (fun x => log |x|) (𝓝[≠] 0) atBot

Next tactic:
refine' Tendsto.comp (g := log) _ tendsto_abs_nhdsWithin_zero
theorem tendsto_log_nhdsWithin_zero : Tendsto log (𝓝[≠] 0) atBot := by
  rw [← show _ = log from funext log_abs]
  refine' Tendsto.comp (g := log) _ tendsto_abs_nhdsWithin_zero
  

Proof state:
x y : ℝ
⊢ Tendsto log (𝓝[>] 0) atBot

Next tactic:
simpa [← tendsto_comp_exp_atBot] using tendsto_id
theorem continuousOn_log : ContinuousOn log {0}ᶜ := by
  

Proof state:
x y : ℝ
⊢ ContinuousOn log {0}ᶜ

Next tactic:
simp (config := { unfoldPartialApp := true }) only [continuousOn_iff_continuous_restrict,
    restrict]
theorem continuousOn_log : ContinuousOn log {0}ᶜ := by
  simp (config := { unfoldPartialApp := true }) only [continuousOn_iff_continuous_restrict,
    restrict]
  

Proof state:
x y : ℝ
⊢ Continuous fun x => log ↑x

Next tactic:
conv in log _ => rw [log_of_ne_zero (show (x : ℝ) ≠ 0 from x.2)]
theorem continuousOn_log : ContinuousOn log {0}ᶜ := by
  simp (config := { unfoldPartialApp := true }) only [continuousOn_iff_continuous_restrict,
    restrict]
  conv in log _ => 

Proof state:
x✝ y : ℝ
x : ↑{0}ᶜ
| log ↑x

Next tactic:
rw [log_of_ne_zero (show (x : ℝ) ≠ 0 from x.2)]
theorem continuousOn_log : ContinuousOn log {0}ᶜ := by
  simp (config := { unfoldPartialApp := true }) only [continuousOn_iff_continuous_restrict,
    restrict]
  conv in log _ => rw [log_of_ne_zero (show (x : ℝ) ≠ 0 from x.2)]
  

Proof state:
x y : ℝ
⊢ Continuous fun x => (OrderIso.symm expOrderIso) { val := |↑x|, property := (_ : 0 < |↑x|) }

Next tactic:
exact expOrderIso.symm.continuous.comp (continuous_subtype_val.norm.subtype_mk _)
@[simp]
theorem continuousAt_log_iff : ContinuousAt log x ↔ x ≠ 0 := by
  

Proof state:
x y : ℝ
⊢ ContinuousAt log x ↔ x ≠ 0

Next tactic:
refine' ⟨_, continuousAt_log⟩
@[simp]
theorem continuousAt_log_iff : ContinuousAt log x ↔ x ≠ 0 := by
  refine' ⟨_, continuousAt_log⟩
  

Proof state:
x y : ℝ
⊢ ContinuousAt log x → x ≠ 0

Next tactic:
rintro h rfl
@[simp]
theorem continuousAt_log_iff : ContinuousAt log x ↔ x ≠ 0 := by
  refine' ⟨_, continuousAt_log⟩
  rintro h rfl
  

Proof state:
y : ℝ
h : ContinuousAt log 0
⊢ False

Next tactic:
exact not_tendsto_nhds_of_tendsto_atBot tendsto_log_nhdsWithin_zero _
    (h.tendsto.mono_left inf_le_left)
theorem log_prod {α : Type*} (s : Finset α) (f : α → ℝ) (hf : ∀ x ∈ s, f x ≠ 0) :
    log (∏ i in s, f i) = ∑ i in s, log (f i) := by
  

Proof state:
x y : ℝ
α : Type u_1
s : Finset α
f : α → ℝ
hf : ∀ x ∈ s, f x ≠ 0
⊢ log (∏ i in s, f i) = ∑ i in s, log (f i)

Next tactic:
induction' s using Finset.cons_induction_on with a s ha ih
theorem log_prod {α : Type*} (s : Finset α) (f : α → ℝ) (hf : ∀ x ∈ s, f x ≠ 0) :
    log (∏ i in s, f i) = ∑ i in s, log (f i) := by
  induction' s using Finset.cons_induction_on with a s ha ih
  · 

Proof state:
case h₁
x y : ℝ
α : Type u_1
f : α → ℝ
hf : ∀ x ∈ ∅, f x ≠ 0
⊢ log (∏ i in ∅, f i) = ∑ i in ∅, log (f i)

Next tactic:
simp