l3lab/ntp-mathlib huggingface dataset:
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  

Proof state:
b : ℕ
hb : 1 < b
x y : ℕ
hy : y ≠ 0
⊢ b ^ x ≤ y ↔ x ≤ log b y

Next tactic:
induction' y using Nat.strong_induction_on with y ih generalizing x
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  

Proof state:
case h
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
x : ℕ
hy : y ≠ 0
⊢ b ^ x ≤ y ↔ x ≤ log b y

Next tactic:
cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  | succ x =>
    rw [log]; split_ifs with h
    · have b_pos : 0 < b := zero_le_one.trans_lt hb
      rw [succ_eq_add_one, add_le_add_iff_right, ←
        ih (y / b) (div_lt_self hy.bot_lt hb) (Nat.div_pos h.1 b_pos).ne', le_div_iff_mul_le b_pos,
        pow_succ', mul_comm]
    · exact iff_of_false (fun hby => h ⟨(le_self_pow x.succ_ne_zero _).trans hby, hb⟩)
        (not_succ_le_zero _)
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  

Proof state:
case h.zero
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
⊢ b ^ zero ≤ y ↔ zero ≤ log b y

Next tactic:
| zero => exact iff_of_true hy.bot_lt (zero_le _)
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => 

Proof state:
case h.zero
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
⊢ b ^ zero ≤ y ↔ zero ≤ log b y

Next tactic:
exact iff_of_true hy.bot_lt (zero_le _)
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  

Proof state:
case h.succ
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
x : ℕ
⊢ b ^ succ x ≤ y ↔ succ x ≤ log b y

Next tactic:
| succ x =>
    rw [log]; split_ifs with h
    · have b_pos : 0 < b := zero_le_one.trans_lt hb
      rw [succ_eq_add_one, add_le_add_iff_right, ←
        ih (y / b) (div_lt_self hy.bot_lt hb) (Nat.div_pos h.1 b_pos).ne', le_div_iff_mul_le b_pos,
        pow_succ', mul_comm]
    · exact iff_of_false (fun hby => h ⟨(le_self_pow x.succ_ne_zero _).trans hby, hb⟩)
        (not_succ_le_zero _)
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  | succ x =>
    

Proof state:
case h.succ
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
x : ℕ
⊢ b ^ succ x ≤ y ↔ succ x ≤ log b y

Next tactic:
rw [log]
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  | succ x =>
    rw [log]; 

Proof state:
case h.succ
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
x : ℕ
⊢ b ^ succ x ≤ y ↔
    succ x ≤
      if h : b ≤ y ∧ 1 < b then
        let_fun this := (_ : y / b < y);
        log b (y / b) + 1
      else 0

Next tactic:
split_ifs with h
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  | succ x =>
    rw [log]; split_ifs with h
    · 

Proof state:
case pos
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
x : ℕ
h : b ≤ y ∧ 1 < b
⊢ b ^ succ x ≤ y ↔
    succ x ≤
      let_fun this := (_ : y / b < y);
      log b (y / b) + 1

Next tactic:
have b_pos : 0 < b := zero_le_one.trans_lt hb
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  | succ x =>
    rw [log]; split_ifs with h
    · have b_pos : 0 < b := zero_le_one.trans_lt hb
      

Proof state:
case pos
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
x : ℕ
h : b ≤ y ∧ 1 < b
b_pos : 0 < b
⊢ b ^ succ x ≤ y ↔
    succ x ≤
      let_fun this := (_ : y / b < y);
      log b (y / b) + 1

Next tactic:
rw [succ_eq_add_one, add_le_add_iff_right, ←
        ih (y / b) (div_lt_self hy.bot_lt hb) (Nat.div_pos h.1 b_pos).ne', le_div_iff_mul_le b_pos,
        pow_succ', mul_comm]
/-- `pow b` and `log b` (almost) form a Galois connection. See also `Nat.pow_le_of_le_log` and
`Nat.le_log_of_pow_le` for individual implications under weaker assumptions. -/
theorem pow_le_iff_le_log {b : ℕ} (hb : 1 < b) {x y : ℕ} (hy : y ≠ 0) :
    b ^ x ≤ y ↔ x ≤ log b y := by
  induction' y using Nat.strong_induction_on with y ih generalizing x
  cases x with
  | zero => exact iff_of_true hy.bot_lt (zero_le _)
  | succ x =>
    rw [log]; split_ifs with h
    · have b_pos : 0 < b := zero_le_one.trans_lt hb
      rw [succ_eq_add_one, add_le_add_iff_right, ←
        ih (y / b) (div_lt_self hy.bot_lt hb) (Nat.div_pos h.1 b_pos).ne', le_div_iff_mul_le b_pos,
        pow_succ', mul_comm]
    · 

Proof state:
case neg
b : ℕ
hb : 1 < b
y : ℕ
ih : ∀ m < y, ∀ {x : ℕ}, m ≠ 0 → (b ^ x ≤ m ↔ x ≤ log b m)
hy : y ≠ 0
x : ℕ
h : ¬(b ≤ y ∧ 1 < b)
⊢ b ^ succ x ≤ y ↔ succ x ≤ 0

Next tactic:
exact iff_of_false (fun hby => h ⟨(le_self_pow x.succ_ne_zero _).trans hby, hb⟩)
        (not_succ_le_zero _)
theorem pow_le_of_le_log {b x y : ℕ} (hy : y ≠ 0) (h : x ≤ log b y) : b ^ x ≤ y := by
  

Proof state:
b x y : ℕ
hy : y ≠ 0
h : x ≤ log b y
⊢ b ^ x ≤ y

Next tactic:
refine' (le_or_lt b 1).elim (fun hb => _) fun hb => (pow_le_iff_le_log hb hy).2 h
theorem pow_le_of_le_log {b x y : ℕ} (hy : y ≠ 0) (h : x ≤ log b y) : b ^ x ≤ y := by
  refine' (le_or_lt b 1).elim (fun hb => _) fun hb => (pow_le_iff_le_log hb hy).2 h
  

Proof state:
b x y : ℕ
hy : y ≠ 0
h : x ≤ log b y
hb : b ≤ 1
⊢ b ^ x ≤ y

Next tactic:
rw [log_of_left_le_one hb, nonpos_iff_eq_zero] at h
theorem pow_le_of_le_log {b x y : ℕ} (hy : y ≠ 0) (h : x ≤ log b y) : b ^ x ≤ y := by
  refine' (le_or_lt b 1).elim (fun hb => _) fun hb => (pow_le_iff_le_log hb hy).2 h
  rw [log_of_left_le_one hb, nonpos_iff_eq_zero] at h
  

Proof state:
b x y : ℕ
hy : y ≠ 0
h : x = 0
hb : b ≤ 1
⊢ b ^ x ≤ y

Next tactic:
rwa [h, pow_zero, one_le_iff_ne_zero]
theorem le_log_of_pow_le {b x y : ℕ} (hb : 1 < b) (h : b ^ x ≤ y) : x ≤ log b y := by
  

Proof state:
b x y : ℕ
hb : 1 < b
h : b ^ x ≤ y
⊢ x ≤ log b y

Next tactic:
rcases ne_or_eq y 0 with (hy | rfl)
theorem le_log_of_pow_le {b x y : ℕ} (hb : 1 < b) (h : b ^ x ≤ y) : x ≤ log b y := by
  rcases ne_or_eq y 0 with (hy | rfl)
  

Proof state:
case inl
b x y : ℕ
hb : 1 < b
h : b ^ x ≤ y
hy : y ≠ 0
⊢ x ≤ log b y
case inr b x : ℕ hb : 1 < b h : b ^ x ≤ 0 ⊢ x ≤ log b 0

Next tactic:
exacts [(pow_le_iff_le_log hb hy).1 h, (h.not_lt (pow_pos (zero_lt_one.trans hb) _)).elim]
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  

Proof state:
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
⊢ log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1)

Next tactic:
rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · 

Proof state:
case inl.intro
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hb : 1 < b
hn : n ≠ 0
⊢ log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1)

Next tactic:
rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm]
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      

Proof state:
case inl.intro.hb
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hb : 1 < b
hn : n ≠ 0
⊢ 1 < b

Next tactic:
assumption
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      

Proof state:
case inl.intro.hy
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hb : 1 < b
hn : n ≠ 0
⊢ n ≠ 0

Next tactic:
assumption
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      assumption
  · 

Proof state:
case inr
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hbn : ¬(1 < b ∧ n ≠ 0)
⊢ log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1)

