number_theory.legendre_symbol.basicMathlib.NumberTheory.LegendreSymbol.Basic

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
@@ -316,7 +316,7 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
 theorem prime_dvd_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendreSym p a = -1) {x y : ℤ}
     (hxy : ↑p ∣ x ^ 2 - a * y ^ 2) : ↑p ∣ x ∧ ↑p ∣ y :=
   by
-  simp_rw [← ZMod.int_cast_zmod_eq_zero_iff_dvd] at hxy ⊢
+  simp_rw [← ZMod.intCast_zmod_eq_zero_iff_dvd] at hxy ⊢
   push_cast at hxy
   exact eq_zero_mod_of_eq_neg_one h hxy
 #align legendre_sym.prime_dvd_of_eq_neg_one legendreSym.prime_dvd_of_eq_neg_one
Diff
@@ -60,7 +60,7 @@ theorem euler_criterion_units (x : (ZMod p)ˣ) : (∃ y : (ZMod p)ˣ, y ^ 2 = x)
       rw [isSquare_iff_exists_sq x]
       simp_rw [eq_comm]
     rw [hs]
-    rwa [card p] at h₀ 
+    rwa [card p] at h₀
 #align zmod.euler_criterion_units ZMod.euler_criterion_units
 -/
 
@@ -268,10 +268,10 @@ of the equation `x^2 - a*y^2 = 0` with `y ≠ 0`. -/
 theorem eq_one_of_sq_sub_mul_sq_eq_zero {p : ℕ} [Fact p.Prime] {a : ℤ} (ha : (a : ZMod p) ≠ 0)
     {x y : ZMod p} (hy : y ≠ 0) (hxy : x ^ 2 - a * y ^ 2 = 0) : legendreSym p a = 1 :=
   by
-  apply_fun (· * y⁻¹ ^ 2) at hxy 
-  simp only [MulZeroClass.zero_mul] at hxy 
+  apply_fun (· * y⁻¹ ^ 2) at hxy
+  simp only [MulZeroClass.zero_mul] at hxy
   rw [(by ring : (x ^ 2 - ↑a * y ^ 2) * y⁻¹ ^ 2 = (x * y⁻¹) ^ 2 - a * (y * y⁻¹) ^ 2),
-    mul_inv_cancel hy, one_pow, mul_one, sub_eq_zero, pow_two] at hxy 
+    mul_inv_cancel hy, one_pow, mul_one, sub_eq_zero, pow_two] at hxy
   exact (eq_one_iff p ha).mpr ⟨x * y⁻¹, hxy.symm⟩
 #align legendre_sym.eq_one_of_sq_sub_mul_sq_eq_zero legendreSym.eq_one_of_sq_sub_mul_sq_eq_zero
 -/
@@ -284,7 +284,7 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha
   haveI hy : y ≠ 0 := by
     rintro rfl
     rw [zero_pow 2 (by norm_num), MulZeroClass.mul_zero, sub_zero,
-      pow_eq_zero_iff (by norm_num : 0 < 2)] at hxy 
+      pow_eq_zero_iff (by norm_num : 0 < 2)] at hxy
     exacts [hx hxy, inferInstance]
   -- why is the instance not inferred automatically?
     eq_one_of_sq_sub_mul_sq_eq_zero
@@ -300,13 +300,13 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
   by
   have ha : (a : ZMod p) ≠ 0 := by
     intro hf
-    rw [(eq_zero_iff p a).mpr hf] at h 
+    rw [(eq_zero_iff p a).mpr hf] at h
     exact Int.zero_ne_neg_of_ne zero_ne_one h
   by_contra hf
   cases' not_and_distrib.mp hf with hx hy
