Zulip Chat Archive

Stream: Is there code for X?

Topic: Two lemmas about rational power of natural number


Ilmārs Cīrulis (Dec 03 2025 at 15:12):

Are they in Mathlib in some form? If not, would they be good for Mathlib?
Thank you!

import Mathlib

lemma aux4 (a : ) (p q : ) (h : (q : ) = (a : ) ^ (p : )) :
     (b : ), a = b ^ p.den := by sorry

lemma aux5 (a : ) (p q : ) (hp : 0  p) (h : (q : ) = (a : ) ^ (p : )) :
     (n : ), (n : ) = q := by sorry

Ilmārs Cīrulis (Dec 03 2025 at 17:02):

Their use?... For finding/proving natural number solutions for some equations that contain exponentiation, probably. At least that's where I used them.

Maybe there are some other use cases, I don't know.

Snir Broshi (Dec 03 2025 at 22:58):

I like these, they seem to lead to equations of the form a ^ b = c ^ d for (a b c d : ℕ), and specifically the case where Nat.Coprime b d.
Though I'm not a fan of the particular way they're stated, using rationals and reals. Can you make them only about naturals/integers?
btw I think aux5 is a single application of docs#irrational_nrt_of_notint_nrt, and its statement can be strengthened to q.den = 1.

Ilmārs Cīrulis (Dec 03 2025 at 23:08):

They are in such form because I wanted to reason about natural number to rational power, and that's only possible, I believe, when both base and exponent are coerced to real numbers. :thinking:

The first proof ultimately uses the nice theorem docs#Nat.exists_eq_pow_of_exponent_coprime_of_pow_eq_pow

Snir Broshi (Dec 03 2025 at 23:11):

Oh wow, merged just last week (#28557), didn't know this existed, thanks!

Ilmārs Cīrulis (Dec 03 2025 at 23:13):

Can you make them only about naturals/integers?

I will try to make such versions too.

Ilmārs Cīrulis (Dec 03 2025 at 23:58):

:partying_face: There they are, if I did everything correctly. Now they look trivial. :D

import Mathlib

lemma aux₁ {n a b c d : } (hb : b  0) (h : c ^ b = d ^ b * n ^ a) : d  c := by
  have h₁ : d ^ b  c ^ b := by use (n ^ a)
  exact (Nat.pow_dvd_pow_iff hb).mp h₁

lemma aux₂ (n a b c d : ) (hb : b  0) (hd : d  0) (hab : a.Coprime b) (h : c ^ b = d ^ b * n ^ a) :
     (m : ), n = m ^ b := by
  obtain e, rfl := aux₁ hb h
  grind [Nat.eq_of_mul_eq_mul_left, Nat.pow_pos, mul_pow,
    Nat.exists_eq_pow_of_exponent_coprime_of_pow_eq_pow]

Ilmārs Cīrulis (Dec 03 2025 at 23:59):

Hmm, maybe I can remake the proof where I used them, to use natural numbers only. :thinking:

Snir Broshi (Dec 04 2025 at 00:04):

Cool! Though I agree they look trivial now, maybe they can be inlined to the parent proof?

Ilmārs Cīrulis (Dec 04 2025 at 00:10):

Yes, that could be possible. Will try.

Thank you! :)

Ilmārs Cīrulis (Dec 04 2025 at 00:37):

Wow, now the proof seems like super-easy and will be soon finished. Damn you, weird human proof I formalized. :joy:

Ilmārs Cīrulis (Dec 04 2025 at 10:03):

Anyway, there's the parent proof, even if it is a bit off-topic. So tiny! :octopus:

import Mathlib

lemma ineq₁ {n b : } (hb : 2  b) (hn : 5  n) : n < b ^ (n - 2) := by
  induction n, hn using Nat.le_induction with
  | base => norm_num; linarith [Nat.pow_le_pow_left hb 3]
  | succ n hn iH => rw [show n + 1 - 2 = n - 2 + 1 by cutsat, Nat.pow_succ]; nlinarith

lemma ineq₂ {n b : } (hb : 2  b) (hn : 5  n) : n * b ^ 2 < b ^ n := by
  nth_rw 2 [show n = n - 2 + 2 by cutsat]
  rw [Nat.pow_add]
  nlinarith [ineq₁ hb hn]

lemma ineq₃ {x y b : } (hb : 2  b) (hxy : x < y) : b + x < b ^ 2 * y := by
  induction b, hb using Nat.le_induction <;> nlinarith

lemma ineq₄ {b : } (n : ) (hb : 2  b) : b * n < (b ^ n) ^ 2 := by
  induction n with
  | zero => simp
  | succ n iH => ring_nf at *; exact ineq₃ hb iH

lemma aux₁ {n b : } (h : n * b ^ 2 = b ^ n) : b  1  n  4 := by grind [ineq₂]

lemma aux₂ {n b : } (h : b * n = (b ^ n) ^ 2) : b  1 := by grind [ineq₄]

lemma aux₃ {n a b c d : } (hb : b  0) (h : c ^ b = d ^ b * n ^ a) : d  c :=
  (Nat.pow_dvd_pow_iff hb).mp (Dvd.intro (n ^ a) h.symm)

theorem T (a b : ) (ha : 0 < a) (hb : 0 < b) :
    a ^ (b ^ 2) = b ^ a  ((a, b) = (1, 1)  (a, b) = (16, 2)  (a, b) = (27, 3)) := by
  constructor <;> intro H
  · by_cases h₁ : 2 * b ^ 2  a
    · have h₂ : b ^ a = (b ^ 2) ^ (b ^ 2) * b ^ (a - 2 * b ^ 2) := by
        rw [ pow_mul,  pow_add]; congr; cutsat
      have h₃ : b ^ 2  a := by
        rw [h₂] at H
        exact aux₃ (by nlinarith) H
      obtain d, hd := h₃
      rw [hd, mul_comm, pow_mul, Nat.pow_left_inj (pow_ne_zero 2 (Nat.ne_zero_of_lt hb))] at H
      obtain h₄ | h₄ := aux₁ H
      · interval_cases b; grind
      · interval_cases d
        · simp at H
        · have h₃ : b = 1 := by nlinarith
          grind
        · nlinarith
        · have h₃ : b = 3 := by nlinarith
          grind
        · have h₃ : b = 2 := by
            rw [show b ^ 4 = b ^ 2 * b ^ 2 by ring] at H
            have h₄ : b ^ 2 = 4 := by nlinarith
            nlinarith
          grind
    · simp at h₁
      have h₂ : (b ^ 2) ^ (b ^ 2) = a ^ (b ^ 2) * b ^ (2 * b ^ 2 - a) := by
        rw [H,  pow_add,  pow_mul]; congr; cutsat
      have h₃ : a  b ^ 2 := aux₃ (by nlinarith) h₂
      obtain d, hd := h₃
      rw [hd, mul_comm, pow_mul, Nat.pow_left_inj (Nat.ne_zero_of_lt ha)] at H
      rw [ H] at hd
      have h₄ := aux₂ hd.symm
      interval_cases a; grind
  · grind

Last updated: Dec 20 2025 at 21:32 UTC