Next tactic:
have hm : m ≠ 0 := h.resolve_right hbn
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      assumption
  · have hm : m ≠ 0 := h.resolve_right hbn
    

Proof state:
case inr
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hbn : ¬(1 < b ∧ n ≠ 0)
hm : m ≠ 0
⊢ log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1)

Next tactic:
rw [not_and_or, not_lt, Ne.def, not_not] at hbn
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      assumption
  · have hm : m ≠ 0 := h.resolve_right hbn
    rw [not_and_or, not_lt, Ne.def, not_not] at hbn
    

Proof state:
case inr
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hbn : b ≤ 1 ∨ n = 0
hm : m ≠ 0
⊢ log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1)

Next tactic:
rcases hbn with (hb | rfl)
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      assumption
  · have hm : m ≠ 0 := h.resolve_right hbn
    rw [not_and_or, not_lt, Ne.def, not_not] at hbn
    rcases hbn with (hb | rfl)
    · 

Proof state:
case inr.inl
b m n : ℕ
h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0
hm : m ≠ 0
hb : b ≤ 1
⊢ log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1)

Next tactic:
simpa only [log_of_left_le_one hb, hm.symm, false_iff_iff, not_and, not_lt] using
        le_trans (pow_le_pow_right_of_le_one' hb m.le_succ)
theorem log_eq_iff {b m n : ℕ} (h : m ≠ 0 ∨ 1 < b ∧ n ≠ 0) :
    log b n = m ↔ b ^ m ≤ n ∧ n < b ^ (m + 1) := by
  rcases em (1 < b ∧ n ≠ 0) with (⟨hb, hn⟩ | hbn)
  · rw [le_antisymm_iff, ← lt_succ_iff, ← pow_le_iff_le_log, ← lt_pow_iff_log_lt, and_comm] <;>
      assumption
  · have hm : m ≠ 0 := h.resolve_right hbn
    rw [not_and_or, not_lt, Ne.def, not_not] at hbn
    rcases hbn with (hb | rfl)
    · simpa only [log_of_left_le_one hb, hm.symm, false_iff_iff, not_and, not_lt] using
        le_trans (pow_le_pow_right_of_le_one' hb m.le_succ)
    · 

Proof state:
case inr.inr
b m : ℕ
hm : m ≠ 0
h : m ≠ 0 ∨ 1 < b ∧ 0 ≠ 0
⊢ log b 0 = m ↔ b ^ m ≤ 0 ∧ 0 < b ^ (m + 1)

Next tactic:
simpa only [log_zero_right, hm.symm, nonpos_iff_eq_zero, false_iff, not_and, not_lt,
        add_pos_iff, zero_lt_one, or_true, pow_eq_zero_iff] using pow_eq_zero
theorem log_eq_of_pow_le_of_lt_pow {b m n : ℕ} (h₁ : b ^ m ≤ n) (h₂ : n < b ^ (m + 1)) :
    log b n = m := by
  

Proof state:
b m n : ℕ
h₁ : b ^ m ≤ n
h₂ : n < b ^ (m + 1)
⊢ log b n = m

Next tactic:
rcases eq_or_ne m 0 with (rfl | hm)
theorem log_eq_of_pow_le_of_lt_pow {b m n : ℕ} (h₁ : b ^ m ≤ n) (h₂ : n < b ^ (m + 1)) :
    log b n = m := by
  rcases eq_or_ne m 0 with (rfl | hm)
  · 

Proof state:
case inl
b n : ℕ
h₁ : b ^ 0 ≤ n
h₂ : n < b ^ (0 + 1)
⊢ log b n = 0

Next tactic:
rw [pow_one] at h₂
theorem log_eq_of_pow_le_of_lt_pow {b m n : ℕ} (h₁ : b ^ m ≤ n) (h₂ : n < b ^ (m + 1)) :
    log b n = m := by
  rcases eq_or_ne m 0 with (rfl | hm)
  · rw [pow_one] at h₂
    

Proof state:
case inl
b n : ℕ
h₁ : b ^ 0 ≤ n
h₂ : n < b
⊢ log b n = 0

Next tactic:
exact log_of_lt h₂
theorem log_eq_of_pow_le_of_lt_pow {b m n : ℕ} (h₁ : b ^ m ≤ n) (h₂ : n < b ^ (m + 1)) :
    log b n = m := by
  rcases eq_or_ne m 0 with (rfl | hm)
  · rw [pow_one] at h₂
    exact log_of_lt h₂
  · 

Proof state:
case inr
b m n : ℕ
h₁ : b ^ m ≤ n
h₂ : n < b ^ (m + 1)
hm : m ≠ 0
⊢ log b n = m

Next tactic:
exact (log_eq_iff (Or.inl hm)).2 ⟨h₁, h₂⟩
theorem log_eq_one_iff' {b n : ℕ} : log b n = 1 ↔ b ≤ n ∧ n < b * b := by
  

Proof state:
b n : ℕ
⊢ log b n = 1 ↔ b ≤ n ∧ n < b * b

Next tactic:
rw [log_eq_iff (Or.inl one_ne_zero), pow_add, pow_one]
theorem log_mul_base {b n : ℕ} (hb : 1 < b) (hn : n ≠ 0) : log b (n * b) = log b n + 1 := by
  

Proof state:
b n : ℕ
hb : 1 < b
hn : n ≠ 0
⊢ log b (n * b) = log b n + 1

Next tactic:
apply log_eq_of_pow_le_of_lt_pow
theorem log_mul_base {b n : ℕ} (hb : 1 < b) (hn : n ≠ 0) : log b (n * b) = log b n + 1 := by
  apply log_eq_of_pow_le_of_lt_pow <;> 

Proof state:
case h₁
b n : ℕ
hb : 1 < b
hn : n ≠ 0
⊢ b ^ (log b n + 1) ≤ n * b

Next tactic:
rw [pow_succ', mul_comm b]
theorem log_mul_base {b n : ℕ} (hb : 1 < b) (hn : n ≠ 0) : log b (n * b) = log b n + 1 := by
  apply log_eq_of_pow_le_of_lt_pow <;> 

Proof state:
case h₂
b n : ℕ
hb : 1 < b
hn : n ≠ 0
⊢ n * b < b ^ (log b n + 1 + 1)

Next tactic:
rw [pow_succ', mul_comm b]
theorem log_mul_base {b n : ℕ} (hb : 1 < b) (hn : n ≠ 0) : log b (n * b) = log b n + 1 := by
  apply log_eq_of_pow_le_of_lt_pow <;> rw [pow_succ', mul_comm b]
  

Proof state:
case h₁
b n : ℕ
hb : 1 < b
hn : n ≠ 0
⊢ b ^ log b n * b ≤ n * b
case h₂ b n : ℕ hb : 1 < b hn : n ≠ 0 ⊢ n * b < b ^ (log b n + 1) * b

Next tactic:
exacts [mul_le_mul_right' (pow_log_le_self _ hn) _,
    (mul_lt_mul_right (zero_lt_one.trans hb)).2 (lt_pow_succ_log_self hb _)]
theorem pow_log_le_add_one (b : ℕ) : ∀ x, b ^ log b x ≤ x + 1
  | 0 => by 

Proof state:
b : ℕ
⊢ b ^ log b 0 ≤ 0 + 1

Next tactic:
rw [log_zero_right, pow_zero]
theorem log_monotone {b : ℕ} : Monotone (log b) := by
  

Proof state:
b : ℕ
⊢ Monotone (log b)

Next tactic:
refine' monotone_nat_of_le_succ fun n => _
theorem log_monotone {b : ℕ} : Monotone (log b) := by
  refine' monotone_nat_of_le_succ fun n => _
  

Proof state:
b n : ℕ
⊢ log b n ≤ log b (n + 1)

Next tactic:
rcases le_or_lt b 1 with hb | hb
theorem log_monotone {b : ℕ} : Monotone (log b) := by
  refine' monotone_nat_of_le_succ fun n => _
  rcases le_or_lt b 1 with hb | hb
  · 

Proof state:
case inl
b n : ℕ
hb : b ≤ 1
⊢ log b n ≤ log b (n + 1)

Next tactic:
rw [log_of_left_le_one hb]
theorem log_monotone {b : ℕ} : Monotone (log b) := by
  refine' monotone_nat_of_le_succ fun n => _
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb]
    

Proof state:
case inl
b n : ℕ
hb : b ≤ 1
⊢ 0 ≤ log b (n + 1)

Next tactic:
exact zero_le _
theorem log_monotone {b : ℕ} : Monotone (log b) := by
  refine' monotone_nat_of_le_succ fun n => _
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb]
    exact zero_le _
  · 

Proof state:
case inr
b n : ℕ
hb : 1 < b
⊢ log b n ≤ log b (n + 1)

Next tactic:
exact le_log_of_pow_le hb (pow_log_le_add_one _ _)
@[mono]
theorem log_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : log b n ≤ log c n := by
  

Proof state:
b c n : ℕ
hc : 1 < c
hb : c ≤ b
⊢ log b n ≤ log c n

Next tactic:
rcases eq_or_ne n 0 with (rfl | hn)
@[mono]
theorem log_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : log b n ≤ log c n := by
  rcases eq_or_ne n 0 with (rfl | hn); · 

Proof state:
case inl
b c : ℕ
hc : 1 < c
hb : c ≤ b
⊢ log b 0 ≤ log c 0

Next tactic:
rw [log_zero_right, log_zero_right]
@[mono]
theorem log_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : log b n ≤ log c n := by
  rcases eq_or_ne n 0 with (rfl | hn); · rw [log_zero_right, log_zero_right]
  

Proof state:
case inr
b c n : ℕ
hc : 1 < c
hb : c ≤ b
hn : n ≠ 0
⊢ log b n ≤ log c n

Next tactic:
apply le_log_of_pow_le hc
@[mono]
theorem log_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : log b n ≤ log c n := by
  rcases eq_or_ne n 0 with (rfl | hn); · rw [log_zero_right, log_zero_right]
  apply le_log_of_pow_le hc
  

Proof state:
case inr
b c n : ℕ
hc : 1 < c
hb : c ≤ b
hn : n ≠ 0
⊢ c ^ log b n ≤ n

Next tactic:
calc
    c ^ log b n ≤ b ^ log b n := pow_le_pow_left' hb _
    _ ≤ n := pow_log_le_self _ hn
@[simp]
theorem log_div_base (b n : ℕ) : log b (n / b) = log b n - 1 := by
  

Proof state:
b n : ℕ
⊢ log b (n / b) = log b n - 1

Next tactic:
rcases le_or_lt b 1 with hb | hb
@[simp]
theorem log_div_base (b n : ℕ) : log b (n / b) = log b n - 1 := by
  rcases le_or_lt b 1 with hb | hb
  · 

Proof state:
case inl
b n : ℕ
hb : b ≤ 1
⊢ log b (n / b) = log b n - 1

Next tactic:
rw [log_of_left_le_one hb, log_of_left_le_one hb, Nat.zero_sub]
@[simp]
theorem log_div_base (b n : ℕ) : log b (n / b) = log b n - 1 := by
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb, log_of_left_le_one hb, Nat.zero_sub]
  

Proof state:
case inr
b n : ℕ
hb : 1 < b
⊢ log b (n / b) = log b n - 1

Next tactic:
cases' lt_or_le n b with h h
@[simp]
theorem log_div_base (b n : ℕ) : log b (n / b) = log b n - 1 := by
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb, log_of_left_le_one hb, Nat.zero_sub]
  cases' lt_or_le n b with h h
  · 

Proof state:
case inr.inl
b n : ℕ
hb : 1 < b
h : n < b
⊢ log b (n / b) = log b n - 1

Next tactic:
rw [div_eq_of_lt h, log_of_lt h, log_zero_right]
@[simp]
theorem log_div_base (b n : ℕ) : log b (n / b) = log b n - 1 := by
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb, log_of_left_le_one hb, Nat.zero_sub]
  cases' lt_or_le n b with h h
  · rw [div_eq_of_lt h, log_of_lt h, log_zero_right]
  

