number_theory.legendre_symbol.norm_numMathlib.Tactic.NormNum.LegendreSymbol

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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

(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
@@ -163,6 +163,7 @@ theorem Mathlib.Meta.NormNum.jacobiSymNat.odd_even (a b : ℕ) (r : ℤ)
   cases' eq_or_ne b 0 with hb hb
   · rw [← hr, hb, jacobi_sym_nat.zero_right]
   · haveI : NeZero b := ⟨hb⟩
+    -- for `jacobi_sym.mul_right`
     rwa [bit0_eq_two_mul b, jacobi_sym_nat, jacobiSym.mul_right, ←
       _root_.legendre_sym.to_jacobi_sym, Nat.cast_bit1, ha, one_mul]
 #align norm_num.jacobi_sym_nat.odd_even Mathlib.Meta.NormNum.jacobiSymNat.odd_even
Diff
@@ -145,8 +145,8 @@ theorem Mathlib.Meta.NormNum.jacobiSymNat.even_even (a b : ℕ) (hb₀ : b ≠ 0
   by
   refine' jacobi_sym.eq_zero_iff.mpr ⟨Nat.bit0_ne_zero hb₀, fun hf => _⟩
   have h : 2 ∣ (bit0 a).gcd (bit0 b) := Nat.dvd_gcd two_dvd_bit0 two_dvd_bit0
-  change 2 ∣ (bit0 a : ℤ).gcd (bit0 b) at h 
-  rw [← Nat.cast_bit0, ← Nat.cast_bit0, hf, ← even_iff_two_dvd] at h 
+  change 2 ∣ (bit0 a : ℤ).gcd (bit0 b) at h
+  rw [← Nat.cast_bit0, ← Nat.cast_bit0, hf, ← even_iff_two_dvd] at h
   exact Nat.not_even_one h
 #align norm_num.jacobi_sym_nat.even_even Mathlib.Meta.NormNum.jacobiSymNat.even_even
 -/
@@ -163,7 +163,6 @@ theorem Mathlib.Meta.NormNum.jacobiSymNat.odd_even (a b : ℕ) (r : ℤ)
   cases' eq_or_ne b 0 with hb hb
   · rw [← hr, hb, jacobi_sym_nat.zero_right]
   · haveI : NeZero b := ⟨hb⟩
-    -- for `jacobi_sym.mul_right`
     rwa [bit0_eq_two_mul b, jacobi_sym_nat, jacobiSym.mul_right, ←
       _root_.legendre_sym.to_jacobi_sym, Nat.cast_bit1, ha, one_mul]
 #align norm_num.jacobi_sym_nat.odd_even Mathlib.Meta.NormNum.jacobiSymNat.odd_even
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2022 Michael Stoll. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Michael Stoll
 -/
-import Mathbin.NumberTheory.LegendreSymbol.JacobiSymbol
+import NumberTheory.LegendreSymbol.JacobiSymbol
 
 #align_import number_theory.legendre_symbol.norm_num from "leanprover-community/mathlib"@"d0b1936853671209a866fa35b9e54949c81116e2"
 
Diff
@@ -2,14 +2,11 @@
 Copyright (c) 2022 Michael Stoll. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Michael Stoll
-
-! This file was ported from Lean 3 source module number_theory.legendre_symbol.norm_num
-! leanprover-community/mathlib commit d0b1936853671209a866fa35b9e54949c81116e2
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.NumberTheory.LegendreSymbol.JacobiSymbol
 
+#align_import number_theory.legendre_symbol.norm_num from "leanprover-community/mathlib"@"d0b1936853671209a866fa35b9e54949c81116e2"
+
 /-!
 # A `norm_num` extension for Jacobi and Legendre symbols
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Michael Stoll
 
 ! This file was ported from Lean 3 source module number_theory.legendre_symbol.norm_num
-! leanprover-community/mathlib commit e2621d935895abe70071ab828a4ee6e26a52afe4
+! leanprover-community/mathlib commit d0b1936853671209a866fa35b9e54949c81116e2
 ! 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.JacobiSymbol
 /-!
 # A `norm_num` extension for Jacobi and Legendre symbols
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 We extend the `tactic.interactive.norm_num` tactic so that it can be used to provably compute
 the value of the Jacobi symbol `J(a | b)` or the Legendre symbol `legendre_sym p a` when
 the arguments are numerals.
Diff
@@ -54,10 +54,12 @@ section Lemmas
 
 namespace NormNum
 
+#print Mathlib.Meta.NormNum.jacobiSymNat /-
 /-- The Jacobi symbol restricted to natural numbers in both arguments. -/
-def jacobiSymNat (a b : ℕ) : ℤ :=
+def Mathlib.Meta.NormNum.jacobiSymNat (a b : ℕ) : ℤ :=
   jacobiSym a b
-#align norm_num.jacobi_sym_nat NormNum.jacobiSymNat
+#align norm_num.jacobi_sym_nat Mathlib.Meta.NormNum.jacobiSymNat
+-/
 
 /-!
 ### API Lemmas
@@ -67,60 +69,93 @@ arguments, in a form that is suitable for constructing proofs in `norm_num`.
 -/
 
 
+#print Mathlib.Meta.NormNum.jacobiSymNat.zero_right /-
 /-- Base cases: `b = 0`, `b = 1`, `a = 0`, `a = 1`. -/
-theorem jacobiSymNat.zero_right (a : ℕ) : jacobiSymNat a 0 = 1 := by
-  rwa [jacobi_sym_nat, jacobiSym.zero_right]
-#align norm_num.jacobi_sym_nat.zero_right NormNum.jacobiSymNat.zero_right
+theorem Mathlib.Meta.NormNum.jacobiSymNat.zero_right (a : ℕ) :
+    Mathlib.Meta.NormNum.jacobiSymNat a 0 = 1 := by rwa [jacobi_sym_nat, jacobiSym.zero_right]
+#align norm_num.jacobi_sym_nat.zero_right Mathlib.Meta.NormNum.jacobiSymNat.zero_right
+-/
 
-theorem jacobiSymNat.one_right (a : ℕ) : jacobiSymNat a 1 = 1 := by
-  rwa [jacobi_sym_nat, jacobiSym.one_right]
-#align norm_num.jacobi_sym_nat.one_right NormNum.jacobiSymNat.one_right
+#print Mathlib.Meta.NormNum.jacobiSymNat.one_right /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.one_right (a : ℕ) :
+    Mathlib.Meta.NormNum.jacobiSymNat a 1 = 1 := by rwa [jacobi_sym_nat, jacobiSym.one_right]
+#align norm_num.jacobi_sym_nat.one_right Mathlib.Meta.NormNum.jacobiSymNat.one_right
+-/
 
-theorem jacobiSymNat.zero_left_even (b : ℕ) (hb : b ≠ 0) : jacobiSymNat 0 (bit0 b) = 0 := by
+#print Mathlib.Meta.NormNum.jacobiSymNat.zero_left /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.zero_left (b : ℕ) (hb : b ≠ 0) :
+    Mathlib.Meta.NormNum.jacobiSymNat 0 (bit0 b) = 0 := by
   rw [jacobi_sym_nat, Nat.cast_zero, jacobiSym.zero_left (Nat.one_lt_bit0 hb)]
-#align norm_num.jacobi_sym_nat.zero_left_even NormNum.jacobiSymNat.zero_left_even
+#align norm_num.jacobi_sym_nat.zero_left_even Mathlib.Meta.NormNum.jacobiSymNat.zero_left
+-/
 
-theorem jacobiSymNat.zero_left_odd (b : ℕ) (hb : b ≠ 0) : jacobiSymNat 0 (bit1 b) = 0 := by
+/- warning: norm_num.jacobi_sym_nat.zero_left_odd clashes with norm_num.jacobi_sym_nat.zero_left_even -> Mathlib.Meta.NormNum.jacobiSymNat.zero_left
+Case conversion may be inaccurate. Consider using '#align norm_num.jacobi_sym_nat.zero_left_odd Mathlib.Meta.NormNum.jacobiSymNat.zero_leftₓ'. -/
+#print Mathlib.Meta.NormNum.jacobiSymNat.zero_left /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.zero_left (b : ℕ) (hb : b ≠ 0) :
+    Mathlib.Meta.NormNum.jacobiSymNat 0 (bit1 b) = 0 := by
   rw [jacobi_sym_nat, Nat.cast_zero, jacobiSym.zero_left (Nat.one_lt_bit1 hb)]
-#align norm_num.jacobi_sym_nat.zero_left_odd NormNum.jacobiSymNat.zero_left_odd
+#align norm_num.jacobi_sym_nat.zero_left_odd Mathlib.Meta.NormNum.jacobiSymNat.zero_left
+-/
 
-theorem jacobiSymNat.one_left_even (b : ℕ) : jacobiSymNat 1 (bit0 b) = 1 := by
+#print Mathlib.Meta.NormNum.jacobiSymNat.one_left /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.one_left (b : ℕ) :
+    Mathlib.Meta.NormNum.jacobiSymNat 1 (bit0 b) = 1 := by
   rw [jacobi_sym_nat, Nat.cast_one, jacobiSym.one_left]
-#align norm_num.jacobi_sym_nat.one_left_even NormNum.jacobiSymNat.one_left_even
+#align norm_num.jacobi_sym_nat.one_left_even Mathlib.Meta.NormNum.jacobiSymNat.one_left
+-/
 
-theorem jacobiSymNat.one_left_odd (b : ℕ) : jacobiSymNat 1 (bit1 b) = 1 := by
+/- warning: norm_num.jacobi_sym_nat.one_left_odd clashes with norm_num.jacobi_sym_nat.one_left_even -> Mathlib.Meta.NormNum.jacobiSymNat.one_left
+Case conversion may be inaccurate. Consider using '#align norm_num.jacobi_sym_nat.one_left_odd Mathlib.Meta.NormNum.jacobiSymNat.one_leftₓ'. -/
+#print Mathlib.Meta.NormNum.jacobiSymNat.one_left /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.one_left (b : ℕ) :
+    Mathlib.Meta.NormNum.jacobiSymNat 1 (bit1 b) = 1 := by
   rw [jacobi_sym_nat, Nat.cast_one, jacobiSym.one_left]
-#align norm_num.jacobi_sym_nat.one_left_odd NormNum.jacobiSymNat.one_left_odd
+#align norm_num.jacobi_sym_nat.one_left_odd Mathlib.Meta.NormNum.jacobiSymNat.one_left
+-/
 
+#print Mathlib.Meta.NormNum.LegendreSym.to_jacobiSym /-
 /-- Turn a Legendre symbol into a Jacobi symbol. -/
-theorem LegendreSym.to_jacobiSym (p : ℕ) (pp : Fact p.Prime) (a r : ℤ) (hr : jacobiSym a p = r) :
-    legendreSym p a = r := by rwa [@jacobiSym.legendreSym.to_jacobiSym p pp a]
-#align norm_num.legendre_sym.to_jacobi_sym NormNum.LegendreSym.to_jacobiSym
+theorem Mathlib.Meta.NormNum.LegendreSym.to_jacobiSym (p : ℕ) (pp : Fact p.Prime) (a r : ℤ)
+    (hr : jacobiSym a p = r) : legendreSym p a = r := by
+  rwa [@jacobiSym.legendreSym.to_jacobiSym p pp a]
+#align norm_num.legendre_sym.to_jacobi_sym Mathlib.Meta.NormNum.LegendreSym.to_jacobiSym
+-/
 
+#print Mathlib.Meta.NormNum.JacobiSym.mod_left /-
 /-- 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 := by
+theorem Mathlib.Meta.NormNum.JacobiSym.mod_left (a : ℤ) (b ab' : ℕ) (ab r b' : ℤ)
+    (hb' : (b : ℤ) = b') (hab : a % b' = ab) (h : (ab' : ℤ) = ab)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat ab' b = r) : jacobiSym a b = r := by
   rw [← hr, jacobi_sym_nat, jacobiSym.mod_left, hb', hab, ← h]
-#align norm_num.jacobi_sym.mod_left NormNum.JacobiSym.mod_left
+#align norm_num.jacobi_sym.mod_left Mathlib.Meta.NormNum.JacobiSym.mod_left
+-/
 
-theorem jacobiSymNat.mod_left (a b ab : ℕ) (r : ℤ) (hab : a % b = ab) (hr : jacobiSymNat ab b = r) :
-    jacobiSymNat a b = r := by
-  rw [← hr, jacobi_sym_nat, jacobi_sym_nat, _root_.jacobi_sym.mod_left a b, ← hab]; rfl
-#align norm_num.jacobi_sym_nat.mod_left NormNum.jacobiSymNat.mod_left
+#print Mathlib.Meta.NormNum.jacobiSymNat.mod_left /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.mod_left (a b ab : ℕ) (r : ℤ) (hab : a % b = ab)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat ab b = r) : Mathlib.Meta.NormNum.jacobiSymNat a b = r :=
+  by rw [← hr, jacobi_sym_nat, jacobi_sym_nat, _root_.jacobi_sym.mod_left a b, ← hab]; rfl
+#align norm_num.jacobi_sym_nat.mod_left Mathlib.Meta.NormNum.jacobiSymNat.mod_left
+-/
 
+#print Mathlib.Meta.NormNum.jacobiSymNat.even_even /-
 /-- The symbol vanishes when both entries are even (and `b ≠ 0`). -/
-theorem jacobiSymNat.even_even (a b : ℕ) (hb₀ : b ≠ 0) : jacobiSymNat (bit0 a) (bit0 b) = 0 :=
+theorem Mathlib.Meta.NormNum.jacobiSymNat.even_even (a b : ℕ) (hb₀ : b ≠ 0) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit0 a) (bit0 b) = 0 :=
   by
   refine' jacobi_sym.eq_zero_iff.mpr ⟨Nat.bit0_ne_zero hb₀, fun hf => _⟩
   have h : 2 ∣ (bit0 a).gcd (bit0 b) := Nat.dvd_gcd two_dvd_bit0 two_dvd_bit0
   change 2 ∣ (bit0 a : ℤ).gcd (bit0 b) at h 
   rw [← Nat.cast_bit0, ← Nat.cast_bit0, hf, ← even_iff_two_dvd] at h 
   exact Nat.not_even_one h
-#align norm_num.jacobi_sym_nat.even_even NormNum.jacobiSymNat.even_even
+#align norm_num.jacobi_sym_nat.even_even Mathlib.Meta.NormNum.jacobiSymNat.even_even
+-/
 
+#print Mathlib.Meta.NormNum.jacobiSymNat.odd_even /-
 /-- When `a` is odd and `b` is even, we can replace `b` by `b / 2`. -/
-theorem jacobiSymNat.odd_even (a b : ℕ) (r : ℤ) (hr : jacobiSymNat (bit1 a) b = r) :
-    jacobiSymNat (bit1 a) (bit0 b) = r :=
+theorem Mathlib.Meta.NormNum.jacobiSymNat.odd_even (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat (bit1 a) b = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 a) (bit0 b) = r :=
   by
   have ha : legendreSym 2 (bit1 a) = 1 := by
     simp only [legendreSym, quadraticChar_apply, quadraticCharFun_one, Int.cast_bit1,
@@ -131,24 +166,30 @@ theorem jacobiSymNat.odd_even (a b : ℕ) (r : ℤ) (hr : jacobiSymNat (bit1 a)
     -- for `jacobi_sym.mul_right`
     rwa [bit0_eq_two_mul b, jacobi_sym_nat, jacobiSym.mul_right, ←
       _root_.legendre_sym.to_jacobi_sym, Nat.cast_bit1, ha, one_mul]
-#align norm_num.jacobi_sym_nat.odd_even NormNum.jacobiSymNat.odd_even
+#align norm_num.jacobi_sym_nat.odd_even Mathlib.Meta.NormNum.jacobiSymNat.odd_even
+-/
 
+#print Mathlib.Meta.NormNum.jacobiSymNat.double_even /-
 /-- 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 : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit1 b) = r) :
-    jacobiSymNat (bit0 (bit0 a)) (bit1 b) = r :=
+theorem Mathlib.Meta.NormNum.jacobiSymNat.double_even (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat a (bit1 b) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit0 (bit0 a)) (bit1 b) = r :=
   by
   have : ((2 : ℕ) : ℤ).gcd (bit1 b : ℕ) = 1 := by
     rw [Int.coe_nat_gcd, Nat.bit1_eq_succ_bit0, bit0_eq_two_mul b, Nat.succ_eq_add_one,
       Nat.gcd_mul_left_add_right, Nat.gcd_one_right]
   rwa [bit0_eq_two_mul a, bit0_eq_two_mul (2 * a), ← mul_assoc, ← pow_two, jacobi_sym_nat,
     Nat.cast_mul, Nat.cast_pow, jacobiSym.mul_left, jacobiSym.sq_one' this, one_mul]
-#align norm_num.jacobi_sym_nat.double_even NormNum.jacobiSymNat.double_even
+#align norm_num.jacobi_sym_nat.double_even Mathlib.Meta.NormNum.jacobiSymNat.double_even
+-/
 
+#print Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁ /-
 /-- 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 : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit1 (bit0 (bit0 b))) = r) :
