number_theory.legendre_symbol.gauss_eisenstein_lemmas
⟷
Mathlib.NumberTheory.LegendreSymbol.GaussEisensteinLemmas
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
The Ahlswede-Zhang identity is a sharpening of the Lubell-Yamamoto-Meshalkin identity, by expliciting the correction term.
This PR defines finset.truncated_sup
/finset.truncated_inf
, whose cardinalities show up in the correction term.
Co-authored-by: Vladimir Ivanov <volodimir1024@gmail.com>
@@ -114,13 +114,14 @@ lemma gauss_lemma {p : ℕ} [fact p.prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a :
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card :=
begin
haveI hp' : fact (p % 2 = 1) := ⟨nat.prime.mod_two_eq_one_iff_ne_two.mpr hp⟩,
+ haveI : fact (2 < p) := ⟨hp.lt_of_le' (fact.out p.prime).two_le⟩,
have : (legendre_sym p a : zmod p) = (((-1)^((Ico 1 (p / 2).succ).filter
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card : ℤ) : zmod p) :=
by { rw [legendre_sym.eq_pow, gauss_lemma_aux p ha0]; simp },
cases legendre_sym.eq_one_or_neg_one p ha0;
cases neg_one_pow_eq_or ℤ ((Ico 1 (p / 2).succ).filter
(λ x : ℕ, p / 2 < (a * x : zmod p).val)).card;
- simp [*, ne_neg_self p one_ne_zero, (ne_neg_self p one_ne_zero).symm] at *
+ simp only [*, neg_one_ne_one, neg_one_ne_one.symm, algebra_map.coe_one, int.cast_neg] at *,
end
private lemma eisenstein_lemma_aux₁ (p : ℕ) [fact p.prime] [hp2 : fact (p % 2 = 1)]
sup'
/inf'
lemmas (#18989)
Match (most of) the lemmas between finset.sup
/finset.inf
and finset.sup'
/finset.inf'
. Also golf two proofs using eq_of_forall_ge_iff
to make sure both APIs prove their lemmas in as closely as possible a way. Also define finset.nontrivial
to match set.nontrivial
.
@@ -90,7 +90,7 @@ calc (a ^ (p / 2) * (p / 2)! : zmod p) =
(λ _ _ _ _ _ _, id)
(λ b h _, ⟨b, by simp [-not_le, *] at *⟩)
(by intros; split_ifs at *; simp * at *),
- by rw [prod_mul_distrib, this]; simp
+ by rw [prod_mul_distrib, this, prod_const]
... = (-1)^((Ico 1 (p / 2).succ).filter
(λ x : ℕ, ¬(a * x : zmod p).val ≤ p / 2)).card * (p / 2)! :
by rw [← prod_nat_cast, finset.prod_eq_multiset_prod,
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(first ported)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -61,10 +61,10 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
· rw [nat_cast_nat_abs_val_min_abs]
split_ifs
·
- erw [mul_div_cancel' _ hap, val_min_abs_def_pos, val_cast_of_lt (hep hb),
+ erw [mul_div_cancel₀ _ hap, val_min_abs_def_pos, val_cast_of_lt (hep hb),
if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
·
- erw [mul_neg, mul_div_cancel' _ hap, nat_abs_val_min_abs_neg, val_min_abs_def_pos,
+ erw [mul_neg, mul_div_cancel₀ _ hap, nat_abs_val_min_abs_neg, val_min_abs_def_pos,
val_cast_of_lt (hep hb), if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
exact
Multiset.map_eq_map_of_bij_of_nodup _ _ (Finset.nodup _) (Finset.nodup _)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -285,8 +285,8 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
(Nat.div_lt_self hp.1.Pos (by decide))
have : (x.1 : ZMod p) = 0 := by
simpa [hq0] using congr_arg (coe : ℕ → ZMod p) (le_antisymm hpq hqp)
- apply_fun ZMod.val at this
- rw [val_cast_of_lt hxp, val_zero] at this
+ apply_fun ZMod.val at this
+ rw [val_cast_of_lt hxp, val_zero] at this
simpa only [this, nonpos_iff_eq_zero, mem_Ico, one_ne_zero, false_and_iff, mem_product] using hx
have hunion :
(((Ico 1 (p / 2).succ ×ˢ Ico 1 (q / 2).succ).filterₓ fun x : ℕ × ℕ => x.2 * p ≤ x.1 * q) ∪
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,7 +3,7 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-/
-import Mathbin.NumberTheory.LegendreSymbol.QuadraticReciprocity
+import NumberTheory.LegendreSymbol.QuadraticReciprocity
#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"8818fdefc78642a7e6afcd20be5c184f3c7d9699"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8818fdefc78642a7e6afcd20be5c184f3c7d9699
@@ -5,7 +5,7 @@ Authors: Chris Hughes
-/
import Mathbin.NumberTheory.LegendreSymbol.QuadraticReciprocity
-#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"442a83d738cb208d3600056c489be16900ba701d"
+#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"8818fdefc78642a7e6afcd20be5c184f3c7d9699"
/-!
# Lemmas of Gauss and Eisenstein
@@ -132,6 +132,7 @@ theorem gauss_lemma {p : ℕ} [Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a
(-1) ^ ((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card :=
by
haveI hp' : Fact (p % 2 = 1) := ⟨nat.prime.mod_two_eq_one_iff_ne_two.mpr hp⟩
+ haveI : Fact (2 < p) := ⟨hp.lt_of_le' (Fact.out p.prime).two_le⟩
have :
(legendreSym p a : ZMod p) =
(((-1) ^ ((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card : ℤ) :
@@ -141,7 +142,7 @@ theorem gauss_lemma {p : ℕ} [Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a
cases
neg_one_pow_eq_or ℤ
((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card <;>
- simp_all [ne_neg_self p one_ne_zero, (ne_neg_self p one_ne_zero).symm]
+ simp_all only [neg_one_ne_one, neg_one_ne_one.symm, algebraMap.coe_one, Int.cast_neg]
#align zmod.gauss_lemma ZMod.gauss_lemma
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/442a83d738cb208d3600056c489be16900ba701d
@@ -5,7 +5,7 @@ Authors: Chris Hughes
-/
import Mathbin.NumberTheory.LegendreSymbol.QuadraticReciprocity
-#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
+#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"442a83d738cb208d3600056c489be16900ba701d"
/-!
# Lemmas of Gauss and Eisenstein
@@ -102,7 +102,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
(fun x => by split_ifs <;> simp_all (config := { contextual := true }))
(fun _ _ _ _ _ _ => id) (fun b h _ => ⟨b, by simp_all [-not_le]⟩)
(by intros <;> split_ifs at * <;> simp_all)
- rw [prod_mul_distrib, this] <;> simp
+ rw [prod_mul_distrib, this, prod_const]
_ =
(-1) ^ ((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => ¬(a * x : ZMod p).val ≤ p / 2).card *
(p / 2)! :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,14 +2,11 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-
-! This file was ported from Lean 3 source module number_theory.legendre_symbol.gauss_eisenstein_lemmas
-! leanprover-community/mathlib commit 08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.NumberTheory.LegendreSymbol.QuadraticReciprocity
+#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
+
/-!
# Lemmas of Gauss and Eisenstein
mathlib commit https://github.com/leanprover-community/mathlib/commit/9240e8be927a0955b9a82c6c85ef499ee3a626b8
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
! This file was ported from Lean 3 source module number_theory.legendre_symbol.gauss_eisenstein_lemmas
-! leanprover-community/mathlib commit c471da714c044131b90c133701e51b877c246677
+! leanprover-community/mathlib commit 08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5
! 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.QuadraticReciprocity
/-!
# Lemmas of Gauss and Eisenstein
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file contains the Lemmas of Gauss and Eisenstein on the Legendre symbol.
The main results are `zmod.gauss_lemma` and `zmod.eisenstein_lemma`.
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/fdc286cc6967a012f41b87f76dcd2797b53152af
@@ -26,6 +26,7 @@ section GaussEisenstein
namespace ZMod
+#print ZMod.Ico_map_valMinAbs_natAbs_eq_Ico_map_id /-
/-- The image of the map sending a non zero natural number `x ≤ p / 2` to the absolute value
of the element of interger in the interval `(-p/2, p/2]` congruent to `a * x` mod p is the set
of non zero natural numbers `x` such that `x ≤ p / 2` -/
@@ -70,6 +71,7 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
(fun x _ => (a * x : ZMod p).valMinAbs.natAbs) hmem (fun _ _ => rfl)
(inj_on_of_surj_on_of_card_le _ hmem hsurj le_rfl) hsurj
#align zmod.Ico_map_val_min_abs_nat_abs_eq_Ico_map_id ZMod.Ico_map_valMinAbs_natAbs_eq_Ico_map_id
+-/
private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) :
@@ -109,6 +111,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
Ico_map_val_min_abs_nat_abs_eq_Ico_map_id p a hap, ← Finset.prod_eq_multiset_prod,
prod_Ico_id_eq_factorial]
+#print ZMod.gauss_lemma_aux /-
theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] [Fact (p % 2 = 1)] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) :
(a ^ (p / 2) : ZMod p) =
@@ -119,7 +122,9 @@ theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] [Fact (p % 2 = 1)] {a :
exact Nat.div_lt_self hp.1.Pos (by decide))).1 <|
by simpa using gauss_lemma_aux₁ p hap
#align zmod.gauss_lemma_aux ZMod.gauss_lemma_aux
+-/
+#print ZMod.gauss_lemma /-
/-- Gauss' lemma. The legendre symbol can be computed by considering the number of naturals less
than `p/2` such that `(a * x) % p > p / 2` -/
theorem gauss_lemma {p : ℕ} [Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a : ZMod p) ≠ 0) :
@@ -138,6 +143,7 @@ theorem gauss_lemma {p : ℕ} [Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a
((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card <;>
simp_all [ne_neg_self p one_ne_zero, (ne_neg_self p one_ne_zero).symm]
#align zmod.gauss_lemma ZMod.gauss_lemma
+-/
private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p % 2 = 1)] {a : ℕ}
(hap : (a : ZMod p) ≠ 0) :
@@ -174,6 +180,7 @@ private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p
simp [Nat.cast_sum])
rfl
+#print ZMod.eisenstein_lemma_aux /-
theorem eisenstein_lemma_aux (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a : ℕ} (ha2 : a % 2 = 1)
(hap : (a : ZMod p) ≠ 0) :
((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card ≡
@@ -185,7 +192,9 @@ theorem eisenstein_lemma_aux (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a :
add_neg_eq_iff_eq_add.symm, neg_eq_self_mod_two, add_assoc] using
Eq.symm (eisenstein_lemma_aux₁ p hap)
#align zmod.eisenstein_lemma_aux ZMod.eisenstein_lemma_aux
+-/
+#print ZMod.div_eq_filter_card /-
theorem div_eq_filter_card {a b c : ℕ} (hb0 : 0 < b) (hc : a / b ≤ c) :
a / b = ((Ico 1 c.succ).filterₓ fun x => x * b ≤ a).card :=
calc
@@ -197,6 +206,7 @@ theorem div_eq_filter_card {a b c : ℕ} (hb0 : 0 < b) (hc : a / b ≤ c) :
have : x * b ≤ a → x ≤ c := fun h => le_trans (by rwa [le_div_iff_mul_le hb0]) hc
simp [lt_succ_iff, le_div_iff_mul_le hb0] <;> tauto
#align zmod.div_eq_filter_card ZMod.div_eq_filter_card
+-/
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
/-- The given sum is the number of integer points in the triangle formed by the diagonal of the
@@ -240,6 +250,7 @@ private theorem sum_Ico_eq_card_lt {p q : ℕ} :
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print ZMod.sum_mul_div_add_sum_mul_div_eq_mul /-
/-- Each of the sums in this lemma is the cardinality of the set integer points in each of the
two triangles formed by the diagonal of the rectangle `(0, p/2) × (0, q/2)`. Adding them
gives the number of points in the rectangle. -/
@@ -288,7 +299,9 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
card_product]
simp only [card_Ico, tsub_zero, succ_sub_succ_eq_sub]
#align zmod.sum_mul_div_add_sum_mul_div_eq_mul ZMod.sum_mul_div_add_sum_mul_div_eq_mul
+-/
+#print ZMod.eisenstein_lemma /-
theorem eisenstein_lemma {p : ℕ} [Fact p.Prime] (hp : p ≠ 2) {a : ℕ} (ha1 : a % 2 = 1)
(ha0 : (a : ZMod p) ≠ 0) : legendreSym p a = (-1) ^ ∑ x in Ico 1 (p / 2).succ, x * a / p :=
by
@@ -298,6 +311,7 @@ theorem eisenstein_lemma {p : ℕ} [Fact p.Prime] (hp : p ≠ 2) {a : ℕ} (ha1
(by norm_cast : ((a : ℤ) : ZMod p) = (a : ZMod p)),
show _ = _ from eisenstein_lemma_aux p ha1 ha0]
#align zmod.eisenstein_lemma ZMod.eisenstein_lemma
+-/
end ZMod
mathlib commit https://github.com/leanprover-community/mathlib/commit/c471da714c044131b90c133701e51b877c246677
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
! This file was ported from Lean 3 source module number_theory.legendre_symbol.gauss_eisenstein_lemmas
-! leanprover-community/mathlib commit e1452ef24e117a92df20b6d45f80b53cabe5a177
+! leanprover-community/mathlib commit c471da714c044131b90c133701e51b877c246677
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -13,64 +13,15 @@ import Mathbin.NumberTheory.LegendreSymbol.QuadraticReciprocity
/-!
# Lemmas of Gauss and Eisenstein
-This file contains code for the proof of the Lemmas of Gauss and Eisenstein
-on the Legendre symbol. The main results are `zmod.gauss_lemma_aux` and
-`zmod.eisenstein_lemma_aux`.
+This file contains the Lemmas of Gauss and Eisenstein on the Legendre symbol.
+The main results are `zmod.gauss_lemma` and `zmod.eisenstein_lemma`.
-/
-open Function Finset Nat FiniteField ZMod
+open Finset Nat
open scoped BigOperators Nat
-namespace ZMod
-
-section Wilson
-
-variable (p : ℕ) [Fact p.Prime]
-
-/-- **Wilson's Lemma**: the product of `1`, ..., `p-1` is `-1` modulo `p`. -/
-@[simp]
-theorem wilsons_lemma : ((p - 1)! : ZMod p) = -1 :=
- by
- refine'
- calc
- ((p - 1)! : ZMod p) = ∏ x in Ico 1 (succ (p - 1)), x := by
- rw [← Finset.prod_Ico_id_eq_factorial, prod_nat_cast]
- _ = ∏ x : (ZMod p)ˣ, x := _
- _ = -1 := by
- simp_rw [← Units.coeHom_apply, ← (Units.coeHom (ZMod p)).map_prod,
- prod_univ_units_id_eq_neg_one, Units.coeHom_apply, Units.val_neg, Units.val_one]
- have hp : 0 < p := (Fact.out p.prime).Pos
- symm
- refine' prod_bij (fun a _ => (a : ZMod p).val) _ _ _ _
- · intro a ha
- rw [mem_Ico, ← Nat.succ_sub hp, Nat.succ_sub_one]
- constructor
- · apply Nat.pos_of_ne_zero; rw [← @val_zero p]
- intro h; apply Units.ne_zero a (val_injective p h)
- · exact val_lt _
- · intro a ha; simp only [cast_id, nat_cast_val]
- · intro _ _ _ _ h; rw [Units.ext_iff]; exact val_injective p h
- · intro b hb
- rw [mem_Ico, Nat.succ_le_iff, ← succ_sub hp, succ_sub_one, pos_iff_ne_zero] at hb
- refine' ⟨Units.mk0 b _, Finset.mem_univ _, _⟩
- · intro h; apply hb.1; apply_fun val at h
- simpa only [val_cast_of_lt hb.right, val_zero] using h
- · simp only [val_cast_of_lt hb.right, Units.val_mk0]
-#align zmod.wilsons_lemma ZMod.wilsons_lemma
-
-@[simp]
-theorem prod_Ico_one_prime : ∏ x in Ico 1 p, (x : ZMod p) = -1 :=
- by
- conv in Ico 1 p => rw [← succ_sub_one p, succ_sub (Fact.out p.prime).Pos]
- rw [← prod_nat_cast, Finset.prod_Ico_id_eq_factorial, wilsons_lemma]
-#align zmod.prod_Ico_one_prime ZMod.prod_Ico_one_prime
-
-end Wilson
-
-end ZMod
-
section GaussEisenstein
namespace ZMod
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -61,7 +61,7 @@ theorem wilsons_lemma : ((p - 1)! : ZMod p) = -1 :=
#align zmod.wilsons_lemma ZMod.wilsons_lemma
@[simp]
-theorem prod_Ico_one_prime : (∏ x in Ico 1 p, (x : ZMod p)) = -1 :=
+theorem prod_Ico_one_prime : ∏ x in Ico 1 p, (x : ZMod p) = -1 :=
by
conv in Ico 1 p => rw [← succ_sub_one p, succ_sub (Fact.out p.prime).Pos]
rw [← prod_nat_cast, Finset.prod_Ico_id_eq_factorial, wilsons_lemma]
@@ -191,13 +191,13 @@ theorem gauss_lemma {p : ℕ} [Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a
private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p % 2 = 1)] {a : ℕ}
(hap : (a : ZMod p) ≠ 0) :
((∑ x in Ico 1 (p / 2).succ, a * x : ℕ) : ZMod 2) =
- (((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card +
- ∑ x in Ico 1 (p / 2).succ, x) +
+ ((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => p / 2 < (a * x : ZMod p).val).card +
+ ∑ x in Ico 1 (p / 2).succ, x +
(∑ x in Ico 1 (p / 2).succ, a * x / p : ℕ) :=
have hp2 : (p : ZMod 2) = (1 : ℕ) := (eq_iff_modEq_nat _).2 hp2.1
calc
((∑ x in Ico 1 (p / 2).succ, a * x : ℕ) : ZMod 2) =
- ((∑ x in Ico 1 (p / 2).succ, a * x % p + p * (a * x / p) : ℕ) : ZMod 2) :=
+ ((∑ x in Ico 1 (p / 2).succ, (a * x % p + p * (a * x / p)) : ℕ) : ZMod 2) :=
by simp only [mod_add_div]
_ =
(∑ x in Ico 1 (p / 2).succ, ((a * x : ℕ) : ZMod p).val : ℕ) +
@@ -251,13 +251,13 @@ theorem div_eq_filter_card {a b c : ℕ} (hb0 : 0 < b) (hc : a / b ≤ c) :
/-- The given sum is the number of integer points in the triangle formed by the diagonal of the
rectangle `(0, p/2) × (0, q/2)` -/
private theorem sum_Ico_eq_card_lt {p q : ℕ} :
- (∑ a in Ico 1 (p / 2).succ, a * q / p) =
+ ∑ a in Ico 1 (p / 2).succ, a * q / p =
((Ico 1 (p / 2).succ ×ˢ Ico 1 (q / 2).succ).filterₓ fun x : ℕ × ℕ =>
x.2 * p ≤ x.1 * q).card :=
if hp0 : p = 0 then by simp [hp0, Finset.ext_iff]
else
calc
- (∑ a in Ico 1 (p / 2).succ, a * q / p) =
+ ∑ a in Ico 1 (p / 2).succ, a * q / p =
∑ a in Ico 1 (p / 2).succ, ((Ico 1 (q / 2).succ).filterₓ fun x => x * p ≤ a * q).card :=
Finset.sum_congr rfl fun x hx =>
div_eq_filter_card (Nat.pos_of_ne_zero hp0)
@@ -293,8 +293,7 @@ private theorem sum_Ico_eq_card_lt {p q : ℕ} :
two triangles formed by the diagonal of the rectangle `(0, p/2) × (0, q/2)`. Adding them
gives the number of points in the rectangle. -/
theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0 : (q : ZMod p) ≠ 0) :
- ((∑ a in Ico 1 (p / 2).succ, a * q / p) + ∑ a in Ico 1 (q / 2).succ, a * p / q) =
- p / 2 * (q / 2) :=
+ ∑ a in Ico 1 (p / 2).succ, a * q / p + ∑ a in Ico 1 (q / 2).succ, a * p / q = p / 2 * (q / 2) :=
by
have hswap :
((Ico 1 (q / 2).succ ×ˢ Ico 1 (p / 2).succ).filterₓ fun x : ℕ × ℕ => x.2 * q ≤ x.1 * p).card =
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -41,7 +41,6 @@ theorem wilsons_lemma : ((p - 1)! : ZMod p) = -1 :=
_ = -1 := by
simp_rw [← Units.coeHom_apply, ← (Units.coeHom (ZMod p)).map_prod,
prod_univ_units_id_eq_neg_one, Units.coeHom_apply, Units.val_neg, Units.val_one]
-
have hp : 0 < p := (Fact.out p.prime).Pos
symm
refine' prod_bij (fun a _ => (a : ZMod p).val) _ _ _ _
@@ -158,7 +157,6 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
rw [← prod_nat_cast, Finset.prod_eq_multiset_prod,
Ico_map_val_min_abs_nat_abs_eq_Ico_map_id p a hap, ← Finset.prod_eq_multiset_prod,
prod_Ico_id_eq_factorial]
-
theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] [Fact (p % 2 = 1)] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) :
@@ -222,10 +220,8 @@ private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p
_ = _ := by
rw [Finset.sum_eq_multiset_sum, Ico_map_val_min_abs_nat_abs_eq_Ico_map_id p a hap, ←
Finset.sum_eq_multiset_sum] <;>
- simp [Nat.cast_sum]
- )
+ simp [Nat.cast_sum])
rfl
-
theorem eisenstein_lemma_aux (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a : ℕ} (ha2 : a % 2 = 1)
(hap : (a : ZMod p) ≠ 0) :
@@ -249,7 +245,6 @@ theorem div_eq_filter_card {a b c : ℕ} (hb0 : 0 < b) (hc : a / b ≤ c) :
by
have : x * b ≤ a → x ≤ c := fun h => le_trans (by rwa [le_div_iff_mul_le hb0]) hc
simp [lt_succ_iff, le_div_iff_mul_le hb0] <;> tauto
-
#align zmod.div_eq_filter_card ZMod.div_eq_filter_card
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -270,8 +265,7 @@ private theorem sum_Ico_eq_card_lt {p q : ℕ} :
x * q / p ≤ p / 2 * q / p :=
Nat.div_le_div_right
(mul_le_mul_of_nonneg_right (le_of_lt_succ <| (mem_Ico.mp hx).2) (Nat.zero_le _))
- _ ≤ _ := Nat.div_mul_div_le_div _ _ _
- )
+ _ ≤ _ := Nat.div_mul_div_le_div _ _ _)
_ = _ := by
rw [← card_sigma] <;>
exact
@@ -287,7 +281,6 @@ private theorem sum_Ico_eq_card_lt {p q : ℕ} :
revert h <;>
simp (config := { contextual := true }) only [mem_filter, eq_self_iff_true,
exists_prop_of_true, mem_sigma, and_self_iff, forall_true_iff, mem_product]⟩
-
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -56,7 +56,7 @@ theorem wilsons_lemma : ((p - 1)! : ZMod p) = -1 :=
· intro b hb
rw [mem_Ico, Nat.succ_le_iff, ← succ_sub hp, succ_sub_one, pos_iff_ne_zero] at hb
refine' ⟨Units.mk0 b _, Finset.mem_univ _, _⟩
- · intro h; apply hb.1; apply_fun val at h
+ · intro h; apply hb.1; apply_fun val at h
simpa only [val_cast_of_lt hb.right, val_zero] using h
· simp only [val_cast_of_lt hb.right, Units.val_mk0]
#align zmod.wilsons_lemma ZMod.wilsons_lemma
@@ -149,7 +149,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
prod_bij_ne_one (fun x _ _ => x)
(fun x => by split_ifs <;> simp_all (config := { contextual := true }))
(fun _ _ _ _ _ _ => id) (fun b h _ => ⟨b, by simp_all [-not_le]⟩)
- (by intros <;> split_ifs at * <;> simp_all)
+ (by intros <;> split_ifs at * <;> simp_all)
rw [prod_mul_distrib, this] <;> simp
_ =
(-1) ^ ((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => ¬(a * x : ZMod p).val ≤ p / 2).card *
@@ -330,7 +330,7 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
(Nat.div_lt_self hp.1.Pos (by decide))
have : (x.1 : ZMod p) = 0 := by
simpa [hq0] using congr_arg (coe : ℕ → ZMod p) (le_antisymm hpq hqp)
- apply_fun ZMod.val at this
+ apply_fun ZMod.val at this
rw [val_cast_of_lt hxp, val_zero] at this
simpa only [this, nonpos_iff_eq_zero, mem_Ico, one_ne_zero, false_and_iff, mem_product] using hx
have hunion :
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -54,9 +54,9 @@ theorem wilsons_lemma : ((p - 1)! : ZMod p) = -1 :=
· intro a ha; simp only [cast_id, nat_cast_val]
· intro _ _ _ _ h; rw [Units.ext_iff]; exact val_injective p h
· intro b hb
- rw [mem_Ico, Nat.succ_le_iff, ← succ_sub hp, succ_sub_one, pos_iff_ne_zero] at hb
+ rw [mem_Ico, Nat.succ_le_iff, ← succ_sub hp, succ_sub_one, pos_iff_ne_zero] at hb
refine' ⟨Units.mk0 b _, Finset.mem_univ _, _⟩
- · intro h; apply hb.1; apply_fun val at h
+ · intro h; apply hb.1; apply_fun val at h
simpa only [val_cast_of_lt hb.right, val_zero] using h
· simp only [val_cast_of_lt hb.right, Units.val_mk0]
#align zmod.wilsons_lemma ZMod.wilsons_lemma
@@ -330,8 +330,8 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
(Nat.div_lt_self hp.1.Pos (by decide))
have : (x.1 : ZMod p) = 0 := by
simpa [hq0] using congr_arg (coe : ℕ → ZMod p) (le_antisymm hpq hqp)
- apply_fun ZMod.val at this
- rw [val_cast_of_lt hxp, val_zero] at this
+ apply_fun ZMod.val at this
+ rw [val_cast_of_lt hxp, val_zero] at this
simpa only [this, nonpos_iff_eq_zero, mem_Ico, one_ne_zero, false_and_iff, mem_product] using hx
have hunion :
(((Ico 1 (p / 2).succ ×ˢ Ico 1 (q / 2).succ).filterₓ fun x : ℕ × ℕ => x.2 * p ≤ x.1 * q) ∪
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -21,7 +21,7 @@ on the Legendre symbol. The main results are `zmod.gauss_lemma_aux` and
open Function Finset Nat FiniteField ZMod
-open BigOperators Nat
+open scoped BigOperators Nat
namespace ZMod
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -48,22 +48,15 @@ theorem wilsons_lemma : ((p - 1)! : ZMod p) = -1 :=
· intro a ha
rw [mem_Ico, ← Nat.succ_sub hp, Nat.succ_sub_one]
constructor
- · apply Nat.pos_of_ne_zero
- rw [← @val_zero p]
- intro h
- apply Units.ne_zero a (val_injective p h)
+ · apply Nat.pos_of_ne_zero; rw [← @val_zero p]
+ intro h; apply Units.ne_zero a (val_injective p h)
· exact val_lt _
- · intro a ha
- simp only [cast_id, nat_cast_val]
- · intro _ _ _ _ h
- rw [Units.ext_iff]
- exact val_injective p h
+ · intro a ha; simp only [cast_id, nat_cast_val]
+ · intro _ _ _ _ h; rw [Units.ext_iff]; exact val_injective p h
· intro b hb
rw [mem_Ico, Nat.succ_le_iff, ← succ_sub hp, succ_sub_one, pos_iff_ne_zero] at hb
refine' ⟨Units.mk0 b _, Finset.mem_univ _, _⟩
- · intro h
- apply hb.1
- apply_fun val at h
+ · intro h; apply hb.1; apply_fun val at h
simpa only [val_cast_of_lt hb.right, val_zero] using h
· simp only [val_cast_of_lt hb.right, Units.val_mk0]
#align zmod.wilsons_lemma ZMod.wilsons_lemma
@@ -113,8 +106,7 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
· apply Nat.pos_of_ne_zero
simp only [div_eq_mul_inv, hap, CharP.cast_eq_zero_iff (ZMod p) p, hpe hb, not_false_iff,
val_min_abs_eq_zero, inv_eq_zero, Int.natAbs_eq_zero, Ne.def, mul_eq_zero, or_self_iff]
- · apply lt_succ_of_le
- apply nat_abs_val_min_abs_le
+ · apply lt_succ_of_le; apply nat_abs_val_min_abs_le
· rw [nat_cast_nat_abs_val_min_abs]
split_ifs
·
@@ -358,9 +350,7 @@ theorem eisenstein_lemma {p : ℕ} [Fact p.Prime] (hp : p ≠ 2) {a : ℕ} (ha1
(ha0 : (a : ZMod p) ≠ 0) : legendreSym p a = (-1) ^ ∑ x in Ico 1 (p / 2).succ, x * a / p :=
by
haveI hp' : Fact (p % 2 = 1) := ⟨nat.prime.mod_two_eq_one_iff_ne_two.mpr hp⟩
- have ha0' : ((a : ℤ) : ZMod p) ≠ 0 := by
- norm_cast
- exact ha0
+ have ha0' : ((a : ℤ) : ZMod p) ≠ 0 := by norm_cast; exact ha0
rw [neg_one_pow_eq_pow_mod_two, gauss_lemma hp ha0', neg_one_pow_eq_pow_mod_two,
(by norm_cast : ((a : ℤ) : ZMod p) = (a : ZMod p)),
show _ = _ from eisenstein_lemma_aux p ha1 ha0]
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -167,7 +167,6 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
Ico_map_val_min_abs_nat_abs_eq_Ico_map_id p a hap, ← Finset.prod_eq_multiset_prod,
prod_Ico_id_eq_factorial]
-#align zmod.gauss_lemma_aux₁ zmod.gauss_lemma_aux₁
theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] [Fact (p % 2 = 1)] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) :
@@ -235,7 +234,6 @@ private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p
)
rfl
-#align zmod.eisenstein_lemma_aux₁ zmod.eisenstein_lemma_aux₁
theorem eisenstein_lemma_aux (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a : ℕ} (ha2 : a % 2 = 1)
(hap : (a : ZMod p) ≠ 0) :
@@ -298,7 +296,6 @@ private theorem sum_Ico_eq_card_lt {p q : ℕ} :
simp (config := { contextual := true }) only [mem_filter, eq_self_iff_true,
exists_prop_of_true, mem_sigma, and_self_iff, forall_true_iff, mem_product]⟩
-#align zmod.sum_Ico_eq_card_lt zmod.sum_Ico_eq_card_lt
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -143,9 +143,10 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
_ =
∏ x in Ico 1 (p / 2).succ,
(if (a * x : ZMod p).val ≤ p / 2 then 1 else -1) * (a * x : ZMod p).valMinAbs.natAbs :=
- prod_congr rfl fun _ _ => by
+ (prod_congr rfl fun _ _ =>
+ by
simp only [nat_cast_nat_abs_val_min_abs]
- split_ifs <;> simp
+ split_ifs <;> simp)
_ =
(-1) ^ ((Ico 1 (p / 2).succ).filterₓ fun x : ℕ => ¬(a * x : ZMod p).val ≤ p / 2).card *
∏ x in Ico 1 (p / 2).succ, (a * x : ZMod p).valMinAbs.natAbs :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
nat_cast
/int_cast
/rat_cast
to natCast
/intCast
/ratCast
(#11486)
Now that I am defining NNRat.cast
, I want a definitive answer to this naming issue. Plenty of lemmas in mathlib already use natCast
/intCast
/ratCast
over nat_cast
/int_cast
/rat_cast
, and this matches with the general expectation that underscore-separated name parts correspond to a single declaration.
@@ -49,7 +49,7 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
simp only [div_eq_mul_inv, hap, CharP.cast_eq_zero_iff (ZMod p) p, hpe hb, not_false_iff,
valMinAbs_eq_zero, inv_eq_zero, Int.natAbs_eq_zero, Ne, _root_.mul_eq_zero, or_self_iff]
· apply lt_succ_of_le; apply natAbs_valMinAbs_le
- · rw [nat_cast_natAbs_valMinAbs]
+ · rw [natCast_natAbs_valMinAbs]
split_ifs
· erw [mul_div_cancel₀ _ hap, valMinAbs_def_pos, val_cast_of_lt (hep hb),
if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
@@ -72,7 +72,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
_ = ∏ x in Ico 1 (p / 2).succ, (if (a * x : ZMod p).val ≤ p / 2 then (1 : ZMod p) else -1) *
(a * x : ZMod p).valMinAbs.natAbs :=
(prod_congr rfl fun _ _ => by
- simp only [nat_cast_natAbs_valMinAbs]
+ simp only [natCast_natAbs_valMinAbs]
split_ifs <;> simp)
_ = (-1 : ZMod p) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ =>
¬(a * x : ZMod p).val ≤ p / 2).card * ∏ x in Ico 1 (p / 2).succ,
@@ -126,7 +126,7 @@ private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p
simp only [mod_add_div]
_ = (∑ x in Ico 1 (p / 2).succ, ((a * x : ℕ) : ZMod p).val : ℕ) +
(∑ x in Ico 1 (p / 2).succ, a * x / p : ℕ) := by
- simp only [val_nat_cast]
+ simp only [val_natCast]
simp [sum_add_distrib, ← mul_sum, Nat.cast_add, Nat.cast_mul, Nat.cast_sum, hp2]
_ = _ :=
congr_arg₂ (· + ·)
@@ -47,7 +47,7 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
refine' ⟨(b / a : ZMod p).valMinAbs.natAbs, mem_Ico.mpr ⟨_, _⟩, _⟩
· apply Nat.pos_of_ne_zero
simp only [div_eq_mul_inv, hap, CharP.cast_eq_zero_iff (ZMod p) p, hpe hb, not_false_iff,
- valMinAbs_eq_zero, inv_eq_zero, Int.natAbs_eq_zero, Ne.def, _root_.mul_eq_zero, or_self_iff]
+ valMinAbs_eq_zero, inv_eq_zero, Int.natAbs_eq_zero, Ne, _root_.mul_eq_zero, or_self_iff]
· apply lt_succ_of_le; apply natAbs_valMinAbs_le
· rw [nat_cast_natAbs_valMinAbs]
split_ifs
@@ -95,7 +95,7 @@ theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) : (↑a ^ (p / 2) : ZMod p) =
((-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ => p / 2 < (a * x : ZMod p).val).card :) :=
(mul_left_inj' (show ((p / 2)! : ZMod p) ≠ 0 by
- rw [Ne.def, CharP.cast_eq_zero_iff (ZMod p) p, hp.1.dvd_factorial, not_le]
+ rw [Ne, CharP.cast_eq_zero_iff (ZMod p) p, hp.1.dvd_factorial, not_le]
exact Nat.div_lt_self hp.1.pos (by decide))).1 <| by
simpa using gauss_lemma_aux₁ p hap
#align zmod.gauss_lemma_aux ZMod.gauss_lemma_aux
mul
-div
cancellation lemmas (#11530)
Lemma names around cancellation of multiplication and division are a mess.
This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero
lemma name, the Group
lemma, the AddGroup
lemma name).
| Statement | New name | Old name | |
@@ -51,9 +51,9 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
· apply lt_succ_of_le; apply natAbs_valMinAbs_le
· rw [nat_cast_natAbs_valMinAbs]
split_ifs
- · erw [mul_div_cancel' _ hap, valMinAbs_def_pos, val_cast_of_lt (hep hb),
+ · erw [mul_div_cancel₀ _ hap, valMinAbs_def_pos, val_cast_of_lt (hep hb),
if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
- · erw [mul_neg, mul_div_cancel' _ hap, natAbs_valMinAbs_neg, valMinAbs_def_pos,
+ · erw [mul_neg, mul_div_cancel₀ _ hap, natAbs_valMinAbs_neg, valMinAbs_def_pos,
val_cast_of_lt (hep hb), if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
exact Multiset.map_eq_map_of_bij_of_nodup _ _ (Finset.nodup _) (Finset.nodup _)
(fun x _ => (a * x : ZMod p).valMinAbs.natAbs) hmem
@[gcongr]
tags around (#9393)
import Mathlib.Tactic.GCongr.Core
to Algebra/Order/Ring/Lemmas
.@[gcongr]
tags next to the lemmas.See Zulip thread
Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com>
@@ -175,11 +175,10 @@ private theorem sum_Ico_eq_card_lt {p q : ℕ} :
calc
∑ a in Ico 1 (p / 2).succ, a * q / p =
∑ a in Ico 1 (p / 2).succ, ((Ico 1 (q / 2).succ).filter fun x => x * p ≤ a * q).card :=
- Finset.sum_congr rfl fun x hx => div_eq_filter_card (Nat.pos_of_ne_zero hp0)
- (calc
- x * q / p ≤ p / 2 * q / p := Nat.div_le_div_right
- (mul_le_mul_of_nonneg_right (le_of_lt_succ <| (mem_Ico.mp hx).2) (Nat.zero_le _))
- _ ≤ _ := Nat.div_mul_div_le_div _ _ _)
+ Finset.sum_congr rfl fun x hx => div_eq_filter_card (Nat.pos_of_ne_zero hp0) <|
+ calc
+ x * q / p ≤ p / 2 * q / p := by have := le_of_lt_succ (mem_Ico.mp hx).2; gcongr
+ _ ≤ _ := Nat.div_mul_div_le_div _ _ _
_ = _ := by
rw [← card_sigma]
exact card_congr (fun a _ => ⟨a.1, a.2⟩) (by
(s ∩ t).card = s.card + t.card - (s ∪ t).card
(#10224)
once coerced to an AddGroupWithOne
. Also unify Finset.card_disjoint_union
and Finset.card_union_eq
From LeanAPAP
@@ -234,7 +234,7 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
have := le_total (x.2 * p) (x.1 * q)
simp only [mem_union, mem_filter, mem_Ico, mem_product]
tauto
- rw [sum_Ico_eq_card_lt, sum_Ico_eq_card_lt, hswap, ← card_disjoint_union hdisj, hunion,
+ rw [sum_Ico_eq_card_lt, sum_Ico_eq_card_lt, hswap, ← card_union_of_disjoint hdisj, hunion,
card_product]
simp only [card_Ico, tsub_zero, succ_sub_succ_eq_sub]
#align zmod.sum_mul_div_add_sum_mul_div_eq_mul ZMod.sum_mul_div_add_sum_mul_div_eq_mul
@@ -39,8 +39,8 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
have hmem : ∀ (x : ℕ) (hx : x ∈ Ico 1 (p / 2).succ),
(a * x : ZMod p).valMinAbs.natAbs ∈ Ico 1 (p / 2).succ := by
intro x hx
- simp [hap, CharP.cast_eq_zero_iff (ZMod p) p, hpe hx, lt_succ_iff, succ_le_iff, pos_iff_ne_zero,
- natAbs_valMinAbs_le _]
+ simp [hap, CharP.cast_eq_zero_iff (ZMod p) p, hpe hx, Nat.lt_succ_iff, succ_le_iff,
+ pos_iff_ne_zero, natAbs_valMinAbs_le _]
have hsurj : ∀ (b : ℕ) (hb : b ∈ Ico 1 (p / 2).succ),
∃ x, ∃ _ : x ∈ Ico 1 (p / 2).succ, (a * x : ZMod p).valMinAbs.natAbs = b := by
intro b hb
@@ -161,7 +161,7 @@ theorem div_eq_filter_card {a b c : ℕ} (hb0 : 0 < b) (hc : a / b ≤ c) :
_ = ((Ico 1 c.succ).filter fun x => x * b ≤ a).card :=
congr_arg _ <| Finset.ext fun x => by
have : x * b ≤ a → x ≤ c := fun h => le_trans (by rwa [le_div_iff_mul_le hb0]) hc
- simp [lt_succ_iff, le_div_iff_mul_le hb0]; tauto
+ simp [Nat.lt_succ_iff, le_div_iff_mul_le hb0]; tauto
#align zmod.div_eq_filter_card ZMod.div_eq_filter_card
/-- The given sum is the number of integer points in the triangle formed by the diagonal of the
@@ -219,7 +219,7 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
((Ico 1 (p / 2).succ ×ˢ Ico 1 (q / 2).succ).filter fun x : ℕ × ℕ => x.1 * q ≤ x.2 * p) := by
apply disjoint_filter.2 fun x hx hpq hqp => ?_
have hxp : x.1 < p := lt_of_le_of_lt
- (show x.1 ≤ p / 2 by simp_all only [lt_succ_iff, mem_Ico, mem_product])
+ (show x.1 ≤ p / 2 by simp_all only [Nat.lt_succ_iff, mem_Ico, mem_product])
(Nat.div_lt_self hp.1.pos (by decide))
have : (x.1 : ZMod p) = 0 := by
simpa [hq0] using congr_arg ((↑) : ℕ → ZMod p) (le_antisymm hpq hqp)
@@ -3,7 +3,8 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-/
-import Mathlib.NumberTheory.LegendreSymbol.QuadraticReciprocity
+import Mathlib.NumberTheory.LegendreSymbol.Basic
+import Mathlib.Analysis.Normed.Field.Basic
#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"8818fdefc78642a7e6afcd20be5c184f3c7d9699"
A bunch of lemmas in Algebra.BigOperators.Ring
were not about rings. This PR moves them along with some lemmas from Data.Fintype.BigOperators
to their correct place.
I create a new file with the content from #6605 to avoid importing Fin
material in finset files as a result.
From LeanAPAP
@@ -126,7 +126,7 @@ private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p
_ = (∑ x in Ico 1 (p / 2).succ, ((a * x : ℕ) : ZMod p).val : ℕ) +
(∑ x in Ico 1 (p / 2).succ, a * x / p : ℕ) := by
simp only [val_nat_cast]
- simp [sum_add_distrib, mul_sum.symm, Nat.cast_add, Nat.cast_mul, Nat.cast_sum, hp2]
+ simp [sum_add_distrib, ← mul_sum, Nat.cast_add, Nat.cast_mul, Nat.cast_sum, hp2]
_ = _ :=
congr_arg₂ (· + ·)
(calc
@@ -148,7 +148,7 @@ theorem eisenstein_lemma_aux (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a :
∑ x in Ico 1 (p / 2).succ, x * a / p [MOD 2] :=
have ha2 : (a : ZMod 2) = (1 : ℕ) := (eq_iff_modEq_nat _).2 ha2
(eq_iff_modEq_nat 2).1 <| sub_eq_zero.1 <| by
- simpa [add_left_comm, sub_eq_add_neg, Finset.mul_sum.symm, mul_comm, ha2, Nat.cast_sum,
+ simpa [add_left_comm, sub_eq_add_neg, ← mul_sum, mul_comm, ha2, Nat.cast_sum,
add_neg_eq_iff_eq_add.symm, neg_eq_self_mod_two, add_assoc] using
Eq.symm (eisenstein_lemma_aux₁ p hap)
#align zmod.eisenstein_lemma_aux ZMod.eisenstein_lemma_aux
Lemmas around this were a mess, throth in terms of names, statement and location. This PR standardises everything to be in Algebra.BigOperators.Basic
and changes the lemmas to take in InjOn
and SurjOn
assumptions where possible (and where impossible make sure the hypotheses are taken in the correct order) and moves the equality of functions hypothesis last.
Also add a few lemmas that help fix downstream uses by golfing.
From LeanAPAP and LeanCamCombi
@@ -41,7 +41,7 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
simp [hap, CharP.cast_eq_zero_iff (ZMod p) p, hpe hx, lt_succ_iff, succ_le_iff, pos_iff_ne_zero,
natAbs_valMinAbs_le _]
have hsurj : ∀ (b : ℕ) (hb : b ∈ Ico 1 (p / 2).succ),
- ∃ x ∈ Ico 1 (p / 2).succ, b = (a * x : ZMod p).valMinAbs.natAbs := by
+ ∃ x, ∃ _ : x ∈ Ico 1 (p / 2).succ, (a * x : ZMod p).valMinAbs.natAbs = b := by
intro b hb
refine' ⟨(b / a : ZMod p).valMinAbs.natAbs, mem_Ico.mpr ⟨_, _⟩, _⟩
· apply Nat.pos_of_ne_zero
@@ -54,10 +54,9 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
· erw [mul_neg, mul_div_cancel' _ hap, natAbs_valMinAbs_neg, valMinAbs_def_pos,
val_cast_of_lt (hep hb), if_pos (le_of_lt_succ (mem_Ico.1 hb).2), Int.natAbs_ofNat]
- simp only [← exists_prop] at hsurj
exact Multiset.map_eq_map_of_bij_of_nodup _ _ (Finset.nodup _) (Finset.nodup _)
- (fun x _ => (a * x : ZMod p).valMinAbs.natAbs) hmem (fun _ _ => rfl)
- (inj_on_of_surj_on_of_card_le _ hmem hsurj le_rfl) hsurj
+ (fun x _ => (a * x : ZMod p).valMinAbs.natAbs) hmem
+ (inj_on_of_surj_on_of_card_le _ hmem hsurj le_rfl) hsurj (fun _ _ => rfl)
#align zmod.Ico_map_val_min_abs_nat_abs_eq_Ico_map_id ZMod.Ico_map_valMinAbs_natAbs_eq_Ico_map_id
private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
@@ -100,7 +100,7 @@ theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] {a : ℤ}
simpa using gauss_lemma_aux₁ p hap
#align zmod.gauss_lemma_aux ZMod.gauss_lemma_aux
-/-- Gauss' lemma. The Legendre symbol can be computed by considering the number of naturals less
+/-- **Gauss' lemma**. The Legendre symbol can be computed by considering the number of naturals less
than `p/2` such that `(a * x) % p > p / 2`. -/
theorem gauss_lemma {p : ℕ} [h : Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a : ZMod p) ≠ 0) :
legendreSym p a = (-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ =>
@@ -239,6 +239,7 @@ theorem sum_mul_div_add_sum_mul_div_eq_mul (p q : ℕ) [hp : Fact p.Prime] (hq0
simp only [card_Ico, tsub_zero, succ_sub_succ_eq_sub]
#align zmod.sum_mul_div_add_sum_mul_div_eq_mul ZMod.sum_mul_div_add_sum_mul_div_eq_mul
+/-- **Eisenstein's lemma** -/
theorem eisenstein_lemma {p : ℕ} [Fact p.Prime] (hp : p ≠ 2) {a : ℕ} (ha1 : a % 2 = 1)
(ha0 : (a : ZMod p) ≠ 0) : legendreSym p a = (-1) ^ ∑ x in Ico 1 (p / 2).succ, x * a / p := by
haveI hp' : Fact (p % 2 = 1) := ⟨Nat.Prime.mod_two_eq_one_iff_ne_two.mpr hp⟩
@@ -67,7 +67,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
calc
(a ^ (p / 2) * (p / 2)! : ZMod p) = ∏ x in Ico 1 (p / 2).succ, a * x := by
rw [prod_mul_distrib, ← prod_natCast, prod_Ico_id_eq_factorial, prod_const, card_Ico,
- succ_sub_one]; simp
+ Nat.add_one_sub_one]; simp
_ = ∏ x in Ico 1 (p / 2).succ, ↑((a * x : ZMod p).val) := by simp
_ = ∏ x in Ico 1 (p / 2).succ, (if (a * x : ZMod p).val ≤ p / 2 then (1 : ZMod p) else -1) *
(a * x : ZMod p).valMinAbs.natAbs :=
This is the supremum of
along with some minor fixes from failures on nightly-testing as Mathlib master
is merged into it.
Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.
I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0
branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.
In particular this includes adjustments for the Lean PRs
We can get rid of all the
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)
macros across Mathlib (and in any projects that want to write natural number powers of reals).
Changes the default behaviour of simp
to (config := {decide := false})
. This makes simp
(and consequentially norm_num
) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp
or norm_num
to decide
or rfl
, or adding (config := {decide := true})
.
This changed the behaviour of simp
so that simp [f]
will only unfold "fully applied" occurrences of f
. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true })
. We may in future add a syntax for this, e.g. simp [!f]
; please provide feedback! In the meantime, we have made the following changes:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[eqns]
to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp
and Function.flip
.This change in Lean may require further changes down the line (e.g. adding the !f
syntax, and/or upstreaming the special treatment for Function.comp
and Function.flip
, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>
@@ -19,8 +19,6 @@ open Finset Nat
open scoped BigOperators Nat
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
-
section GaussEisenstein
namespace ZMod
@@ -95,7 +93,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) : (↑a ^ (p / 2) : ZMod p) =
- (-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ => p / 2 < (a * x : ZMod p).val).card :=
+ ((-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ => p / 2 < (a * x : ZMod p).val).card :) :=
(mul_left_inj' (show ((p / 2)! : ZMod p) ≠ 0 by
rw [Ne.def, CharP.cast_eq_zero_iff (ZMod p) p, hp.1.dvd_factorial, not_le]
exact Nat.div_lt_self hp.1.pos (by decide))).1 <| by
sups
(#7254)
Match https://github.com/leanprover-community/mathlib/pull/18612.
The lemmas were already added in #7382, though a slight difference in the statement means that we need a new decidableExistsAndFinsetCoe
instance.
@@ -5,7 +5,7 @@ Authors: Chris Hughes
-/
import Mathlib.NumberTheory.LegendreSymbol.QuadraticReciprocity
-#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"442a83d738cb208d3600056c489be16900ba701d"
+#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"8818fdefc78642a7e6afcd20be5c184f3c7d9699"
/-!
# Lemmas of Gauss and Eisenstein
This incorporates changes from
nightly-testing
are unexciting: we need to fully qualify a few names)They can all be closed when this is merged.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -83,7 +83,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
(∏ x in Ico 1 (p / 2).succ, if (a * x : ZMod p).val ≤ p / 2 then (1 : ZMod p) else -1) =
∏ x in (Ico 1 (p / 2).succ).filter fun x : ℕ => ¬(a * x : ZMod p).val ≤ p / 2, -1 :=
prod_bij_ne_one (fun x _ _ => x)
- (fun x => by split_ifs <;> simp_all (config := { contextual := true }))
+ (fun x => by split_ifs <;> (dsimp; simp_all))
(fun _ _ _ _ _ _ => id) (fun b h _ => ⟨b, by simp_all [-not_le]⟩)
(by intros; split_ifs at * <;> simp_all)
rw [prod_mul_distrib, this, prod_const]
Finset.sup'
lemmas (#7021)
Match https://github.com/leanprover-community/mathlib/pull/18989
@@ -5,7 +5,7 @@ Authors: Chris Hughes
-/
import Mathlib.NumberTheory.LegendreSymbol.QuadraticReciprocity
-#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"c471da714c044131b90c133701e51b877c246677"
+#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"442a83d738cb208d3600056c489be16900ba701d"
/-!
# Lemmas of Gauss and Eisenstein
@@ -86,7 +86,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
(fun x => by split_ifs <;> simp_all (config := { contextual := true }))
(fun _ _ _ _ _ _ => id) (fun b h _ => ⟨b, by simp_all [-not_le]⟩)
(by intros; split_ifs at * <;> simp_all)
- rw [prod_mul_distrib, this]; simp
+ rw [prod_mul_distrib, this, prod_const]
_ = (-1 : ZMod p) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ =>
¬(a * x : ZMod p).val ≤ p / 2).card * (p / 2)! := by
rw [← prod_natCast, Finset.prod_eq_multiset_prod,
@@ -19,7 +19,7 @@ open Finset Nat
open scoped BigOperators Nat
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue #2220
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
section GaussEisenstein
@@ -62,7 +62,7 @@ theorem Ico_map_valMinAbs_natAbs_eq_Ico_map_id (p : ℕ) [hp : Fact p.Prime] (a
(inj_on_of_surj_on_of_card_le _ hmem hsurj le_rfl) hsurj
#align zmod.Ico_map_val_min_abs_nat_abs_eq_Ico_map_id ZMod.Ico_map_valMinAbs_natAbs_eq_Ico_map_id
-private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {a : ℤ}
+private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) : (a ^ (p / 2) * (p / 2)! : ZMod p) =
(-1 : ZMod p) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ =>
¬(a * x : ZMod p).val ≤ p / 2).card * (p / 2)! :=
@@ -93,7 +93,7 @@ private theorem gauss_lemma_aux₁ (p : ℕ) [Fact p.Prime] [Fact (p % 2 = 1)] {
Ico_map_valMinAbs_natAbs_eq_Ico_map_id p a hap, ← Finset.prod_eq_multiset_prod,
prod_Ico_id_eq_factorial]
-theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] [Fact (p % 2 = 1)] {a : ℤ}
+theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] {a : ℤ}
(hap : (a : ZMod p) ≠ 0) : (↑a ^ (p / 2) : ZMod p) =
(-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ => p / 2 < (a * x : ZMod p).val).card :=
(mul_left_inj' (show ((p / 2)! : ZMod p) ≠ 0 by
@@ -104,17 +104,17 @@ theorem gauss_lemma_aux (p : ℕ) [hp : Fact p.Prime] [Fact (p % 2 = 1)] {a :
/-- Gauss' lemma. The Legendre symbol can be computed by considering the number of naturals less
than `p/2` such that `(a * x) % p > p / 2`. -/
-theorem gauss_lemma {p : ℕ} [Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a : ZMod p) ≠ 0) :
+theorem gauss_lemma {p : ℕ} [h : Fact p.Prime] {a : ℤ} (hp : p ≠ 2) (ha0 : (a : ZMod p) ≠ 0) :
legendreSym p a = (-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ =>
p / 2 < (a * x : ZMod p).val).card := by
- haveI hp' : Fact (p % 2 = 1) := ⟨Nat.Prime.mod_two_eq_one_iff_ne_two.mpr hp⟩
+ replace hp : Odd p := h.out.odd_of_ne_two hp
have : (legendreSym p a : ZMod p) = (((-1) ^ ((Ico 1 (p / 2).succ).filter fun x : ℕ =>
p / 2 < (a * x : ZMod p).val).card : ℤ) : ZMod p) := by
rw [legendreSym.eq_pow, gauss_lemma_aux p ha0]
cases legendreSym.eq_one_or_neg_one p ha0 <;>
cases neg_one_pow_eq_or ℤ
((Ico 1 (p / 2).succ).filter fun x : ℕ => p / 2 < (a * x : ZMod p).val).card <;>
- simp_all [ne_neg_self p one_ne_zero, (ne_neg_self p one_ne_zero).symm]
+ simp_all [ne_neg_self hp one_ne_zero, (ne_neg_self hp one_ne_zero).symm]
#align zmod.gauss_lemma ZMod.gauss_lemma
private theorem eisenstein_lemma_aux₁ (p : ℕ) [Fact p.Prime] [hp2 : Fact (p % 2 = 1)] {a : ℕ}
@@ -2,14 +2,11 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-
-! This file was ported from Lean 3 source module number_theory.legendre_symbol.gauss_eisenstein_lemmas
-! leanprover-community/mathlib commit c471da714c044131b90c133701e51b877c246677
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.NumberTheory.LegendreSymbol.QuadraticReciprocity
+#align_import number_theory.legendre_symbol.gauss_eisenstein_lemmas from "leanprover-community/mathlib"@"c471da714c044131b90c133701e51b877c246677"
+
/-!
# Lemmas of Gauss and Eisenstein
The unported dependencies are
algebra.order.module
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
init.data.list.basic
linear_algebra.free_module.rank
algebra.order.monoid.cancel.basic
init.data.list.default
topology.subset_properties
init.logic
The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file