Zulip Chat Archive
Stream: Is there code for X?
Topic: divisibilty of powers
Niels Voss (Dec 20 2022 at 19:49):
In my PR, I also proved the following statements
lemma odd_pow_lem (a : ℤ) (n k : ℕ) (h₁ : k ∣ n) (h₂ : odd (n / k)) : a^k + 1 ∣ a^n + 1
lemma sub_one_dvd_pow_sub_one (a n : ℕ) (h : 1 ≤ a) : a - 1 ∣ a^n - 1
I wasn't able to find these in mathlib. Technically I only need the case when k = 1
for odd_pow_lem
. If they aren't already in mathlib, do they belong?
I also have proofs of the more general lemma ab_lem (a b n : ℕ) : (a - b) ∣ (a^n - b^n)
and Kevin Buzzard suggested that I reformalize odd_pow_lem
as lemma odd_pow_lem (a : ℤ) (q k : ℕ) (h₂ : odd q) : a^k + 1 ∣ a^(q * k) + 1
to avoid natural number division.
Yaël Dillies (Dec 20 2022 at 19:52):
@Mantas Baksys, thoughts?
Martin Dvořák (Dec 20 2022 at 20:00):
I think that lemma ab_lem (a b n : ℕ) : (a - b) ∣ (a^n - b^n)
is extremely useful.
Martin Dvořák (Dec 20 2022 at 20:05):
This one is not in your PR, is it?
Niels Voss (Dec 20 2022 at 20:06):
It used to be, but I removed it because I only ever used the b = 1
case.
It has a (ungolfed) proof here
Kevin Buzzard (Dec 20 2022 at 20:08):
I would say that odd_pow_lem
is better stated off as odd q -> a + 1 | a^q + 1
avoiding natural division and the divisibility hypothesis, and then you can apply with a = a^k
if you want your version. As for sub_one_dvd_pow_sub_one
I think it's probably better stated for a : int
, and deduced for naturals afterwards (note that it looks true for a=0 so h
should be removed in the final version, but you can do cases on a when proving the natural version)
Martin Dvořák (Dec 20 2022 at 20:13):
Niels Voss said:
It used to be, but I removed it because I only ever used the
b = 1
case.
It has a (ungolfed) proof here
Nice!
Just one comment... for me, the terms with "triangle" are hard to read.
Instead of:
exact (eq.symm h₈) ▸ h₇
I'd write:
rwa ←h₈ at h₇
Michael Stoll (Dec 20 2022 at 20:17):
docs#geom_sum₂_mul and friends might be useful.
Michael Stoll (Dec 20 2022 at 20:18):
(This came up in my seminar a while ago. I was certain I had seen this somewhere in mathlib, but could not find it when I was looking for it. The name is not what I had expected...)
Niels Voss (Dec 20 2022 at 20:22):
I would say that
odd_pow_lem
is better stated off asodd q -> a + 1 | a^q + 1
avoiding natural division and the divisibility hypothesis, and then you can apply witha = a^k
if you want your version.
I agree, for some reason it never occurred to me that the two forms are actually equivalent
Niels Voss (Dec 20 2022 at 20:44):
Here are some short proofs of ab_lem
for ℤ
and ℕ
using the lemma Michael Stoll suggested
private lemma ab_lem (a b : ℤ) (n : ℕ) : a - b ∣ a^n - b^n :=
dvd.intro_left _ (geom_sum₂_mul a b n)
private lemma ab_lem' (a b n : ℕ) : a - b ∣ a^n - b^n :=
begin
by_cases h : b ≤ a,
{ have : b^n ≤ a^n := nat.pow_le_pow_of_le_left h _,
exact_mod_cast ab_lem ↑a ↑b n },
{ have : a^n ≤ b^n := nat.pow_le_pow_of_le_left (show a ≤ b, by linarith) _,
exact (nat.sub_eq_zero_iff_le.mpr this).symm ▸ dvd_zero (a - b) }
end
Junyan Xu (Dec 20 2022 at 21:08):
You can cases le_total b a
Kevin Buzzard (Dec 20 2022 at 22:55):
Or split on le_or_lt
.
Niels Voss (Dec 22 2022 at 00:23):
This link suggests that for all a, b, n
where n
is odd then a + b ∣ a^n + b^n
, which is basically a more general version of what I proved. Since geom_sum₂_mul
is in the library, is there something similar for sums of odd powers?
Eric Rodriguez (Dec 22 2022 at 00:28):
docs#geom_sum₂_mul
Eric Rodriguez (Dec 22 2022 at 00:28):
oh great the linkifier is broken
Eric Rodriguez (Dec 22 2022 at 00:29):
geom_sum2_mul seems to pretty much be that lemma with x = a, y = -b
, no?
Niels Voss (Dec 22 2022 at 00:31):
Yeah it does, I was just wondering if there was a more convenient form to use
Eric Rodriguez (Dec 22 2022 at 00:40):
I don't think so, I also don't think a PR that makes it would be unwelcome though! not sure how far away geom_sum
is from a port but some lemma called odd.pow_add_X
or something of the sort would be nice
Niels Voss (Dec 22 2022 at 01:14):
I tried proving that (finset.range n).sum (λ (i : ℕ), (-1)^i * a ^ i * b ^ (n - 1 - i)) * (a + b) = a^n + b^n
. Proving that (finset.range n).sum (λ (i : ℕ), (a ^ i * (-b) ^ (n - 1 - i)) * (a + b) = a^n + b^n
is basically a direct result of geom_sum₂_mul
. Proving that the two finset sums are equal is harder, as it requires showing that (-1 : ℤ) ^ i = (-1) ^ (n - 1 - i)
, for odd n, which is not true in general due to how natural number subtraction works.
I don't actually care about what is inside the finset sum for my PR because it only depends on divisibility, but I could try finishing the proof if it would be helpful to have in the library.
Eric Rodriguez (Dec 22 2022 at 01:15):
I'd say just upload the divisibility proof and if people want the "proper" proof, they'll ask. Mention these details in the PR description!
Niels Voss (Dec 22 2022 at 01:18):
Which file and namespace would these go into? I'm planning on doing a - b | a^n - b^n
and odd n -> a + b | a^n + b^n
for both a b : nat
and a b : int
(maybe it works for any comm ring in general)?
Eric Rodriguez (Dec 22 2022 at 01:20):
I'd try to stick to comm_rings if you can, I find it unlikely it'd be accepted for a b : int
only. I'd put the second one in the odd
namespace (not sure about the name) and the first one, I'd call sub_dvd_pow_sub_pow
maybe?
Niels Voss (Dec 22 2022 at 01:23):
I don't know how far down the import chain algebra.geom_sum
is, but I'd imagine it would be after data.nat.parity
. Should these just go in algebra.geom_sum
?
Junyan Xu (Dec 22 2022 at 01:29):
It may be easier to plug in x = -a, y = b
into geom_sum2_mul to get
(finset.range n).sum (λ (i : ℕ), (-a) ^ i * b ^ (n - 1 - i)) * (-a - b) = (-a) ^ n - b ^ n
and cancel a minus sign from both sides (when n is odd).
Niels Voss (Dec 22 2022 at 01:32):
That definitely would help if I was trying to provide a version of geom_sum₂_mul
for subtraction. I don't think it matters for just divisibility though.
It would avoid all problems with natural number subtraction in my attempted proof above though.
Kevin Buzzard (Dec 22 2022 at 01:38):
@Niels Voss I don't understand why docs#geom_sum₂_mul doesn't solve all your problems? What are you trying to prove?
Kevin Buzzard (Dec 22 2022 at 01:40):
To get a + b ∣ a^n + b^n
for n
odd and a
, b
naturals, just prove it for integers and then observe that a natural divides another one iff the corresponding integer divides the other one.
Niels Voss (Dec 22 2022 at 01:42):
It does, I just thought that it would be nice if the lemmas were in a more convenient and library_search
friendly form for the rest of the library. If this isn't necessary, my PR could just use geom_sum₂_mul
directly.
Kevin Buzzard (Dec 22 2022 at 01:50):
I was just referring to the fact that you seemed to be re-proving results about (finset.range n).sum (λ (i : ℕ), (-1)^i * a ^ i * b ^ (n - 1 - i))
, which should not be necessary. You don't want to go there.
Niels Voss (Dec 22 2022 at 01:52):
Yeah, I don't really know why I was trying to do that (I guess I thought it would add something to algebra.geom_sum
?) but you are right that it isn't necessary for divisibility.
Niels Voss (Dec 22 2022 at 01:59):
Here's what I have so far:
theorem sub_dvd_pow_sub_pow [comm_ring α] (x y : α) (n : ℕ) : x - y ∣ x^n - y^n :=
dvd.intro_left _ (geom_sum₂_mul x y n)
theorem nat.sub_dvd_pow_sub_pow (x y n : ℕ) : x - y ∣ x^n - y^n :=
begin
cases le_or_lt y x with h,
{ have : y^n ≤ x^n := nat.pow_le_pow_of_le_left h _,
exact_mod_cast sub_dvd_pow_sub_pow (x : ℤ) ↑y n },
{ have : x^n ≤ y^n := nat.pow_le_pow_of_le_left h.le _,
exact (nat.sub_eq_zero_of_le this).symm ▸ dvd_zero (x - y) }
end
theorem odd.add_dvd_pow_add_pow [comm_ring α] (x y : α) {n : ℕ} (h : odd n) : x + y ∣ x^n + y^n :=
begin
have h₁ := geom_sum₂_mul x (-y) n,
rw [odd.neg_pow h y, sub_neg_eq_add, sub_neg_eq_add] at h₁,
exact dvd.intro_left _ h₁,
end
theorem nat.add_dvd_pow_add_pow_of_odd (x y : ℕ) {n : ℕ} (h : odd n) : x + y ∣ x^n + y^n :=
by exact_mod_cast odd.add_dvd_pow_add_pow (x : ℤ) ↑y h
I don't really know if I should change any of the names.
Kevin Buzzard (Dec 22 2022 at 02:07):
Nice!
import tactic
import algebra.geom_sum
variable {α : Type*}
for the #mwe
Niels Voss (Dec 22 2022 at 02:08):
Oh yeah, sorry I forgot to mention that this is in algebra/geom_sum.lean
(outside of any namespace though). It can be moved if needed.
Niels Voss (Dec 22 2022 at 02:26):
As a general guideline, is there always a space between x
and ^
in x ^ y
? Because I haven't always been adding them.
Kevin Buzzard (Dec 22 2022 at 03:05):
I always put them in, others often don't; it's a bit weird because usually there are concrete conventions for everything.
Martin Dvořák (Dec 24 2022 at 10:48):
I put them too.
Yaël Dillies (Dec 24 2022 at 12:49):
It is an infix operator. As such, it should get spaces around it. But this rule is loosely enforced.
Last updated: Dec 20 2023 at 11:08 UTC