File: Mathlib/Tactic/NormNum/LegendreSymbol.lean

full_name: Mathlib.Meta.NormNum.jacobiSymNat
code: /-- The Jacobi symbol restricted to natural numbers in both arguments. -/
def jacobiSymNat (a b : ℕ) : ℤ 
goal: ℤ

full_name: Mathlib.Meta.NormNum.jacobiSymNat.zero_right
code: /-- Base cases: `b = 0`, `b = 1`, `a = 0`, `a = 1`. -/
theorem jacobiSymNat.zero_right (a : ℕ) : jacobiSymNat a 0 = 1 
goal: Mathlib.Meta.NormNum.jacobiSymNat a 0 = 1

full_name: Mathlib.Meta.NormNum.jacobiSymNat.one_right
code: theorem jacobiSymNat.one_right (a : ℕ) : jacobiSymNat a 1 = 1 
goal: Mathlib.Meta.NormNum.jacobiSymNat a 1 = 1

full_name: Mathlib.Meta.NormNum.jacobiSymNat.zero_left
code: theorem jacobiSymNat.zero_left (b : ℕ) (hb : Nat.beq (b / 2) 0 = false) : jacobiSymNat 0 b = 0 
goal: Mathlib.Meta.NormNum.jacobiSymNat 0 b = 0

full_name: Mathlib.Meta.NormNum.jacobiSymNat.one_left
code: theorem jacobiSymNat.one_left (b : ℕ) : jacobiSymNat 1 b = 1 
goal: Mathlib.Meta.NormNum.jacobiSymNat 1 b = 1

full_name: Mathlib.Meta.NormNum.LegendreSym.to_jacobiSym
code: /-- Turn a Legendre symbol into a Jacobi symbol. -/
theorem LegendreSym.to_jacobiSym (p : ℕ) (pp : Fact p.Prime) (a r : ℤ)
    (hr : IsInt (jacobiSym a p) r) : IsInt (legendreSym p a) r 
goal: Mathlib.Meta.NormNum.IsInt (legendreSym p a) r

