l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem pure_isPure (a : α) : IsPure (pure a)
  | b, ab, c, ac => by
    rw [mem_pure] at ab ac
    

Proof state:
α : Type u_1
β : Type u_2
a b : α
ab : b = a
c : α
ac : c = a
⊢ b = c

Next tactic:
rwa [← ac] at ab
theorem IsPure.min {s t : Semiquot α} (h : IsPure t) : s ≤ t ↔ s = t :=
  ⟨fun st =>
    le_antisymm st <| by
      

Proof state:
α : Type u_1
β : Type u_2
s t : Semiquot α
h : IsPure t
st : s ≤ t
⊢ t ≤ s

Next tactic:
rw [eq_pure h, eq_pure (h.mono st)]
theorem IsPure.min {s t : Semiquot α} (h : IsPure t) : s ≤ t ↔ s = t :=
  ⟨fun st =>
    le_antisymm st <| by
      rw [eq_pure h, eq_pure (h.mono st)]; 

Proof state:
α : Type u_1
β : Type u_2
s t : Semiquot α
h : IsPure t
st : s ≤ t
⊢ pure (get t h) ≤ pure (get s (_ : IsPure s))

Next tactic:
simp
theorem IsPure.min {s t : Semiquot α} (h : IsPure t) : s ≤ t ↔ s = t :=
  ⟨fun st =>
    le_antisymm st <| by
      rw [eq_pure h, eq_pure (h.mono st)]; simp; 

Proof state:
α : Type u_1
β : Type u_2
s t : Semiquot α
h : IsPure t
st : s ≤ t
⊢ get t h = get s (_ : IsPure s)

Next tactic:
exact h _ (get_mem _) _ (st <| get_mem _)
theorem lt_pow_self {p : ℕ} (h : 1 < p) : ∀ n : ℕ, n < p ^ n
  | 0 => by 

Proof state:
m n x y p : ℕ
h : 1 < p
⊢ 0 < p ^ 0

