number_theory.sum_two_squaresMathlib.NumberTheory.SumTwoSquares

This file has been ported!

Changes since the initial port

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.

Changes in mathlib3

(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)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -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
 -/
 
Diff
@@ -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
 -/
 
Diff
@@ -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
Diff
@@ -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
 -/
 
Diff
@@ -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',
Diff
@@ -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"
 
Diff
@@ -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
Diff
@@ -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
Diff
@@ -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
 
Diff
@@ -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`).
 
Diff
@@ -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
 
Diff
@@ -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
 
 /-!
Diff
@@ -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
 
Diff
@@ -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
+

Changes in mathlib4

mathlib3
mathlib4
chore: Rename 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.

Diff
@@ -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
chore(Data/Int): Rename coe_nat to natCast (#11637)

Reduce the diff of #11499

Renames

All in the Int namespace:

  • ofNat_eq_castofNat_eq_natCast
  • cast_eq_cast_iff_NatnatCast_inj
  • natCast_eq_ofNatofNat_eq_natCast
  • coe_nat_subnatCast_sub
  • coe_nat_nonnegnatCast_nonneg
  • sign_coe_add_onesign_natCast_add_one
  • nat_succ_eq_int_succnatCast_succ
  • succ_neg_nat_succsucc_neg_natCast_succ
  • coe_pred_of_posnatCast_pred_of_pos
  • coe_nat_divnatCast_div
  • coe_nat_edivnatCast_ediv
  • sign_coe_nat_of_nonzerosign_natCast_of_ne_zero
  • toNat_coe_nattoNat_natCast
  • toNat_coe_nat_add_onetoNat_natCast_add_one
  • coe_nat_dvdnatCast_dvd_natCast
  • coe_nat_dvd_leftnatCast_dvd
  • coe_nat_dvd_rightdvd_natCast
  • le_coe_nat_suble_natCast_sub
  • succ_coe_nat_possucc_natCast_pos
  • coe_nat_modEq_iffnatCast_modEq_iff
  • coe_natAbsnatCast_natAbs
  • coe_nat_eq_zeronatCast_eq_zero
  • coe_nat_ne_zeronatCast_ne_zero
  • coe_nat_ne_zero_iff_posnatCast_ne_zero_iff_pos
  • abs_coe_natabs_natCast
  • coe_nat_nonpos_iffnatCast_nonpos_iff

Also rename Nat.coe_nat_dvd to Nat.cast_dvd_cast

Diff
@@ -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
chore: avoid Ne.def (adaptation for nightly-2024-03-27) (#11813)
Diff
@@ -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'
feat: introduce 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 DecompositionMonoids to automatically apply to UniqueFactorizationMonoids, 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.

Zulip

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>

Diff
@@ -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
feat: The support of 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

Diff
@@ -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
chore: reduce imports (#9830)

This uses the improved shake script from #9772 to reduce imports across mathlib. The corresponding noshake.json file has been added to #9772.

Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -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
 
feat: Squarefree lemmas for Nat (#8323)
Diff
@@ -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',
chore: bump to v4.3.0-rc2 (#8366)

PR contents

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.

Lean PRs involved in this bump

In particular this includes adjustments for the Lean PRs

leanprover/lean4#2778

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).

leanprover/lean4#2722

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}).

leanprover/lean4#2783

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:

  • switching to using explicit lemmas that have the intended level of application
  • (config := { unfoldPartialApp := true }) in some places, to recover the old behaviour
  • Using @[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>

Diff
@@ -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
chore: bump to v4.1.0-rc1 (2nd attempt) (#7216)

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -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
Revert "chore: bump to v4.1.0-rc1 (#7174)" (#7198)

This reverts commit 6f8e8104. Unfortunately this bump was not linted correctly, as CI did not run runLinter Mathlib.

We can unrevert once that's fixed.

Diff
@@ -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
chore: bump to v4.1.0-rc1 (#7174)

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>

Diff
@@ -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
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -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
 
feat: port NumberTheory.SumTwoSquares (#5487)

Dependencies 12 + 1024

1025 files ported (98.8%)
438545 lines ported (98.7%)
Show graph

The unported dependencies are

The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file