-    jacobiSymNat (bit0 a) (bit1 (bit0 (bit0 b))) = r :=
+theorem Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁ (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat a (bit1 (bit0 (bit0 b))) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit0 a) (bit1 (bit0 (bit0 b))) = r :=
   by
   have hb : bit1 (bit0 (bit0 b)) % 8 = 1 := by
     rw [Nat.bit1_mod_bit0, Nat.bit0_mod_bit0, Nat.bit0_mod_two]
@@ -156,10 +197,13 @@ theorem jacobiSymNat.even_odd₁ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit
     jacobiSym.at_two (odd_bit1 _), ZMod.χ₈_nat_mod_eight, hb]
   norm_num
   exact hr
-#align norm_num.jacobi_sym_nat.even_odd₁ NormNum.jacobiSymNat.even_odd₁
+#align norm_num.jacobi_sym_nat.even_odd₁ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁
+-/
 
-theorem jacobiSymNat.even_odd₇ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit1 (bit1 (bit1 b))) = r) :
-    jacobiSymNat (bit0 a) (bit1 (bit1 (bit1 b))) = r :=
+#print Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇ /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇ (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat a (bit1 (bit1 (bit1 b))) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit0 a) (bit1 (bit1 (bit1 b))) = r :=
   by
   have hb : bit1 (bit1 (bit1 b)) % 8 = 7 := by
     rw [Nat.bit1_mod_bit0, Nat.bit1_mod_bit0, Nat.bit1_mod_two]
