Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

[Merged by Bors] - refactor(number_theory/padics/padic_norm): Switch nat and rat definitions #12454

Closed
wants to merge 61 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
65a410c
initial commit
BoltonBailey Mar 5, 2022
3b75911
remove unused lemma
BoltonBailey Mar 10, 2022
c578361
fix lemma
BoltonBailey Mar 10, 2022
24fe9a6
golfing
BoltonBailey Mar 10, 2022
27b5af4
revert change
BoltonBailey Mar 10, 2022
bb7bb90
golf
BoltonBailey Mar 10, 2022
14882a1
revert to pos
BoltonBailey Mar 10, 2022
5fed609
revert
BoltonBailey Mar 10, 2022
1a17933
remove old simplification
BoltonBailey Mar 10, 2022
ad6c6d7
golf
BoltonBailey Mar 10, 2022
9b3ba9f
Update src/number_theory/padics/padic_norm.lean
BoltonBailey Mar 10, 2022
3b8f6d5
Update src/number_theory/padics/padic_norm.lean
BoltonBailey Mar 10, 2022
f3be9eb
Update src/number_theory/padics/padic_norm.lean
BoltonBailey Mar 10, 2022
85b0e8d
Update src/number_theory/padics/padic_norm.lean
BoltonBailey Mar 10, 2022
ae586d5
Update src/number_theory/padics/padic_norm.lean
BoltonBailey Mar 10, 2022
b0387aa
Update src/number_theory/padics/padic_norm.lean
BoltonBailey Mar 10, 2022
9ded751
fix proof
BoltonBailey Mar 10, 2022
81ca3f3
Merge branch 'BoltonBailey/padic-val-nat-rat-switch' of github.com:le…
BoltonBailey Mar 10, 2022
b58ee9a
docs
BoltonBailey Mar 10, 2022
d72e09d
Merge branch 'master' of github.com:leanprover-community/mathlib into…
BoltonBailey Mar 10, 2022
e26cf1c
delete old version
BoltonBailey Mar 11, 2022
a0759e5
fix indent
BoltonBailey Mar 11, 2022
61e69b9
golfs
BoltonBailey Mar 11, 2022
ab16b3d
remove example
BoltonBailey Mar 11, 2022
9525be1
add johan's suggestion
BoltonBailey Mar 11, 2022
a776c8c
golf
BoltonBailey Mar 11, 2022
a4642e1
delete comment
BoltonBailey Mar 11, 2022
dfe0bb5
golf defn
BoltonBailey Mar 11, 2022
2cc1eed
golf
BoltonBailey Mar 11, 2022
b238113
more changes
BoltonBailey Mar 11, 2022
3ed868a
added API lemmas and golfed long proof
BoltonBailey Mar 11, 2022
a656b63
golfing
BoltonBailey Mar 12, 2022
6870e23
delete nat_cast_nat_abs
BoltonBailey Mar 12, 2022
149184a
Update src/ring_theory/multiplicity.lean
BoltonBailey Mar 12, 2022
5245086
fix line too long
BoltonBailey Mar 12, 2022
fe820e9
Merge branch 'BoltonBailey/padic-val-nat-rat-switch' of github.com:le…
BoltonBailey Mar 12, 2022
abf21f5
fix spaces
BoltonBailey Mar 12, 2022
6af5881
delete extraneous lemma
BoltonBailey Mar 12, 2022
f9b0bfc
trying to please simp linter
BoltonBailey Mar 12, 2022
978f0f2
Merge branch 'master' of github.com:leanprover-community/mathlib into…
BoltonBailey Mar 12, 2022
0799314
remove fixed todo about library_search
BoltonBailey Mar 12, 2022
df02270
experimenting with self
BoltonBailey Mar 12, 2022
283718b
simp only
BoltonBailey Mar 12, 2022
a5fae2f
golf
BoltonBailey Mar 12, 2022
281308b
golf
BoltonBailey Mar 12, 2022
807122d
minor cleanup
BoltonBailey Mar 19, 2022
b45e355
undo weird change
BoltonBailey Mar 19, 2022
5af66d3
undo simp
BoltonBailey Mar 21, 2022
947e15f
rearrange lemma
BoltonBailey Mar 21, 2022
d3f4042
Merge branch 'master' of github.com:leanprover-community/mathlib into…
BoltonBailey Mar 23, 2022
1327667
fix docstring
BoltonBailey Apr 3, 2022
a93bb74
delete duplicate lemma
BoltonBailey Apr 3, 2022
a55921d
add todos
BoltonBailey Apr 3, 2022
82170e1
Merge branch 'master' of github.com:leanprover-community/mathlib into…
BoltonBailey Apr 13, 2022
193a8b7
fix bug
BoltonBailey Apr 13, 2022
5ff0158
solve todos
BoltonBailey Apr 13, 2022
c3e1c59
no auto vars
BoltonBailey Apr 13, 2022
59514ab
remove unnecessary argument
BoltonBailey Apr 14, 2022
987b7ea
golf
BoltonBailey Apr 14, 2022
f05482b
golf
BoltonBailey Apr 14, 2022
a7c1379
Merge branch 'master' into BoltonBailey/padic-val-nat-rat-switch
BoltonBailey Apr 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 123 additions & 68 deletions src/number_theory/padics/padic_norm.lean
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,70 @@ open_locale rat