Next tactic:
simp [zero_lt_one]
theorem lt_two_pow (n : ℕ) : n < 2 ^ n :=
  lt_pow_self (by 

Proof state:
m n✝ x y n : ℕ
⊢ 1 < 2

Next tactic:
decide
theorem one_le_pow (n m : ℕ) (h : 0 < m) : 1 ≤ m ^ n := by
  

Proof state:
m✝ n✝ x y n m : ℕ
h : 0 < m
⊢ 1 ≤ m ^ n

Next tactic:
rw [← one_pow n]
theorem one_le_pow (n m : ℕ) (h : 0 < m) : 1 ≤ m ^ n := by
  rw [← one_pow n]
  

Proof state:
m✝ n✝ x y n m : ℕ
h : 0 < m
⊢ 1 ^ n ≤ m ^ n

Next tactic:
exact Nat.pow_le_pow_of_le_left h n
theorem one_le_two_pow (n : ℕ) : 1 ≤ 2 ^ n :=
  one_le_pow n 2 (by 

Proof state:
m n✝ x y n : ℕ
⊢ 0 < 2

Next tactic:
decide
theorem one_lt_pow (n m : ℕ) (h₀ : n ≠ 0) (h₁ : 1 < m) : 1 < m ^ n := by
  

Proof state:
m✝ n✝ x y n m : ℕ
h₀ : n ≠ 0
h₁ : 1 < m
⊢ 1 < m ^ n

Next tactic:
rw [← one_pow n]
theorem one_lt_pow (n m : ℕ) (h₀ : n ≠ 0) (h₁ : 1 < m) : 1 < m ^ n := by
  rw [← one_pow n]
  

Proof state:
m✝ n✝ x y n m : ℕ
h₀ : n ≠ 0
h₁ : 1 < m
⊢ 1 ^ n < m ^ n

Next tactic:
exact Nat.pow_lt_pow_left h₁ h₀
theorem two_pow_pos (n : ℕ) : 0 < 2^n := Nat.pos_pow_of_pos _ (by 

Proof state:
m n✝ x y n : ℕ
⊢ 0 < 2

Next tactic:
decide
theorem two_pow_succ (n : ℕ) : 2^(n + 1) = 2^n + 2^n := by 

Proof state:
m n✝ x y n : ℕ
⊢ 2 ^ (n + 1) = 2 ^ n + 2 ^ n

Next tactic:
simp [pow_succ, mul_two]
theorem one_lt_two_pow (n : ℕ) (h₀ : n ≠ 0) : 1 < 2 ^ n := one_lt_pow n 2 h₀ (by 

Proof state:
m n✝ x y n : ℕ
h₀ : n ≠ 0
⊢ 1 < 2

Next tactic:
decide
theorem one_lt_two_pow' (n : ℕ) : 1 < 2 ^ (n + 1) :=
  one_lt_pow (n + 1) 2 n.succ_ne_zero (by 

Proof state:
m n✝ x y n : ℕ
⊢ 1 < 2

Next tactic:
decide
theorem mul_lt_mul_pow_succ {n a q : ℕ} (a0 : 0 < a) (q1 : 1 < q) : n * q < a * q ^ (n + 1) := by
  

Proof state:
m n✝ x y n a q : ℕ
a0 : 0 < a
q1 : 1 < q
⊢ n * q < a * q ^ (n + 1)

Next tactic:
rw [pow_succ, ← mul_assoc, mul_lt_mul_right (zero_lt_one.trans q1)]
theorem mul_lt_mul_pow_succ {n a q : ℕ} (a0 : 0 < a) (q1 : 1 < q) : n * q < a * q ^ (n + 1) := by
  rw [pow_succ, ← mul_assoc, mul_lt_mul_right (zero_lt_one.trans q1)]
  

Proof state:
m n✝ x y n a q : ℕ
a0 : 0 < a
q1 : 1 < q
⊢ n < a * q ^ n

Next tactic:
exact lt_mul_of_one_le_of_lt (Nat.succ_le_iff.mpr a0) (Nat.lt_pow_self q1 n)
theorem sq_sub_sq (a b : ℕ) : a ^ 2 - b ^ 2 = (a + b) * (a - b) := by
  

Proof state:
m n x y a b : ℕ
⊢ a ^ 2 - b ^ 2 = (a + b) * (a - b)

Next tactic:
rw [sq, sq]
theorem sq_sub_sq (a b : ℕ) : a ^ 2 - b ^ 2 = (a + b) * (a - b) := by
  rw [sq, sq]
  

Proof state:
m n x y a b : ℕ
⊢ a * a - b * b = (a + b) * (a - b)

Next tactic:
exact Nat.mul_self_sub_mul_self_eq a b
theorem pow_mod (a b n : ℕ) : a ^ b % n = (a % n) ^ b % n := by
  

Proof state:
m n✝ x y a b n : ℕ
⊢ a ^ b % n = (a % n) ^ b % n

Next tactic:
induction' b with b ih
theorem pow_mod (a b n : ℕ) : a ^ b % n = (a % n) ^ b % n := by
  induction' b with b ih
  

Proof state:
case zero
m n✝ x y a n : ℕ
⊢ a ^ zero % n = (a % n) ^ zero % n
case succ m n✝ x y a n b : ℕ ih : a ^ b % n = (a % n) ^ b % n ⊢ a ^ succ b % n = (a % n) ^ succ b % n

Next tactic:
rfl
theorem pow_mod (a b n : ℕ) : a ^ b % n = (a % n) ^ b % n := by
  induction' b with b ih
  rfl; 

Proof state:
case succ
m n✝ x y a n b : ℕ
ih : a ^ b % n = (a % n) ^ b % n
⊢ a ^ succ b % n = (a % n) ^ succ b % n

Next tactic:
simp [pow_succ, Nat.mul_mod, ih]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  

Proof state:
m✝ n x y b w m : ℕ
⊢ m % b ^ succ w = b * (m / b % b ^ w) + m % b

Next tactic:
by_cases b_h : b = 0
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · 

Proof state:
case pos
m✝ n x y b w m : ℕ
b_h : b = 0
⊢ m % b ^ succ w = b * (m / b % b ^ w) + m % b

Next tactic:
simp [b_h, pow_succ]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  

Proof state:
case neg
m✝ n x y b w m : ℕ
b_h : ¬b = 0
⊢ m % b ^ succ w = b * (m / b % b ^ w) + m % b

Next tactic:
have b_pos := Nat.pos_of_ne_zero b_h
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  

Proof state:
case neg
m✝ n x y b w m : ℕ
b_h : ¬b = 0
b_pos : 0 < b
⊢ m % b ^ succ w = b * (m / b % b ^ w) + m % b

Next tactic:
induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
        -- Cancel subtraction inside mod b^w
        have p_b_ge : b ^ w ≤ p / b := by
          rw [le_div_iff_mul_le b_pos, mul_comm]
          exact h₁
        rw [Eq.symm (mod_eq_sub_mod p_b_ge)]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    

Proof state:
case neg.h
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
⊢ p % b ^ succ w = b * (p / b % b ^ w) + p % b

Next tactic:
| h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
        -- Cancel subtraction inside mod b^w
        have p_b_ge : b ^ w ≤ p / b := by
          rw [le_div_iff_mul_le b_pos, mul_comm]
          exact h₁
        rw [Eq.symm (mod_eq_sub_mod p_b_ge)]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      

Proof state:
case neg.h
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
⊢ p % b ^ succ w = b * (p / b % b ^ w) + p % b

Next tactic:
cases' lt_or_ge p (b ^ succ w) with h₁ h₁
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        

Proof state:
case neg.h.inl
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p < b ^ succ w
⊢ p % b ^ succ w = b * (p / b % b ^ w) + p % b

Next tactic:
have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          

Proof state:
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p < b ^ succ w
⊢ p / b < b ^ w

Next tactic:
rw [div_lt_iff_lt_mul b_pos]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          

Proof state:
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p < b ^ succ w
⊢ p < b ^ w * b

Next tactic:
simpa [pow_succ] using h₁
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        

Proof state:
case neg.h.inl
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p < b ^ succ w
h₂ : p / b < b ^ w
⊢ p % b ^ succ w = b * (p / b % b ^ w) + p % b

Next tactic:
rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        

Proof state:
case neg.h.inl
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p < b ^ succ w
h₂ : p / b < b ^ w
⊢ p = b * (p / b) + p % b

Next tactic:
simp [div_add_mod]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p ≥ b ^ succ w
⊢ p % b ^ succ w = b * (p / b % b ^ w) + p % b

Next tactic:
have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p ≥ b ^ succ w
h₂ : p - b ^ succ w < p
⊢ p % b ^ succ w = b * (p / b % b ^ w) + p % b

Next tactic:
rw [mod_eq_sub_mod h₁, IH _ h₂]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p ≥ b ^ succ w
h₂ : p - b ^ succ w < p
⊢ b * ((p - b ^ succ w) / b % b ^ w) + (p - b ^ succ w) % b = b * (p / b % b ^ w) + p % b

Next tactic:
simp only [pow_succ']
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₁ : p ≥ b ^ succ w
h₂ : p - b ^ succ w < p
⊢ b * ((p - b * b ^ w) / b % b ^ w) + (p - b * b ^ w) % b = b * (p / b % b ^ w) + p % b

Next tactic:
simp only [GE.ge, pow_succ'] at h₁
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₂ : p - b ^ succ w < p
h₁ : b * b ^ w ≤ p
⊢ b * ((p - b * b ^ w) / b % b ^ w) + (p - b * b ^ w) % b = b * (p / b % b ^ w) + p % b

Next tactic:
rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
        -- Cancel subtraction inside mod b^w
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₂ : p - b ^ succ w < p
h₁ : b * b ^ w ≤ p
⊢ b * ((p / b - b ^ w) % b ^ w) + p % b = b * (p / b % b ^ w) + p % b

Next tactic:
have p_b_ge : b ^ w ≤ p / b := by
          rw [le_div_iff_mul_le b_pos, mul_comm]
          exact h₁
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
        -- Cancel subtraction inside mod b^w
        have p_b_ge : b ^ w ≤ p / b := by
          

Proof state:
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₂ : p - b ^ succ w < p
h₁ : b * b ^ w ≤ p
⊢ b ^ w ≤ p / b

Next tactic:
rw [le_div_iff_mul_le b_pos, mul_comm]
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
        -- Cancel subtraction inside mod b^w
        have p_b_ge : b ^ w ≤ p / b := by
          rw [le_div_iff_mul_le b_pos, mul_comm]
          

Proof state:
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₂ : p - b ^ succ w < p
h₁ : b * b ^ w ≤ p
⊢ b * b ^ w ≤ p

Next tactic:
exact h₁
theorem mod_pow_succ {b : ℕ} (w m : ℕ) : m % b ^ succ w = b * (m / b % b ^ w) + m % b := by
  by_cases b_h : b = 0
  · simp [b_h, pow_succ]
  have b_pos := Nat.pos_of_ne_zero b_h
  induction m using Nat.strong_induction_on with
    | h p IH =>
      cases' lt_or_ge p (b ^ succ w) with h₁ h₁
      · -- base case: p < b^succ w
        have h₂ : p / b < b ^ w := by
          rw [div_lt_iff_lt_mul b_pos]
          simpa [pow_succ] using h₁
        rw [mod_eq_of_lt h₁, mod_eq_of_lt h₂]
        simp [div_add_mod]
      · -- step: p ≥ b^succ w
        -- Generate condition for induction hypothesis
        have h₂ : p - b ^ succ w < p :=
          tsub_lt_self ((pow_pos b_pos _).trans_le h₁) (pow_pos b_pos _)
        -- Apply induction
        rw [mod_eq_sub_mod h₁, IH _ h₂]
        -- Normalize goal and h1
        simp only [pow_succ']
        simp only [GE.ge, pow_succ'] at h₁
        -- Pull subtraction outside mod and div
        rw [sub_mul_mod h₁, sub_mul_div _ _ _ h₁]
        -- Cancel subtraction inside mod b^w
        have p_b_ge : b ^ w ≤ p / b := by
          rw [le_div_iff_mul_le b_pos, mul_comm]
          exact h₁
        

Proof state:
case neg.h.inr
m n x y b w : ℕ
b_h : ¬b = 0
b_pos : 0 < b
p : ℕ
IH : ∀ m < p, m % b ^ succ w = b * (m / b % b ^ w) + m % b
h₂ : p - b ^ succ w < p
h₁ : b * b ^ w ≤ p
p_b_ge : b ^ w ≤ p / b
⊢ b * ((p / b - b ^ w) % b ^ w) + p % b = b * (p / b % b ^ w) + p % b

Next tactic:
rw [Eq.symm (mod_eq_sub_mod p_b_ge)]
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    

Proof state:
m n x✝ y k l x : ℕ
w : 0 < x + 1
⊢ (x + 1) ^ k ∣ (x + 1) ^ l ↔ (x + 1) ^ k ≤ (x + 1) ^ l

Next tactic:
constructor
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · 

Proof state:
case mp
m n x✝ y k l x : ℕ
w : 0 < x + 1
⊢ (x + 1) ^ k ∣ (x + 1) ^ l → (x + 1) ^ k ≤ (x + 1) ^ l

Next tactic:
intro a
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      

Proof state:
case mp
m n x✝ y k l x : ℕ
w : 0 < x + 1
a : (x + 1) ^ k ∣ (x + 1) ^ l
⊢ (x + 1) ^ k ≤ (x + 1) ^ l

Next tactic:
exact le_of_dvd (pow_pos (succ_pos x) l) a
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · 

Proof state:
case mpr
m n x✝ y k l x : ℕ
w : 0 < x + 1
⊢ (x + 1) ^ k ≤ (x + 1) ^ l → (x + 1) ^ k ∣ (x + 1) ^ l

Next tactic:
intro a
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · intro a
      

Proof state:
case mpr
m n x✝ y k l x : ℕ
w : 0 < x + 1
a : (x + 1) ^ k ≤ (x + 1) ^ l
⊢ (x + 1) ^ k ∣ (x + 1) ^ l

Next tactic:
cases' x with x