Proof state:
case inr.inr
b n : ℕ
hb : 1 < b
h : b ≤ n
⊢ log b (n / b) = log b n - 1

Next tactic:
rw [log_of_one_lt_of_le hb h, add_tsub_cancel_right]
@[simp]
theorem log_div_mul_self (b n : ℕ) : log b (n / b * b) = log b n := by
  

Proof state:
b n : ℕ
⊢ log b (n / b * b) = log b n

Next tactic:
rcases le_or_lt b 1 with hb | hb
@[simp]
theorem log_div_mul_self (b n : ℕ) : log b (n / b * b) = log b n := by
  rcases le_or_lt b 1 with hb | hb
  · 

Proof state:
case inl
b n : ℕ
hb : b ≤ 1
⊢ log b (n / b * b) = log b n

Next tactic:
rw [log_of_left_le_one hb, log_of_left_le_one hb]
@[simp]
theorem log_div_mul_self (b n : ℕ) : log b (n / b * b) = log b n := by
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb, log_of_left_le_one hb]
  

Proof state:
case inr
b n : ℕ
hb : 1 < b
⊢ log b (n / b * b) = log b n

Next tactic:
cases' lt_or_le n b with h h
@[simp]
theorem log_div_mul_self (b n : ℕ) : log b (n / b * b) = log b n := by
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb, log_of_left_le_one hb]
  cases' lt_or_le n b with h h
  · 