open multiplicity

def padic_val_nat (p : ℕ) (n : ℕ) : ℕ :=
if h : p ≠ 1 ∧ 0 < n
then (multiplicity p n).get (multiplicity.finite_nat_iff.2 h)
else 0

namespace padic_val_nat
open multiplicity
variables {p : ℕ}

/--
`padic_val_nat p 0` is 0 for any `p`.
-/
@[simp]
protected lemma zero : padic_val_nat p 0 = 0 :=
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
by simp [padic_val_nat]

/--
`padic_val_nat p 1` is 0 for any `p`.
-/
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
@[simp] protected lemma one : padic_val_nat p 1 = 0 :=
by unfold padic_val_nat; split_ifs; simp *

/--
For `p ≠ 0, p ≠ 1, `padic_val_rat p p` is 1.
-/
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
@[simp] lemma self (hp : 1 < p) : padic_val_nat p p = 1 :=
begin
have neq_one : (¬ p = 1) ↔ true,
{ exact iff_of_true ((ne_of_lt hp).symm) trivial, },
have eq_zero_false : (p = 0) ↔ false,
{ exact iff_false_intro ((ne_of_lt (trans zero_lt_one hp)).symm) },
simp [padic_val_nat, neq_one, eq_zero_false],
end

end padic_val_nat

def padic_val_int (p : ℕ) (z : ℤ) : ℕ :=
padic_val_nat p (z.nat_abs)
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved

namespace padic_val_int
open multiplicity
variables {p : ℕ}

/--
`padic_val_int p 0` is 0 for any `p`.
-/
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
@[simp]
protected lemma zero : padic_val_int p 0 = 0 :=
by simp [padic_val_int]

/--
`padic_val_int p 1` is 0 for any `p`.
-/
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
@[simp] protected lemma one : padic_val_int p 1 = 0 :=
by simp [padic_val_int]

/--
For `p ≠ 0, p ≠ 1, `padic_val_rat p p` is 1.
-/
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
@[simp] lemma self (hp : 1 < p) : padic_val_int p p = 1 :=
by simp [padic_val_int, padic_val_nat.self hp]

end padic_val_int

/--
For `p ≠ 1`, the p-adic valuation of an integer `z ≠ 0` is the largest natural number `n` such that
p^n divides z.
Expand All @@ -60,21 +124,7 @@ valuation of `q.denom`.
If `q = 0` or `p = 1`, then `padic_val_rat p q` defaults to 0.
-/
def padic_val_rat (p : ℕ) (q : ℚ) : ℤ :=
if h : q ≠ 0 ∧ p ≠ 1
then (multiplicity (p : ℤ) q.num).get
(multiplicity.finite_int_iff.2 ⟨h.2, rat.num_ne_zero_of_ne_zero h.1⟩) -
(multiplicity (p : ℤ) q.denom).get
(multiplicity.finite_int_iff.2 ⟨h.2, by exact_mod_cast rat.denom_ne_zero _⟩)
else 0