-  · rw [eq_one_of_sq_sub_mul_sq_eq_zero' ha hx hxy, eq_neg_self_iff] at h 
+  · rw [eq_one_of_sq_sub_mul_sq_eq_zero' ha hx hxy, eq_neg_self_iff] at h
     exact one_ne_zero h
-  · rw [eq_one_of_sq_sub_mul_sq_eq_zero ha hy hxy, eq_neg_self_iff] at h 
+  · rw [eq_one_of_sq_sub_mul_sq_eq_zero ha hy hxy, eq_neg_self_iff] at h
     exact one_ne_zero h
 #align legendre_sym.eq_zero_mod_of_eq_neg_one legendreSym.eq_zero_mod_of_eq_neg_one
 -/
@@ -317,7 +317,7 @@ theorem prime_dvd_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendre
     (hxy : ↑p ∣ x ^ 2 - a * y ^ 2) : ↑p ∣ x ∧ ↑p ∣ y :=
   by
   simp_rw [← ZMod.int_cast_zmod_eq_zero_iff_dvd] at hxy ⊢
-  push_cast at hxy 
+  push_cast at hxy
   exact eq_zero_mod_of_eq_neg_one h hxy
 #align legendre_sym.prime_dvd_of_eq_neg_one legendreSym.prime_dvd_of_eq_neg_one
 -/
@@ -368,8 +368,8 @@ theorem mod_four_ne_three_of_sq_eq_neg_sq' {x y : ZMod p} (hy : y ≠ 0) (hxy :
     p % 4 ≠ 3 :=
   @mod_four_ne_three_of_sq_eq_neg_one p _ (x / y)
     (by
-      apply_fun fun z => z / y ^ 2 at hxy 
-      rwa [neg_div, ← div_pow, ← div_pow, div_self hy, one_pow] at hxy )
+      apply_fun fun z => z / y ^ 2 at hxy
+      rwa [neg_div, ← div_pow, ← div_pow, div_self hy, one_pow] at hxy)
 #align zmod.mod_four_ne_three_of_sq_eq_neg_sq' ZMod.mod_four_ne_three_of_sq_eq_neg_sq'
 -/
 
Diff
@@ -283,7 +283,7 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha
     {x y : ZMod p} (hx : x ≠ 0) (hxy : x ^ 2 - a * y ^ 2 = 0) : legendreSym p a = 1 :=
   haveI hy : y ≠ 0 := by
     rintro rfl
-    rw [zero_pow' 2 (by norm_num), MulZeroClass.mul_zero, sub_zero,
+    rw [zero_pow 2 (by norm_num), MulZeroClass.mul_zero, sub_zero,
       pow_eq_zero_iff (by norm_num : 0 < 2)] at hxy 
     exacts [hx hxy, inferInstance]
   -- why is the instance not inferred automatically?
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2018 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.LegendreSymbol.QuadraticChar.Basic
+import NumberTheory.LegendreSymbol.QuadraticChar.Basic
 
 #align_import number_theory.legendre_symbol.basic from "leanprover-community/mathlib"@"e160cefedc932ce41c7049bf0c4b0f061d06216e"
 
Diff
@@ -2,14 +2,11 @@
 Copyright (c) 2018 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.legendre_symbol.basic
-! leanprover-community/mathlib commit e160cefedc932ce41c7049bf0c4b0f061d06216e
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.NumberTheory.LegendreSymbol.QuadraticChar.Basic
 
+#align_import number_theory.legendre_symbol.basic from "leanprover-community/mathlib"@"e160cefedc932ce41c7049bf0c4b0f061d06216e"
+
 /-!
 # Legendre symbol
 
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.legendre_symbol.basic
-! leanprover-community/mathlib commit 5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9
+! leanprover-community/mathlib commit e160cefedc932ce41c7049bf0c4b0f061d06216e
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -13,6 +13,9 @@ import Mathbin.NumberTheory.LegendreSymbol.QuadraticChar.Basic
 /-!
 # Legendre symbol
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 This file contains results about Legendre symbols.
 
 We define the Legendre symbol $\Bigl(\frac{a}{p}\Bigr)$ as `legendre_sym p a`.
Diff
@@ -47,6 +47,7 @@ namespace ZMod
 
 variable (p : ℕ) [Fact p.Prime]
 
+#print ZMod.euler_criterion_units /-
 /-- Euler's Criterion: A unit `x` of `zmod p` is a square if and only if `x ^ (p / 2) = 1`. -/
 theorem euler_criterion_units (x : (ZMod p)ˣ) : (∃ y : (ZMod p)ˣ, y ^ 2 = x) ↔ x ^ (p / 2) = 1 :=
   by
@@ -61,7 +62,9 @@ theorem euler_criterion_units (x : (ZMod p)ˣ) : (∃ y : (ZMod p)ˣ, y ^ 2 = x)
     rw [hs]
     rwa [card p] at h₀ 
 #align zmod.euler_criterion_units ZMod.euler_criterion_units
+-/
 
+#print ZMod.euler_criterion /-
 /-- Euler's Criterion: a nonzero `a : zmod p` is a square if and only if `x ^ (p / 2) = 1`. -/
 theorem euler_criterion {a : ZMod p} (ha : a ≠ 0) : IsSquare (a : ZMod p) ↔ a ^ (p / 2) = 1 :=
   by
@@ -72,7 +75,9 @@ theorem euler_criterion {a : ZMod p} (ha : a ≠ 0) : IsSquare (a : ZMod p) ↔
     have hy : y ≠ 0 := by rintro rfl; simpa [zero_pow] using ha
     refine' ⟨Units.mk0 y hy, _⟩; simp
 #align zmod.euler_criterion ZMod.euler_criterion
+-/
 
+#print ZMod.pow_div_two_eq_neg_one_or_one /-
 /-- If `a : zmod p` is nonzero, then `a^(p/2)` is either `1` or `-1`. -/
 theorem pow_div_two_eq_neg_one_or_one {a : ZMod p} (ha : a ≠ 0) :
     a ^ (p / 2) = 1 ∨ a ^ (p / 2) = -1 :=
@@ -82,6 +87,7 @@ theorem pow_div_two_eq_neg_one_or_one {a : ZMod p} (ha : a ≠ 0) :
   rw [← mul_self_eq_one_iff, ← pow_add, ← two_mul, two_mul_odd_div_two hp_odd]
   exact pow_card_sub_one_eq_one ha
 #align zmod.pow_div_two_eq_neg_one_or_one ZMod.pow_div_two_eq_neg_one_or_one
+-/
 
 end ZMod
 
@@ -98,6 +104,7 @@ open ZMod
 
 variable (p : ℕ) [Fact p.Prime]
 
+#print legendreSym /-
 /-- The Legendre symbol of `a : ℤ` and a prime `p`, `legendre_sym p a`,
 is an integer defined as
 
@@ -111,9 +118,11 @@ that `legendre_sym p` is a multiplicative function `ℤ → ℤ`.
 def legendreSym (a : ℤ) : ℤ :=
   quadraticChar (ZMod p) a
 #align legendre_sym legendreSym
+-/
 
 namespace legendreSym
 
+#print legendreSym.eq_pow /-
 /-- We have the congruence `legendre_sym p a ≡ a ^ (p / 2) mod p`. -/
 theorem eq_pow (a : ℤ) : (legendreSym p a : ZMod p) = a ^ (p / 2) :=
   by
@@ -131,36 +140,50 @@ theorem eq_pow (a : ℤ) : (legendreSym p a : ZMod p) = a ^ (p / 2) :=
   · convert quadraticChar_eq_pow_of_char_ne_two' hc (a : ZMod p)
     exact (card p).symm
 #align legendre_sym.eq_pow legendreSym.eq_pow
+-/
 
+#print legendreSym.eq_one_or_neg_one /-
 /-- If `p ∤ a`, then `legendre_sym p a` is `1` or `-1`. -/
 theorem eq_one_or_neg_one {a : ℤ} (ha : (a : ZMod p) ≠ 0) :
     legendreSym p a = 1 ∨ legendreSym p a = -1 :=
   quadraticChar_dichotomy ha
 #align legendre_sym.eq_one_or_neg_one legendreSym.eq_one_or_neg_one
+-/
 
+#print legendreSym.eq_neg_one_iff_not_one /-
 theorem eq_neg_one_iff_not_one {a : ℤ} (ha : (a : ZMod p) ≠ 0) :
     legendreSym p a = -1 ↔ ¬legendreSym p a = 1 :=
   quadraticChar_eq_neg_one_iff_not_one ha
 #align legendre_sym.eq_neg_one_iff_not_one legendreSym.eq_neg_one_iff_not_one
+-/
 
+#print legendreSym.eq_zero_iff /-
 /-- The Legendre symbol of `p` and `a` is zero iff `p ∣ a`. -/
 theorem eq_zero_iff (a : ℤ) : legendreSym p a = 0 ↔ (a : ZMod p) = 0 :=
   quadraticChar_eq_zero_iff
 #align legendre_sym.eq_zero_iff legendreSym.eq_zero_iff
+-/
 
+#print legendreSym.at_zero /-
 @[simp]
 theorem at_zero : legendreSym p 0 = 0 := by rw [legendreSym, Int.cast_zero, MulChar.map_zero]
 #align legendre_sym.at_zero legendreSym.at_zero
+-/
 
+#print legendreSym.at_one /-
 @[simp]
 theorem at_one : legendreSym p 1 = 1 := by rw [legendreSym, Int.cast_one, MulChar.map_one]
 #align legendre_sym.at_one legendreSym.at_one
+-/
 
+#print legendreSym.mul /-
 /-- The Legendre symbol is multiplicative in `a` for `p` fixed. -/
 protected theorem mul (a b : ℤ) : legendreSym p (a * b) = legendreSym p a * legendreSym p b := by
   simp only [legendreSym, Int.cast_mul, map_mul]
 #align legendre_sym.mul legendreSym.mul
+-/
 
+#print legendreSym.hom /-
 /-- The Legendre symbol is a homomorphism of monoids with zero. -/
 @[simps]
 def hom : ℤ →*₀ ℤ where
@@ -169,45 +192,62 @@ def hom : ℤ →*₀ ℤ where
   map_one' := at_one p
   map_mul' := legendreSym.mul p
 #align legendre_sym.hom legendreSym.hom
+-/
 
+#print legendreSym.sq_one /-
 /-- The square of the symbol is 1 if `p ∤ a`. -/
 theorem sq_one {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p a ^ 2 = 1 :=
   quadraticChar_sq_one ha
 #align legendre_sym.sq_one legendreSym.sq_one
+-/
 
+#print legendreSym.sq_one' /-
 /-- The Legendre symbol of `a^2` at `p` is 1 if `p ∤ a`. -/
 theorem sq_one' {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p (a ^ 2) = 1 := by
   exact_mod_cast quadraticChar_sq_one' ha
 #align legendre_sym.sq_one' legendreSym.sq_one'
+-/
 
+#print legendreSym.mod /-
 /-- The Legendre symbol depends only on `a` mod `p`. -/
 protected theorem mod (a : ℤ) : legendreSym p a = legendreSym p (a % p) := by
   simp only [legendreSym, int_cast_mod]
 #align legendre_sym.mod legendreSym.mod
+-/
 
+#print legendreSym.eq_one_iff /-
 /-- When `p ∤ a`, then `legendre_sym p a = 1` iff `a` is a square mod `p`. -/
 theorem eq_one_iff {a : ℤ} (ha0 : (a : ZMod p) ≠ 0) : legendreSym p a = 1 ↔ IsSquare (a : ZMod p) :=
   quadraticChar_one_iff_isSquare ha0
 #align legendre_sym.eq_one_iff legendreSym.eq_one_iff
+-/
 
+#print legendreSym.eq_one_iff' /-
 theorem eq_one_iff' {a : ℕ} (ha0 : (a : ZMod p) ≠ 0) :
     legendreSym p a = 1 ↔ IsSquare (a : ZMod p) := by rw [eq_one_iff]; norm_cast; exact_mod_cast ha0
 #align legendre_sym.eq_one_iff' legendreSym.eq_one_iff'
+-/
 
+#print legendreSym.eq_neg_one_iff /-
 /-- `legendre_sym p a = -1` iff `a` is a nonsquare mod `p`. -/
 theorem eq_neg_one_iff {a : ℤ} : legendreSym p a = -1 ↔ ¬IsSquare (a : ZMod p) :=
   quadraticChar_neg_one_iff_not_isSquare
 #align legendre_sym.eq_neg_one_iff legendreSym.eq_neg_one_iff
+-/
 
+#print legendreSym.eq_neg_one_iff' /-
 theorem eq_neg_one_iff' {a : ℕ} : legendreSym p a = -1 ↔ ¬IsSquare (a : ZMod p) := by
   rw [eq_neg_one_iff]; norm_cast
 #align legendre_sym.eq_neg_one_iff' legendreSym.eq_neg_one_iff'
+-/
 
+#print legendreSym.card_sqrts /-
 /-- The number of square roots of `a` modulo `p` is determined by the Legendre symbol. -/
 theorem card_sqrts (hp : p ≠ 2) (a : ℤ) :
     ↑{x : ZMod p | x ^ 2 = a}.toFinset.card = legendreSym p a + 1 :=
   quadraticChar_card_sqrts ((ringChar_zmod_n p).substr hp) a
 #align legendre_sym.card_sqrts legendreSym.card_sqrts
+-/
 
 end legendreSym
 
@@ -222,6 +262,7 @@ section QuadraticForm
 
 namespace legendreSym
 
+#print legendreSym.eq_one_of_sq_sub_mul_sq_eq_zero /-
 /-- The Legendre symbol `legendre_sym p a = 1` if there is a solution in `ℤ/pℤ`
 of the equation `x^2 - a*y^2 = 0` with `y ≠ 0`. -/
 theorem eq_one_of_sq_sub_mul_sq_eq_zero {p : ℕ} [Fact p.Prime] {a : ℤ} (ha : (a : ZMod p) ≠ 0)
@@ -233,7 +274,9 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero {p : ℕ} [Fact p.Prime] {a : ℤ} (ha :
     mul_inv_cancel hy, one_pow, mul_one, sub_eq_zero, pow_two] at hxy 
   exact (eq_one_iff p ha).mpr ⟨x * y⁻¹, hxy.symm⟩
 #align legendre_sym.eq_one_of_sq_sub_mul_sq_eq_zero legendreSym.eq_one_of_sq_sub_mul_sq_eq_zero
+-/
 
+#print legendreSym.eq_one_of_sq_sub_mul_sq_eq_zero' /-
 /-- The Legendre symbol `legendre_sym p a = 1` if there is a solution in `ℤ/pℤ`
 of the equation `x^2 - a*y^2 = 0` with `x ≠ 0`. -/
 theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha : (a : ZMod p) ≠ 0)
@@ -247,7 +290,9 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha
     eq_one_of_sq_sub_mul_sq_eq_zero
     ha hy hxy
 #align legendre_sym.eq_one_of_sq_sub_mul_sq_eq_zero' legendreSym.eq_one_of_sq_sub_mul_sq_eq_zero'
+-/
 
+#print legendreSym.eq_zero_mod_of_eq_neg_one /-
 /-- If `legendre_sym p a = -1`, then the only solution of `x^2 - a*y^2 = 0` in `ℤ/pℤ`
 is the trivial one. -/
 theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendreSym p a = -1)
@@ -264,7 +309,9 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
   · rw [eq_one_of_sq_sub_mul_sq_eq_zero ha hy hxy, eq_neg_self_iff] at h 
     exact one_ne_zero h
 #align legendre_sym.eq_zero_mod_of_eq_neg_one legendreSym.eq_zero_mod_of_eq_neg_one
+-/
 
+#print legendreSym.prime_dvd_of_eq_neg_one /-
 /-- If `legendre_sym p a = -1` and `p` divides `x^2 - a*y^2`, then `p` must divide `x` and `y`. -/
 theorem prime_dvd_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendreSym p a = -1) {x y : ℤ}
     (hxy : ↑p ∣ x ^ 2 - a * y ^ 2) : ↑p ∣ x ∧ ↑p ∣ y :=