@@ -167,10 +211,13 @@ theorem jacobiSymNat.even_odd₇ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit
     jacobiSym.at_two (odd_bit1 _), ZMod.χ₈_nat_mod_eight, hb]
   norm_num
   exact hr
-#align norm_num.jacobi_sym_nat.even_odd₇ NormNum.jacobiSymNat.even_odd₇
+#align norm_num.jacobi_sym_nat.even_odd₇ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇
+-/
 
-theorem jacobiSymNat.even_odd₃ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit1 (bit1 (bit0 b))) = r) :
-    jacobiSymNat (bit0 a) (bit1 (bit1 (bit0 b))) = -r :=
+#print Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃ /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃ (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat a (bit1 (bit1 (bit0 b))) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit0 a) (bit1 (bit1 (bit0 b))) = -r :=
   by
   have hb : bit1 (bit1 (bit0 b)) % 8 = 3 := by
     rw [Nat.bit1_mod_bit0, Nat.bit1_mod_bit0, Nat.bit0_mod_two]
@@ -178,10 +225,13 @@ theorem jacobiSymNat.even_odd₃ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit
     jacobiSym.at_two (odd_bit1 _), ZMod.χ₈_nat_mod_eight, hb]
   norm_num
   exact hr
-#align norm_num.jacobi_sym_nat.even_odd₃ NormNum.jacobiSymNat.even_odd₃
+#align norm_num.jacobi_sym_nat.even_odd₃ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃
+-/
 
-theorem jacobiSymNat.even_odd₅ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit1 (bit0 (bit1 b))) = r) :
-    jacobiSymNat (bit0 a) (bit1 (bit0 (bit1 b))) = -r :=
+#print Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅ /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅ (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat a (bit1 (bit0 (bit1 b))) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit0 a) (bit1 (bit0 (bit1 b))) = -r :=
   by
   have hb : bit1 (bit0 (bit1 b)) % 8 = 5 := by
     rw [Nat.bit1_mod_bit0, Nat.bit0_mod_bit0, Nat.bit1_mod_two]
@@ -189,48 +239,71 @@ theorem jacobiSymNat.even_odd₅ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat a (bit
     jacobiSym.at_two (odd_bit1 _), ZMod.χ₈_nat_mod_eight, hb]
   norm_num
   exact hr
-#align norm_num.jacobi_sym_nat.even_odd₅ NormNum.jacobiSymNat.even_odd₅
+#align norm_num.jacobi_sym_nat.even_odd₅ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅
+-/
 
+#print Mathlib.Meta.NormNum.jacobiSymNat.qr₁ /-
 /-- Use quadratic reciproity to reduce to smaller `b`. -/
-theorem jacobiSymNat.qr₁ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat (bit1 b) (bit1 (bit0 a)) = r) :
-    jacobiSymNat (bit1 (bit0 a)) (bit1 b) = r :=
+theorem Mathlib.Meta.NormNum.jacobiSymNat.qr₁ (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat (bit1 b) (bit1 (bit0 a)) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 (bit0 a)) (bit1 b) = r :=
   by
   have ha : bit1 (bit0 a) % 4 = 1 := by rw [Nat.bit1_mod_bit0, Nat.bit0_mod_two]
   have hb := Nat.bit1_mod_two
   rwa [jacobi_sym_nat, jacobiSym.quadratic_reciprocity_one_mod_four ha (nat.odd_iff.mpr hb)]
-#align norm_num.jacobi_sym_nat.qr₁ NormNum.jacobiSymNat.qr₁
+#align norm_num.jacobi_sym_nat.qr₁ Mathlib.Meta.NormNum.jacobiSymNat.qr₁
+-/
 
-theorem jacobiSymNat.qr₁_mod (a b ab : ℕ) (r : ℤ) (hab : bit1 b % bit1 (bit0 a) = ab)
-    (hr : jacobiSymNat ab (bit1 (bit0 a)) = r) : jacobiSymNat (bit1 (bit0 a)) (bit1 b) = r :=
-  jacobiSymNat.qr₁ _ _ _ <| jacobiSymNat.mod_left _ _ ab r hab hr
-#align norm_num.jacobi_sym_nat.qr₁_mod NormNum.jacobiSymNat.qr₁_mod
+#print Mathlib.Meta.NormNum.jacobiSymNat.qr₁_mod /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.qr₁_mod (a b ab : ℕ) (r : ℤ)
+    (hab : bit1 b % bit1 (bit0 a) = ab)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat ab (bit1 (bit0 a)) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 (bit0 a)) (bit1 b) = r :=
+  Mathlib.Meta.NormNum.jacobiSymNat.qr₁ _ _ _ <|
+    Mathlib.Meta.NormNum.jacobiSymNat.mod_left _ _ ab r hab hr
+#align norm_num.jacobi_sym_nat.qr₁_mod Mathlib.Meta.NormNum.jacobiSymNat.qr₁_mod
+-/
 
-theorem jacobiSymNat.qr₁' (a b : ℕ) (r : ℤ) (hr : jacobiSymNat (bit1 (bit0 b)) (bit1 a) = r) :
-    jacobiSymNat (bit1 a) (bit1 (bit0 b)) = r :=
+#print Mathlib.Meta.NormNum.jacobiSymNat.qr₁' /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.qr₁' (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat (bit1 (bit0 b)) (bit1 a) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 a) (bit1 (bit0 b)) = r :=
   by
   have hb : bit1 (bit0 b) % 4 = 1 := by rw [Nat.bit1_mod_bit0, Nat.bit0_mod_two]
   have ha := Nat.bit1_mod_two
   rwa [jacobi_sym_nat, ← jacobiSym.quadratic_reciprocity_one_mod_four hb (nat.odd_iff.mpr ha)]
-#align norm_num.jacobi_sym_nat.qr₁' NormNum.jacobiSymNat.qr₁'
+#align norm_num.jacobi_sym_nat.qr₁' Mathlib.Meta.NormNum.jacobiSymNat.qr₁'
+-/
 
-theorem jacobiSymNat.qr₁'_mod (a b ab : ℕ) (r : ℤ) (hab : bit1 (bit0 b) % bit1 a = ab)
-    (hr : jacobiSymNat ab (bit1 a) = r) : jacobiSymNat (bit1 a) (bit1 (bit0 b)) = r :=
-  jacobiSymNat.qr₁' _ _ _ <| jacobiSymNat.mod_left _ _ ab r hab hr
-#align norm_num.jacobi_sym_nat.qr₁'_mod NormNum.jacobiSymNat.qr₁'_mod
+#print Mathlib.Meta.NormNum.jacobiSymNat.qr₁'_mod /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.qr₁'_mod (a b ab : ℕ) (r : ℤ)
+    (hab : bit1 (bit0 b) % bit1 a = ab) (hr : Mathlib.Meta.NormNum.jacobiSymNat ab (bit1 a) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 a) (bit1 (bit0 b)) = r :=
+  Mathlib.Meta.NormNum.jacobiSymNat.qr₁' _ _ _ <|
+    Mathlib.Meta.NormNum.jacobiSymNat.mod_left _ _ ab r hab hr
+#align norm_num.jacobi_sym_nat.qr₁'_mod Mathlib.Meta.NormNum.jacobiSymNat.qr₁'_mod
+-/
 