Proof state:
case inr.inl
b n : ℕ
hb : 1 < b
h : n < b
⊢ log b (n / b * b) = log b n

Next tactic:
rw [div_eq_of_lt h, zero_mul, log_zero_right, log_of_lt h]
@[simp]
theorem log_div_mul_self (b n : ℕ) : log b (n / b * b) = log b n := by
  rcases le_or_lt b 1 with hb | hb
  · rw [log_of_left_le_one hb, log_of_left_le_one hb]
  cases' lt_or_le n b with h h
  · rw [div_eq_of_lt h, zero_mul, log_zero_right, log_of_lt h]
  

Proof state:
case inr.inr
b n : ℕ
hb : 1 < b
h : b ≤ n
⊢ log b (n / b * b) = log b n

Next tactic:
rw [log_mul_base hb (Nat.div_pos h (zero_le_one.trans_lt hb)).ne', log_div_base,
    tsub_add_cancel_of_le (succ_le_iff.2 <| log_pos hb h)]
theorem add_pred_div_lt {b n : ℕ} (hb : 1 < b) (hn : 2 ≤ n) : (n + b - 1) / b < n := by
  

Proof state:
b n : ℕ
hb : 1 < b
hn : 2 ≤ n
⊢ (n + b - 1) / b < n

Next tactic:
rw [div_lt_iff_lt_mul (zero_lt_one.trans hb), ← succ_le_iff, ← pred_eq_sub_one,
    succ_pred_eq_of_pos (add_pos (zero_lt_one.trans hn) (zero_lt_one.trans hb))]