full_name: Mathlib.Meta.NormNum.JacobiSym.mod_left
code: /-- The value depends only on the residue class of `a` mod `b`. -/
theorem JacobiSym.mod_left (a : ℤ) (b ab' : ℕ) (ab r b' : ℤ) (hb' : (b : ℤ) = b')
    (hab : a % b' = ab) (h : (ab' : ℤ) = ab) (hr : jacobiSymNat ab' b = r) : jacobiSym a b = r 
goal: jacobiSym a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.mod_left
code: theorem jacobiSymNat.mod_left (a b ab : ℕ) (r : ℤ) (hab : a % b = ab) (hr : jacobiSymNat ab b = r) :
    jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.even_even
code: /-- The symbol vanishes when both entries are even (and `b / 2 ≠ 0`). -/
theorem jacobiSymNat.even_even (a b : ℕ) (hb₀ : Nat.beq (b / 2) 0 = false) (ha : a % 2 = 0)
    (hb₁ : b % 2 = 0) : jacobiSymNat a b = 0 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = 0

full_name: Mathlib.Meta.NormNum.jacobiSymNat.odd_even
code: /-- When `a` is odd and `b` is even, we can replace `b` by `b / 2`. -/
theorem jacobiSymNat.odd_even (a b c : ℕ) (r : ℤ) (ha : a % 2 = 1) (hb : b % 2 = 0) (hc : b / 2 = c)
    (hr : jacobiSymNat a c = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.double_even
code: /-- If `a` is divisible by `4` and `b` is odd, then we can remove the factor `4` from `a`. -/
theorem jacobiSymNat.double_even (a b c : ℕ) (r : ℤ) (ha : a % 4 = 0) (hb : b % 2 = 1)
    (hc : a / 4 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁
code: /-- If `a` is even and `b` is odd, then we can remove a factor `2` from `a`,
but we may have to change the sign, depending on `b % 8`.
We give one version for each of the four odd residue classes mod `8`. -/
theorem jacobiSymNat.even_odd₁ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 1)
    (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇
code: theorem jacobiSymNat.even_odd₇ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 7)
    (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃
code: theorem jacobiSymNat.even_odd₃ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 3)
    (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = -r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = -r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅
code: theorem jacobiSymNat.even_odd₅ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb : b % 8 = 5)
    (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = -r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = -r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.qr₁
code: /-- Use quadratic reciproity to reduce to smaller `b`. -/
theorem jacobiSymNat.qr₁ (a b : ℕ) (r : ℤ) (ha : a % 4 = 1) (hb : b % 2 = 1)
    (hr : jacobiSymNat b a = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.qr₁_mod
code: theorem jacobiSymNat.qr₁_mod (a b ab : ℕ) (r : ℤ) (ha : a % 4 = 1) (hb : b % 2 = 1)
    (hab : b % a = ab) (hr : jacobiSymNat ab a = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.qr₁'
code: theorem jacobiSymNat.qr₁' (a b : ℕ) (r : ℤ) (ha : a % 2 = 1) (hb : b % 4 = 1)
    (hr : jacobiSymNat b a = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.qr₁'_mod
code: theorem jacobiSymNat.qr₁'_mod (a b ab : ℕ) (r : ℤ) (ha : a % 2 = 1) (hb : b % 4 = 1)
    (hab : b % a = ab) (hr : jacobiSymNat ab a = r) : jacobiSymNat a b = r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.qr₃
code: theorem jacobiSymNat.qr₃ (a b : ℕ) (r : ℤ) (ha : a % 4 = 3) (hb : b % 4 = 3)
    (hr : jacobiSymNat b a = r) : jacobiSymNat a b = -r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = -r

full_name: Mathlib.Meta.NormNum.jacobiSymNat.qr₃_mod
code: theorem jacobiSymNat.qr₃_mod (a b ab : ℕ) (r : ℤ) (ha : a % 4 = 3) (hb : b % 4 = 3)
    (hab : b % a = ab) (hr : jacobiSymNat ab a = r) : jacobiSymNat a b = -r 
goal: Mathlib.Meta.NormNum.jacobiSymNat a b = -r

full_name: Mathlib.Meta.NormNum.isInt_jacobiSym
code: theorem isInt_jacobiSym : {a na : ℤ} → {b nb : ℕ} → {r : ℤ} →
    IsInt a na → IsNat b nb → jacobiSym na nb = r → IsInt (jacobiSym a b) r
  
goal: Mathlib.Meta.NormNum.IsInt a na →
  Mathlib.Meta.NormNum.IsNat b nb → jacobiSym na nb = r → Mathlib.Meta.NormNum.IsInt (jacobiSym a b) r

full_name: Mathlib.Meta.NormNum.isInt_jacobiSymNat
code: theorem isInt_jacobiSymNat : {a na : ℕ} → {b nb : ℕ} → {r : ℤ} →
    IsNat a na → IsNat b nb → jacobiSymNat na nb = r → IsInt (jacobiSymNat a b) r
  
goal: Mathlib.Meta.NormNum.IsNat a na →
  Mathlib.Meta.NormNum.IsNat b nb →
    Mathlib.Meta.NormNum.jacobiSymNat na nb = r → Mathlib.Meta.NormNum.IsInt (Mathlib.Meta.NormNum.jacobiSymNat a b) r

full_name: Mathlib.Meta.NormNum.proveJacobiSymOdd
code: /-- This evaluates `r := jacobiSymNat a b` recursively using quadratic reciprocity
and produces a proof term for the equality, assuming that `a < b` and `b` is odd. -/
partial def proveJacobiSymOdd (ea eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSymNat $ea $eb = $er) 
goal: (er : Q(ℤ)) × Q(Mathlib.Meta.NormNum.jacobiSymNat «$ea» «$eb» = «$er»)

full_name: Mathlib.Meta.NormNum.proveJacobiSymNat
code: /-- This evaluates `r := jacobiSymNat a b` and produces a proof term for the equality
by removing powers of `2` from `b` and then calling `proveJacobiSymOdd`. -/
partial def proveJacobiSymNat (ea eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSymNat $ea $eb = $er) 
goal: (er : Q(ℤ)) × Q(Mathlib.Meta.NormNum.jacobiSymNat «$ea» «$eb» = «$er»)

full_name: Mathlib.Meta.NormNum.proveJacobiSym
code: /-- This evaluates `r := jacobiSym a b` and produces a proof term for the equality.
This is done by reducing to `r := jacobiSymNat (a % b) b`. -/
partial def proveJacobiSym (ea : Q(ℤ)) (eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSym $ea $eb = $er) 
goal: (er : Q(ℤ)) × Q(jacobiSym «$ea» «$eb» = «$er»)

full_name: Tactic.NormNum.evalJacobiSym
code: /-- This is the `norm_num` plug-in that evaluates Jacobi symbols. -/
@[norm_num jacobiSym _ _]
def evalJacobiSym : NormNumExt 
goal: Mathlib.Meta.NormNum.NormNumExt

full_name: Tactic.NormNum.evalJacobiSymNat
code: /-- This is the `norm_num` plug-in that evaluates Jacobi symbols on natural numbers. -/
@[norm_num jacobiSymNat _ _]
def evalJacobiSymNat : NormNumExt 
goal: Mathlib.Meta.NormNum.NormNumExt

full_name: Tactic.NormNum.evalLegendreSym
code: /-- This is the `norm_num` plug-in that evaluates Legendre symbols. -/
@[norm_num legendreSym _ _]
def evalLegendreSym : NormNumExt 
goal: Mathlib.Meta.NormNum.NormNumExt