@@ -273,6 +320,7 @@ theorem prime_dvd_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendre
   push_cast at hxy 
   exact eq_zero_mod_of_eq_neg_one h hxy
 #align legendre_sym.prime_dvd_of_eq_neg_one legendreSym.prime_dvd_of_eq_neg_one
+-/
 
 end legendreSym
 
@@ -291,23 +339,30 @@ variable {p : ℕ} [Fact p.Prime]
 
 open ZMod
 
+#print legendreSym.at_neg_one /-
 /-- `legendre_sym p (-1)` is given by `χ₄ p`. -/
 theorem legendreSym.at_neg_one (hp : p ≠ 2) : legendreSym p (-1) = χ₄ p := by
   simp only [legendreSym, card p, quadraticChar_neg_one ((ring_char_zmod_n p).substr hp),
     Int.cast_neg, Int.cast_one]
 #align legendre_sym.at_neg_one legendreSym.at_neg_one
+-/
 
 namespace ZMod
 
+#print ZMod.exists_sq_eq_neg_one_iff /-
 /-- `-1` is a square in `zmod p` iff `p` is not congruent to `3` mod `4`. -/
 theorem exists_sq_eq_neg_one_iff : IsSquare (-1 : ZMod p) ↔ p % 4 ≠ 3 := by
   rw [FiniteField.isSquare_neg_one_iff, card p]
 #align zmod.exists_sq_eq_neg_one_iff ZMod.exists_sq_eq_neg_one_iff