theorem add_pred_div_lt {b n : ℕ} (hb : 1 < b) (hn : 2 ≤ n) : (n + b - 1) / b < n := by
  rw [div_lt_iff_lt_mul (zero_lt_one.trans hb), ← succ_le_iff, ← pred_eq_sub_one,
    succ_pred_eq_of_pos (add_pos (zero_lt_one.trans hn) (zero_lt_one.trans hb))]
  

Proof state:
b n : ℕ
hb : 1 < b
hn : 2 ≤ n
⊢ n + b ≤ n * b

Next tactic:
exact add_le_mul hn hb
theorem clog_of_left_le_one {b : ℕ} (hb : b ≤ 1) (n : ℕ) : clog b n = 0 := by
  

Proof state:
b : ℕ
hb : b ≤ 1
n : ℕ
⊢ clog b n = 0

Next tactic:
rw [clog, dif_neg fun h : 1 < b ∧ 1 < n => h.1.not_le hb]
theorem clog_of_right_le_one {n : ℕ} (hn : n ≤ 1) (b : ℕ) : clog b n = 0 := by
  

Proof state:
n : ℕ
hn : n ≤ 1
b : ℕ
⊢ clog b n = 0

Next tactic:
rw [clog, dif_neg fun h : 1 < b ∧ 1 < n => h.2.not_le hn]
theorem clog_of_two_le {b n : ℕ} (hb : 1 < b) (hn : 2 ≤ n) :
    clog b n = clog b ((n + b - 1) / b) + 1 := by 

