number_theory.sum_two_squares
⟷
Mathlib.NumberTheory.SumTwoSquares
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -156,7 +156,7 @@ theorem ZMod.isSquare_neg_one_iff' {n : ℕ} (hn : Squarefree n) :
· exact fun _ => by norm_num
· replace hp := H hp (dvd_of_mul_right_dvd hpq)
replace hq := hq (dvd_of_mul_left_dvd hpq)
- rw [show 3 = 3 % 4 by norm_num, Ne.def, ← ZMod.nat_cast_eq_nat_cast_iff'] at hp hq ⊢
+ rw [show 3 = 3 % 4 by norm_num, Ne.def, ← ZMod.natCast_eq_natCast_iff'] at hp hq ⊢
rw [Nat.cast_mul]
exact help p q hp hq
#align zmod.is_square_neg_one_iff' ZMod.isSquare_neg_one_iff'
@@ -199,7 +199,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
refine' ⟨u * y, _⟩
norm_cast
rw [(by push_cast : (-1 : ZMod n.nat_abs) = (-1 : ℤ))]
- exact (ZMod.int_cast_eq_int_cast_iff_dvd_sub _ _ _).mpr (int.nat_abs_dvd.mpr ⟨_, H⟩)
+ exact (ZMod.intCast_eq_intCast_iff_dvd_sub _ _ _).mpr (int.nat_abs_dvd.mpr ⟨_, H⟩)
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_is_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -66,7 +66,7 @@ theorem Nat.sq_add_sq_mul {a b x y u v : ℕ} (ha : a = x ^ 2 + y ^ 2) (hb : b =
zify at ha hb ⊢
obtain ⟨r, s, h⟩ := sq_add_sq_mul ha hb
refine' ⟨r.nat_abs, s.nat_abs, _⟩
- simpa only [Int.coe_natAbs, sq_abs]
+ simpa only [Int.natCast_natAbs, sq_abs]
#align nat.sq_add_sq_mul Nat.sq_add_sq_mul
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -116,7 +116,7 @@ theorem Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one {p n : ℕ} (hpp : p
(hs : IsSquare (-1 : ZMod n)) : p % 4 ≠ 3 :=
by
obtain ⟨y, h⟩ := ZMod.isSquare_neg_one_of_dvd hp hs
- rw [← sq, eq_comm, show (-1 : ZMod p) = -1 ^ 2 by ring] at h
+ rw [← sq, eq_comm, show (-1 : ZMod p) = -1 ^ 2 by ring] at h
haveI : Fact p.prime := ⟨hpp⟩
exact ZMod.mod_four_ne_three_of_sq_eq_neg_sq' one_ne_zero h
#align nat.prime.mod_four_ne_three_of_dvd_is_square_neg_one Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one
@@ -192,7 +192,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
obtain ⟨u, v, huv⟩ : IsCoprime x n :=
by
have hc2 : IsCoprime (x ^ 2) (y ^ 2) := hc.pow
- rw [show y ^ 2 = n + -1 * x ^ 2 by rw [h]; ring] at hc2
+ rw [show y ^ 2 = n + -1 * x ^ 2 by rw [h]; ring] at hc2
exact (IsCoprime.pow_left_iff zero_lt_two).mp hc2.of_add_mul_right_right
have H : u * y * (u * y) - -1 = n * (-v ^ 2 * n + u ^ 2 + 2 * v) := by
linear_combination -u ^ 2 * h + (n * v - u * x - 1) * huv
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -37,7 +37,7 @@ theorem Nat.Prime.sq_add_sq {p : ℕ} [Fact p.Prime] (hp : p % 4 ≠ 3) :
∃ a b : ℕ, a ^ 2 + b ^ 2 = p :=
by
apply sq_add_sq_of_nat_prime_of_not_irreducible p
- rwa [PrincipalIdealRing.irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p]
+ rwa [irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p]
#align nat.prime.sq_add_sq Nat.Prime.sq_add_sq
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -276,7 +276,7 @@ theorem Nat.eq_sq_add_sq_iff {n : ℕ} :
refine' nat.odd_iff_not_even.mp _ (H hqp hq4)
have hqb' : padicValNat q b = 1 :=
b.factorization_def hqp ▸
- le_antisymm (Nat.Squarefree.factorization_le_one _ hb)
+ le_antisymm (Squarefree.natFactorization_le_one _ hb)
((hqp.dvd_iff_one_le_factorization hb₀.ne').mp hqb)
haveI hqi : Fact q.prime := ⟨hqp⟩
simp_rw [← hab, padicValNat.mul (pow_ne_zero 2 ha₀.ne') hb₀.ne', hqb',
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,8 +3,8 @@ Copyright (c) 2019 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Michael Stoll
-/
-import Mathbin.NumberTheory.Zsqrtd.QuadraticReciprocity
-import Mathbin.Tactic.LinearCombination
+import NumberTheory.Zsqrtd.QuadraticReciprocity
+import Tactic.LinearCombination
#align_import number_theory.sum_two_squares from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -96,7 +96,7 @@ theorem ZMod.isSquare_neg_one_of_dvd {m n : ℕ} (hd : m ∣ n) (hs : IsSquare (
#print ZMod.isSquare_neg_one_mul /-
/-- If `-1` is a square modulo coprime natural numbers `m` and `n`, then `-1` is also
a square modulo `m*n`. -/
-theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare (-1 : ZMod m))
+theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.Coprime n) (hm : IsSquare (-1 : ZMod m))
(hn : IsSquare (-1 : ZMod n)) : IsSquare (-1 : ZMod (m * n)) :=
by
have : IsSquare (-1 : ZMod m × ZMod n) :=
@@ -207,7 +207,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
`-1` is a square modulo `n`. -/
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
- (hc : x.coprime y) : IsSquare (-1 : ZMod n) :=
+ (hc : x.Coprime y) : IsSquare (-1 : ZMod n) :=
by
zify at *
exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.is_coprime
mathlib commit https://github.com/leanprover-community/mathlib/commit/63721b2c3eba6c325ecf8ae8cca27155a4f6306f
@@ -131,7 +131,7 @@ theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
refine' ⟨fun H q hqp hqd => hqp.mod_four_ne_three_of_dvd_isSquare_neg_one hqd H, fun H => _⟩
induction' n using induction_on_primes with p n hpp ih
· exact False.elim (hn.ne_zero rfl)
- · exact ⟨0, by simp only [Fin.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩
+ · exact ⟨0, by simp only [Fin.zero_mul', neg_eq_zero, Fin.one_eq_zero_iff]⟩
· haveI : Fact p.prime := ⟨hpp⟩
have hcp : p.coprime n := by
by_contra hc
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,15 +2,12 @@
Copyright (c) 2019 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Michael Stoll
-
-! This file was ported from Lean 3 source module number_theory.sum_two_squares
-! leanprover-community/mathlib commit 08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.NumberTheory.Zsqrtd.QuadraticReciprocity
import Mathbin.Tactic.LinearCombination
+#align_import number_theory.sum_two_squares from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
+
/-!
# Sums of two squares
mathlib commit https://github.com/leanprover-community/mathlib/commit/9240e8be927a0955b9a82c6c85ef499ee3a626b8
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Michael Stoll
! This file was ported from Lean 3 source module number_theory.sum_two_squares
-! leanprover-community/mathlib commit 5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9
+! leanprover-community/mathlib commit 08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -14,6 +14,9 @@ import Mathbin.Tactic.LinearCombination
/-!
# Sums of two squares
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
Fermat's theorem on the sum of two squares. Every prime `p` congruent to 1 mod 4 is the
sum of two squares; see `nat.prime.sq_add_sq` (which has the weaker assumption `p % 4 ≠ 3`).
mathlib commit https://github.com/leanprover-community/mathlib/commit/fdc286cc6967a012f41b87f76dcd2797b53152af
@@ -30,6 +30,7 @@ section Fermat
open GaussianInt
+#print Nat.Prime.sq_add_sq /-
/-- **Fermat's theorem on the sum of two squares**. Every prime not congruent to 3 mod 4 is the sum
of two squares. Also known as **Fermat's Christmas theorem**. -/
theorem Nat.Prime.sq_add_sq {p : ℕ} [Fact p.Prime] (hp : p % 4 ≠ 3) :
@@ -38,6 +39,7 @@ theorem Nat.Prime.sq_add_sq {p : ℕ} [Fact p.Prime] (hp : p % 4 ≠ 3) :
apply sq_add_sq_of_nat_prime_of_not_irreducible p
rwa [PrincipalIdealRing.irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p]
#align nat.prime.sq_add_sq Nat.Prime.sq_add_sq
+-/
end Fermat
@@ -48,13 +50,16 @@ end Fermat
section General
+#print sq_add_sq_mul /-
/-- The set of sums of two squares is closed under multiplication in any commutative ring.
See also `sq_add_sq_mul_sq_add_sq`. -/
theorem sq_add_sq_mul {R} [CommRing R] {a b x y u v : R} (ha : a = x ^ 2 + y ^ 2)
(hb : b = u ^ 2 + v ^ 2) : ∃ r s : R, a * b = r ^ 2 + s ^ 2 :=
⟨x * u - y * v, x * v + y * u, by rw [ha, hb]; ring⟩
#align sq_add_sq_mul sq_add_sq_mul
+-/
+#print Nat.sq_add_sq_mul /-
/-- The set of natural numbers that are sums of two squares is closed under multiplication. -/
theorem Nat.sq_add_sq_mul {a b x y u v : ℕ} (ha : a = x ^ 2 + y ^ 2) (hb : b = u ^ 2 + v ^ 2) :
∃ r s : ℕ, a * b = r ^ 2 + s ^ 2 := by
@@ -63,6 +68,7 @@ theorem Nat.sq_add_sq_mul {a b x y u v : ℕ} (ha : a = x ^ 2 + y ^ 2) (hb : b =
refine' ⟨r.nat_abs, s.nat_abs, _⟩
simpa only [Int.coe_natAbs, sq_abs]
#align nat.sq_add_sq_mul Nat.sq_add_sq_mul
+-/
end General
@@ -73,6 +79,7 @@ end General
section NegOneSquare
+#print ZMod.isSquare_neg_one_of_dvd /-
-- This could be formulated for a general integer `a` in place of `-1`,
-- but it would not directly specialize to `-1`,
-- because `((-1 : ℤ) : zmod n)` is not the same as `(-1 : zmod n)`.
@@ -84,7 +91,9 @@ theorem ZMod.isSquare_neg_one_of_dvd {m n : ℕ} (hd : m ∣ n) (hs : IsSquare (
rw [← RingHom.map_one f, ← RingHom.map_neg]
exact hs.map f
#align zmod.is_square_neg_one_of_dvd ZMod.isSquare_neg_one_of_dvd
+-/
+#print ZMod.isSquare_neg_one_mul /-
/-- If `-1` is a square modulo coprime natural numbers `m` and `n`, then `-1` is also
a square modulo `m*n`. -/
theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare (-1 : ZMod m))
@@ -99,7 +108,9 @@ theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare
exact ⟨(x, y), rfl⟩
simpa only [RingEquiv.map_neg_one] using this.map (ZMod.chineseRemainder hc).symm
#align zmod.is_square_neg_one_mul ZMod.isSquare_neg_one_mul
+-/
+#print Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one /-
/-- If a prime `p` divides `n` such that `-1` is a square modulo `n`, then `p % 4 ≠ 3`. -/
theorem Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one {p n : ℕ} (hpp : p.Prime) (hp : p ∣ n)
(hs : IsSquare (-1 : ZMod n)) : p % 4 ≠ 3 :=
@@ -109,7 +120,9 @@ theorem Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one {p n : ℕ} (hpp : p
haveI : Fact p.prime := ⟨hpp⟩
exact ZMod.mod_four_ne_three_of_sq_eq_neg_sq' one_ne_zero h
#align nat.prime.mod_four_ne_three_of_dvd_is_square_neg_one Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one
+-/
+#print ZMod.isSquare_neg_one_iff /-
/-- If `n` is a squarefree natural number, then `-1` is a square modulo `n` if and only if
`n` is not divisible by a prime `q` such that `q % 4 = 3`. -/
theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
@@ -128,7 +141,9 @@ theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
ZMod.isSquare_neg_one_mul hcp hp₁
(ih hn.of_mul_right fun q hqp hqd => H hqp <| dvd_mul_of_dvd_right hqd _)
#align zmod.is_square_neg_one_iff ZMod.isSquare_neg_one_iff
+-/
+#print ZMod.isSquare_neg_one_iff' /-
/-- If `n` is a squarefree natural number, then `-1` is a square modulo `n` if and only if
`n` has no divisor `q` that is `≡ 3 mod 4`. -/
theorem ZMod.isSquare_neg_one_iff' {n : ℕ} (hn : Squarefree n) :
@@ -145,12 +160,14 @@ theorem ZMod.isSquare_neg_one_iff' {n : ℕ} (hn : Squarefree n) :
rw [Nat.cast_mul]
exact help p q hp hq
#align zmod.is_square_neg_one_iff' ZMod.isSquare_neg_one_iff'
+-/
/-!
### Relation to sums of two squares
-/
+#print Nat.eq_sq_add_sq_of_isSquare_mod_neg_one /-
/-- If `-1` is a square modulo the natural number `n`, then `n` is a sum of two squares. -/
theorem Nat.eq_sq_add_sq_of_isSquare_mod_neg_one {n : ℕ} (h : IsSquare (-1 : ZMod n)) :
∃ x y : ℕ, n = x ^ 2 + y ^ 2 :=
@@ -164,7 +181,9 @@ theorem Nat.eq_sq_add_sq_of_isSquare_mod_neg_one {n : ℕ} (h : IsSquare (-1 : Z
obtain ⟨x, y, hxy⟩ := ih (ZMod.isSquare_neg_one_of_dvd ⟨p, mul_comm _ _⟩ h)
exact Nat.sq_add_sq_mul huv.symm hxy
#align nat.eq_sq_add_sq_of_is_square_mod_neg_one Nat.eq_sq_add_sq_of_isSquare_mod_neg_one
+-/
+#print ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime /-
/-- If the integer `n` is a sum of two squares of coprime integers,
then `-1` is a square modulo `n`. -/
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n = x ^ 2 + y ^ 2)
@@ -182,7 +201,9 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
rw [(by push_cast : (-1 : ZMod n.nat_abs) = (-1 : ℤ))]
exact (ZMod.int_cast_eq_int_cast_iff_dvd_sub _ _ _).mpr (int.nat_abs_dvd.mpr ⟨_, H⟩)
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_is_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime
+-/
+#print ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime /-
/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
`-1` is a square modulo `n`. -/
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
@@ -191,7 +212,9 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n =
zify at *
exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.is_coprime
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime
+-/
+#print Nat.eq_sq_add_sq_iff_eq_sq_mul /-
/-- A natural number `n` is a sum of two squares if and only if `n = a^2 * b` with natural
numbers `a` and `b` such that `-1` is a square modulo `b`. -/
theorem Nat.eq_sq_add_sq_iff_eq_sq_mul {n : ℕ} :
@@ -213,6 +236,7 @@ theorem Nat.eq_sq_add_sq_iff_eq_sq_mul {n : ℕ} :
obtain ⟨x', y', h⟩ := Nat.eq_sq_add_sq_of_isSquare_mod_neg_one h₂
exact ⟨a * x', a * y', by rw [h₁, h]; ring⟩
#align nat.eq_sq_add_sq_iff_eq_sq_mul Nat.eq_sq_add_sq_iff_eq_sq_mul
+-/
end NegOneSquare
@@ -223,6 +247,7 @@ end NegOneSquare
section Main
+#print Nat.eq_sq_add_sq_iff /-
/-- A (positive) natural number `n` is a sum of two squares if and only if the exponent of
every prime `q` such that `q % 4 = 3` in the prime factorization of `n` is even.
(The assumption `0 < n` is not present, since for `n = 0`, both sides are satisfied;
@@ -258,6 +283,7 @@ theorem Nat.eq_sq_add_sq_iff {n : ℕ} :
padicValNat.pow 2 ha₀.ne']
exact odd_two_mul_add_one _
#align nat.eq_sq_add_sq_iff Nat.eq_sq_add_sq_iff
+-/
end Main
mathlib commit https://github.com/leanprover-community/mathlib/commit/893964fc28cefbcffc7cb784ed00a2895b4e65cf
@@ -4,11 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Michael Stoll
! This file was ported from Lean 3 source module number_theory.sum_two_squares
-! leanprover-community/mathlib commit 34ebaffc1d1e8e783fc05438ec2e70af87275ac9
+! leanprover-community/mathlib commit 5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
-import Mathbin.NumberTheory.Zsqrtd.GaussianInt
+import Mathbin.NumberTheory.Zsqrtd.QuadraticReciprocity
import Mathbin.Tactic.LinearCombination
/-!
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -58,7 +58,7 @@ theorem sq_add_sq_mul {R} [CommRing R] {a b x y u v : R} (ha : a = x ^ 2 + y ^ 2
/-- The set of natural numbers that are sums of two squares is closed under multiplication. -/
theorem Nat.sq_add_sq_mul {a b x y u v : ℕ} (ha : a = x ^ 2 + y ^ 2) (hb : b = u ^ 2 + v ^ 2) :
∃ r s : ℕ, a * b = r ^ 2 + s ^ 2 := by
- zify at ha hb ⊢
+ zify at ha hb ⊢
obtain ⟨r, s, h⟩ := sq_add_sq_mul ha hb
refine' ⟨r.nat_abs, s.nat_abs, _⟩
simpa only [Int.coe_natAbs, sq_abs]
@@ -188,7 +188,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
(hc : x.coprime y) : IsSquare (-1 : ZMod n) :=
by
- zify at *
+ zify at *
exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.is_coprime
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime
mathlib commit https://github.com/leanprover-community/mathlib/commit/34ebaffc1d1e8e783fc05438ec2e70af87275ac9
@@ -1,37 +1,263 @@
/-
Copyright (c) 2019 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
-Authors: Chris Hughes
+Authors: Chris Hughes, Michael Stoll
! This file was ported from Lean 3 source module number_theory.sum_two_squares
-! leanprover-community/mathlib commit 9101c48bb8cbb6a683d0afd58f8d521a16bd6eea
+! leanprover-community/mathlib commit 34ebaffc1d1e8e783fc05438ec2e70af87275ac9
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.NumberTheory.Zsqrtd.GaussianInt
+import Mathbin.Tactic.LinearCombination
/-!
# Sums of two squares
-Proof of Fermat's theorem on the sum of two squares. Every prime congruent to 1 mod 4 is the sum
-of two squares.
+Fermat's theorem on the sum of two squares. Every prime `p` congruent to 1 mod 4 is the
+sum of two squares; see `nat.prime.sq_add_sq` (which has the weaker assumption `p % 4 ≠ 3`).
-# Todo
+We also give the result that characterizes the (positive) natural numbers that are sums
+of two squares as those numbers `n` such that for every prime `q` congruent to 3 mod 4, the
+exponent of the largest power of `q` dividing `n` is even; see `nat.eq_sq_add_sq_iff`.
-Fully characterize the natural numbers that are the sum of two squares: those such that for every
-prime p congruent to 3 mod 4, the largest power of p dividing them is even.
+There is an alternative characterization as the numbers of the form `a^2 * b`, where `b` is a
+natural number such that `-1` is a square modulo `b`; see `nat.eq_sq_add_sq_iff_eq_sq_mul`.
-/
+section Fermat
+
open GaussianInt
-/-- **Fermat's theorem on the sum of two squares**. Every prime congruent to 1 mod 4 is the sum
+/-- **Fermat's theorem on the sum of two squares**. Every prime not congruent to 3 mod 4 is the sum
of two squares. Also known as **Fermat's Christmas theorem**. -/
-theorem Nat.Prime.sq_add_sq {p : ℕ} [Fact p.Prime] (hp : p % 4 = 1) :
+theorem Nat.Prime.sq_add_sq {p : ℕ} [Fact p.Prime] (hp : p % 4 ≠ 3) :
∃ a b : ℕ, a ^ 2 + b ^ 2 = p :=
by
apply sq_add_sq_of_nat_prime_of_not_irreducible p
- rw [PrincipalIdealRing.irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p, hp]
- norm_num
+ rwa [PrincipalIdealRing.irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p]
#align nat.prime.sq_add_sq Nat.Prime.sq_add_sq
+end Fermat
+
+/-!
+### Generalities on sums of two squares
+-/
+
+
+section General
+
+/-- The set of sums of two squares is closed under multiplication in any commutative ring.
+See also `sq_add_sq_mul_sq_add_sq`. -/
+theorem sq_add_sq_mul {R} [CommRing R] {a b x y u v : R} (ha : a = x ^ 2 + y ^ 2)
+ (hb : b = u ^ 2 + v ^ 2) : ∃ r s : R, a * b = r ^ 2 + s ^ 2 :=
+ ⟨x * u - y * v, x * v + y * u, by rw [ha, hb]; ring⟩
+#align sq_add_sq_mul sq_add_sq_mul
+
+/-- The set of natural numbers that are sums of two squares is closed under multiplication. -/
+theorem Nat.sq_add_sq_mul {a b x y u v : ℕ} (ha : a = x ^ 2 + y ^ 2) (hb : b = u ^ 2 + v ^ 2) :
+ ∃ r s : ℕ, a * b = r ^ 2 + s ^ 2 := by
+ zify at ha hb ⊢
+ obtain ⟨r, s, h⟩ := sq_add_sq_mul ha hb
+ refine' ⟨r.nat_abs, s.nat_abs, _⟩
+ simpa only [Int.coe_natAbs, sq_abs]
+#align nat.sq_add_sq_mul Nat.sq_add_sq_mul
+
+end General
+
+/-!
+### Results on when -1 is a square modulo a natural number
+-/
+
+
+section NegOneSquare
+
+-- This could be formulated for a general integer `a` in place of `-1`,
+-- but it would not directly specialize to `-1`,
+-- because `((-1 : ℤ) : zmod n)` is not the same as `(-1 : zmod n)`.
+/-- If `-1` is a square modulo `n` and `m` divides `n`, then `-1` is also a square modulo `m`. -/
+theorem ZMod.isSquare_neg_one_of_dvd {m n : ℕ} (hd : m ∣ n) (hs : IsSquare (-1 : ZMod n)) :
+ IsSquare (-1 : ZMod m) :=
+ by
+ let f : ZMod n →+* ZMod m := ZMod.castHom hd _
+ rw [← RingHom.map_one f, ← RingHom.map_neg]
+ exact hs.map f
+#align zmod.is_square_neg_one_of_dvd ZMod.isSquare_neg_one_of_dvd
+
+/-- If `-1` is a square modulo coprime natural numbers `m` and `n`, then `-1` is also
+a square modulo `m*n`. -/
+theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare (-1 : ZMod m))
+ (hn : IsSquare (-1 : ZMod n)) : IsSquare (-1 : ZMod (m * n)) :=
+ by
+ have : IsSquare (-1 : ZMod m × ZMod n) :=
+ by
+ rw [show (-1 : ZMod m × ZMod n) = ((-1 : ZMod m), (-1 : ZMod n)) from rfl]
+ obtain ⟨x, hx⟩ := hm
+ obtain ⟨y, hy⟩ := hn
+ rw [hx, hy]
+ exact ⟨(x, y), rfl⟩
+ simpa only [RingEquiv.map_neg_one] using this.map (ZMod.chineseRemainder hc).symm
+#align zmod.is_square_neg_one_mul ZMod.isSquare_neg_one_mul
+
+/-- If a prime `p` divides `n` such that `-1` is a square modulo `n`, then `p % 4 ≠ 3`. -/
+theorem Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one {p n : ℕ} (hpp : p.Prime) (hp : p ∣ n)
+ (hs : IsSquare (-1 : ZMod n)) : p % 4 ≠ 3 :=
+ by
+ obtain ⟨y, h⟩ := ZMod.isSquare_neg_one_of_dvd hp hs
+ rw [← sq, eq_comm, show (-1 : ZMod p) = -1 ^ 2 by ring] at h
+ haveI : Fact p.prime := ⟨hpp⟩
+ exact ZMod.mod_four_ne_three_of_sq_eq_neg_sq' one_ne_zero h
+#align nat.prime.mod_four_ne_three_of_dvd_is_square_neg_one Nat.Prime.mod_four_ne_three_of_dvd_isSquare_neg_one
+
+/-- If `n` is a squarefree natural number, then `-1` is a square modulo `n` if and only if
+`n` is not divisible by a prime `q` such that `q % 4 = 3`. -/
+theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
+ IsSquare (-1 : ZMod n) ↔ ∀ {q : ℕ}, q.Prime → q ∣ n → q % 4 ≠ 3 :=
+ by
+ refine' ⟨fun H q hqp hqd => hqp.mod_four_ne_three_of_dvd_isSquare_neg_one hqd H, fun H => _⟩
+ induction' n using induction_on_primes with p n hpp ih
+ · exact False.elim (hn.ne_zero rfl)
+ · exact ⟨0, by simp only [Fin.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩
+ · haveI : Fact p.prime := ⟨hpp⟩
+ have hcp : p.coprime n := by
+ by_contra hc
+ exact hpp.not_unit (hn p <| mul_dvd_mul_left p <| hpp.dvd_iff_not_coprime.mpr hc)
+ have hp₁ := zmod.exists_sq_eq_neg_one_iff.mpr (H hpp (dvd_mul_right p n))
+ exact
+ ZMod.isSquare_neg_one_mul hcp hp₁
+ (ih hn.of_mul_right fun q hqp hqd => H hqp <| dvd_mul_of_dvd_right hqd _)
+#align zmod.is_square_neg_one_iff ZMod.isSquare_neg_one_iff
+
+/-- If `n` is a squarefree natural number, then `-1` is a square modulo `n` if and only if
+`n` has no divisor `q` that is `≡ 3 mod 4`. -/
+theorem ZMod.isSquare_neg_one_iff' {n : ℕ} (hn : Squarefree n) :
+ IsSquare (-1 : ZMod n) ↔ ∀ {q : ℕ}, q ∣ n → q % 4 ≠ 3 :=
+ by
+ have help : ∀ a b : ZMod 4, a ≠ 3 → b ≠ 3 → a * b ≠ 3 := by decide
+ rw [ZMod.isSquare_neg_one_iff hn]
+ refine' ⟨fun H => induction_on_primes _ _ fun p q hp hq hpq => _, fun H q hq₁ => H⟩
+ · exact fun _ => by norm_num
+ · exact fun _ => by norm_num
+ · replace hp := H hp (dvd_of_mul_right_dvd hpq)
+ replace hq := hq (dvd_of_mul_left_dvd hpq)
+ rw [show 3 = 3 % 4 by norm_num, Ne.def, ← ZMod.nat_cast_eq_nat_cast_iff'] at hp hq ⊢
+ rw [Nat.cast_mul]
+ exact help p q hp hq
+#align zmod.is_square_neg_one_iff' ZMod.isSquare_neg_one_iff'
+
+/-!
+### Relation to sums of two squares
+-/
+
+
+/-- If `-1` is a square modulo the natural number `n`, then `n` is a sum of two squares. -/
+theorem Nat.eq_sq_add_sq_of_isSquare_mod_neg_one {n : ℕ} (h : IsSquare (-1 : ZMod n)) :
+ ∃ x y : ℕ, n = x ^ 2 + y ^ 2 :=
+ by
+ induction' n using induction_on_primes with p n hpp ih
+ · exact ⟨0, 0, rfl⟩
+ · exact ⟨0, 1, rfl⟩
+ · haveI : Fact p.prime := ⟨hpp⟩
+ have hp : IsSquare (-1 : ZMod p) := ZMod.isSquare_neg_one_of_dvd ⟨n, rfl⟩ h
+ obtain ⟨u, v, huv⟩ := Nat.Prime.sq_add_sq (zmod.exists_sq_eq_neg_one_iff.mp hp)
+ obtain ⟨x, y, hxy⟩ := ih (ZMod.isSquare_neg_one_of_dvd ⟨p, mul_comm _ _⟩ h)
+ exact Nat.sq_add_sq_mul huv.symm hxy
+#align nat.eq_sq_add_sq_of_is_square_mod_neg_one Nat.eq_sq_add_sq_of_isSquare_mod_neg_one
+
+/-- If the integer `n` is a sum of two squares of coprime integers,
+then `-1` is a square modulo `n`. -/
+theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n = x ^ 2 + y ^ 2)
+ (hc : IsCoprime x y) : IsSquare (-1 : ZMod n.natAbs) :=
+ by
+ obtain ⟨u, v, huv⟩ : IsCoprime x n :=
+ by
+ have hc2 : IsCoprime (x ^ 2) (y ^ 2) := hc.pow
+ rw [show y ^ 2 = n + -1 * x ^ 2 by rw [h]; ring] at hc2
+ exact (IsCoprime.pow_left_iff zero_lt_two).mp hc2.of_add_mul_right_right
+ have H : u * y * (u * y) - -1 = n * (-v ^ 2 * n + u ^ 2 + 2 * v) := by
+ linear_combination -u ^ 2 * h + (n * v - u * x - 1) * huv
+ refine' ⟨u * y, _⟩
+ norm_cast
+ rw [(by push_cast : (-1 : ZMod n.nat_abs) = (-1 : ℤ))]
+ exact (ZMod.int_cast_eq_int_cast_iff_dvd_sub _ _ _).mpr (int.nat_abs_dvd.mpr ⟨_, H⟩)
+#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_is_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime
+
+/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
+`-1` is a square modulo `n`. -/
+theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
+ (hc : x.coprime y) : IsSquare (-1 : ZMod n) :=
+ by
+ zify at *
+ exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.is_coprime
+#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime
+
+/-- A natural number `n` is a sum of two squares if and only if `n = a^2 * b` with natural
+numbers `a` and `b` such that `-1` is a square modulo `b`. -/
+theorem Nat.eq_sq_add_sq_iff_eq_sq_mul {n : ℕ} :
+ (∃ x y : ℕ, n = x ^ 2 + y ^ 2) ↔ ∃ a b : ℕ, n = a ^ 2 * b ∧ IsSquare (-1 : ZMod b) :=
+ by
+ constructor
+ · rintro ⟨x, y, h⟩
+ by_cases hxy : x = 0 ∧ y = 0
+ ·
+ exact
+ ⟨0, 1, by rw [h, hxy.1, hxy.2, zero_pow zero_lt_two, add_zero, MulZeroClass.zero_mul],
+ ⟨0, by rw [MulZeroClass.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩⟩
+ · have hg := Nat.pos_of_ne_zero (mt nat.gcd_eq_zero_iff.mp hxy)
+ obtain ⟨g, x₁, y₁, h₁, h₂, h₃, h₄⟩ := Nat.exists_coprime' hg
+ exact
+ ⟨g, x₁ ^ 2 + y₁ ^ 2, by rw [h, h₃, h₄]; ring,
+ ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime rfl h₂⟩
+ · rintro ⟨a, b, h₁, h₂⟩
+ obtain ⟨x', y', h⟩ := Nat.eq_sq_add_sq_of_isSquare_mod_neg_one h₂
+ exact ⟨a * x', a * y', by rw [h₁, h]; ring⟩
+#align nat.eq_sq_add_sq_iff_eq_sq_mul Nat.eq_sq_add_sq_iff_eq_sq_mul
+
+end NegOneSquare
+
+/-!
+### Characterization in terms of the prime factorization
+-/
+
+
+section Main
+
+/-- A (positive) natural number `n` is a sum of two squares if and only if the exponent of
+every prime `q` such that `q % 4 = 3` in the prime factorization of `n` is even.
+(The assumption `0 < n` is not present, since for `n = 0`, both sides are satisfied;
+the right hand side holds, since `padic_val_nat q 0 = 0` by definition.) -/
+theorem Nat.eq_sq_add_sq_iff {n : ℕ} :
+ (∃ x y : ℕ, n = x ^ 2 + y ^ 2) ↔ ∀ {q : ℕ}, q.Prime → q % 4 = 3 → Even (padicValNat q n) :=
+ by
+ rcases n.eq_zero_or_pos with (rfl | hn₀)
+ · exact ⟨fun H q hq h => (@padicValNat.zero q).symm ▸ even_zero, fun H => ⟨0, 0, rfl⟩⟩
+ -- now `0 < n`
+ rw [Nat.eq_sq_add_sq_iff_eq_sq_mul]
+ refine' ⟨fun H q hq h => _, fun H => _⟩
+ · obtain ⟨a, b, h₁, h₂⟩ := H
+ have hqb :=
+ padicValNat.eq_zero_of_not_dvd fun hf =>
+ (hq.mod_four_ne_three_of_dvd_is_square_neg_one hf h₂) h
+ have hab : a ^ 2 * b ≠ 0 := h₁ ▸ hn₀.ne'
+ have ha₂ := left_ne_zero_of_mul hab
+ have ha := mt sq_eq_zero_iff.mpr ha₂
+ have hb := right_ne_zero_of_mul hab
+ haveI hqi : Fact q.prime := ⟨hq⟩
+ simp_rw [h₁, padicValNat.mul ha₂ hb, padicValNat.pow 2 ha, hqb, add_zero]
+ exact even_two_mul _
+ · obtain ⟨b, a, hb₀, ha₀, hab, hb⟩ := Nat.sq_mul_squarefree_of_pos hn₀
+ refine' ⟨a, b, hab.symm, (ZMod.isSquare_neg_one_iff hb).mpr fun q hqp hqb hq4 => _⟩
+ refine' nat.odd_iff_not_even.mp _ (H hqp hq4)
+ have hqb' : padicValNat q b = 1 :=
+ b.factorization_def hqp ▸
+ le_antisymm (Nat.Squarefree.factorization_le_one _ hb)
+ ((hqp.dvd_iff_one_le_factorization hb₀.ne').mp hqb)
+ haveI hqi : Fact q.prime := ⟨hqp⟩
+ simp_rw [← hab, padicValNat.mul (pow_ne_zero 2 ha₀.ne') hb₀.ne', hqb',
+ padicValNat.pow 2 ha₀.ne']
+ exact odd_two_mul_add_one _
+#align nat.eq_sq_add_sq_iff Nat.eq_sq_add_sq_iff
+
+end Main
+
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
nat_cast
/int_cast
/rat_cast
to natCast
/intCast
/ratCast
(#11486)
Now that I am defining NNRat.cast
, I want a definitive answer to this naming issue. Plenty of lemmas in mathlib already use natCast
/intCast
/ratCast
over nat_cast
/int_cast
/rat_cast
, and this matches with the general expectation that underscore-separated name parts correspond to a single declaration.
@@ -133,7 +133,7 @@ theorem ZMod.isSquare_neg_one_iff' {n : ℕ} (hn : Squarefree n) :
· exact fun _ => by norm_num
· replace hp := H hp (dvd_of_mul_right_dvd hpq)
replace hq := hq (dvd_of_mul_left_dvd hpq)
- rw [show 3 = 3 % 4 by norm_num, Ne, ← ZMod.nat_cast_eq_nat_cast_iff'] at hp hq ⊢
+ rw [show 3 = 3 % 4 by norm_num, Ne, ← ZMod.natCast_eq_natCast_iff'] at hp hq ⊢
rw [Nat.cast_mul]
exact help p q hp hq
#align zmod.is_square_neg_one_iff' ZMod.isSquare_neg_one_iff'
@@ -169,7 +169,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
refine' ⟨u * y, _⟩
conv_rhs => tactic => norm_cast
rw [(by norm_cast : (-1 : ZMod n.natAbs) = (-1 : ℤ))]
- exact (ZMod.int_cast_eq_int_cast_iff_dvd_sub _ _ _).mpr (Int.natAbs_dvd.mpr ⟨_, H⟩)
+ exact (ZMod.intCast_eq_intCast_iff_dvd_sub _ _ _).mpr (Int.natAbs_dvd.mpr ⟨_, H⟩)
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_is_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime
/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
coe_nat
to natCast
(#11637)
Reduce the diff of #11499
All in the Int
namespace:
ofNat_eq_cast
→ ofNat_eq_natCast
cast_eq_cast_iff_Nat
→ natCast_inj
natCast_eq_ofNat
→ ofNat_eq_natCast
coe_nat_sub
→ natCast_sub
coe_nat_nonneg
→ natCast_nonneg
sign_coe_add_one
→ sign_natCast_add_one
nat_succ_eq_int_succ
→ natCast_succ
succ_neg_nat_succ
→ succ_neg_natCast_succ
coe_pred_of_pos
→ natCast_pred_of_pos
coe_nat_div
→ natCast_div
coe_nat_ediv
→ natCast_ediv
sign_coe_nat_of_nonzero
→ sign_natCast_of_ne_zero
toNat_coe_nat
→ toNat_natCast
toNat_coe_nat_add_one
→ toNat_natCast_add_one
coe_nat_dvd
→ natCast_dvd_natCast
coe_nat_dvd_left
→ natCast_dvd
coe_nat_dvd_right
→ dvd_natCast
le_coe_nat_sub
→ le_natCast_sub
succ_coe_nat_pos
→ succ_natCast_pos
coe_nat_modEq_iff
→ natCast_modEq_iff
coe_natAbs
→ natCast_natAbs
coe_nat_eq_zero
→ natCast_eq_zero
coe_nat_ne_zero
→ natCast_ne_zero
coe_nat_ne_zero_iff_pos
→ natCast_ne_zero_iff_pos
abs_coe_nat
→ abs_natCast
coe_nat_nonpos_iff
→ natCast_nonpos_iff
Also rename Nat.coe_nat_dvd
to Nat.cast_dvd_cast
@@ -58,7 +58,7 @@ theorem Nat.sq_add_sq_mul {a b x y u v : ℕ} (ha : a = x ^ 2 + y ^ 2) (hb : b =
zify at ha hb ⊢
obtain ⟨r, s, h⟩ := _root_.sq_add_sq_mul ha hb
refine' ⟨r.natAbs, s.natAbs, _⟩
- simpa only [Int.coe_natAbs, sq_abs]
+ simpa only [Int.natCast_natAbs, sq_abs]
#align nat.sq_add_sq_mul Nat.sq_add_sq_mul
end General
@@ -133,7 +133,7 @@ theorem ZMod.isSquare_neg_one_iff' {n : ℕ} (hn : Squarefree n) :
· exact fun _ => by norm_num
· replace hp := H hp (dvd_of_mul_right_dvd hpq)
replace hq := hq (dvd_of_mul_left_dvd hpq)
- rw [show 3 = 3 % 4 by norm_num, Ne.def, ← ZMod.nat_cast_eq_nat_cast_iff'] at hp hq ⊢
+ rw [show 3 = 3 % 4 by norm_num, Ne, ← ZMod.nat_cast_eq_nat_cast_iff'] at hp hq ⊢
rw [Nat.cast_mul]
exact help p q hp hq
#align zmod.is_square_neg_one_iff' ZMod.isSquare_neg_one_iff'
IsRelPrime
and DecompositionMonoid
and refactor (#10327)
Introduce typeclass DecompositionMonoid
, which says every element in the monoid is primal, i.e., whenever an element divides a product b * c
, it can be factored into a product such that the factors divides b
and c
respectively. A domain is called pre-Schreier if its multiplicative monoid is a decomposition monoid, and these are more general than GCD domains.
Show that any GCDMonoid
is a DecompositionMonoid
. In order for lemmas about DecompositionMonoid
s to automatically apply to UniqueFactorizationMonoid
s, we add instances from UniqueFactorizationMonoid α
to Nonempty (NormalizedGCDMonoid α)
to Nonempty (GCDMonoid α)
to DecompositionMonoid α
. (Zulip) See the bottom of message for an updated diagram of classes and instances.
Introduce binary predicate IsRelPrime
which says that the only common divisors of the two elements are units. Replace previous occurrences in mathlib by this predicate.
Duplicate all lemmas about IsCoprime
in Coprime/Basic (except three lemmas about smul) to IsRelPrime
. Due to import constraints, they are spread into three files Algebra/Divisibility/Units (including key lemmas assuming DecompositionMonoid), GroupWithZero/Divisibility, and Coprime/Basic.
Show IsCoprime
always imply IsRelPrime
and is equivalent to it in Bezout rings. To reduce duplication, the definition of Bezout rings and the GCDMonoid instance are moved from RingTheory/Bezout to RingTheory/PrincipalIdealDomain, and some results in PrincipalIdealDomain are generalized to Bezout rings.
Remove the recently added file Squarefree/UniqueFactorizationMonoid and place the results appropriately within Squarefree/Basic. All results are generalized to DecompositionMonoid or weaker except the last one.
With this PR, all the following instances (indicated by arrows) now work; this PR fills the central part.
EuclideanDomain (bundled)
↙ ↖
IsPrincipalIdealRing ← Field (bundled)
↓ ↓
NormalizationMonoid ← NormalizedGCDMonoid → GCDMonoid IsBezout ← ValuationRing ← DiscreteValuationRing
↓ ↓ ↘ ↙
Nonempty NormalizationMonoid ← Nonempty NormalizedGCDMonoid → Nonempty GCDMonoid → IsIntegrallyClosed
↑ ↓
WfDvdMonoid ← UniqueFactorizationMonoid → DecompositionMonoid
↑
IsPrincipalIdealRing
Co-authored-by: Junyan Xu <junyanxu.math@gmail.com> Co-authored-by: Oliver Nash <github@olivernash.org>
@@ -33,7 +33,7 @@ of two squares. Also known as **Fermat's Christmas theorem**. -/
theorem Nat.Prime.sq_add_sq {p : ℕ} [Fact p.Prime] (hp : p % 4 ≠ 3) :
∃ a b : ℕ, a ^ 2 + b ^ 2 = p := by
apply sq_add_sq_of_nat_prime_of_not_irreducible p
- rwa [PrincipalIdealRing.irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p]
+ rwa [_root_.irreducible_iff_prime, prime_iff_mod_four_eq_three_of_nat_prime p]
#align nat.prime.sq_add_sq Nat.Prime.sq_add_sq
end Fermat
f ^ n
(#9617)
This involves moving lemmas from Algebra.GroupPower.Ring
to Algebra.GroupWithZero.Basic
and changing some 0 < n
assumptions to n ≠ 0
.
From LeanAPAP
@@ -187,7 +187,7 @@ theorem Nat.eq_sq_add_sq_iff_eq_sq_mul {n : ℕ} :
constructor
· rintro ⟨x, y, h⟩
by_cases hxy : x = 0 ∧ y = 0
- · exact ⟨0, 1, by rw [h, hxy.1, hxy.2, zero_pow zero_lt_two, add_zero, zero_mul],
+ · exact ⟨0, 1, by rw [h, hxy.1, hxy.2, zero_pow two_ne_zero, add_zero, zero_mul],
⟨0, by rw [zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩⟩
· have hg := Nat.pos_of_ne_zero (mt Nat.gcd_eq_zero_iff.mp hxy)
obtain ⟨g, x₁, y₁, _, h₂, h₃, h₄⟩ := Nat.exists_coprime' hg
@@ -3,6 +3,7 @@ Copyright (c) 2019 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Michael Stoll
-/
+import Mathlib.Data.Nat.Squarefree
import Mathlib.NumberTheory.Zsqrtd.QuadraticReciprocity
import Mathlib.Tactic.LinearCombination
@@ -231,7 +231,7 @@ theorem Nat.eq_sq_add_sq_iff {n : ℕ} :
refine' ⟨a, b, hab.symm, (ZMod.isSquare_neg_one_iff hb).mpr fun {q} hqp hqb hq4 => _⟩
refine' Nat.odd_iff_not_even.mp _ (H hqp hq4)
have hqb' : padicValNat q b = 1 :=
- b.factorization_def hqp ▸ le_antisymm (Nat.Squarefree.factorization_le_one _ hb)
+ b.factorization_def hqp ▸ le_antisymm (hb.natFactorization_le_one _)
((hqp.dvd_iff_one_le_factorization hb₀.ne').mp hqb)
haveI hqi : Fact q.Prime := ⟨hqp⟩
simp_rw [← hab, padicValNat.mul (pow_ne_zero 2 ha₀.ne') hb₀.ne', hqb',
This is the supremum of
along with some minor fixes from failures on nightly-testing as Mathlib master
is merged into it.
Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.
I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0
branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.
In particular this includes adjustments for the Lean PRs
We can get rid of all the
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)
macros across Mathlib (and in any projects that want to write natural number powers of reals).
Changes the default behaviour of simp
to (config := {decide := false})
. This makes simp
(and consequentially norm_num
) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp
or norm_num
to decide
or rfl
, or adding (config := {decide := true})
.
This changed the behaviour of simp
so that simp [f]
will only unfold "fully applied" occurrences of f
. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true })
. We may in future add a syntax for this, e.g. simp [!f]
; please provide feedback! In the meantime, we have made the following changes:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[eqns]
to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp
and Function.flip
.This change in Lean may require further changes down the line (e.g. adding the !f
syntax, and/or upstreaming the special treatment for Function.comp
and Function.flip
, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>
@@ -109,7 +109,7 @@ theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
refine' ⟨fun H q hqp hqd => hqp.mod_four_ne_three_of_dvd_isSquare_neg_one hqd H, fun H => _⟩
induction' n using induction_on_primes with p n hpp ih
· exact False.elim (hn.ne_zero rfl)
- · exact ⟨0, by simp only [Fin.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩
+ · exact ⟨0, by simp only [mul_zero, eq_iff_true_of_subsingleton]⟩
· haveI : Fact p.Prime := ⟨hpp⟩
have hcp : p.Coprime n := by
by_contra hc
@@ -82,7 +82,7 @@ theorem ZMod.isSquare_neg_one_of_dvd {m n : ℕ} (hd : m ∣ n) (hs : IsSquare (
/-- If `-1` is a square modulo coprime natural numbers `m` and `n`, then `-1` is also
a square modulo `m*n`. -/
-theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare (-1 : ZMod m))
+theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.Coprime n) (hm : IsSquare (-1 : ZMod m))
(hn : IsSquare (-1 : ZMod n)) : IsSquare (-1 : ZMod (m * n)) := by
have : IsSquare (-1 : ZMod m × ZMod n) := by
rw [show (-1 : ZMod m × ZMod n) = ((-1 : ZMod m), (-1 : ZMod n)) from rfl]
@@ -111,7 +111,7 @@ theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
· exact False.elim (hn.ne_zero rfl)
· exact ⟨0, by simp only [Fin.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩
· haveI : Fact p.Prime := ⟨hpp⟩
- have hcp : p.coprime n := by
+ have hcp : p.Coprime n := by
by_contra hc
exact hpp.not_unit (hn p <| mul_dvd_mul_left p <| hpp.dvd_iff_not_coprime.mpr hc)
have hp₁ := ZMod.exists_sq_eq_neg_one_iff.mpr (H hpp (dvd_mul_right p n))
@@ -174,7 +174,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
`-1` is a square modulo `n`. -/
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
- (hc : x.coprime y) : IsSquare (-1 : ZMod n) := by
+ (hc : x.Coprime y) : IsSquare (-1 : ZMod n) := by
zify at h
exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.isCoprime
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime
@@ -82,7 +82,7 @@ theorem ZMod.isSquare_neg_one_of_dvd {m n : ℕ} (hd : m ∣ n) (hs : IsSquare (
/-- If `-1` is a square modulo coprime natural numbers `m` and `n`, then `-1` is also
a square modulo `m*n`. -/
-theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.Coprime n) (hm : IsSquare (-1 : ZMod m))
+theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare (-1 : ZMod m))
(hn : IsSquare (-1 : ZMod n)) : IsSquare (-1 : ZMod (m * n)) := by
have : IsSquare (-1 : ZMod m × ZMod n) := by
rw [show (-1 : ZMod m × ZMod n) = ((-1 : ZMod m), (-1 : ZMod n)) from rfl]
@@ -111,7 +111,7 @@ theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
· exact False.elim (hn.ne_zero rfl)
· exact ⟨0, by simp only [Fin.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩
· haveI : Fact p.Prime := ⟨hpp⟩
- have hcp : p.Coprime n := by
+ have hcp : p.coprime n := by
by_contra hc
exact hpp.not_unit (hn p <| mul_dvd_mul_left p <| hpp.dvd_iff_not_coprime.mpr hc)
have hp₁ := ZMod.exists_sq_eq_neg_one_iff.mpr (H hpp (dvd_mul_right p n))
@@ -174,7 +174,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
`-1` is a square modulo `n`. -/
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
- (hc : x.Coprime y) : IsSquare (-1 : ZMod n) := by
+ (hc : x.coprime y) : IsSquare (-1 : ZMod n) := by
zify at h
exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.isCoprime
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime
Some changes have already been review and delegated in #6910 and #7148.
The diff that needs looking at is https://github.com/leanprover-community/mathlib4/pull/7174/commits/64d6d07ee18163627c8f517eb31455411921c5ac
The std bump PR was insta-merged already!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -82,7 +82,7 @@ theorem ZMod.isSquare_neg_one_of_dvd {m n : ℕ} (hd : m ∣ n) (hs : IsSquare (
/-- If `-1` is a square modulo coprime natural numbers `m` and `n`, then `-1` is also
a square modulo `m*n`. -/
-theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.coprime n) (hm : IsSquare (-1 : ZMod m))
+theorem ZMod.isSquare_neg_one_mul {m n : ℕ} (hc : m.Coprime n) (hm : IsSquare (-1 : ZMod m))
(hn : IsSquare (-1 : ZMod n)) : IsSquare (-1 : ZMod (m * n)) := by
have : IsSquare (-1 : ZMod m × ZMod n) := by
rw [show (-1 : ZMod m × ZMod n) = ((-1 : ZMod m), (-1 : ZMod n)) from rfl]
@@ -111,7 +111,7 @@ theorem ZMod.isSquare_neg_one_iff {n : ℕ} (hn : Squarefree n) :
· exact False.elim (hn.ne_zero rfl)
· exact ⟨0, by simp only [Fin.zero_mul, neg_eq_zero, Fin.one_eq_zero_iff]⟩
· haveI : Fact p.Prime := ⟨hpp⟩
- have hcp : p.coprime n := by
+ have hcp : p.Coprime n := by
by_contra hc
exact hpp.not_unit (hn p <| mul_dvd_mul_left p <| hpp.dvd_iff_not_coprime.mpr hc)
have hp₁ := ZMod.exists_sq_eq_neg_one_iff.mpr (H hpp (dvd_mul_right p n))
@@ -174,7 +174,7 @@ theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime {n x y : ℤ} (h : n
/-- If the natural number `n` is a sum of two squares of coprime natural numbers, then
`-1` is a square modulo `n`. -/
theorem ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime {n x y : ℕ} (h : n = x ^ 2 + y ^ 2)
- (hc : x.coprime y) : IsSquare (-1 : ZMod n) := by
+ (hc : x.Coprime y) : IsSquare (-1 : ZMod n) := by
zify at h
exact ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_isCoprime h hc.isCoprime
#align zmod.is_square_neg_one_of_eq_sq_add_sq_of_coprime ZMod.isSquare_neg_one_of_eq_sq_add_sq_of_coprime
@@ -2,15 +2,12 @@
Copyright (c) 2019 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Michael Stoll
-
-! This file was ported from Lean 3 source module number_theory.sum_two_squares
-! leanprover-community/mathlib commit 5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.NumberTheory.Zsqrtd.QuadraticReciprocity
import Mathlib.Tactic.LinearCombination
+#align_import number_theory.sum_two_squares from "leanprover-community/mathlib"@"5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9"
+
/-!
# Sums of two squares
The unported dependencies are
algebra.order.module
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
init.data.list.basic
linear_algebra.free_module.rank
algebra.order.monoid.cancel.basic
init.data.list.default
topology.subset_properties
init.logic
The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file