+-/
 
+#print ZMod.mod_four_ne_three_of_sq_eq_neg_one /-
 theorem mod_four_ne_three_of_sq_eq_neg_one {y : ZMod p} (hy : y ^ 2 = -1) : p % 4 ≠ 3 :=
   exists_sq_eq_neg_one_iff.1 ⟨y, hy ▸ pow_two y⟩
 #align zmod.mod_four_ne_three_of_sq_eq_neg_one ZMod.mod_four_ne_three_of_sq_eq_neg_one
+-/
 
+#print ZMod.mod_four_ne_three_of_sq_eq_neg_sq' /-
 /-- If two nonzero squares are negatives of each other in `zmod p`, then `p % 4 ≠ 3`. -/
 theorem mod_four_ne_three_of_sq_eq_neg_sq' {x y : ZMod p} (hy : y ≠ 0) (hxy : x ^ 2 = -y ^ 2) :
     p % 4 ≠ 3 :=
@@ -316,11 +371,14 @@ theorem mod_four_ne_three_of_sq_eq_neg_sq' {x y : ZMod p} (hy : y ≠ 0) (hxy :
       apply_fun fun z => z / y ^ 2 at hxy 
       rwa [neg_div, ← div_pow, ← div_pow, div_self hy, one_pow] at hxy )
 #align zmod.mod_four_ne_three_of_sq_eq_neg_sq' ZMod.mod_four_ne_three_of_sq_eq_neg_sq'