Proof state:
b n : ℕ
hb : 1 < b
hn : 2 ≤ n
⊢ clog b n = clog b ((n + b - 1) / b) + 1

Next tactic:
rw [clog, dif_pos (⟨hb, hn⟩ : 1 < b ∧ 1 < n)]
theorem clog_pos {b n : ℕ} (hb : 1 < b) (hn : 2 ≤ n) : 0 < clog b n := by
  

Proof state:
b n : ℕ
hb : 1 < b
hn : 2 ≤ n
⊢ 0 < clog b n

Next tactic:
rw [clog_of_two_le hb hn]
theorem clog_pos {b n : ℕ} (hb : 1 < b) (hn : 2 ≤ n) : 0 < clog b n := by
  rw [clog_of_two_le hb hn]
  

Proof state:
b n : ℕ
hb : 1 < b
hn : 2 ≤ n
⊢ 0 < clog b ((n + b - 1) / b) + 1

Next tactic:
exact zero_lt_succ _
theorem clog_eq_one {b n : ℕ} (hn : 2 ≤ n) (h : n ≤ b) : clog b n = 1 := by
  

Proof state:
b n : ℕ
hn : 2 ≤ n
h : n ≤ b
⊢ clog b n = 1

Next tactic:
rw [clog_of_two_le (hn.trans h) hn, clog_of_right_le_one]
theorem clog_eq_one {b n : ℕ} (hn : 2 ≤ n) (h : n ≤ b) : clog b n = 1 := by
  rw [clog_of_two_le (hn.trans h) hn, clog_of_right_le_one]
  

Proof state:
case hn
b n : ℕ
hn : 2 ≤ n
h : n ≤ b
⊢ (n + b - 1) / b ≤ 1

Next tactic:
have n_pos : 0 < n := (zero_lt_two' ℕ).trans_le hn