/--
A simplification of the definition of `padic_val_rat p q` when `q ≠ 0` and `p` is prime.
-/
lemma padic_val_rat_def (p : ℕ) [hp : fact p.prime] {q : ℚ} (hq : q ≠ 0) : padic_val_rat p q =
(multiplicity (p : ℤ) q.num).get (finite_int_iff.2 ⟨hp.1.ne_one, rat.num_ne_zero_of_ne_zero hq⟩) -
(multiplicity (p : ℤ) q.denom).get
(finite_int_iff.2 ⟨hp.1.ne_one, by exact_mod_cast rat.denom_ne_zero _⟩) :=
dif_pos ⟨hq, hp.1.ne_one⟩
padic_val_int p q.num - padic_val_nat p q.denom

namespace padic_val_rat
open multiplicity
Expand All @@ -84,49 +134,49 @@ variables {p : ℕ}
`padic_val_rat p q` is symmetric in `q`.
-/
@[simp] protected lemma neg (q : ℚ) : padic_val_rat p (-q) = padic_val_rat p q :=
begin
unfold padic_val_rat,
split_ifs,
{ simp [-add_comm]; refl },
{ exfalso, simp * at * },
{ exfalso, simp * at * },
{ refl }
end
by simp [padic_val_rat, padic_val_int]

/--
`padic_val_rat p 0` is 0 for any `p`.
-/
@[simp]
protected lemma zero (m : nat) : padic_val_rat m 0 = 0 := rfl
protected lemma zero (m : nat) : padic_val_rat m 0 = 0 := by simp [padic_val_rat, padic_val_int]

/--
`padic_val_rat p 1` is 0 for any `p`.
-/
@[simp] protected lemma one : padic_val_rat p 1 = 0 :=
by unfold padic_val_rat; split_ifs; simp *
@[simp] protected lemma one : padic_val_rat p 1 = 0 := by simp [padic_val_rat, padic_val_int]