+-/
 
+#print ZMod.mod_four_ne_three_of_sq_eq_neg_sq /-
 theorem mod_four_ne_three_of_sq_eq_neg_sq {x y : ZMod p} (hx : x ≠ 0) (hxy : x ^ 2 = -y ^ 2) :
     p % 4 ≠ 3 :=
   mod_four_ne_three_of_sq_eq_neg_sq' hx (neg_eq_iff_eq_neg.mpr hxy).symm
 #align zmod.mod_four_ne_three_of_sq_eq_neg_sq ZMod.mod_four_ne_three_of_sq_eq_neg_sq
+-/
 
 end ZMod
 

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
@@ -182,7 +182,7 @@ theorem sq_one' {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p (a ^ 2) = 1
 
 /-- The Legendre symbol depends only on `a` mod `p`. -/
 protected theorem mod (a : ℤ) : legendreSym p a = legendreSym p (a % p) := by
-  simp only [legendreSym, int_cast_mod]
+  simp only [legendreSym, intCast_mod]
 #align legendre_sym.mod legendreSym.mod
 
 /-- When `p ∤ a`, then `legendreSym p a = 1` iff `a` is a square mod `p`. -/
@@ -263,7 +263,7 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
 /-- If `legendreSym p a = -1` and `p` divides `x^2 - a*y^2`, then `p` must divide `x` and `y`. -/
 theorem prime_dvd_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendreSym p a = -1) {x y : ℤ}
     (hxy : (p : ℤ) ∣ x ^ 2 - a * y ^ 2) : ↑p ∣ x ∧ ↑p ∣ y := by
-  simp_rw [← ZMod.int_cast_zmod_eq_zero_iff_dvd] at hxy ⊢
+  simp_rw [← ZMod.intCast_zmod_eq_zero_iff_dvd] at hxy ⊢
   push_cast at hxy
   exact eq_zero_mod_of_eq_neg_one h hxy
 #align legendre_sym.prime_dvd_of_eq_neg_one legendreSym.prime_dvd_of_eq_neg_one