-theorem jacobiSymNat.qr₃ (a b : ℕ) (r : ℤ) (hr : jacobiSymNat (bit1 (bit1 b)) (bit1 (bit1 a)) = r) :
-    jacobiSymNat (bit1 (bit1 a)) (bit1 (bit1 b)) = -r :=
+#print Mathlib.Meta.NormNum.jacobiSymNat.qr₃ /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.qr₃ (a b : ℕ) (r : ℤ)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat (bit1 (bit1 b)) (bit1 (bit1 a)) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 (bit1 a)) (bit1 (bit1 b)) = -r :=
   by
   have hb : bit1 (bit1 b) % 4 = 3 := by rw [Nat.bit1_mod_bit0, Nat.bit1_mod_two]
   have ha : bit1 (bit1 a) % 4 = 3 := by rw [Nat.bit1_mod_bit0, Nat.bit1_mod_two]
   rwa [jacobi_sym_nat, jacobiSym.quadratic_reciprocity_three_mod_four ha hb, neg_inj]
-#align norm_num.jacobi_sym_nat.qr₃ NormNum.jacobiSymNat.qr₃
+#align norm_num.jacobi_sym_nat.qr₃ Mathlib.Meta.NormNum.jacobiSymNat.qr₃
+-/
 
-theorem jacobiSymNat.qr₃_mod (a b ab : ℕ) (r : ℤ) (hab : bit1 (bit1 b) % bit1 (bit1 a) = ab)
-    (hr : jacobiSymNat ab (bit1 (bit1 a)) = r) :
-    jacobiSymNat (bit1 (bit1 a)) (bit1 (bit1 b)) = -r :=
-  jacobiSymNat.qr₃ _ _ _ <| jacobiSymNat.mod_left _ _ ab r hab hr
-#align norm_num.jacobi_sym_nat.qr₃_mod NormNum.jacobiSymNat.qr₃_mod
+#print Mathlib.Meta.NormNum.jacobiSymNat.qr₃_mod /-
+theorem Mathlib.Meta.NormNum.jacobiSymNat.qr₃_mod (a b ab : ℕ) (r : ℤ)
+    (hab : bit1 (bit1 b) % bit1 (bit1 a) = ab)
+    (hr : Mathlib.Meta.NormNum.jacobiSymNat ab (bit1 (bit1 a)) = r) :
+    Mathlib.Meta.NormNum.jacobiSymNat (bit1 (bit1 a)) (bit1 (bit1 b)) = -r :=
+  Mathlib.Meta.NormNum.jacobiSymNat.qr₃ _ _ _ <|
+    Mathlib.Meta.NormNum.jacobiSymNat.mod_left _ _ ab r hab hr
+#align norm_num.jacobi_sym_nat.qr₃_mod Mathlib.Meta.NormNum.jacobiSymNat.qr₃_mod
+-/
 
 end NormNum
 
@@ -250,9 +323,10 @@ namespace NormNum
 
 open Tactic
 
+#print Mathlib.Meta.NormNum.proveJacobiSymOdd /-
 /-- This evaluates `r := jacobi_sym_nat a b` recursively using quadratic reciprocity
 and produces a proof term for the equality, assuming that `a < b` and `b` is odd. -/
-unsafe def prove_jacobi_sym_odd :
+unsafe def Mathlib.Meta.NormNum.proveJacobiSymOdd :
     instance_cache →
       instance_cache → expr → expr → tactic (instance_cache × instance_cache × expr × expr)
   | zc, nc, ea, eb => do
@@ -260,7 +334,7 @@ unsafe def prove_jacobi_sym_odd :
       |
       match_numeral_result.one =>-- `b = 1`, result is `1`
           pure
-          (zc, nc, q((1 : ℤ)), q(jacobiSymNat.one_right).mk_app [ea])
+          (zc, nc, q((1 : ℤ)), q(Mathlib.Meta.NormNum.jacobiSymNat.one_right).mk_app [ea])
       | match_numeral_result.bit1 eb₁ => do
         -- `b > 1` (recall that `b` is odd)
           match match_numeral ea with
@@ -271,11 +345,12 @@ unsafe def prove_jacobi_sym_odd :
             let (nc, phb₀) ← prove_ne nc eb₁ q((0 : ℕ)) b 0
             -- proof of `b ≠ 0`
                 pure
-                (zc, nc, q((0 : ℤ)), q(jacobiSymNat.zero_left_odd).mk_app [eb₁, phb₀])
+                (zc, nc, q((0 : ℤ)),
+                  q(Mathlib.Meta.NormNum.jacobiSymNat.zero_left).mk_app [eb₁, phb₀])
           | match_numeral_result.one => do
             -- `a = 1`, result is `1`
                 pure
-                (zc, nc, q((1 : ℤ)), q(jacobiSymNat.one_left_odd).mk_app [eb₁])
+                (zc, nc, q((1 : ℤ)), q(Mathlib.Meta.NormNum.jacobiSymNat.one_left).mk_app [eb₁])
           | match_numeral_result.bit0 ea₁ => do
             -- `a` is even; check if divisible by `4`
               match match_numeral ea₁ with
@@ -283,7 +358,8 @@ unsafe def prove_jacobi_sym_odd :
                 let (zc, nc, er, p) ← prove_jacobi_sym_odd zc nc ea₂ eb
                 -- compute `jacobi_sym_nat (a / 4) b`
                     pure
-                    (zc, nc, er, q(jacobiSymNat.double_even).mk_app [ea₂, eb₁, er, p])
+                    (zc, nc, er,
+                      q(Mathlib.Meta.NormNum.jacobiSymNat.double_even).mk_app [ea₂, eb₁, er, p])
               | _ => do
                 let-- reduce to `a / 2`; need to consider `b % 8`
                   (zc, nc, er, p)