/--
For `p ≠ 0, p ≠ 1, `padic_val_rat p p` is 1.
-/
@[simp] lemma padic_val_rat_self (hp : 1 < p) : padic_val_rat p p = 1 :=
by unfold padic_val_rat; split_ifs; simp [*, nat.one_lt_iff_ne_zero_and_ne_one] at *
begin
simp only [padic_val_rat, padic_val_int, rat.coe_nat_num, int.nat_abs_of_nat, rat.coe_nat_denom,
padic_val_nat.one, int.coe_nat_zero, sub_zero, padic_val_nat.self hp],
refl,
end

/--
The p-adic value of an integer `z ≠ 0` is the multiplicity of `p` in `z`.
-/
lemma padic_val_rat_of_int (z : ℤ) (hp : p ≠ 1) (hz : z ≠ 0) :
padic_val_rat p (z : ℚ) = (multiplicity (p : ℤ) z).get
(finite_int_iff.2 ⟨hp, hz⟩) :=
by rw [padic_val_rat, dif_pos]; simp *; refl
begin
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
rw [padic_val_rat, padic_val_int, padic_val_nat, padic_val_nat, dif_pos, dif_pos],
simp_rw multiplicity.int.nat_abs,
simp only [rat.coe_int_denom, int.coe_nat_zero, rat.coe_int_num, int.coe_nat_inj',
sub_zero, multiplicity.get_one_right],
refl,
simp [hp],
simp [hp],
apply nat.pos_of_ne_zero,
simp [hz],
end

end padic_val_rat

/--
A convenience function for the case of `padic_val_rat` when both inputs are natural numbers.
-/
def padic_val_nat (p : ℕ) (n : ℕ) : ℕ :=
int.to_nat (padic_val_rat p n)

section padic_val_nat

/--
Expand All @@ -135,48 +185,40 @@ this lemma ensures that the cast is well-behaved.
-/
lemma zero_le_padic_val_rat_of_nat (p n : ℕ) : 0 ≤ padic_val_rat p n :=
begin
unfold padic_val_rat,
split_ifs,
{ simp, },
{ trivial, },
unfold padic_val_rat padic_val_int padic_val_nat,
split_ifs; simp,
end

/--
`padic_val_rat` coincides with `padic_val_nat`.
-/
@[simp, norm_cast] lemma padic_val_rat_of_nat (p n : ℕ) :
↑(padic_val_nat p n) = padic_val_rat p n :=
begin
unfold padic_val_nat,
rw int.to_nat_of_nonneg (zero_le_padic_val_rat_of_nat p n),
end
by simp [padic_val_rat, padic_val_int]

/--
A simplification of `padic_val_nat` when one input is prime, by analogy with `padic_val_rat_def`.
-/
lemma padic_val_nat_def {p : ℕ} [hp : fact p.prime] {n : ℕ} (hn : n ≠ 0) :
lemma padic_val_nat_def {p : ℕ} [hp : fact p.prime] {n : ℕ} (hn : 0 < n) :
padic_val_nat p n =
(multiplicity p n).get
(multiplicity.finite_nat_iff.2 ⟨nat.prime.ne_one hp.1, bot_lt_iff_ne_bot.mpr hn⟩) :=
(multiplicity.finite_nat_iff.2 ⟨nat.prime.ne_one hp.1, hn⟩) :=
begin
have n_nonzero : (n : ℚ) ≠ 0, by simpa only [cast_eq_zero, ne.def],
-- Infinite loop with @simp padic_val_rat_of_nat unless we restrict the available lemmas here,
-- hence the very long list
simpa only
[ int.coe_nat_multiplicity p n, rat.coe_nat_denom n, (padic_val_rat_of_nat p n).symm,
int.coe_nat_zero, int.coe_nat_inj', sub_zero, get_one_right, int.coe_nat_succ, zero_add,
rat.coe_nat_num ]
using padic_val_rat_def p n_nonzero,
simp [padic_val_nat],
split_ifs,
{ refl, },
{ exfalso,
apply h ⟨(hp.out).ne_one, hn⟩, }
end

@[simp] lemma padic_val_nat_self (p : ℕ) [fact p.prime] : padic_val_nat p p = 1 :=
by simp [padic_val_nat_def (fact.out p.prime).ne_zero]
by simp [padic_val_nat_def (fact.out p.prime).pos]

lemma one_le_padic_val_nat_of_dvd
{n p : nat} [prime : fact p.prime] (nonzero : n ≠ 0) (div : p ∣ n) :
{n p : nat} [prime : fact p.prime] (n_pos : 0 < n) (div : p ∣ n) :
1 ≤ padic_val_nat p n :=
begin
rw @padic_val_nat_def _ prime _ nonzero,
rw @padic_val_nat_def _ prime _ n_pos,
let one_le_mul : _ ≤ multiplicity p n :=
@multiplicity.le_multiplicity_of_pow_dvd _ _ _ p n 1 (begin norm_num, exact div end),
simp only [nat.cast_one] at one_le_mul,
Expand All @@ -185,12 +227,6 @@ begin
solve_by_elim,
end

@[simp]
lemma padic_val_nat_zero (m : nat) : padic_val_nat m 0 = 0 := rfl

@[simp]
lemma padic_val_nat_one (m : nat) : padic_val_nat m 1 = 0 := by simp [padic_val_nat]

end padic_val_nat

namespace padic_val_rat
Expand All @@ -215,9 +251,27 @@ protected lemma defn {q : ℚ} {n d : ℤ} (hqz : q ≠ 0) (qdf : q = n /. d) :
have hn : n ≠ 0, from rat.mk_num_ne_zero_of_ne_zero hqz qdf,
have hd : d ≠ 0, from rat.mk_denom_ne_zero_of_ne_zero hqz qdf,
let ⟨c, hc1, hc2⟩ := rat.num_denom_mk hn hd qdf in
by rw [padic_val_rat, dif_pos];
begin
simp [hc1, hc2, multiplicity.mul' (nat.prime_iff_prime_int.1 p_prime.1),
(ne.symm (ne_of_lt p_prime.1.one_lt)), hqz]
(ne.symm (ne_of_lt p_prime.1.one_lt)), hqz],
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
rw [padic_val_rat, padic_val_int, padic_val_nat, padic_val_nat, dif_pos, dif_pos],
simp_rw [int.coe_nat_multiplicity p q.denom],
simp_rw multiplicity.int.nat_abs,
refl,
split,
{ exact nat.prime.ne_one p_prime.out, },
{ apply nat.pos_of_ne_zero,
intro hq,
simp [hq] at hc2,
exact hd hc2, },
split,
{ exact nat.prime.ne_one p_prime.out, },
{ apply nat.pos_of_ne_zero,
intro hq,
simp only [int.nat_abs_eq_zero] at hq,
simp [hq] at hc1,
exact hn hc1, },
end

/--
A rewrite lemma for `padic_val_rat p (q * r)` with conditions `q ≠ 0`, `r ≠ 0`.
Expand Down Expand Up @@ -415,7 +469,7 @@ lemma padic_val_nat_of_not_dvd {p : ℕ} [fact p.prime] {n : ℕ} (not_dvd : ¬(
begin
by_cases hn : n = 0,
{ subst hn, simp at not_dvd, trivial, },
{ rw padic_val_nat_def hn,
{ rw padic_val_nat_def (nat.pos_of_ne_zero hn),
exact (@multiplicity.unique' _ _ _ p n 0 (by simp) (by simpa using not_dvd)).symm,
assumption, },
end
Expand All @@ -434,7 +488,7 @@ begin
{ rw hn, exact dvd_zero (p ^ padic_val_nat p 0) },
{ rw multiplicity.pow_dvd_iff_le_multiplicity,
apply le_of_eq,
rw padic_val_nat_def (ne_of_gt hn),
rw padic_val_nat_def hn,
{ apply enat.coe_get },
{ apply_instance } }
end
Expand All @@ -443,10 +497,11 @@ lemma pow_succ_padic_val_nat_not_dvd {p n : ℕ} [hp : fact (nat.prime p)] (hn :
¬ p ^ (padic_val_nat p n + 1) ∣ n :=
begin
{ rw multiplicity.pow_dvd_iff_le_multiplicity,
rw padic_val_nat_def (ne_of_gt hn),
rw padic_val_nat_def hn,
{ rw [nat.cast_add, enat.coe_get],
simp only [nat.cast_one, not_le],
apply enat.lt_add_one (ne_top_iff_finite.2 (finite_nat_iff.2 ⟨hp.elim.ne_one, hn⟩)) },
exact enat.lt_add_one (ne_top_iff_finite.mpr
(finite_nat_iff.mpr ⟨(fact.elim hp).ne_one, hn⟩)), },
{ apply_instance } }
end

Expand Down Expand Up @@ -477,7 +532,7 @@ lemma padic_val_nat_eq_factorization (p n : ℕ) [hp : fact p.prime] :
padic_val_nat p n = n.factorization p :=
begin
by_cases hn : n = 0, { subst hn, simp },
rw @padic_val_nat_def p _ n hn,
rw @padic_val_nat_def p _ n (nat.pos_of_ne_zero hn),
simp [@multiplicity_eq_factorization n p hp.elim hn],
end

Expand Down
25 changes: 25 additions & 0 deletions src/ring_theory/multiplicity.lean
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ begin
apply _root_.le_antisymm; { apply nat.find_mono, norm_cast, simp } }
end

example (a b : ℤ) : a ∣ b ↔ a ∣ b.nat_abs := int.dvd_nat_abs.symm
BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved

theorem nat_cast_nat_abs (a b : ℕ) :
multiplicity a (b : ℤ).nat_abs = multiplicity (a : ℤ) (b : ℤ) :=
begin
apply part.ext',
{ repeat { rw [← finite_iff_dom, finite_def] },
norm_cast },
{ intros h1 h2,
apply _root_.le_antisymm; { apply nat.find_mono, norm_cast, simp } }
end

BoltonBailey marked this conversation as resolved.
Show resolved Hide resolved
lemma not_finite_iff_forall {a b : α} : (¬ finite a b) ↔ ∀ n : ℕ, a ^ n ∣ b :=
⟨λ h n, nat.cases_on n (by { rw pow_zero, exact one_dvd _ }) (by simpa [finite, not_not] using h),
by simp [finite, multiplicity, not_not]; tauto⟩
Expand Down Expand Up @@ -287,6 +299,19 @@ part.ext' (by simp only [multiplicity, enat.find, dvd_neg])
eq.symm (unique ((dvd_neg _ _).2 (pow_multiplicity_dvd _))
(mt (dvd_neg _ _).1 (is_greatest' _ (lt_succ_self _))))))

theorem int.nat_abs (a : ℕ) (b : ℤ) :
multiplicity a b.nat_abs = multiplicity (a : ℤ) b :=
begin
have h := @int.nat_abs_eq_iff b b.nat_abs,
simp only [true_iff, eq_self_iff_true] at h,
cases h,
{ conv_rhs { rw h },
apply nat_cast_nat_abs, },
{ conv_rhs { rw h },
rw multiplicity.neg,
apply nat_cast_nat_abs, },
end

lemma multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) :
multiplicity p (a + b) = multiplicity p b :=
begin
Expand Down