chore: remove unused tactics (#11351)

I removed some of the tactics that were not used and are hopefully uncontroversial arising from the linter at #11308.

As the commit messages should convey, the removed tactics are, essentially,

push_cast
norm_cast
congr
norm_num
dsimp
funext
intro
infer_instance
Diff
@@ -127,8 +127,6 @@ theorem eq_pow (a : ℤ) : (legendreSym p a : ZMod p) = (a : ZMod p) ^ (p / 2) :
       · tauto
       · simp
   · convert quadraticChar_eq_pow_of_char_ne_two' hc (a : ZMod p)
-    norm_cast
-    congr
     exact (card p).symm
 #align legendre_sym.eq_pow legendreSym.eq_pow
 
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
@@ -115,7 +115,7 @@ theorem eq_pow (a : ℤ) : (legendreSym p a : ZMod p) = (a : ZMod p) ^ (p / 2) :
   rcases eq_or_ne (ringChar (ZMod p)) 2 with hc | hc
   · by_cases ha : (a : ZMod p) = 0
     · rw [legendreSym, ha, quadraticChar_zero,
-        zero_pow (Nat.div_pos (@Fact.out p.Prime).two_le (succ_pos 1))]
+        zero_pow (Nat.div_pos (@Fact.out p.Prime).two_le (succ_pos 1)).ne']
       norm_cast
     · have := (ringChar_zmod_n p).symm.trans hc
       -- p = 2
@@ -241,8 +241,7 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha
     {x y : ZMod p} (hx : x ≠ 0) (hxy : x ^ 2 - a * y ^ 2 = 0) : legendreSym p a = 1 := by
   haveI hy : y ≠ 0 := by
     rintro rfl
-    rw [zero_pow' 2 (by norm_num), mul_zero, sub_zero, pow_eq_zero_iff
-        (by norm_num : 0 < 2)] at hxy
+    rw [zero_pow two_ne_zero, mul_zero, sub_zero, sq_eq_zero_iff] at hxy
     exact hx hxy
   exact eq_one_of_sq_sub_mul_sq_eq_zero ha hy hxy
 #align legendre_sym.eq_one_of_sq_sub_mul_sq_eq_zero' legendreSym.eq_one_of_sq_sub_mul_sq_eq_zero'
chore: remove uses of cases' (#9171)

I literally went through and regex'd some uses of cases', replacing them with rcases; this is meant to be a low effort PR as I hope that tools can do this in the future.

rcases is an easier replacement than cases, though with better tools we could in future do a second pass converting simple rcases added here (and existing ones) to cases.

Diff
@@ -112,7 +112,7 @@ namespace legendreSym
 
 /-- We have the congruence `legendreSym p a ≡ a ^ (p / 2) mod p`. -/
 theorem eq_pow (a : ℤ) : (legendreSym p a : ZMod p) = (a : ZMod p) ^ (p / 2) := by
-  cases' eq_or_ne (ringChar (ZMod p)) 2 with hc hc
+  rcases eq_or_ne (ringChar (ZMod p)) 2 with hc | hc
   · by_cases ha : (a : ZMod p) = 0
     · rw [legendreSym, ha, quadraticChar_zero,
         zero_pow (Nat.div_pos (@Fact.out p.Prime).two_le (succ_pos 1))]
chore: replace exact_mod_cast tactic with mod_cast elaborator where possible (#8404)

We still have the exact_mod_cast tactic, used in a few places, which somehow (?) works a little bit harder to prevent the expected type influencing the elaboration of the term. I would like to get to the bottom of this, and it will be easier once the only usages of exact_mod_cast are the ones that don't work using the term elaborator by itself.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -193,7 +193,7 @@ theorem eq_one_iff {a : ℤ} (ha0 : (a : ZMod p) ≠ 0) : legendreSym p a = 1 
 #align legendre_sym.eq_one_iff legendreSym.eq_one_iff
 
 theorem eq_one_iff' {a : ℕ} (ha0 : (a : ZMod p) ≠ 0) :
-    legendreSym p a = 1 ↔ IsSquare (a : ZMod p) := by rw [eq_one_iff]; norm_cast; exact_mod_cast ha0
+    legendreSym p a = 1 ↔ IsSquare (a : ZMod p) := by rw [eq_one_iff]; norm_cast; exact mod_cast ha0
 #align legendre_sym.eq_one_iff' legendreSym.eq_one_iff'
 
 /-- `legendreSym p a = -1` iff `a` is a nonsquare mod `p`. -/
chore: cleanup some spaces (#7484)

Purely cosmetic PR.

Diff
@@ -265,7 +265,7 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
 
 /-- If `legendreSym p a = -1` and `p` divides `x^2 - a*y^2`, then `p` must divide `x` and `y`. -/
 theorem prime_dvd_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legendreSym p a = -1) {x y : ℤ}
-    (hxy : (p : ℤ) ∣ x ^ 2 - a * y ^ 2 ) : ↑p ∣ x ∧ ↑p ∣ y := by
+    (hxy : (p : ℤ) ∣ x ^ 2 - a * y ^ 2) : ↑p ∣ x ∧ ↑p ∣ y := by
   simp_rw [← ZMod.int_cast_zmod_eq_zero_iff_dvd] at hxy ⊢
   push_cast at hxy
   exact eq_zero_mod_of_eq_neg_one h hxy
@@ -311,7 +311,7 @@ theorem mod_four_ne_three_of_sq_eq_neg_sq' {x y : ZMod p} (hy : y ≠ 0) (hxy :
   @mod_four_ne_three_of_sq_eq_neg_one p _ (x / y)
     (by
       apply_fun fun z => z / y ^ 2 at hxy
-      rwa [neg_div, ← div_pow, ← div_pow, div_self hy, one_pow] at hxy )
+      rwa [neg_div, ← div_pow, ← div_pow, div_self hy, one_pow] at hxy)
 #align zmod.mod_four_ne_three_of_sq_eq_neg_sq' ZMod.mod_four_ne_three_of_sq_eq_neg_sq'
 
 theorem mod_four_ne_three_of_sq_eq_neg_sq {x y : ZMod p} (hx : x ≠ 0) (hxy : x ^ 2 = -y ^ 2) :
chore: reduce use of Init.Data.Int.CompLemmas (#7142)

Mathlib.Init.Data.Int.CompLemmas was ported from core, and was never really intended for outside use. Nevertheless, people started using it. (Surprise!)

This PR removes one out of the two uses in Mathlib.

If anyone would like to do the other in a separate PR, please do! You would need to reprove

theorem natAbs_add_nonneg {a b : ℤ} (wa : 0 ≤ a) (wb : 0 ≤ b) :
    Int.natAbs (a + b) = Int.natAbs a + Int.natAbs b := sorry

theorem natAbs_add_neg {a b : ℤ} (wa : a < 0) (wb : b < 0) :
    Int.natAbs (a + b) = Int.natAbs a + Int.natAbs b := sorry

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -3,7 +3,6 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Chris Hughes, Michael Stoll
 -/
-import Mathlib.Init.Data.Int.CompLemmas
 import Mathlib.NumberTheory.LegendreSymbol.QuadraticChar.Basic
 
 #align_import number_theory.legendre_symbol.basic from "leanprover-community/mathlib"@"5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9"
@@ -255,7 +254,7 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
   have ha : (a : ZMod p) ≠ 0 := by
     intro hf
     rw [(eq_zero_iff p a).mpr hf] at h
-    exact Int.zero_ne_neg_of_ne zero_ne_one h
+    simp at h
   by_contra hf
   cases' imp_iff_or_not.mp (not_and'.mp hf) with hx hy
   · rw [eq_one_of_sq_sub_mul_sq_eq_zero' ha hx hxy, eq_neg_self_iff] at h
chore: drop MulZeroClass. in mul_zero/zero_mul (#6682)

Search&replace MulZeroClass.mul_zero -> mul_zero, MulZeroClass.zero_mul -> zero_mul.

These were introduced by Mathport, as the full name of mul_zero is actually MulZeroClass.mul_zero (it's exported with the short name).

Diff
@@ -230,7 +230,7 @@ of the equation `x^2 - a*y^2 = 0` with `y ≠ 0`. -/
 theorem eq_one_of_sq_sub_mul_sq_eq_zero {p : ℕ} [Fact p.Prime] {a : ℤ} (ha : (a : ZMod p) ≠ 0)
     {x y : ZMod p} (hy : y ≠ 0) (hxy : x ^ 2 - a * y ^ 2 = 0) : legendreSym p a = 1 := by
   apply_fun (· * y⁻¹ ^ 2) at hxy
-  simp only [MulZeroClass.zero_mul] at hxy
+  simp only [zero_mul] at hxy
   rw [(by ring : (x ^ 2 - ↑a * y ^ 2) * y⁻¹ ^ 2 = (x * y⁻¹) ^ 2 - a * (y * y⁻¹) ^ 2),
     mul_inv_cancel hy, one_pow, mul_one, sub_eq_zero, pow_two] at hxy
   exact (eq_one_iff p ha).mpr ⟨x * y⁻¹, hxy.symm⟩
@@ -242,7 +242,7 @@ theorem eq_one_of_sq_sub_mul_sq_eq_zero' {p : ℕ} [Fact p.Prime] {a : ℤ} (ha
     {x y : ZMod p} (hx : x ≠ 0) (hxy : x ^ 2 - a * y ^ 2 = 0) : legendreSym p a = 1 := by
   haveI hy : y ≠ 0 := by
     rintro rfl
-    rw [zero_pow' 2 (by norm_num), MulZeroClass.mul_zero, sub_zero, pow_eq_zero_iff
+    rw [zero_pow' 2 (by norm_num), mul_zero, sub_zero, pow_eq_zero_iff
         (by norm_num : 0 < 2)] at hxy
     exact hx hxy
   exact eq_one_of_sq_sub_mul_sq_eq_zero ha hy hxy
style: remove trailing whitespace and modify the linter to detect it (#6519)
Diff
@@ -178,7 +178,7 @@ theorem sq_one {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p a ^ 2 = 1 :=
 
 /-- The Legendre symbol of `a^2` at `p` is 1 if `p ∤ a`. -/
 theorem sq_one' {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p (a ^ 2) = 1 := by
-  dsimp only [legendreSym] 
+  dsimp only [legendreSym]
   rw [Int.cast_pow]
   exact quadraticChar_sq_one' ha
 #align legendre_sym.sq_one' legendreSym.sq_one'
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) 2018 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.legendre_symbol.basic
-! 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.Init.Data.Int.CompLemmas
 import Mathlib.NumberTheory.LegendreSymbol.QuadraticChar.Basic
 
+#align_import number_theory.legendre_symbol.basic from "leanprover-community/mathlib"@"5b2fe80501ff327b9109fb09b7cc8c325cd0d7d9"
+
 /-!
 # Legendre symbol
 
feat: port NumberTheory.LegendreSymbol.GaussSum (#5419)

This PR incorporates also the changes to NumberTheory.LegendreSymbol.MulCharacter discussed here

Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>

Diff
@@ -181,7 +181,9 @@ theorem sq_one {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p a ^ 2 = 1 :=
 
 /-- The Legendre symbol of `a^2` at `p` is 1 if `p ∤ a`. -/
 theorem sq_one' {a : ℤ} (ha : (a : ZMod p) ≠ 0) : legendreSym p (a ^ 2) = 1 := by
-  exact_mod_cast quadraticChar_sq_one' ha
+  dsimp only [legendreSym] 
+  rw [Int.cast_pow]
+  exact quadraticChar_sq_one' ha
 #align legendre_sym.sq_one' legendreSym.sq_one'
 
 /-- The Legendre symbol depends only on `a` mod `p`. -/
chore: tidy various files (#5449)
Diff
@@ -65,7 +65,8 @@ theorem euler_criterion_units (x : (ZMod p)ˣ) : (∃ y : (ZMod p)ˣ, y ^ 2 = x)
 theorem euler_criterion {a : ZMod p} (ha : a ≠ 0) : IsSquare (a : ZMod p) ↔ a ^ (p / 2) = 1 := by
   apply (iff_congr _ (by simp [Units.ext_iff])).mp (euler_criterion_units p (Units.mk0 a ha))
   simp only [Units.ext_iff, sq, Units.val_mk0, Units.val_mul]
-  constructor; · rintro ⟨y, hy⟩; exact ⟨y, hy.symm⟩
+  constructor
+  · rintro ⟨y, hy⟩; exact ⟨y, hy.symm⟩
   · rintro ⟨y, rfl⟩
     have hy : y ≠ 0 := by
       rintro rfl
@@ -126,7 +127,9 @@ theorem eq_pow (a : ℤ) : (legendreSym p a : ZMod p) = (a : ZMod p) ^ (p / 2) :
       rw [legendreSym, quadraticChar_eq_one_of_char_two hc ha]
       revert ha
       push_cast
-      generalize (a : ZMod 2) = b; fin_cases b; tauto; simp
+      generalize (a : ZMod 2) = b; fin_cases b
+      · tauto
+      · simp
   · convert quadraticChar_eq_pow_of_char_ne_two' hc (a : ZMod p)
     norm_cast
     congr
feat: port Mathlib.Init.Data.Int.CompLemmas (#5269)
Diff
@@ -8,6 +8,7 @@ Authors: Chris Hughes, Michael Stoll
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
+import Mathlib.Init.Data.Int.CompLemmas
 import Mathlib.NumberTheory.LegendreSymbol.QuadraticChar.Basic
 
 /-!
@@ -252,8 +253,7 @@ theorem eq_zero_mod_of_eq_neg_one {p : ℕ} [Fact p.Prime] {a : ℤ} (h : legend
   have ha : (a : ZMod p) ≠ 0 := by
     intro hf
     rw [(eq_zero_iff p a).mpr hf] at h
-    -- porting note: `zero_ne_neg_of_ne` not ported. Fixed by using `linarith` instead
-    linarith
+    exact Int.zero_ne_neg_of_ne zero_ne_one h
   by_contra hf
   cases' imp_iff_or_not.mp (not_and'.mp hf) with hx hy
   · rw [eq_one_of_sq_sub_mul_sq_eq_zero' ha hx hxy, eq_neg_self_iff] at h
feat: port NumberTheory.LegendreSymbol.Basic (#5197)

Co-authored-by: Moritz Firsching <firsching@google.com>

Dependencies 10 + 665

666 files ported (98.5%)
276847 lines ported (98.8%)
Show graph

The unported dependencies are