@@ -297,7 +373,10 @@ unsafe def prove_jacobi_sym_odd :
                       ←-- `b = 3`
                         er
                     let (zc, er') ← zc (-r)
-                    pure (zc, nc, er', q(jacobiSymNat.even_odd₃).mk_app [ea₁, q((0 : ℕ)), er, p])
+                    pure
+                        (zc, nc, er',
+                          q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃).mk_app
+                            [ea₁, q((0 : ℕ)), er, p])
                   | match_numeral_result.bit0 eb₂ => do
                     -- `b % 4 = 1`
                       match match_numeral eb₂ with
@@ -309,17 +388,24 @@ unsafe def prove_jacobi_sym_odd :
                             er
                         let (zc, er') ← zc (-r)
                         pure
-                            (zc, nc, er', q(jacobiSymNat.even_odd₅).mk_app [ea₁, q((0 : ℕ)), er, p])
+                            (zc, nc, er',
+                              q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅).mk_app
+                                [ea₁, q((0 : ℕ)), er, p])
                       | match_numeral_result.bit0 eb₃ => do
                         -- `b % 8 = 1`
                             pure
-                            (zc, nc, er, q(jacobiSymNat.even_odd₁).mk_app [ea₁, eb₃, er, p])
+                            (zc, nc, er,
+                              q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁).mk_app
+                                [ea₁, eb₃, er, p])
                       | match_numeral_result.bit1 eb₃ => do
                         let r
                           ←-- `b % 8 = 5`
                             er
                         let (zc, er') ← zc (-r)
-                        pure (zc, nc, er', q(jacobiSymNat.even_odd₅).mk_app [ea₁, eb₃, er, p])
+                        pure
+                            (zc, nc, er',
+                              q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅).mk_app
+                                [ea₁, eb₃, er, p])
                       | _ => failed
                   | match_numeral_result.bit1 eb₂ => do
                     -- `b % 4 = 3`
@@ -329,17 +415,24 @@ unsafe def prove_jacobi_sym_odd :
                         do
                         -- `b = 7`
                             pure
-                            (zc, nc, er, q(jacobiSymNat.even_odd₇).mk_app [ea₁, q((0 : ℕ)), er, p])
+                            (zc, nc, er,
+                              q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇).mk_app
+                                [ea₁, q((0 : ℕ)), er, p])
                       | match_numeral_result.bit0 eb₃ => do
                         let r
                           ←-- `b % 8 = 3`
                             er
                         let (zc, er') ← zc (-r)
-                        pure (zc, nc, er', q(jacobiSymNat.even_odd₃).mk_app [ea₁, eb₃, er, p])
+                        pure
+                            (zc, nc, er',
+                              q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃).mk_app
+                                [ea₁, eb₃, er, p])
                       | match_numeral_result.bit1 eb₃ => do
                         -- `b % 8 = 7`
                             pure
-                            (zc, nc, er, q(jacobiSymNat.even_odd₇).mk_app [ea₁, eb₃, er, p])
+                            (zc, nc, er,
+                              q(Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇).mk_app
+                                [ea₁, eb₃, er, p])
                       | _ => failed
                   | _ => failed
           | match_numeral_result.bit1 ea₁ => do
@@ -364,7 +457,9 @@ unsafe def prove_jacobi_sym_odd :
                     do
                     -- `b % 4 = 1`
                         pure
-                        (zc, nc, er, q(jacobiSymNat.qr₁'_mod).mk_app [ea₁, eb₂, bma, er, phab, p])
+                        (zc, nc, er,
+                          q(Mathlib.Meta.NormNum.jacobiSymNat.qr₁'_mod).mk_app
+                            [ea₁, eb₂, bma, er, phab, p])
                   | match_numeral_result.bit1 eb₂ => do
                     let r
                       ←-- `b % 4 = 3`
@@ -372,12 +467,15 @@ unsafe def prove_jacobi_sym_odd :
                     let (zc, er') ← zc (-r)
                     pure
                         (zc, nc, er',
-                          q(jacobiSymNat.qr₃_mod).mk_app [q((0 : ℕ)), eb₂, bma, er, phab, p])
+                          q(Mathlib.Meta.NormNum.jacobiSymNat.qr₃_mod).mk_app
+                            [q((0 : ℕ)), eb₂, bma, er, phab, p])
                   | _ => failed
               | match_numeral_result.bit0 ea₂ => do
                 -- `a % 4 = 1`
                     pure
-                    (zc, nc, er, q(jacobiSymNat.qr₁_mod).mk_app [ea₂, eb₁, bma, er, phab, p])
+                    (zc, nc, er,
+                      q(Mathlib.Meta.NormNum.jacobiSymNat.qr₁_mod).mk_app
+                        [ea₂, eb₁, bma, er, phab, p])
               | match_numeral_result.bit1 ea₂ => do
                 -- `a % 4 = 3`; need to consider `b`
                   match match_numeral eb₁ with
@@ -388,22 +486,29 @@ unsafe def prove_jacobi_sym_odd :
                     do
                     -- `b % 4 = 1`
                         pure
-                        (zc, nc, er, q(jacobiSymNat.qr₁'_mod).mk_app [ea₁, eb₂, bma, er, phab, p])
+                        (zc, nc, er,
+                          q(Mathlib.Meta.NormNum.jacobiSymNat.qr₁'_mod).mk_app
+                            [ea₁, eb₂, bma, er, phab, p])
                   | match_numeral_result.bit1 eb₂ => do
                     let r
                       ←-- `b % 4 = 3`
                         er
                     let (zc, er') ← zc (-r)
-                    pure (zc, nc, er', q(jacobiSymNat.qr₃_mod).mk_app [ea₂, eb₂, bma, er, phab, p])
+                    pure
+                        (zc, nc, er',
+                          q(Mathlib.Meta.NormNum.jacobiSymNat.qr₃_mod).mk_app
+                            [ea₂, eb₂, bma, er, phab, p])
                   | _ => failed
               | _ => failed
           | _ => failed
       | _ => failed
-#align norm_num.prove_jacobi_sym_odd norm_num.prove_jacobi_sym_odd
+#align norm_num.prove_jacobi_sym_odd Mathlib.Meta.NormNum.proveJacobiSymOdd
+-/
 
+#print Mathlib.Meta.NormNum.proveJacobiSymNat /-
 /-- This evaluates `r := jacobi_sym_nat a b` and produces a proof term for the equality
 by removing powers of `2` from `b` and then calling `prove_jacobi_sym_odd`. -/
-unsafe def prove_jacobi_sym_nat :
+unsafe def Mathlib.Meta.NormNum.proveJacobiSymNat :
     instance_cache →
       instance_cache → expr → expr → tactic (instance_cache × instance_cache × expr × expr)
   | zc, nc, ea, eb => do
@@ -411,11 +516,11 @@ unsafe def prove_jacobi_sym_nat :
       |
       match_numeral_result.zero =>-- `b = 0`, result is `1`
           pure
-          (zc, nc, q((1 : ℤ)), q(jacobiSymNat.zero_right).mk_app [ea])
+          (zc, nc, q((1 : ℤ)), q(Mathlib.Meta.NormNum.jacobiSymNat.zero_right).mk_app [ea])
       |
       match_numeral_result.one =>-- `b = 1`, result is `1`
           pure
-          (zc, nc, q((1 : ℤ)), q(jacobiSymNat.one_right).mk_app [ea])
+          (zc, nc, q((1 : ℤ)), q(Mathlib.Meta.NormNum.jacobiSymNat.one_right).mk_app [ea])
       |
       match_numeral_result.bit0 eb₁ =>-- `b` is even and nonzero
         match match_numeral ea with
@@ -426,11 +531,12 @@ unsafe def prove_jacobi_sym_nat :
           let (nc, phb₀) ← prove_ne nc eb₁ q((0 : ℕ)) b 0
           -- proof of `b ≠ 0`
               pure
-              (zc, nc, q((0 : ℤ)), q(jacobiSymNat.zero_left_even).mk_app [eb₁, phb₀])
+              (zc, nc, q((0 : ℤ)),
+                q(Mathlib.Meta.NormNum.jacobiSymNat.zero_left).mk_app [eb₁, phb₀])
         | match_numeral_result.one => do
           -- `a = 1`, result is `1`
               pure
-              (zc, nc, q((1 : ℤ)), q(jacobiSymNat.one_left_even).mk_app [eb₁])
+              (zc, nc, q((1 : ℤ)), q(Mathlib.Meta.NormNum.jacobiSymNat.one_left).mk_app [eb₁])
         | match_numeral_result.bit0 ea₁ => do
           let b
             ←-- `a` is even, result is `0`
@@ -438,12 +544,12 @@ unsafe def prove_jacobi_sym_nat :
           let (nc, phb₀) ← prove_ne nc eb₁ q((0 : ℕ)) b 0
           let-- proof of `b ≠ 0`
           er : expr := q((0 : ℤ))
-          pure (zc, nc, er, q(jacobiSymNat.even_even).mk_app [ea₁, eb₁, phb₀])
+          pure (zc, nc, er, q(Mathlib.Meta.NormNum.jacobiSymNat.even_even).mk_app [ea₁, eb₁, phb₀])
         | match_numeral_result.bit1 ea₁ => do
           let-- `a` is odd, reduce to `b / 2`
             (zc, nc, er, p)
             ← prove_jacobi_sym_nat zc nc ea eb₁
-          pure (zc, nc, er, q(jacobiSymNat.odd_even).mk_app [ea₁, eb₁, er, p])
+          pure (zc, nc, er, q(Mathlib.Meta.NormNum.jacobiSymNat.odd_even).mk_app [ea₁, eb₁, er, p])
         | _ => failed
       | match_numeral_result.bit1 eb₁ => do
         let a
@@ -459,14 +565,17 @@ unsafe def prove_jacobi_sym_nat :
               ← prove_jacobi_sym_odd zc nc amb eb
             -- compute `jacobi_sym_nat (a % b) b`
                 pure
-                (zc, nc, er, q(jacobiSymNat.mod_left).mk_app [ea, eb, amb, er, phab, p])
+                (zc, nc, er,
+                  q(Mathlib.Meta.NormNum.jacobiSymNat.mod_left).mk_app [ea, eb, amb, er, phab, p])
           else prove_jacobi_sym_odd zc nc ea eb
       | _ => failed
-#align norm_num.prove_jacobi_sym_nat norm_num.prove_jacobi_sym_nat
+#align norm_num.prove_jacobi_sym_nat Mathlib.Meta.NormNum.proveJacobiSymNat
+-/
 
+#print Mathlib.Meta.NormNum.proveJacobiSym /-
 /-- This evaluates `r := jacobi_sym a b` and produces a proof term for the equality.
 This is done by reducing to `r := jacobi_sym_nat (a % b) b`. -/
-unsafe def prove_jacobi_sym :
+unsafe def Mathlib.Meta.NormNum.proveJacobiSym :
     instance_cache →
       instance_cache → expr → expr → tactic (instance_cache × instance_cache × expr × expr)
   | zc, nc, ea, eb => do
@@ -494,8 +603,10 @@ unsafe def prove_jacobi_sym :
         -- compute `jacobi_sym_nat (a % b) b`
             pure
             (zc, nc, er,
-              q(JacobiSym.mod_left).mk_app [ea, eb₁, amb', amb, er, eb', pb', phab, phab', p])
-#align norm_num.prove_jacobi_sym norm_num.prove_jacobi_sym
+              q(Mathlib.Meta.NormNum.JacobiSym.mod_left).mk_app
+                [ea, eb₁, amb', amb, er, eb', pb', phab, phab', p])
+#align norm_num.prove_jacobi_sym Mathlib.Meta.NormNum.proveJacobiSym
+-/
 
 end NormNum
 
@@ -512,33 +623,35 @@ namespace Tactic
 
 namespace NormNum
 
+#print Tactic.NormNum.evalJacobiSym /-
 /-- This is the `norm_num` plug-in that evaluates Jacobi and Legendre symbols. -/
 @[norm_num]
-unsafe def eval_jacobi_sym : expr → tactic (expr × expr)
+unsafe def evalJacobiSym : expr → tactic (expr × expr)
   | q(jacobiSym $(ea) $(eb)) => do
     let zc
       ←-- Jacobi symbol
           mk_instance_cache
           q(ℤ)
     let nc ← mk_instance_cache q(ℕ)
-    (Prod.snd ∘ Prod.snd) <$> norm_num.prove_jacobi_sym zc nc ea eb
-  | q(NormNum.jacobiSymNat $(ea) $(eb)) => do
+    (Prod.snd ∘ Prod.snd) <$> Mathlib.Meta.NormNum.proveJacobiSym zc nc ea eb
+  | q(Mathlib.Meta.NormNum.jacobiSymNat $(ea) $(eb)) => do
     let zc
       ←-- Jacobi symbol on natural numbers
           mk_instance_cache
           q(ℤ)
     let nc ← mk_instance_cache q(ℕ)
-    (Prod.snd ∘ Prod.snd) <$> norm_num.prove_jacobi_sym_nat zc nc ea eb
+    (Prod.snd ∘ Prod.snd) <$> Mathlib.Meta.NormNum.proveJacobiSymNat zc nc ea eb
   | q(@legendreSym $(ep) $(inst) $(ea)) => do
     let zc
       ←-- Legendre symbol
           mk_instance_cache
           q(ℤ)
     let nc ← mk_instance_cache q(ℕ)
-    let (zc, nc, er, pf) ← norm_num.prove_jacobi_sym zc nc ea ep
-    pure (er, q(NormNum.LegendreSym.to_jacobiSym).mk_app [ep, inst, ea, er, pf])
+    let (zc, nc, er, pf) ← Mathlib.Meta.NormNum.proveJacobiSym zc nc ea ep
+    pure (er, q(Mathlib.Meta.NormNum.LegendreSym.to_jacobiSym).mk_app [ep, inst, ea, er, pf])
   | _ => failed
-#align tactic.norm_num.eval_jacobi_sym tactic.norm_num.eval_jacobi_sym
+#align tactic.norm_num.eval_jacobi_sym Tactic.NormNum.evalJacobiSym
+-/
 
 end NormNum
 
Diff
@@ -94,7 +94,7 @@ theorem jacobiSymNat.one_left_odd (b : ℕ) : jacobiSymNat 1 (bit1 b) = 1 := by
 
 /-- Turn a Legendre symbol into a Jacobi symbol. -/
 theorem LegendreSym.to_jacobiSym (p : ℕ) (pp : Fact p.Prime) (a r : ℤ) (hr : jacobiSym a p = r) :
-    legendreSym p a = r := by rwa [@legendreSym.to_jacobiSym p pp a]
+    legendreSym p a = r := by rwa [@jacobiSym.legendreSym.to_jacobiSym p pp a]
 #align norm_num.legendre_sym.to_jacobi_sym NormNum.LegendreSym.to_jacobiSym
 
 /-- The value depends only on the residue class of `a` mod `b`. -/
Diff
@@ -113,8 +113,8 @@ theorem jacobiSymNat.even_even (a b : ℕ) (hb₀ : b ≠ 0) : jacobiSymNat (bit
   by
   refine' jacobi_sym.eq_zero_iff.mpr ⟨Nat.bit0_ne_zero hb₀, fun hf => _⟩
   have h : 2 ∣ (bit0 a).gcd (bit0 b) := Nat.dvd_gcd two_dvd_bit0 two_dvd_bit0
-  change 2 ∣ (bit0 a : ℤ).gcd (bit0 b) at h
-  rw [← Nat.cast_bit0, ← Nat.cast_bit0, hf, ← even_iff_two_dvd] at h
+  change 2 ∣ (bit0 a : ℤ).gcd (bit0 b) at h 
+  rw [← Nat.cast_bit0, ← Nat.cast_bit0, hf, ← even_iff_two_dvd] at h 
   exact Nat.not_even_one h
 #align norm_num.jacobi_sym_nat.even_even NormNum.jacobiSymNat.even_even
 
Diff
@@ -104,10 +104,8 @@ theorem JacobiSym.mod_left (a : ℤ) (b ab' : ℕ) (ab r b' : ℤ) (hb' : (b : 
 #align norm_num.jacobi_sym.mod_left NormNum.JacobiSym.mod_left
 
 theorem jacobiSymNat.mod_left (a b ab : ℕ) (r : ℤ) (hab : a % b = ab) (hr : jacobiSymNat ab b = r) :
-    jacobiSymNat a b = r :=
-  by
-  rw [← hr, jacobi_sym_nat, jacobi_sym_nat, _root_.jacobi_sym.mod_left a b, ← hab]
-  rfl
+    jacobiSymNat a b = r := by
+  rw [← hr, jacobi_sym_nat, jacobi_sym_nat, _root_.jacobi_sym.mod_left a b, ← hab]; rfl
 #align norm_num.jacobi_sym_nat.mod_left NormNum.jacobiSymNat.mod_left
 
 /-- The symbol vanishes when both entries are even (and `b ≠ 0`). -/

Changes in mathlib4

mathlib3
mathlib4
chore: move Mathlib to v4.7.0-rc1 (#11162)

This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0 branch as we update to intermediate nightlies.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>

Diff
@@ -145,28 +145,28 @@ theorem jacobiSymNat.even_odd₁ (a b c : ℕ) (r : ℤ) (ha : a % 2 = 0) (hb :
     (hc : a / 2 = c) (hr : jacobiSymNat c b = r) : jacobiSymNat a b = r := by
   simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
   rw [← jacobiSym.even_odd (mod_cast ha), if_neg (by simp [hb])]
-  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
+  rw [← Nat.mod_mod_of_dvd, hb]; norm_num
 #align norm_num.jacobi_sym_nat.even_odd₁ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁
 
 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 := by
   simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
   rw [← jacobiSym.even_odd (mod_cast ha), if_neg (by simp [hb])]
-  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
+  rw [← Nat.mod_mod_of_dvd, hb]; norm_num
 #align norm_num.jacobi_sym_nat.even_odd₇ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇
 
 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 := by
   simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
   rw [← jacobiSym.even_odd (mod_cast ha), if_pos (by simp [hb])]
-  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
+  rw [← Nat.mod_mod_of_dvd, hb]; norm_num
 #align norm_num.jacobi_sym_nat.even_odd₃ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃
 
 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 := by
   simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
   rw [← jacobiSym.even_odd (mod_cast ha), if_pos (by simp [hb])]
-  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
+  rw [← Nat.mod_mod_of_dvd, hb]; norm_num
 #align norm_num.jacobi_sym_nat.even_odd₅ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅
 
 /-- Use quadratic reciproity to reduce to smaller `b`. -/
feat(NumberTheory/LegendreSymbol): @[csimp] rule for jacobiSym and legendreSym (#9329)

Main definitions:

  • def jacobiSym.fastJacobiSym (a : ℤ) (b : ℕ) : ℤ
  • @[csimp] theorem jacobiSym.fastJacobiSym.eq : jacobiSym = jacobiSym.fastJacobiSym
  • def legendreSym.fastLegendreSym (p : ℕ) [Fact p.Prime] (a : ℤ) : ℤ
  • @[csimp] theorem legendreSym.fastLegendreSym.eq : legendreSym = legendreSym.fastLegendreSym

Also added tests

Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>

Diff
@@ -119,8 +119,7 @@ theorem jacobiSymNat.even_even (a b : ℕ) (hb₀ : Nat.beq (b / 2) 0 = false) (
 
 /-- 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 := by
+    (hr : jacobiSymNat a c = r) : jacobiSymNat a b = r := by
   have ha' : legendreSym 2 a = 1 := by
     simp only [legendreSym.mod 2 a, Int.ofNat_mod_ofNat, ha]
     decide
@@ -135,10 +134,8 @@ theorem jacobiSymNat.odd_even (a b c : ℕ) (r : ℤ) (ha : a % 2 = 1) (hb : b %
 /-- 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 := by
-  have : ((2 : ℕ) : ℤ).gcd b = 1 := by
-    rw [Int.coe_nat_gcd, ← Nat.mod_add_div b 2, hb, Nat.gcd_add_mul_left_right, Nat.gcd_one_right]
-  rwa [← Nat.mod_add_div a 4, ha, hc, Nat.zero_add, (by decide : 4 = 2 ^ 2), jacobiSymNat,
-    Nat.cast_mul, Nat.cast_pow, jacobiSym.mul_left, jacobiSym.sq_one' this, one_mul]
+  simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
+  exact (jacobiSym.div_four_left (mod_cast ha) hb).symm
 #align norm_num.jacobi_sym_nat.double_even Mathlib.Meta.NormNum.jacobiSymNat.double_even
 
 /-- If `a` is even and `b` is odd, then we can remove a factor `2` from `a`,
@@ -146,49 +143,30 @@ 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 := by
-  have hb' : Odd b := by
-    rw [← Nat.div_add_mod b 8, hb, Odd]
-    use 4 * (b / 8); rw [← Nat.mul_assoc]; congr
-  rw [jacobiSymNat, ← Nat.mod_add_div a 2, ha, hc, Nat.zero_add, Nat.cast_mul, jacobiSym.mul_left,
-    Nat.cast_two, jacobiSym.at_two hb', ZMod.χ₈_nat_mod_eight, hb]
-  norm_num
-  exact hr
+  simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
+  rw [← jacobiSym.even_odd (mod_cast ha), if_neg (by simp [hb])]
+  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
 #align norm_num.jacobi_sym_nat.even_odd₁ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₁
 
 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 := by
-  have hb' : Odd b := by
-    rw [← Nat.div_add_mod b 8, hb, Odd]
-    use 4 * (b / 8) + 3; rw [Nat.mul_add, ← Nat.mul_assoc, Nat.add_assoc]; congr
-  rw [jacobiSymNat, ← Nat.mod_add_div a 2, ha, hc, Nat.zero_add, Nat.cast_mul, jacobiSym.mul_left,
-    Nat.cast_two, jacobiSym.at_two hb', ZMod.χ₈_nat_mod_eight, hb,
-    (by decide : ZMod.χ₈ (7 : ℕ) = 1)]
-  norm_num
-  exact hr
+  simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
+  rw [← jacobiSym.even_odd (mod_cast ha), if_neg (by simp [hb])]
+  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
 #align norm_num.jacobi_sym_nat.even_odd₇ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₇
 
 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 := by
-  have hb' : Odd b := by
-    rw [← Nat.div_add_mod b 8, hb, Odd]
-    use 4 * (b / 8) + 1; rw [Nat.mul_add, ← Nat.mul_assoc, Nat.add_assoc]; congr
-  rw [jacobiSymNat, ← Nat.mod_add_div a 2, ha, hc, Nat.zero_add, Nat.cast_mul, jacobiSym.mul_left,
-    Nat.cast_two, jacobiSym.at_two hb', ZMod.χ₈_nat_mod_eight, hb,
-    (by decide : ZMod.χ₈ (3 : ℕ) = -1)]
-  norm_num
-  exact hr
+  simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
+  rw [← jacobiSym.even_odd (mod_cast ha), if_pos (by simp [hb])]
+  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
 #align norm_num.jacobi_sym_nat.even_odd₃ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₃
 
 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 := by
-  have hb' : Odd b := by
-    rw [← Nat.div_add_mod b 8, hb, Odd]
-    use 4 * (b / 8) + 2; rw [Nat.mul_add, ← Nat.mul_assoc, Nat.add_assoc]; congr
-  rw [jacobiSymNat, ← Nat.mod_add_div a 2, ha, hc, Nat.zero_add, Nat.cast_mul, jacobiSym.mul_left,
-    Nat.cast_two, jacobiSym.at_two hb', ZMod.χ₈_nat_mod_eight, hb,
-    (by decide : ZMod.χ₈ (5 : ℕ) = -1)]
-  norm_num
-  exact hr
+  simp only [jacobiSymNat, ← hr, ← hc, Int.ofNat_ediv, Nat.cast_ofNat]
+  rw [← jacobiSym.even_odd (mod_cast ha), if_pos (by simp [hb])]
+  rw [← Nat.mod_mod_of_dvd, hb] <;> norm_num
 #align norm_num.jacobi_sym_nat.even_odd₅ Mathlib.Meta.NormNum.jacobiSymNat.even_odd₅
 
 /-- Use quadratic reciproity to reduce to smaller `b`. -/
fix: patch for std4#198 (more mul lemmas for Nat) (#6204)

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

Diff
@@ -78,8 +78,7 @@ theorem jacobiSymNat.zero_left (b : ℕ) (hb : Nat.beq (b / 2) 0 = false) : jaco
   · calc
       1 < 2 * 1       := by decide
       _ ≤ 2 * (b / 2) :=
-        Nat.mul_le_mul_of_nonneg_left
-          (Nat.succ_le.mpr (Nat.pos_of_ne_zero (Nat.ne_of_beq_eq_false hb)))
+        Nat.mul_le_mul_left _ (Nat.succ_le.mpr (Nat.pos_of_ne_zero (Nat.ne_of_beq_eq_false hb)))
       _ ≤ b           := Nat.mul_div_le b 2
 #align norm_num.jacobi_sym_nat.zero_left_even Mathlib.Meta.NormNum.jacobiSymNat.zero_left
 #align norm_num.jacobi_sym_nat.zero_left_odd Mathlib.Meta.NormNum.jacobiSymNat.zero_left
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
@@ -124,6 +124,7 @@ theorem jacobiSymNat.odd_even (a b c : ℕ) (r : ℤ) (ha : a % 2 = 1) (hb : b %
     jacobiSymNat a b = r := by
   have ha' : legendreSym 2 a = 1 := by
     simp only [legendreSym.mod 2 a, Int.ofNat_mod_ofNat, ha]
+    decide
   rcases eq_or_ne c 0 with (rfl | hc')
   · rw [← hr, Nat.eq_zero_of_dvd_of_div_eq_zero (Nat.dvd_of_mod_eq_zero hb) hc]
   · haveI : NeZero c := ⟨hc'⟩
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,14 +2,11 @@
 Copyright (c) 2022 Michael Stoll. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Michael Stoll
-
-! This file was ported from Lean 3 source module number_theory.legendre_symbol.norm_num
-! leanprover-community/mathlib commit e2621d935895abe70071ab828a4ee6e26a52afe4
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.NumberTheory.LegendreSymbol.JacobiSymbol
 
+#align_import number_theory.legendre_symbol.norm_num from "leanprover-community/mathlib"@"e2621d935895abe70071ab828a4ee6e26a52afe4"
+
 /-!
 # A `norm_num` extension for Jacobi and Legendre symbols
 
chore: bump quote4 (#5975)
Diff
@@ -257,17 +257,17 @@ 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) :=
   match eb.natLit! with
   | 1 =>
-    show (er : Q(ℤ)) × Q(jacobiSymNat $ea 1 = $er) from
-      ⟨mkRawIntLit 1, q(jacobiSymNat.one_right $ea)⟩
+    haveI : $eb =Q 1 := ⟨⟩
+    ⟨mkRawIntLit 1, q(jacobiSymNat.one_right $ea)⟩
   | b =>
     match ea.natLit! with
     | 0 =>
+      haveI : $ea =Q 0 := ⟨⟩
       have hb : Q(Nat.beq ($eb / 2) 0 = false) := (q(Eq.refl false) : Expr)
-      show (er : Q(ℤ)) × Q(jacobiSymNat 0 $eb = $er) from
-        ⟨mkRawIntLit 0, q(jacobiSymNat.zero_left $eb $hb)⟩
+      ⟨mkRawIntLit 0, q(jacobiSymNat.zero_left $eb $hb)⟩
     | 1 =>
-      show (er : Q(ℤ)) × Q(jacobiSymNat 1 $eb = $er) from
-        ⟨mkRawIntLit 1, q(jacobiSymNat.one_left $eb)⟩
+      haveI : $ea =Q 1 := ⟨⟩
+      ⟨mkRawIntLit 1, q(jacobiSymNat.one_left $eb)⟩
     | a =>
       match a % 2 with
       | 0 =>
@@ -295,9 +295,9 @@ partial def proveJacobiSymOdd (ea eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSymNat
               ⟨er', q(jacobiSymNat.even_odd₃ $ea $eb $ec $er $ha $hb $hc $p)⟩
           | 5 =>
             have er' := mkRawIntLit (-er.intLit!)
+            haveI : $er' =Q -$er := ⟨⟩
             have hb : Q(Nat.mod $eb 8 = 5) := (q(Eq.refl 5) : Expr)
-            show (_ : Q(ℤ)) × Q(jacobiSymNat $ea $eb = -$er) from
-              ⟨er', q(jacobiSymNat.even_odd₅ $ea $eb $ec $er $ha $hb $hc $p)⟩
+            ⟨er', q(jacobiSymNat.even_odd₅ $ea $eb $ec $er $ha $hb $hc $p)⟩
           | _ =>
             have hb : Q(Nat.mod $eb 8 = 7) := (q(Eq.refl 7) : Expr)
             ⟨er, q(jacobiSymNat.even_odd₇ $ea $eb $ec $er $ha $hb $hc $p)⟩
@@ -318,10 +318,10 @@ partial def proveJacobiSymOdd (ea eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSymNat
             ⟨er, q(jacobiSymNat.qr₁'_mod $ea $eb $eab $er $ha $hb $hab $p)⟩
           | _ =>
             have er' := mkRawIntLit (-er.intLit!)
+            haveI : $er' =Q -$er := ⟨⟩
             have ha : Q(Nat.mod $ea 4 = 3) := (q(Eq.refl 3) : Expr)
             have hb : Q(Nat.mod $eb 4 = 3) := (q(Eq.refl 3) : Expr)
-            show (_ : Q(ℤ)) × Q(jacobiSymNat $ea $eb = -$er) from
-              ⟨er', q(jacobiSymNat.qr₃_mod $ea $eb $eab $er $ha $hb $hab $p)⟩
+            ⟨er', q(jacobiSymNat.qr₃_mod $ea $eb $eab $er $ha $hb $hab $p)⟩
 #align norm_num.prove_jacobi_sym_odd Mathlib.Meta.NormNum.proveJacobiSymOdd
 
 /-- This evaluates `r := jacobiSymNat a b` and produces a proof term for the equality
@@ -329,11 +329,11 @@ by removing powers of `2` from `b` and then calling `proveJacobiSymOdd`. -/
 partial def proveJacobiSymNat (ea eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSymNat $ea $eb = $er) :=
   match eb.natLit! with
   | 0 =>
-    show (er : Q(ℤ)) × Q(jacobiSymNat $ea 0 = $er) from
-      ⟨mkRawIntLit 1, q(jacobiSymNat.zero_right $ea)⟩
+    haveI : $eb =Q 0 := ⟨⟩
+    ⟨mkRawIntLit 1, q(jacobiSymNat.zero_right $ea)⟩
   | 1 =>
-    show (er : Q(ℤ)) × Q(jacobiSymNat $ea 1 = $er) from
-      ⟨mkRawIntLit 1, q(jacobiSymNat.one_right $ea)⟩
+    haveI : $eb =Q 1 := ⟨⟩
+    ⟨mkRawIntLit 1, q(jacobiSymNat.one_right $ea)⟩
   | b =>
     match b % 2 with
     | 0 =>
@@ -375,11 +375,11 @@ 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) :=
   match eb.natLit! with
   | 0 =>
-    show (er : Q(ℤ)) × Q(jacobiSym $ea 0 = $er) from
-      ⟨mkRawIntLit 1, q(jacobiSym.zero_right $ea)⟩
+    haveI : $eb =Q 0 := ⟨⟩
+    ⟨mkRawIntLit 1, q(jacobiSym.zero_right $ea)⟩
   | 1 =>
-    show (er : Q(ℤ)) × Q(jacobiSym $ea 1 = $er) from
-      ⟨mkRawIntLit 1, q(jacobiSym.one_right $ea)⟩
+    haveI : $eb =Q 1 := ⟨⟩
+    ⟨mkRawIntLit 1, q(jacobiSym.one_right $ea)⟩
   | b =>
     have eb' := mkRawIntLit b
     have hb' : Q(($eb : ℤ) = $eb') := (q(Eq.refl $eb') : Expr)
@@ -411,46 +411,39 @@ open Lean Elab Tactic Qq Mathlib.Meta.NormNum
 
 /-- This is the `norm_num` plug-in that evaluates Jacobi symbols. -/
 @[norm_num jacobiSym _ _]
-def evalJacobiSym : NormNumExt where
-  eval {u α} e := do
+def evalJacobiSym : NormNumExt where eval {u α} e := do
     let .app (.app _ (a : Q(ℤ))) (b : Q(ℕ)) ← Meta.whnfR e | failure
-    let sℕ : Q(AddMonoidWithOne ℕ) := q(instAddMonoidWithOneNat)
-    let sℤ : Q(Ring ℤ) := q(Int.instRingInt)
-    let ⟨ea, pa⟩ ← deriveInt a
-    let ⟨eb, pb⟩ ← deriveNat b
+    let ⟨ea, pa⟩ ← deriveInt a _
+    let ⟨eb, pb⟩ ← deriveNat b _
+    haveI' : u =QL 0 := ⟨⟩ haveI' : $α =Q ℤ := ⟨⟩
     have ⟨er, pr⟩ := proveJacobiSym ea eb
-    have p : Q(IsInt (jacobiSym $a $b) $er) := q(isInt_jacobiSym $pa $pb $pr)
-    return .isInt sℤ er er.intLit! p
+    haveI' : $e =Q jacobiSym $a $b := ⟨⟩
+    return .isInt _ er er.intLit! q(isInt_jacobiSym $pa $pb $pr)
 #align tactic.norm_num.eval_jacobi_sym Tactic.NormNum.evalJacobiSym
 
 /-- This is the `norm_num` plug-in that evaluates Jacobi symbols on natural numbers. -/
 @[norm_num jacobiSymNat _ _]
-def evalJacobiSymNat : NormNumExt where
-  eval {u α} e := do
+def evalJacobiSymNat : NormNumExt where eval {u α} e := do
     let .app (.app _ (a : Q(ℕ))) (b : Q(ℕ)) ← Meta.whnfR e | failure
-    let sℕ : Q(AddMonoidWithOne ℕ) := q(instAddMonoidWithOneNat)
-    let sℤ : Q(Ring ℤ) := q(Int.instRingInt)
-    let ⟨ea, pa⟩ ← deriveNat a
-    let ⟨eb, pb⟩ ← deriveNat b
+    let ⟨ea, pa⟩ ← deriveNat a _
+    let ⟨eb, pb⟩ ← deriveNat b _
+    haveI' : u =QL 0 := ⟨⟩ haveI' : $α =Q ℤ := ⟨⟩
     have ⟨er, pr⟩ := proveJacobiSymNat ea eb
-    have p : Q(IsInt (jacobiSymNat $a $b) $er) := q(isInt_jacobiSymNat $pa $pb $pr)
-    return .isInt sℤ er er.intLit! p
+    haveI' : $e =Q jacobiSymNat $a $b := ⟨⟩
+    return .isInt _ er er.intLit!  q(isInt_jacobiSymNat $pa $pb $pr)
 
 /-- This is the `norm_num` plug-in that evaluates Legendre symbols. -/
 @[norm_num legendreSym _ _]
-def evalLegendreSym : NormNumExt where
-  eval {u α} e := do
+def evalLegendreSym : NormNumExt where eval {u α} e := do
     let .app (.app (.app _ (p : Q(ℕ))) (fp : Q(Fact (Nat.Prime $p)))) (a : Q(ℤ)) ← Meta.whnfR e |
       failure
-    let sℕ : Q(AddMonoidWithOne ℕ) := q(instAddMonoidWithOneNat)
-    let sℤ : Q(Ring ℤ) := q(Int.instRingInt)
-    let ⟨ea, pa⟩ ← deriveInt a
-    let ⟨ep, pp⟩ ← deriveNat p
+    let ⟨ea, pa⟩ ← deriveInt a _
+    let ⟨ep, pp⟩ ← deriveNat p _
+    haveI' : u =QL 0 := ⟨⟩ haveI' : $α =Q ℤ := ⟨⟩
     have ⟨er, pr⟩ := proveJacobiSym ea ep
-    have p' : Q(IsInt (jacobiSym $a $p) $er) := q(isInt_jacobiSym $pa $pp $pr)
-    have p : Q(IsInt (legendreSym $p $a) $er) :=
-      q(LegendreSym.to_jacobiSym $p $fp $a $er $p')
-    return .isInt sℤ er er.intLit! p
+    haveI' : $e =Q legendreSym $p $a := ⟨⟩
+    return .isInt _ er er.intLit!
+      q(LegendreSym.to_jacobiSym $p $fp $a $er (isInt_jacobiSym $pa $pp $pr))
 
 end NormNum
 
fix(Tactic.NormNum.LegendreSymbol): not a % 0 but a % 2 (#5719)
Diff
@@ -346,7 +346,7 @@ partial def proveJacobiSymNat (ea eb : Q(ℕ)) : (er : Q(ℤ)) × Q(jacobiSymNat
         show (er : Q(ℤ)) × Q(jacobiSymNat 1 $eb = $er) from
           ⟨mkRawIntLit 1, q(jacobiSymNat.one_left $eb)⟩
       | a =>
-        match a % 0 with
+        match a % 2 with
         | 0 =>
           have hb₀ : Q(Nat.beq ($eb / 2) 0 = false) := (q(Eq.refl false) : Expr)
           have ha : Q(Nat.mod $ea 2 = 0) := (q(Eq.refl 0) : Expr)
feat: port number_theory.legendre_symbol.norm_num to Tactic.NormNum.LegendreSymbol (#5548)

Dependencies 12 + 1022

1023 files ported (98.8%)
438089 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