ring_theory.ideal.normMathlib.RingTheory.Ideal.Norm

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)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -9,9 +9,9 @@ import Data.Int.AbsoluteValue
 import Data.Int.Associated
 import LinearAlgebra.FreeModule.Determinant
 import LinearAlgebra.FreeModule.IdealQuotient
-import RingTheory.DedekindDomain.Pid
+import RingTheory.DedekindDomain.PID
 import RingTheory.LocalProperties
-import RingTheory.Localization.Norm
+import RingTheory.Localization.NormTrace
 
 #align_import ring_theory.ideal.norm from "leanprover-community/mathlib"@"5d0c76894ada7940957143163d7b921345474cbc"
 
@@ -151,7 +151,7 @@ theorem Ideal.mul_add_mem_pow_succ_inj (P : Ideal S) {i : ℕ} (a d d' e e' : S)
     a * d + e - (a * d' + e') ∈ P ^ (i + 1) :=
   by
   have : a * d - a * d' ∈ P ^ (i + 1) := by
-    convert Ideal.mul_mem_mul a_mem h <;> simp [mul_sub, pow_succ, mul_comm]
+    convert Ideal.mul_mem_mul a_mem h <;> simp [mul_sub, pow_succ', mul_comm]
   convert Ideal.add_mem _ this (Ideal.sub_mem _ e_mem e'_mem)
   ring
 #align ideal.mul_add_mem_pow_succ_inj Ideal.mul_add_mem_pow_succ_inj
@@ -187,7 +187,7 @@ theorem Ideal.mem_prime_of_mul_mem_pow [IsDedekindDomain S] {P : Ideal S} [P_pri
     (hP : P ≠ ⊥) {i : ℕ} {a b : S} (a_not_mem : a ∉ P ^ (i + 1)) (ab_mem : a * b ∈ P ^ (i + 1)) :
     b ∈ P :=
   by
-  simp only [← Ideal.span_singleton_le_iff_mem, ← Ideal.dvd_iff_le, pow_succ, ←
+  simp only [← Ideal.span_singleton_le_iff_mem, ← Ideal.dvd_iff_le, pow_succ', ←
     Ideal.span_singleton_mul_span_singleton] at a_not_mem ab_mem ⊢
   exact (prime_pow_succ_dvd_mul (Ideal.prime_of_isPrime hP P_prime) ab_mem).resolve_left a_not_mem
 #align ideal.mem_prime_of_mul_mem_pow Ideal.mem_prime_of_mul_mem_pow
@@ -223,7 +223,7 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
   letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
   have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
   suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
-  · rw [pow_succ (card_quot P), ← ih, card_quot_apply (P ^ i.succ), ←
+  · rw [pow_succ' (card_quot P), ← ih, card_quot_apply (P ^ i.succ), ←
       card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, card_quot_apply (P ^ i),
       card_quot_apply P]
     congr 1
@@ -457,7 +457,7 @@ theorem absNorm_dvd_absNorm_of_le {I J : Ideal S} (h : J ≤ I) : I.absNorm ∣
 #print Ideal.absNorm_dvd_norm_of_mem /-
 theorem absNorm_dvd_norm_of_mem {I : Ideal S} {x : S} (h : x ∈ I) : ↑I.absNorm ∣ Algebra.norm ℤ x :=
   by
-  rw [← Int.dvd_natAbs, ← abs_norm_span_singleton x, Int.coe_nat_dvd]
+  rw [← Int.dvd_natAbs, ← abs_norm_span_singleton x, Int.natCast_dvd_natCast]
   exact abs_norm_dvd_abs_norm_of_le ((span_singleton_le_iff_mem _).mpr h)
 #align ideal.abs_norm_dvd_norm_of_mem Ideal.absNorm_dvd_norm_of_mem
 -/
Diff
@@ -169,7 +169,7 @@ theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c :
     (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) : ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c :=
   by
   suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
-  · rw [eq_b] at c_mem 
+  · rw [eq_b] at c_mem
     simp only [mul_comm a]
     exact ideal.mem_span_singleton_sup.mp c_mem
   refine'
@@ -646,10 +646,10 @@ theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S
         ⟨s ^ Fintype.card (Module.Free.ChooseBasisIndex R S), pow_mem hs _⟩, _⟩
     swap
     simp only [Submodule.coe_mk, Subtype.coe_mk, map_pow] at has ⊢
-    apply_fun Algebra.norm Rₘ at has 
+    apply_fun Algebra.norm Rₘ at has
     rwa [_root_.map_mul, ← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_apply R Rₘ,
       Algebra.norm_algebraMap_of_basis (b.localization_localization Rₘ M Sₘ),
-      Algebra.norm_localization R M a] at has 
+      Algebra.norm_localization R M a] at has
     all_goals infer_instance
   · intro a ha
     rw [Set.mem_preimage, Function.comp_apply, ← Algebra.norm_localization R M a]
Diff
@@ -216,6 +216,41 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
   by
   let b := Module.Free.chooseBasis ℤ S
   classical
+  induction' i with i ih
+  · simp
+  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
+  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
+  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
+  have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
+  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
+  · rw [pow_succ (card_quot P), ← ih, card_quot_apply (P ^ i.succ), ←
+      card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, card_quot_apply (P ^ i),
+      card_quot_apply P]
+    congr 1
+    rw [Fintype.card_eq]
+    exact ⟨hquot⟩
+  choose a a_mem a_not_mem using SetLike.exists_of_lt this
+  choose f g hg hf using fun c (hc : c ∈ P ^ i) =>
+    Ideal.exists_mul_add_mem_pow_succ hP a c a_mem a_not_mem hc
+  choose k hk_mem hk_eq using fun c' (hc' : c' ∈ map (mkq (P ^ i.succ)) (P ^ i)) =>
+    submodule.mem_map.mp hc'
+  refine' Equiv.ofBijective (fun c' => Quotient.mk'' (f (k c' c'.Prop) (hk_mem c' c'.Prop))) ⟨_, _⟩
+  · rintro ⟨c₁', hc₁'⟩ ⟨c₂', hc₂'⟩ h
+    rw [Subtype.mk_eq_mk, ← hk_eq _ hc₁', ← hk_eq _ hc₂', mkq_apply, mkq_apply,
+      Submodule.Quotient.eq, ← hf _ (hk_mem _ hc₁'), ← hf _ (hk_mem _ hc₂')]
+    refine' Ideal.mul_add_mem_pow_succ_inj _ _ _ _ _ _ a_mem (hg _ _) (hg _ _) _
+    simpa only [Submodule.Quotient.mk''_eq_mk, Submodule.Quotient.mk''_eq_mk,
+      Submodule.Quotient.eq] using h
+  · intro d'
+    refine' Quotient.inductionOn' d' fun d => _
+    have hd' := mem_map.mpr ⟨a * d, Ideal.mul_mem_right d _ a_mem, rfl⟩
+    refine' ⟨⟨_, hd'⟩, _⟩
+    simp only [Submodule.Quotient.mk''_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.Quotient.eq,
+      Subtype.coe_mk]
+    refine'
+      Ideal.mul_add_mem_pow_succ_unique hP a _ _ _ _ a_not_mem (hg _ (hk_mem _ hd')) (zero_mem _) _
+    rw [hf, add_zero]
+    exact (Submodule.Quotient.eq _).mp (hk_eq _ hd')
 #align card_quot_pow_of_prime cardQuot_pow_of_prime
 -/
 
Diff
@@ -216,41 +216,6 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
   by
   let b := Module.Free.chooseBasis ℤ S
   classical
-  induction' i with i ih
-  · simp
-  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
-  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
-  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
-  have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
-  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
-  · rw [pow_succ (card_quot P), ← ih, card_quot_apply (P ^ i.succ), ←
-      card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, card_quot_apply (P ^ i),
-      card_quot_apply P]
-    congr 1
-    rw [Fintype.card_eq]
-    exact ⟨hquot⟩
-  choose a a_mem a_not_mem using SetLike.exists_of_lt this
-  choose f g hg hf using fun c (hc : c ∈ P ^ i) =>
-    Ideal.exists_mul_add_mem_pow_succ hP a c a_mem a_not_mem hc
-  choose k hk_mem hk_eq using fun c' (hc' : c' ∈ map (mkq (P ^ i.succ)) (P ^ i)) =>
-    submodule.mem_map.mp hc'
-  refine' Equiv.ofBijective (fun c' => Quotient.mk'' (f (k c' c'.Prop) (hk_mem c' c'.Prop))) ⟨_, _⟩
-  · rintro ⟨c₁', hc₁'⟩ ⟨c₂', hc₂'⟩ h
-    rw [Subtype.mk_eq_mk, ← hk_eq _ hc₁', ← hk_eq _ hc₂', mkq_apply, mkq_apply,
-      Submodule.Quotient.eq, ← hf _ (hk_mem _ hc₁'), ← hf _ (hk_mem _ hc₂')]
-    refine' Ideal.mul_add_mem_pow_succ_inj _ _ _ _ _ _ a_mem (hg _ _) (hg _ _) _
-    simpa only [Submodule.Quotient.mk''_eq_mk, Submodule.Quotient.mk''_eq_mk,
-      Submodule.Quotient.eq] using h
-  · intro d'
-    refine' Quotient.inductionOn' d' fun d => _
-    have hd' := mem_map.mpr ⟨a * d, Ideal.mul_mem_right d _ a_mem, rfl⟩
-    refine' ⟨⟨_, hd'⟩, _⟩
-    simp only [Submodule.Quotient.mk''_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.Quotient.eq,
-      Subtype.coe_mk]
-    refine'
-      Ideal.mul_add_mem_pow_succ_unique hP a _ _ _ _ a_not_mem (hg _ (hk_mem _ hd')) (zero_mem _) _
-    rw [hf, add_zero]
-    exact (Submodule.Quotient.eq _).mp (hk_eq _ hd')
 #align card_quot_pow_of_prime cardQuot_pow_of_prime
 -/
 
Diff
@@ -3,15 +3,15 @@ Copyright (c) 2022 Anne Baanen. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
 -/
-import Mathbin.Algebra.CharP.Quotient
-import Mathbin.Data.Finsupp.Fintype
-import Mathbin.Data.Int.AbsoluteValue
-import Mathbin.Data.Int.Associated
-import Mathbin.LinearAlgebra.FreeModule.Determinant
-import Mathbin.LinearAlgebra.FreeModule.IdealQuotient
-import Mathbin.RingTheory.DedekindDomain.Pid
-import Mathbin.RingTheory.LocalProperties
-import Mathbin.RingTheory.Localization.Norm
+import Algebra.CharP.Quotient
+import Data.Finsupp.Fintype
+import Data.Int.AbsoluteValue
+import Data.Int.Associated
+import LinearAlgebra.FreeModule.Determinant
+import LinearAlgebra.FreeModule.IdealQuotient
+import RingTheory.DedekindDomain.Pid
+import RingTheory.LocalProperties
+import RingTheory.Localization.Norm
 
 #align_import ring_theory.ideal.norm from "leanprover-community/mathlib"@"5d0c76894ada7940957143163d7b921345474cbc"
 
Diff
@@ -382,7 +382,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
     have : ∀ (c : ι → ℤ) (i), b'.repr (∑ j : ι, c j • a j • b' j) i = a i * c i :=
       by
       intro c i
-      simp only [← MulAction.mul_smul, b'.repr_sum_self, mul_comm]
+      simp only [← MulAction.hMul_smul, b'.repr_sum_self, mul_comm]
     constructor
     · rintro ⟨c, rfl⟩ i; exact ⟨c i, this c i⟩
     · rintro ha
Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2022 Anne Baanen. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
-
-! This file was ported from Lean 3 source module ring_theory.ideal.norm
-! leanprover-community/mathlib commit 5d0c76894ada7940957143163d7b921345474cbc
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Algebra.CharP.Quotient
 import Mathbin.Data.Finsupp.Fintype
@@ -18,6 +13,8 @@ import Mathbin.RingTheory.DedekindDomain.Pid
 import Mathbin.RingTheory.LocalProperties
 import Mathbin.RingTheory.Localization.Norm
 
+#align_import ring_theory.ideal.norm from "leanprover-community/mathlib"@"5d0c76894ada7940957143163d7b921345474cbc"
+
 /-!
 
 # Ideal norms
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
 
 ! This file was ported from Lean 3 source module ring_theory.ideal.norm
-! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
+! leanprover-community/mathlib commit 5d0c76894ada7940957143163d7b921345474cbc
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -22,6 +22,9 @@ import Mathbin.RingTheory.Localization.Norm
 
 # Ideal norms
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 This file defines the absolute ideal norm `ideal.abs_norm (I : ideal R) : ℕ` as the cardinality of
 the quotient `R ⧸ I` (setting it to 0 if the cardinality is infinite),
 and the relative ideal norm `ideal.span_norm R (I : ideal S) : ideal S` as the ideal spanned by
Diff
@@ -62,36 +62,46 @@ variable {R M : Type _} [Ring R] [AddCommGroup M] [Module R M]
 
 section
 
+#print Submodule.cardQuot /-
 /-- The cardinality of `(M ⧸ S)`, if `(M ⧸ S)` is finite, and `0` otherwise.
 This is used to define the absolute ideal norm `ideal.abs_norm`.
 -/
 noncomputable def cardQuot (S : Submodule R M) : ℕ :=
   AddSubgroup.index S.toAddSubgroup
 #align submodule.card_quot Submodule.cardQuot
+-/
 
+#print Submodule.cardQuot_apply /-
 @[simp]
 theorem cardQuot_apply (S : Submodule R M) [Fintype (M ⧸ S)] : cardQuot S = Fintype.card (M ⧸ S) :=
   AddSubgroup.index_eq_card _
 #align submodule.card_quot_apply Submodule.cardQuot_apply
+-/
 
 variable (R M)
 
+#print Submodule.cardQuot_bot /-
 @[simp]
 theorem cardQuot_bot [Infinite M] : cardQuot (⊥ : Submodule R M) = 0 :=
   AddSubgroup.index_bot.trans Nat.card_eq_zero_of_infinite
 #align submodule.card_quot_bot Submodule.cardQuot_bot
+-/
 
+#print Submodule.cardQuot_top /-
 @[simp]
 theorem cardQuot_top : cardQuot (⊤ : Submodule R M) = 1 :=
   AddSubgroup.index_top
 #align submodule.card_quot_top Submodule.cardQuot_top
+-/
 
 variable {R M}
 
+#print Submodule.cardQuot_eq_one_iff /-
 @[simp]
 theorem cardQuot_eq_one_iff {P : Submodule R M} : cardQuot P = 1 ↔ P = ⊤ :=
   AddSubgroup.index_eq_one.trans (by simp [SetLike.ext_iff])
 #align submodule.card_quot_eq_one_iff Submodule.cardQuot_eq_one_iff
+-/
 
 end
 
@@ -103,6 +113,7 @@ variable {S : Type _} [CommRing S] [IsDomain S]
 
 open Submodule
 
+#print cardQuot_mul_of_coprime /-
 /-- Multiplicity of the ideal norm, for coprime ideals.
 This is essentially just a repackaging of the Chinese Remainder Theorem.
 -/
@@ -129,7 +140,9 @@ theorem cardQuot_mul_of_coprime [IsDedekindDomain S] [Module.Free ℤ S] [Module
     fintype.card_eq.mpr ⟨(Ideal.quotientMulEquivQuotientProd I J coprime).toEquiv⟩,
     Fintype.card_prod]
 #align card_quot_mul_of_coprime cardQuot_mul_of_coprime
+-/
 
+#print Ideal.mul_add_mem_pow_succ_inj /-
 /-- If the `d` from `ideal.exists_mul_add_mem_pow_succ` is unique, up to `P`,
 then so are the `c`s, up to `P ^ (i + 1)`.
 Inspired by [Neukirch], proposition 6.1 -/
@@ -142,11 +155,13 @@ theorem Ideal.mul_add_mem_pow_succ_inj (P : Ideal S) {i : ℕ} (a d d' e e' : S)
   convert Ideal.add_mem _ this (Ideal.sub_mem _ e_mem e'_mem)
   ring
 #align ideal.mul_add_mem_pow_succ_inj Ideal.mul_add_mem_pow_succ_inj
+-/
 
 section PPrime
 
 variable {P : Ideal S} [P_prime : P.IsPrime] (hP : P ≠ ⊥)
 
+#print Ideal.exists_mul_add_mem_pow_succ /-
 /-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
 `ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
 Inspired by [Neukirch], proposition 6.1 -/
@@ -165,7 +180,9 @@ theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c :
   rw [this]
   exact mem_sup.mpr ⟨a, mem_span_singleton_self a, 0, by simp, by simp⟩
 #align ideal.exists_mul_add_mem_pow_succ Ideal.exists_mul_add_mem_pow_succ
+-/
 
+#print Ideal.mem_prime_of_mul_mem_pow /-
 theorem Ideal.mem_prime_of_mul_mem_pow [IsDedekindDomain S] {P : Ideal S} [P_prime : P.IsPrime]
     (hP : P ≠ ⊥) {i : ℕ} {a b : S} (a_not_mem : a ∉ P ^ (i + 1)) (ab_mem : a * b ∈ P ^ (i + 1)) :
     b ∈ P :=
@@ -174,7 +191,9 @@ theorem Ideal.mem_prime_of_mul_mem_pow [IsDedekindDomain S] {P : Ideal S} [P_pri
     Ideal.span_singleton_mul_span_singleton] at a_not_mem ab_mem ⊢
   exact (prime_pow_succ_dvd_mul (Ideal.prime_of_isPrime hP P_prime) ab_mem).resolve_left a_not_mem
 #align ideal.mem_prime_of_mul_mem_pow Ideal.mem_prime_of_mul_mem_pow
+-/
 
+#print Ideal.mul_add_mem_pow_succ_unique /-
 /-- The choice of `d` in `ideal.exists_mul_add_mem_pow_succ` is unique, up to `P`.
 Inspired by [Neukirch], proposition 6.1 -/
 theorem Ideal.mul_add_mem_pow_succ_unique [IsDedekindDomain S] {i : ℕ} (a d d' e e' : S)
@@ -188,7 +207,9 @@ theorem Ideal.mul_add_mem_pow_succ_unique [IsDedekindDomain S] {i : ℕ} (a d d'
     ring
   exact Ideal.mem_prime_of_mul_mem_pow hP a_not_mem h'
 #align ideal.mul_add_mem_pow_succ_unique Ideal.mul_add_mem_pow_succ_unique
+-/
 
+#print cardQuot_pow_of_prime /-
 /-- Multiplicity of the ideal norm, for powers of prime ideals. -/
 theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
     cardQuot (P ^ i) = cardQuot P ^ i :=
@@ -231,9 +252,11 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
     rw [hf, add_zero]
     exact (Submodule.Quotient.eq _).mp (hk_eq _ hd')
 #align card_quot_pow_of_prime cardQuot_pow_of_prime
+-/
 
 end PPrime
 
+#print cardQuot_mul /-
 /-- Multiplicativity of the ideal norm in number rings. -/
 theorem cardQuot_mul [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ S] (I J : Ideal S) :
     cardQuot (I * J) = cardQuot I * cardQuot J :=
@@ -256,7 +279,9 @@ theorem cardQuot_mul [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ
         (ideal.is_unit_iff.mp
           (hIJ _ (ideal.dvd_iff_le.mpr le_sup_left) (ideal.dvd_iff_le.mpr le_sup_right)))
 #align card_quot_mul cardQuot_mul
+-/
 
+#print Ideal.absNorm /-
 /-- The absolute norm of the ideal `I : ideal R` is the cardinality of the quotient `R ⧸ I`. -/
 noncomputable def Ideal.absNorm [Infinite S] [IsDedekindDomain S] [Module.Free ℤ S]
     [Module.Finite ℤ S] : Ideal S →*₀ ℕ
@@ -266,33 +291,45 @@ noncomputable def Ideal.absNorm [Infinite S] [IsDedekindDomain S] [Module.Free 
   map_one' := by rw [Ideal.one_eq_top, card_quot_top]
   map_zero' := by rw [Ideal.zero_eq_bot, card_quot_bot]
 #align ideal.abs_norm Ideal.absNorm
+-/
 
 namespace Ideal
 
 variable [Infinite S] [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ S]
 
+#print Ideal.absNorm_apply /-
 theorem absNorm_apply (I : Ideal S) : absNorm I = cardQuot I :=
   rfl
 #align ideal.abs_norm_apply Ideal.absNorm_apply
+-/
 
+#print Ideal.absNorm_bot /-
 @[simp]
 theorem absNorm_bot : absNorm (⊥ : Ideal S) = 0 := by rw [← Ideal.zero_eq_bot, _root_.map_zero]
 #align ideal.abs_norm_bot Ideal.absNorm_bot
+-/
 
+#print Ideal.absNorm_top /-
 @[simp]
 theorem absNorm_top : absNorm (⊤ : Ideal S) = 1 := by rw [← Ideal.one_eq_top, _root_.map_one]
 #align ideal.abs_norm_top Ideal.absNorm_top
+-/
 
+#print Ideal.absNorm_eq_one_iff /-
 @[simp]
 theorem absNorm_eq_one_iff {I : Ideal S} : absNorm I = 1 ↔ I = ⊤ := by
   rw [abs_norm_apply, card_quot_eq_one_iff]
 #align ideal.abs_norm_eq_one_iff Ideal.absNorm_eq_one_iff
+-/
 
+#print Ideal.absNorm_ne_zero_iff /-
 theorem absNorm_ne_zero_iff (I : Ideal S) : Ideal.absNorm I ≠ 0 ↔ Finite (S ⧸ I) :=
   ⟨fun h => Nat.finite_of_card_ne_zero h, fun h =>
     (@AddSubgroup.finiteIndex_of_finite_quotient _ _ _ h).FiniteIndex⟩
 #align ideal.abs_norm_ne_zero_iff Ideal.absNorm_ne_zero_iff
+-/
 
+#print Ideal.natAbs_det_equiv /-
 /-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
 Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
 See `nat_abs_det_basis_change` for a more familiar formulation of this result. -/
@@ -374,7 +411,9 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
   simp_rw [fintype.card_eq.mpr ⟨(Ideal.quotientEquivPiZMod I b hI).toEquiv⟩, Fintype.card_pi,
     ZMod.card]
 #align ideal.nat_abs_det_equiv Ideal.natAbs_det_equiv
+-/
 
+#print Ideal.natAbs_det_basis_change /-
 /-- Let `b` be a basis for `S` over `ℤ` and `bI` a basis for `I` over `ℤ` of the same dimension.
 Then an alternative way to compute the norm of `I` is given by taking the determinant of `bI`
 over `b`. -/
@@ -388,7 +427,9 @@ theorem natAbs_det_basis_change {ι : Type _} [Fintype ι] [DecidableEq ι] (b :
       by rw [Basis.det_comp_basis]
     _ = _ := nat_abs_det_equiv I e
 #align ideal.nat_abs_det_basis_change Ideal.natAbs_det_basis_change
+-/
 
+#print Ideal.absNorm_span_singleton /-
 @[simp]
 theorem absNorm_span_singleton (r : S) : absNorm (span ({r} : Set S)) = (Algebra.norm ℤ r).natAbs :=
   by
@@ -405,17 +446,23 @@ theorem absNorm_span_singleton (r : S) : absNorm (span ({r} : Set S)) = (Algebra
   refine' b.ext fun i => _
   simp
 #align ideal.abs_norm_span_singleton Ideal.absNorm_span_singleton
+-/
 
+#print Ideal.absNorm_dvd_absNorm_of_le /-
 theorem absNorm_dvd_absNorm_of_le {I J : Ideal S} (h : J ≤ I) : I.absNorm ∣ J.absNorm :=
   map_dvd absNorm (dvd_iff_le.mpr h)
 #align ideal.abs_norm_dvd_abs_norm_of_le Ideal.absNorm_dvd_absNorm_of_le
+-/
 
+#print Ideal.absNorm_dvd_norm_of_mem /-
 theorem absNorm_dvd_norm_of_mem {I : Ideal S} {x : S} (h : x ∈ I) : ↑I.absNorm ∣ Algebra.norm ℤ x :=
   by
   rw [← Int.dvd_natAbs, ← abs_norm_span_singleton x, Int.coe_nat_dvd]
   exact abs_norm_dvd_abs_norm_of_le ((span_singleton_le_iff_mem _).mpr h)
 #align ideal.abs_norm_dvd_norm_of_mem Ideal.absNorm_dvd_norm_of_mem
+-/
 
+#print Ideal.absNorm_span_insert /-
 @[simp]
 theorem absNorm_span_insert (r : S) (s : Set S) :
     absNorm (span (insert r s)) ∣ gcd (absNorm (span s)) (Algebra.norm ℤ r).natAbs :=
@@ -425,7 +472,9 @@ theorem absNorm_span_insert (r : S) (s : Set S) :
         (absNorm_dvd_absNorm_of_le (span_mono (Set.singleton_subset_iff.mpr (Set.mem_insert _ _))))
         (by rw [abs_norm_span_singleton])⟩
 #align ideal.abs_norm_span_insert Ideal.absNorm_span_insert
+-/
 
+#print Ideal.irreducible_of_irreducible_absNorm /-
 theorem irreducible_of_irreducible_absNorm {I : Ideal S} (hI : Irreducible I.absNorm) :
     Irreducible I :=
   irreducible_iff.mpr
@@ -436,26 +485,36 @@ theorem irreducible_of_irreducible_absNorm {I : Ideal S} (hI : Irreducible I.abs
         simpa only [Ideal.isUnit_iff, Nat.isUnit_iff, abs_norm_eq_one_iff] using
           hI.is_unit_or_is_unit (_root_.map_mul abs_norm a b)⟩
 #align ideal.irreducible_of_irreducible_abs_norm Ideal.irreducible_of_irreducible_absNorm
+-/
 
+#print Ideal.isPrime_of_irreducible_absNorm /-
 theorem isPrime_of_irreducible_absNorm {I : Ideal S} (hI : Irreducible I.absNorm) : I.IsPrime :=
   isPrime_of_prime
     (UniqueFactorizationMonoid.irreducible_iff_prime.mp (irreducible_of_irreducible_absNorm hI))
 #align ideal.is_prime_of_irreducible_abs_norm Ideal.isPrime_of_irreducible_absNorm
+-/
 
+#print Ideal.prime_of_irreducible_absNorm_span /-
 theorem prime_of_irreducible_absNorm_span {a : S} (ha : a ≠ 0)
     (hI : Irreducible (Ideal.span ({a} : Set S)).absNorm) : Prime a :=
   (Ideal.span_singleton_prime ha).mp (isPrime_of_irreducible_absNorm hI)
 #align ideal.prime_of_irreducible_abs_norm_span Ideal.prime_of_irreducible_absNorm_span
+-/
 
+#print Ideal.absNorm_mem /-
 theorem absNorm_mem (I : Ideal S) : ↑I.absNorm ∈ I := by
   rw [abs_norm_apply, card_quot, ← Ideal.Quotient.eq_zero_iff_mem, map_natCast,
     quotient.index_eq_zero]
 #align ideal.abs_norm_mem Ideal.absNorm_mem
+-/
 
+#print Ideal.span_singleton_absNorm_le /-
 theorem span_singleton_absNorm_le (I : Ideal S) : Ideal.span {(Ideal.absNorm I : S)} ≤ I := by
   simp only [Ideal.span_le, Set.singleton_subset_iff, SetLike.mem_coe, Ideal.absNorm_mem I]
 #align ideal.span_singleton_abs_norm_le Ideal.span_singleton_absNorm_le
+-/
 
+#print Ideal.finite_setOf_absNorm_eq /-
 theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
     {I : Ideal S | Ideal.absNorm I = n}.Finite :=
   by
@@ -474,6 +533,7 @@ theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
       comap_map_mk (span_singleton_abs_norm_le J), ← hJ.symm]
     exact congr_arg (Ideal.comap (Ideal.Quotient.mk (@Ideal.span S _ {n}))) h
 #align ideal.finite_set_of_abs_norm_eq Ideal.finite_setOf_absNorm_eq
+-/
 
 end Ideal
 
@@ -489,6 +549,7 @@ open Submodule
 
 variable (R : Type _) [CommRing R] {S : Type _} [CommRing S] [Algebra R S]
 
+#print Ideal.spanNorm /-
 /-- `ideal.span_norm R (I : ideal S)` is the ideal generated by mapping `algebra.norm R` over `I`.
 
 See also `ideal.rel_norm`.
@@ -496,15 +557,19 @@ See also `ideal.rel_norm`.
 def spanNorm (I : Ideal S) : Ideal R :=
   Ideal.span (Algebra.norm R '' (I : Set S))
 #align ideal.span_norm Ideal.spanNorm
+-/
 
+#print Ideal.spanNorm_bot /-
 @[simp]
 theorem spanNorm_bot [Nontrivial S] [Module.Free R S] [Module.Finite R S] :
     spanNorm R (⊥ : Ideal S) = ⊥ :=
   span_eq_bot.mpr fun x hx => by simpa using hx
 #align ideal.span_norm_bot Ideal.spanNorm_bot
+-/
 
 variable {R}
 
+#print Ideal.spanNorm_eq_bot_iff /-
 @[simp]
 theorem spanNorm_eq_bot_iff [IsDomain R] [IsDomain S] [Module.Free R S] [Module.Finite R S]
     {I : Ideal S} : spanNorm R I = ⊥ ↔ I = ⊥ :=
@@ -515,13 +580,17 @@ theorem spanNorm_eq_bot_iff [IsDomain R] [IsDomain S] [Module.Free R S] [Module.
     SetLike.le_def]
   rfl
 #align ideal.span_norm_eq_bot_iff Ideal.spanNorm_eq_bot_iff
+-/
 
 variable (R)
 
+#print Ideal.norm_mem_spanNorm /-
 theorem norm_mem_spanNorm {I : Ideal S} (x : S) (hx : x ∈ I) : Algebra.norm R x ∈ I.spanNorm R :=
   subset_span (Set.mem_image_of_mem _ hx)
 #align ideal.norm_mem_span_norm Ideal.norm_mem_spanNorm
+-/
 
+#print Ideal.spanNorm_singleton /-
 @[simp]
 theorem spanNorm_singleton {r : S} : spanNorm R (span ({r} : Set S)) = span {Algebra.norm R r} :=
   le_antisymm
@@ -532,21 +601,29 @@ theorem spanNorm_singleton {r : S} : spanNorm R (span ({r} : Set S)) = span {Alg
           exact map_dvd _ (mem_span_singleton.mp hx')))
     ((span_singleton_le_iff_mem _).mpr (norm_mem_spanNorm _ _ (mem_span_singleton_self _)))
 #align ideal.span_norm_singleton Ideal.spanNorm_singleton
+-/
 
+#print Ideal.spanNorm_top /-
 @[simp]
 theorem spanNorm_top : spanNorm R (⊤ : Ideal S) = ⊤ := by simp [← Ideal.span_singleton_one]
 #align ideal.span_norm_top Ideal.spanNorm_top
+-/
 
+#print Ideal.map_spanNorm /-
 theorem map_spanNorm (I : Ideal S) {T : Type _} [CommRing T] (f : R →+* T) :
     map f (spanNorm R I) = span (f ∘ Algebra.norm R '' (I : Set S)) := by
   rw [span_norm, map_span, Set.image_image]
 #align ideal.map_span_norm Ideal.map_spanNorm
+-/
 
+#print Ideal.spanNorm_mono /-
 @[mono]
 theorem spanNorm_mono {I J : Ideal S} (h : I ≤ J) : spanNorm R I ≤ spanNorm R J :=
   Ideal.span_mono (Set.monotone_image h)
 #align ideal.span_norm_mono Ideal.spanNorm_mono
+-/
 
+#print Ideal.spanNorm_localization /-
 theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S] (M : Submonoid R)
     {Rₘ : Type _} (Sₘ : Type _) [CommRing Rₘ] [Algebra R Rₘ] [CommRing Sₘ] [Algebra S Sₘ]
     [Algebra Rₘ Sₘ] [Algebra R Sₘ] [IsScalarTower R Rₘ Sₘ] [IsScalarTower R S Sₘ]
@@ -579,7 +656,9 @@ theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S
     exact subset_span (Set.mem_image_of_mem _ (mem_map_of_mem _ ha))
     all_goals infer_instance
 #align ideal.span_norm_localization Ideal.spanNorm_localization
+-/
 
+#print Ideal.spanNorm_mul_spanNorm_le /-
 theorem spanNorm_mul_spanNorm_le (I J : Ideal S) :
     spanNorm R I * spanNorm R J ≤ spanNorm R (I * J) :=
   by
@@ -588,7 +667,9 @@ theorem spanNorm_mul_spanNorm_le (I J : Ideal S) :
   rintro _ ⟨x, y, hxI, hyJ, rfl⟩
   exact Ideal.mul_mem_mul hxI hyJ
 #align ideal.span_norm_mul_span_norm_le Ideal.spanNorm_mul_spanNorm_le
+-/
 
+#print Ideal.spanNorm_mul_of_bot_or_top /-
 /-- This condition `eq_bot_or_top` is equivalent to being a field.
 However, `span_norm_mul_of_field` is harder to apply since we'd need to upgrade a `comm_ring R`
 instance to a `field R` instance. -/
@@ -607,17 +688,21 @@ theorem spanNorm_mul_of_bot_or_top [IsDomain R] [IsDomain S] [Module.Free R S] [
   rw [hJ]
   exact le_top
 #align ideal.span_norm_mul_of_bot_or_top Ideal.spanNorm_mul_of_bot_or_top
+-/
 
+#print Ideal.spanNorm_mul_of_field /-
 @[simp]
 theorem spanNorm_mul_of_field {K : Type _} [Field K] [Algebra K S] [IsDomain S] [Module.Finite K S]
     (I J : Ideal S) : spanNorm K (I * J) = spanNorm K I * spanNorm K J :=
   spanNorm_mul_of_bot_or_top K eq_bot_or_top I J
 #align ideal.span_norm_mul_of_field Ideal.spanNorm_mul_of_field
+-/
 
 variable [IsDomain R] [IsDomain S] [IsDedekindDomain R] [IsDedekindDomain S]
 
 variable [Module.Finite R S] [Module.Free R S]
 
+#print Ideal.spanNorm_mul /-
 /-- Multiplicativity of `ideal.span_norm`. simp-normal form is `map_mul (ideal.rel_norm R)`. -/
 theorem spanNorm_mul (I J : Ideal S) : spanNorm R (I * J) = spanNorm R I * spanNorm R J :=
   by
@@ -654,7 +739,9 @@ theorem spanNorm_mul (I J : Ideal S) : spanNorm R (I * J) = spanNorm R I * spanN
   repeat' infer_instance
   repeat' assumption
 #align ideal.span_norm_mul Ideal.spanNorm_mul
+-/
 
+#print Ideal.relNorm /-
 /-- The relative norm `ideal.rel_norm R (I : ideal S)`, where `R` and `S` are Dedekind domains,
 and `S` is an extension of `R` that is finite and free as a module. -/
 def relNorm : Ideal S →*₀ Ideal R where
@@ -663,53 +750,72 @@ def relNorm : Ideal S →*₀ Ideal R where
   map_one' := by rw [one_eq_top, span_norm_top R, one_eq_top]
   map_mul' := spanNorm_mul R
 #align ideal.rel_norm Ideal.relNorm
+-/
 
+#print Ideal.relNorm_apply /-
 theorem relNorm_apply (I : Ideal S) : relNorm R I = span (Algebra.norm R '' (I : Set S) : Set R) :=
   rfl
 #align ideal.rel_norm_apply Ideal.relNorm_apply
+-/
 
+#print Ideal.spanNorm_eq /-
 @[simp]
 theorem spanNorm_eq (I : Ideal S) : spanNorm R I = relNorm R I :=
   rfl
 #align ideal.span_norm_eq Ideal.spanNorm_eq
+-/
 
+#print Ideal.relNorm_bot /-
 @[simp]
 theorem relNorm_bot : relNorm R (⊥ : Ideal S) = ⊥ := by
   simpa only [zero_eq_bot] using map_zero (rel_norm R : Ideal S →*₀ _)
 #align ideal.rel_norm_bot Ideal.relNorm_bot
+-/
 
+#print Ideal.relNorm_top /-
 @[simp]
 theorem relNorm_top : relNorm R (⊤ : Ideal S) = ⊤ := by
   simpa only [one_eq_top] using map_one (rel_norm R : Ideal S →*₀ _)
 #align ideal.rel_norm_top Ideal.relNorm_top
+-/
 
 variable {R}
 
+#print Ideal.relNorm_eq_bot_iff /-
 @[simp]
 theorem relNorm_eq_bot_iff {I : Ideal S} : relNorm R I = ⊥ ↔ I = ⊥ :=
   spanNorm_eq_bot_iff
 #align ideal.rel_norm_eq_bot_iff Ideal.relNorm_eq_bot_iff
+-/
 
 variable (R)
 
+#print Ideal.norm_mem_relNorm /-
 theorem norm_mem_relNorm (I : Ideal S) {x : S} (hx : x ∈ I) : Algebra.norm R x ∈ relNorm R I :=
   norm_mem_spanNorm R x hx
 #align ideal.norm_mem_rel_norm Ideal.norm_mem_relNorm
+-/
 
+#print Ideal.relNorm_singleton /-
 @[simp]
 theorem relNorm_singleton (r : S) : relNorm R (span ({r} : Set S)) = span {Algebra.norm R r} :=
   spanNorm_singleton R
 #align ideal.rel_norm_singleton Ideal.relNorm_singleton
+-/
 
+#print Ideal.map_relNorm /-
 theorem map_relNorm (I : Ideal S) {T : Type _} [CommRing T] (f : R →+* T) :
     map f (relNorm R I) = span (f ∘ Algebra.norm R '' (I : Set S)) :=
   map_spanNorm R I f
 #align ideal.map_rel_norm Ideal.map_relNorm
+-/
 
+#print Ideal.relNorm_mono /-
 @[mono]
 theorem relNorm_mono {I J : Ideal S} (h : I ≤ J) : relNorm R I ≤ relNorm R J :=
   spanNorm_mono R h
 #align ideal.rel_norm_mono Ideal.relNorm_mono
+-/
 
 end Ideal
 
Diff
@@ -361,7 +361,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
     _ = Fintype.card (S ⧸ I) := _
     _ = abs_norm I := (Submodule.cardQuot_apply _).symm
   -- since `linear_map.to_matrix b' b' f` is the diagonal matrix with `a` along the diagonal.
-  · congr; ext (i j)
+  · congr; ext i j
     rw [LinearMap.toMatrix_apply, ha, LinearEquiv.map_smul, Basis.repr_self, Finsupp.smul_single,
       smul_eq_mul, mul_one]
     by_cases h : i = j
Diff
@@ -147,8 +147,6 @@ section PPrime
 
 variable {P : Ideal S} [P_prime : P.IsPrime] (hP : P ≠ ⊥)
 
-include P_prime hP
-
 /-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
 `ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
 Inspired by [Neukirch], proposition 6.1 -/
Diff
@@ -339,7 +339,6 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
       _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ _)).natAbs :=
         (int.nat_abs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _))
       _ = abs_norm I := this
-      
   have ha : ∀ i, f (b' i) = a i • b' i := by intro i;
     rw [f_apply, b'.equiv_apply, Equiv.refl_apply, ab_eq]
   have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i :=
@@ -363,7 +362,6 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
     _ = ∏ i, Int.natAbs (a i) := (map_prod Int.natAbsHom a Finset.univ)
     _ = Fintype.card (S ⧸ I) := _
     _ = abs_norm I := (Submodule.cardQuot_apply _).symm
-    
   -- since `linear_map.to_matrix b' b' f` is the diagonal matrix with `a` along the diagonal.
   · congr; ext (i j)
     rw [LinearMap.toMatrix_apply, ha, LinearEquiv.map_smul, Basis.repr_self, Finsupp.smul_single,
@@ -391,7 +389,6 @@ theorem natAbs_det_basis_change {ι : Type _} [Fintype ι] [DecidableEq ι] (b :
         (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ (e : S →ₗ[ℤ] I))).natAbs :=
       by rw [Basis.det_comp_basis]
     _ = _ := nat_abs_det_equiv I e
-    
 #align ideal.nat_abs_det_basis_change Ideal.natAbs_det_basis_change
 
 @[simp]
Diff
@@ -197,43 +197,41 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
   by
   let b := Module.Free.chooseBasis ℤ S
   classical
-    induction' i with i ih
-    · simp
-    letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
-    letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
-    letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
-    have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
-    suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
-    · rw [pow_succ (card_quot P), ← ih, card_quot_apply (P ^ i.succ), ←
-        card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, card_quot_apply (P ^ i),
-        card_quot_apply P]
-      congr 1
-      rw [Fintype.card_eq]
-      exact ⟨hquot⟩
-    choose a a_mem a_not_mem using SetLike.exists_of_lt this
-    choose f g hg hf using fun c (hc : c ∈ P ^ i) =>
-      Ideal.exists_mul_add_mem_pow_succ hP a c a_mem a_not_mem hc
-    choose k hk_mem hk_eq using fun c' (hc' : c' ∈ map (mkq (P ^ i.succ)) (P ^ i)) =>
-      submodule.mem_map.mp hc'
+  induction' i with i ih
+  · simp
+  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
+  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
+  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
+  have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
+  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
+  · rw [pow_succ (card_quot P), ← ih, card_quot_apply (P ^ i.succ), ←
+      card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, card_quot_apply (P ^ i),
+      card_quot_apply P]
+    congr 1
+    rw [Fintype.card_eq]
+    exact ⟨hquot⟩
+  choose a a_mem a_not_mem using SetLike.exists_of_lt this
+  choose f g hg hf using fun c (hc : c ∈ P ^ i) =>
+    Ideal.exists_mul_add_mem_pow_succ hP a c a_mem a_not_mem hc
+  choose k hk_mem hk_eq using fun c' (hc' : c' ∈ map (mkq (P ^ i.succ)) (P ^ i)) =>
+    submodule.mem_map.mp hc'
+  refine' Equiv.ofBijective (fun c' => Quotient.mk'' (f (k c' c'.Prop) (hk_mem c' c'.Prop))) ⟨_, _⟩
+  · rintro ⟨c₁', hc₁'⟩ ⟨c₂', hc₂'⟩ h
+    rw [Subtype.mk_eq_mk, ← hk_eq _ hc₁', ← hk_eq _ hc₂', mkq_apply, mkq_apply,
+      Submodule.Quotient.eq, ← hf _ (hk_mem _ hc₁'), ← hf _ (hk_mem _ hc₂')]
+    refine' Ideal.mul_add_mem_pow_succ_inj _ _ _ _ _ _ a_mem (hg _ _) (hg _ _) _
+    simpa only [Submodule.Quotient.mk''_eq_mk, Submodule.Quotient.mk''_eq_mk,
+      Submodule.Quotient.eq] using h
+  · intro d'
+    refine' Quotient.inductionOn' d' fun d => _
+    have hd' := mem_map.mpr ⟨a * d, Ideal.mul_mem_right d _ a_mem, rfl⟩
+    refine' ⟨⟨_, hd'⟩, _⟩
+    simp only [Submodule.Quotient.mk''_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.Quotient.eq,
+      Subtype.coe_mk]
     refine'
-      Equiv.ofBijective (fun c' => Quotient.mk'' (f (k c' c'.Prop) (hk_mem c' c'.Prop))) ⟨_, _⟩
-    · rintro ⟨c₁', hc₁'⟩ ⟨c₂', hc₂'⟩ h
-      rw [Subtype.mk_eq_mk, ← hk_eq _ hc₁', ← hk_eq _ hc₂', mkq_apply, mkq_apply,
-        Submodule.Quotient.eq, ← hf _ (hk_mem _ hc₁'), ← hf _ (hk_mem _ hc₂')]
-      refine' Ideal.mul_add_mem_pow_succ_inj _ _ _ _ _ _ a_mem (hg _ _) (hg _ _) _
-      simpa only [Submodule.Quotient.mk''_eq_mk, Submodule.Quotient.mk''_eq_mk,
-        Submodule.Quotient.eq] using h
-    · intro d'
-      refine' Quotient.inductionOn' d' fun d => _
-      have hd' := mem_map.mpr ⟨a * d, Ideal.mul_mem_right d _ a_mem, rfl⟩
-      refine' ⟨⟨_, hd'⟩, _⟩
-      simp only [Submodule.Quotient.mk''_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.Quotient.eq,
-        Subtype.coe_mk]
-      refine'
-        Ideal.mul_add_mem_pow_succ_unique hP a _ _ _ _ a_not_mem (hg _ (hk_mem _ hd')) (zero_mem _)
-          _
-      rw [hf, add_zero]
-      exact (Submodule.Quotient.eq _).mp (hk_eq _ hd')
+      Ideal.mul_add_mem_pow_succ_unique hP a _ _ _ _ a_not_mem (hg _ (hk_mem _ hd')) (zero_mem _) _
+    rw [hf, add_zero]
+    exact (Submodule.Quotient.eq _).mp (hk_eq _ hd')
 #align card_quot_pow_of_prime cardQuot_pow_of_prime
 
 end PPrime
@@ -464,7 +462,7 @@ theorem span_singleton_absNorm_le (I : Ideal S) : Ideal.span {(Ideal.absNorm I :
 #align ideal.span_singleton_abs_norm_le Ideal.span_singleton_absNorm_le
 
 theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
-    { I : Ideal S | Ideal.absNorm I = n }.Finite :=
+    {I : Ideal S | Ideal.absNorm I = n}.Finite :=
   by
   let f := fun I : Ideal S => Ideal.map (Ideal.Quotient.mk (@Ideal.span S _ {n})) I
   refine' @Set.Finite.of_finite_image _ _ _ f _ _
@@ -576,7 +574,7 @@ theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S
         ⟨s ^ Fintype.card (Module.Free.ChooseBasisIndex R S), pow_mem hs _⟩, _⟩
     swap
     simp only [Submodule.coe_mk, Subtype.coe_mk, map_pow] at has ⊢
-    apply_fun Algebra.norm Rₘ  at has 
+    apply_fun Algebra.norm Rₘ at has 
     rwa [_root_.map_mul, ← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_apply R Rₘ,
       Algebra.norm_algebraMap_of_basis (b.localization_localization Rₘ M Sₘ),
       Algebra.norm_localization R M a] at has 
Diff
@@ -156,7 +156,7 @@ theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c :
     (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) : ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c :=
   by
   suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
-  · rw [eq_b] at c_mem
+  · rw [eq_b] at c_mem 
     simp only [mul_comm a]
     exact ideal.mem_span_singleton_sup.mp c_mem
   refine'
@@ -173,7 +173,7 @@ theorem Ideal.mem_prime_of_mul_mem_pow [IsDedekindDomain S] {P : Ideal S} [P_pri
     b ∈ P :=
   by
   simp only [← Ideal.span_singleton_le_iff_mem, ← Ideal.dvd_iff_le, pow_succ, ←
-    Ideal.span_singleton_mul_span_singleton] at a_not_mem ab_mem⊢
+    Ideal.span_singleton_mul_span_singleton] at a_not_mem ab_mem ⊢
   exact (prime_pow_succ_dvd_mul (Ideal.prime_of_isPrime hP P_prime) ab_mem).resolve_left a_not_mem
 #align ideal.mem_prime_of_mul_mem_pow Ideal.mem_prime_of_mul_mem_pow
 
@@ -367,7 +367,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
     _ = abs_norm I := (Submodule.cardQuot_apply _).symm
     
   -- since `linear_map.to_matrix b' b' f` is the diagonal matrix with `a` along the diagonal.
-  · congr ; ext (i j)
+  · congr; ext (i j)
     rw [LinearMap.toMatrix_apply, ha, LinearEquiv.map_smul, Basis.repr_self, Finsupp.smul_single,
       smul_eq_mul, mul_one]
     by_cases h : i = j
@@ -569,17 +569,17 @@ theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S
   · rintro a' ha'
     simp only [Set.mem_preimage, submodule_span_eq, ← map_span_norm, SetLike.mem_coe,
       IsLocalization.mem_map_algebraMap_iff (Algebra.algebraMapSubmonoid S M) Sₘ,
-      IsLocalization.mem_map_algebraMap_iff M Rₘ, Prod.exists] at ha'⊢
+      IsLocalization.mem_map_algebraMap_iff M Rₘ, Prod.exists] at ha' ⊢
     obtain ⟨⟨a, ha⟩, ⟨_, ⟨s, hs, rfl⟩⟩, has⟩ := ha'
     refine'
       ⟨⟨Algebra.norm R a, norm_mem_span_norm _ _ ha⟩,
         ⟨s ^ Fintype.card (Module.Free.ChooseBasisIndex R S), pow_mem hs _⟩, _⟩
     swap
-    simp only [Submodule.coe_mk, Subtype.coe_mk, map_pow] at has⊢
-    apply_fun Algebra.norm Rₘ  at has
+    simp only [Submodule.coe_mk, Subtype.coe_mk, map_pow] at has ⊢
+    apply_fun Algebra.norm Rₘ  at has 
     rwa [_root_.map_mul, ← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_apply R Rₘ,
       Algebra.norm_algebraMap_of_basis (b.localization_localization Rₘ M Sₘ),
-      Algebra.norm_localization R M a] at has
+      Algebra.norm_localization R M a] at has 
     all_goals infer_instance
   · intro a ha
     rw [Set.mem_preimage, Function.comp_apply, ← Algebra.norm_localization R M a]
Diff
@@ -50,9 +50,9 @@ the norms of elements in `I`.
 -/
 
 
-open BigOperators
+open scoped BigOperators
 
-open nonZeroDivisors
+open scoped nonZeroDivisors
 
 section abs_norm
 
Diff
@@ -342,23 +342,19 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
         (int.nat_abs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _))
       _ = abs_norm I := this
       
-  have ha : ∀ i, f (b' i) = a i • b' i := by
-    intro i
+  have ha : ∀ i, f (b' i) = a i • b' i := by intro i;
     rw [f_apply, b'.equiv_apply, Equiv.refl_apply, ab_eq]
   have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i :=
     by
-    intro x
-    simp_rw [ab.mem_ideal_iff', ab_eq]
+    intro x; simp_rw [ab.mem_ideal_iff', ab_eq]
     have : ∀ (c : ι → ℤ) (i), b'.repr (∑ j : ι, c j • a j • b' j) i = a i * c i :=
       by
       intro c i
       simp only [← MulAction.mul_smul, b'.repr_sum_self, mul_comm]
     constructor
-    · rintro ⟨c, rfl⟩ i
-      exact ⟨c i, this c i⟩
+    · rintro ⟨c, rfl⟩ i; exact ⟨c i, this c i⟩
     · rintro ha
-      choose c hc using ha
-      exact ⟨c, b'.ext_elem fun i => trans (hc i) (this c i).symm⟩
+      choose c hc using ha; exact ⟨c, b'.ext_elem fun i => trans (hc i) (this c i).symm⟩
   -- `det f` is equal to `∏ i, a i`,
   letI := Classical.decEq ι
   calc
@@ -371,8 +367,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
     _ = abs_norm I := (Submodule.cardQuot_apply _).symm
     
   -- since `linear_map.to_matrix b' b' f` is the diagonal matrix with `a` along the diagonal.
-  · congr
-    ext (i j)
+  · congr ; ext (i j)
     rw [LinearMap.toMatrix_apply, ha, LinearEquiv.map_smul, Basis.repr_self, Finsupp.smul_single,
       smul_eq_mul, mul_one]
     by_cases h : i = j
Diff
@@ -382,7 +382,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
   -- which maps `(S ⧸ I)` to `Π i, zmod (a i).nat_abs`.
   haveI : ∀ i, NeZero (a i).natAbs := fun i =>
     ⟨Int.natAbs_ne_zero_of_ne_zero (Ideal.smithCoeffs_ne_zero b I hI i)⟩
-  simp_rw [fintype.card_eq.mpr ⟨(Ideal.quotientEquivPiZmod I b hI).toEquiv⟩, Fintype.card_pi,
+  simp_rw [fintype.card_eq.mpr ⟨(Ideal.quotientEquivPiZMod I b hI).toEquiv⟩, Fintype.card_pi,
     ZMod.card]
 #align ideal.nat_abs_det_equiv Ideal.natAbs_det_equiv
 
Diff
@@ -54,7 +54,7 @@ open BigOperators
 
 open nonZeroDivisors
 
-section AbsNorm
+section abs_norm
 
 namespace Submodule
 
@@ -491,7 +491,7 @@ end Ideal
 
 end RingOfIntegers
 
-end AbsNorm
+end abs_norm
 
 section SpanNorm
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
 
 ! This file was ported from Lean 3 source module ring_theory.ideal.norm
-! leanprover-community/mathlib commit d3acee0d776b15ffb8318f327325ff343cc8bdcc
+! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -12,7 +12,6 @@ import Mathbin.Algebra.CharP.Quotient
 import Mathbin.Data.Finsupp.Fintype
 import Mathbin.Data.Int.AbsoluteValue
 import Mathbin.Data.Int.Associated
-import Mathbin.NumberTheory.RamificationInertia
 import Mathbin.LinearAlgebra.FreeModule.Determinant
 import Mathbin.LinearAlgebra.FreeModule.IdealQuotient
 import Mathbin.RingTheory.DedekindDomain.Pid
Diff
@@ -408,8 +408,8 @@ theorem absNorm_span_singleton (r : S) : absNorm (span ({r} : Set S)) = (Algebra
   rw [Algebra.norm_apply]
   by_cases hr : r = 0
   ·
-    simp only [hr, Ideal.span_zero, LinearMap.Algebra.coe_lmul_eq_mul, eq_self_iff_true,
-      Ideal.absNorm_bot, LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
+    simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
+      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
   letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
   let b := Module.Free.chooseBasis ℤ S
   rw [← nat_abs_det_equiv _ (b.equiv (basis_span_singleton b hr) (Equiv.refl _))]
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
 
 ! This file was ported from Lean 3 source module ring_theory.ideal.norm
-! leanprover-community/mathlib commit 85e3c05a94b27c84dc6f234cf88326d5e0096ec3
+! leanprover-community/mathlib commit d3acee0d776b15ffb8318f327325ff343cc8bdcc
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -293,6 +293,11 @@ theorem absNorm_eq_one_iff {I : Ideal S} : absNorm I = 1 ↔ I = ⊤ := by
   rw [abs_norm_apply, card_quot_eq_one_iff]
 #align ideal.abs_norm_eq_one_iff Ideal.absNorm_eq_one_iff
 
+theorem absNorm_ne_zero_iff (I : Ideal S) : Ideal.absNorm I ≠ 0 ↔ Finite (S ⧸ I) :=
+  ⟨fun h => Nat.finite_of_card_ne_zero h, fun h =>
+    (@AddSubgroup.finiteIndex_of_finite_quotient _ _ _ h).FiniteIndex⟩
+#align ideal.abs_norm_ne_zero_iff Ideal.absNorm_ne_zero_iff
+
 /-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
 Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
 See `nat_abs_det_basis_change` for a more familiar formulation of this result. -/
@@ -460,6 +465,29 @@ theorem absNorm_mem (I : Ideal S) : ↑I.absNorm ∈ I := by
     quotient.index_eq_zero]
 #align ideal.abs_norm_mem Ideal.absNorm_mem
 
+theorem span_singleton_absNorm_le (I : Ideal S) : Ideal.span {(Ideal.absNorm I : S)} ≤ I := by
+  simp only [Ideal.span_le, Set.singleton_subset_iff, SetLike.mem_coe, Ideal.absNorm_mem I]
+#align ideal.span_singleton_abs_norm_le Ideal.span_singleton_absNorm_le
+
+theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
+    { I : Ideal S | Ideal.absNorm I = n }.Finite :=
+  by
+  let f := fun I : Ideal S => Ideal.map (Ideal.Quotient.mk (@Ideal.span S _ {n})) I
+  refine' @Set.Finite.of_finite_image _ _ _ f _ _
+  · suffices Finite (S ⧸ @Ideal.span S _ {n})
+      by
+      let g := (coe : Ideal (S ⧸ @Ideal.span S _ {n}) → Set (S ⧸ @Ideal.span S _ {n}))
+      refine' @Set.Finite.of_finite_image _ _ _ g _ (set_like.coe_injective.inj_on _)
+      exact Set.Finite.subset (@Set.finite_univ _ (@Set.finite' _ this)) (Set.subset_univ _)
+    rw [← abs_norm_ne_zero_iff, abs_norm_span_singleton]
+    simpa only [Ne.def, Int.natAbs_eq_zero, Algebra.norm_eq_zero_iff, Nat.cast_eq_zero] using
+      ne_of_gt hn
+  · intro I hI J hJ h
+    rw [← comap_map_mk (span_singleton_abs_norm_le I), ← hI.symm, ←
+      comap_map_mk (span_singleton_abs_norm_le J), ← hJ.symm]
+    exact congr_arg (Ideal.comap (Ideal.Quotient.mk (@Ideal.span S _ {n}))) h
+#align ideal.finite_set_of_abs_norm_eq Ideal.finite_setOf_absNorm_eq
+
 end Ideal
 
 end RingOfIntegers
Diff
@@ -118,9 +118,9 @@ theorem cardQuot_mul_of_coprime [IsDedekindDomain S] [Module.Free ℤ S] [Module
     exact not_nontrivial_iff_subsingleton.mpr ‹Subsingleton S› ‹Nontrivial S›
   haveI : Infinite S := Infinite.of_surjective _ b.repr.to_equiv.surjective
   by_cases hI : I = ⊥
-  · rw [hI, Submodule.bot_mul, card_quot_bot, zero_mul]
+  · rw [hI, Submodule.bot_mul, card_quot_bot, MulZeroClass.zero_mul]
   by_cases hJ : J = ⊥
-  · rw [hJ, Submodule.mul_bot, card_quot_bot, mul_zero]
+  · rw [hJ, Submodule.mul_bot, card_quot_bot, MulZeroClass.mul_zero]
   have hIJ : I * J ≠ ⊥ := mt ideal.mul_eq_bot.mp (not_or_of_not hI hJ)
   letI := Classical.decEq (Module.Free.ChooseBasisIndex ℤ S)
   letI := I.fintype_quotient_of_free_of_ne_bot hI
Diff
@@ -335,7 +335,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
                 (↑(AddEquiv.toIntLinearEquiv ↑e) : S →ₗ[ℤ] I))).natAbs :=
         rfl
       _ = (LinearMap.det ((Submodule.subtype I).restrictScalars ℤ ∘ₗ _)).natAbs :=
-        int.nat_abs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _)
+        (int.nat_abs_eq_iff_associated.mpr (LinearMap.associated_det_comp_equiv _ _ _))
       _ = abs_norm I := this
       
   have ha : ∀ i, f (b' i) = a i • b' i := by
@@ -362,7 +362,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
       rw [LinearMap.det_toMatrix]
     _ = Int.natAbs (Matrix.diagonal a).det := _
     _ = Int.natAbs (∏ i, a i) := by rw [Matrix.det_diagonal]
-    _ = ∏ i, Int.natAbs (a i) := map_prod Int.natAbsHom a Finset.univ
+    _ = ∏ i, Int.natAbs (a i) := (map_prod Int.natAbsHom a Finset.univ)
     _ = Fintype.card (S ⧸ I) := _
     _ = abs_norm I := (Submodule.cardQuot_apply _).symm
     
@@ -403,8 +403,8 @@ theorem absNorm_span_singleton (r : S) : absNorm (span ({r} : Set S)) = (Algebra
   rw [Algebra.norm_apply]
   by_cases hr : r = 0
   ·
-    simp only [hr, Ideal.span_zero, Algebra.coe_lmul_eq_mul, eq_self_iff_true, Ideal.absNorm_bot,
-      LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
+    simp only [hr, Ideal.span_zero, LinearMap.Algebra.coe_lmul_eq_mul, eq_self_iff_true,
+      Ideal.absNorm_bot, LinearMap.det_zero'', Set.singleton_zero, _root_.map_zero, Int.natAbs_zero]
   letI := Ideal.fintypeQuotientOfFreeOfNeBot (span {r}) (mt span_singleton_eq_bot.mp hr)
   let b := Module.Free.chooseBasis ℤ S
   rw [← nat_abs_det_equiv _ (b.equiv (basis_span_singleton b hr) (Equiv.refl _))]

Changes in mathlib4

mathlib3
mathlib4
chore: small splits of RingTheory.Ideal.Operations; clean imports (#12090)

This is based on seeing the import RingTheory.Ideal.OperationsLinearAlgebra.Basis on the longest pole. It feels like Ideal.Operations is a bit of a chokepoint for compiling Mathlib since it imports many files and is imported by many files. So splitting out a few obvious parts should help with compile times. Moreover, there are a bunch of imports that I could remove and have the file still compile: presumably these are (were) transitive dependencies that shake does not remove.

The following results and their corollaries were split off:

  • Ideal.basisSpanSingleton
  • Basis.mem_ideal_iff
  • Ideal.colon

In particular, now Ideal.Operations should no longer need to know about Basis or submodule quotients.

Diff
@@ -11,6 +11,7 @@ import Mathlib.Data.Int.Associated
 import Mathlib.LinearAlgebra.FreeModule.Determinant
 import Mathlib.LinearAlgebra.FreeModule.IdealQuotient
 import Mathlib.RingTheory.DedekindDomain.PID
+import Mathlib.RingTheory.Ideal.Basis
 import Mathlib.RingTheory.LocalProperties
 import Mathlib.RingTheory.Localization.NormTrace
 
chore: superfluous parentheses part 2 (#12131)

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

Diff
@@ -331,7 +331,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [EquivLike E S I] [AddEquivCl
       rw [LinearMap.det_toMatrix]
     _ = Int.natAbs (Matrix.diagonal a).det := ?_
     _ = Int.natAbs (∏ i, a i) := by rw [Matrix.det_diagonal]
-    _ = ∏ i, Int.natAbs (a i) := (map_prod Int.natAbsHom a Finset.univ)
+    _ = ∏ i, Int.natAbs (a i) := map_prod Int.natAbsHom a Finset.univ
     _ = Fintype.card (S ⧸ I) := ?_
     _ = absNorm I := (Submodule.cardQuot_apply _).symm
   -- since `LinearMap.toMatrix b' b' f` is the diagonal matrix with `a` along the diagonal.
chore(Data/Int): Rename coe_nat to natCast (#11637)

Reduce the diff of #11499

Renames

All in the Int namespace:

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

Also rename Nat.coe_nat_dvd to Nat.cast_dvd_cast

Diff
@@ -383,7 +383,7 @@ theorem absNorm_dvd_absNorm_of_le {I J : Ideal S} (h : J ≤ I) : Ideal.absNorm
 
 theorem absNorm_dvd_norm_of_mem {I : Ideal S} {x : S} (h : x ∈ I) :
     ↑(Ideal.absNorm I) ∣ Algebra.norm ℤ x := by
-  rw [← Int.dvd_natAbs, ← absNorm_span_singleton x, Int.coe_nat_dvd]
+  rw [← Int.dvd_natAbs, ← absNorm_span_singleton x, Int.natCast_dvd_natCast]
   exact absNorm_dvd_absNorm_of_le ((span_singleton_le_iff_mem _).mpr h)
 #align ideal.abs_norm_dvd_norm_of_mem Ideal.absNorm_dvd_norm_of_mem
 
chore: avoid Ne.def (adaptation for nightly-2024-03-27) (#11813)
Diff
@@ -452,7 +452,7 @@ theorem span_singleton_absNorm {I : Ideal S} (hI : (Ideal.absNorm I).Prime) :
       ((Nat.irreducible_iff_nat_prime _).mpr hI)).comap (algebraMap ℤ S)).ne_top
   · rw [span_singleton_le_iff_mem, mem_comap, algebraMap_int_eq, map_natCast]
     exact absNorm_mem I
-  · rw [Ne.def, span_singleton_eq_bot]
+  · rw [Ne, span_singleton_eq_bot]
     exact Int.ofNat_ne_zero.mpr hI.ne_zero
 
 theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
@@ -464,7 +464,7 @@ theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
       refine @Set.Finite.of_finite_image _ _ _ g ?_ (SetLike.coe_injective.injOn _)
       exact Set.Finite.subset (@Set.finite_univ _ (@Set.finite' _ this)) (Set.subset_univ _)
     rw [← absNorm_ne_zero_iff, absNorm_span_singleton]
-    simpa only [Ne.def, Int.natAbs_eq_zero, Algebra.norm_eq_zero_iff, Nat.cast_eq_zero] using
+    simpa only [Ne, Int.natAbs_eq_zero, Algebra.norm_eq_zero_iff, Nat.cast_eq_zero] using
       ne_of_gt hn
   · intro I hI J hJ h
     rw [← comap_map_mk (span_singleton_absNorm_le I), ← hI.symm, ←
change the order of operation in zsmulRec and nsmulRec (#11451)

We change the following field in the definition of an additive commutative monoid:

 nsmul_succ : ∀ (n : ℕ) (x : G),
-  AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+  AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x

where the latter is more natural

We adjust the definitions of ^ in monoids, groups, etc. Originally there was a warning comment about why this natural order was preferred

use x * npowRec n x and not npowRec n x * x in the definition to make sure that definitional unfolding of npowRec is blocked, to avoid deep recursion issues.

but it seems to no longer apply.

Remarks on the PR :

  • pow_succ and pow_succ' have switched their meanings.
  • Most of the time, the proofs were adjusted by priming/unpriming one lemma, or exchanging left and right; a few proofs were more complicated to adjust.
  • In particular, [Mathlib/NumberTheory/RamificationInertia.lean] used Ideal.IsPrime.mul_mem_pow which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul.
  • the docstring for Cauchy condensation test in [Mathlib/Analysis/PSeries.lean] was mathematically incorrect, I added the mention that the function is antitone.
Diff
@@ -137,7 +137,8 @@ theorem Ideal.mul_add_mem_pow_succ_inj (P : Ideal S) {i : ℕ} (a d d' e e' : S)
     (e_mem : e ∈ P ^ (i + 1)) (e'_mem : e' ∈ P ^ (i + 1)) (h : d - d' ∈ P) :
     a * d + e - (a * d' + e') ∈ P ^ (i + 1) := by
   have : a * d - a * d' ∈ P ^ (i + 1) := by
-    convert Ideal.mul_mem_mul a_mem h using 1 <;> simp [mul_sub, pow_succ, mul_comm]
+    simp only [← mul_sub]
+    exact Ideal.mul_mem_mul a_mem h
   convert Ideal.add_mem _ this (Ideal.sub_mem _ e_mem e'_mem) using 1
   ring
 #align ideal.mul_add_mem_pow_succ_inj Ideal.mul_add_mem_pow_succ_inj
@@ -195,7 +196,7 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
   letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
   have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
   suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P by
-    rw [pow_succ (cardQuot P), ← ih, cardQuot_apply (P ^ i.succ), ←
+    rw [pow_succ' (cardQuot P), ← ih, cardQuot_apply (P ^ i.succ), ←
       card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, cardQuot_apply (P ^ i),
       cardQuot_apply P]
     congr 1
chore(*): remove empty lines between variable statements (#11418)

Empty lines were removed by executing the following Python script twice

import os
import re


# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
  for filename in files:
    if filename.endswith('.lean'):
      file_path = os.path.join(dir_path, filename)

      # Open the file and read its contents
      with open(file_path, 'r') as file:
        content = file.read()

      # Use a regular expression to replace sequences of "variable" lines separated by empty lines
      # with sequences without empty lines
      modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)

      # Write the modified content back to the file
      with open(file_path, 'w') as file:
        file.write(modified_content)
Diff
@@ -614,7 +614,6 @@ theorem spanNorm_mul_of_field {K : Type*} [Field K] [Algebra K S] [IsDomain S] [
 #align ideal.span_norm_mul_of_field Ideal.spanNorm_mul_of_field
 
 variable [IsDomain R] [IsDomain S] [IsDedekindDomain R] [IsDedekindDomain S]
-
 variable [Module.Finite R S] [Module.Free R S]
 
 /-- Multiplicativity of `Ideal.spanNorm`. simp-normal form is `map_mul (Ideal.relNorm R)`. -/
chore: classify simp can do this porting notes (#10619)

Classify by adding issue number (#10618) to porting notes claiming anything semantically equivalent to simp can prove this or simp can simplify this.

Diff
@@ -82,7 +82,7 @@ theorem cardQuot_bot [Infinite M] : cardQuot (⊥ : Submodule R M) = 0 :=
   AddSubgroup.index_bot.trans Nat.card_eq_zero_of_infinite
 #align submodule.card_quot_bot Submodule.cardQuot_bot
 
--- @[simp] -- Porting note: simp can prove this
+-- @[simp] -- Porting note (#10618): simp can prove this
 theorem cardQuot_top : cardQuot (⊤ : Submodule R M) = 1 :=
   AddSubgroup.index_top
 #align submodule.card_quot_top Submodule.cardQuot_top
chore: remove stream-of-consciousness uses of have, replace and suffices (#10640)

No changes to tactic file, it's just boring fixes throughout the library.

This follows on from #6964.

Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -152,8 +152,8 @@ Inspired by [Neukirch], proposition 6.1 -/
 theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
     (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
     ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
-  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
-  · rw [eq_b] at c_mem
+  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1) by
+    rw [eq_b] at c_mem
     simp only [mul_comm a]
     exact Ideal.mem_span_singleton_sup.mp c_mem
   refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
@@ -194,8 +194,8 @@ theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module
   letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
   letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
   have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
-  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
-  · rw [pow_succ (cardQuot P), ← ih, cardQuot_apply (P ^ i.succ), ←
+  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P by
+    rw [pow_succ (cardQuot P), ← ih, cardQuot_apply (P ^ i.succ), ←
       card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, cardQuot_apply (P ^ i),
       cardQuot_apply P]
     congr 1
feat: introduce IsRelPrime and DecompositionMonoid and refactor (#10327)
  • Introduce typeclass DecompositionMonoid, which says every element in the monoid is primal, i.e., whenever an element divides a product b * c, it can be factored into a product such that the factors divides b and c respectively. A domain is called pre-Schreier if its multiplicative monoid is a decomposition monoid, and these are more general than GCD domains.

  • Show that any GCDMonoid is a DecompositionMonoid. In order for lemmas about DecompositionMonoids to automatically apply to UniqueFactorizationMonoids, we add instances from UniqueFactorizationMonoid α to Nonempty (NormalizedGCDMonoid α) to Nonempty (GCDMonoid α) to DecompositionMonoid α. (Zulip) See the bottom of message for an updated diagram of classes and instances.

  • Introduce binary predicate IsRelPrime which says that the only common divisors of the two elements are units. Replace previous occurrences in mathlib by this predicate.

  • Duplicate all lemmas about IsCoprime in Coprime/Basic (except three lemmas about smul) to IsRelPrime. Due to import constraints, they are spread into three files Algebra/Divisibility/Units (including key lemmas assuming DecompositionMonoid), GroupWithZero/Divisibility, and Coprime/Basic.

  • Show IsCoprime always imply IsRelPrime and is equivalent to it in Bezout rings. To reduce duplication, the definition of Bezout rings and the GCDMonoid instance are moved from RingTheory/Bezout to RingTheory/PrincipalIdealDomain, and some results in PrincipalIdealDomain are generalized to Bezout rings.

  • Remove the recently added file Squarefree/UniqueFactorizationMonoid and place the results appropriately within Squarefree/Basic. All results are generalized to DecompositionMonoid or weaker except the last one.

Zulip

With this PR, all the following instances (indicated by arrows) now work; this PR fills the central part.

                                                                          EuclideanDomain (bundled)
                                                                              ↙          ↖
                                                                 IsPrincipalIdealRing ← Field (bundled)
                                                                            ↓             ↓
         NormalizationMonoid ←          NormalizedGCDMonoid → GCDMonoid  IsBezout ← ValuationRing ← DiscreteValuationRing
                   ↓                             ↓                 ↘       ↙
Nonempty NormalizationMonoid ← Nonempty NormalizedGCDMonoid →  Nonempty GCDMonoid → IsIntegrallyClosed
                                                 ↑                    ↓
                    WfDvdMonoid ← UniqueFactorizationMonoid → DecompositionMonoid
                                                 ↑
                                       IsPrincipalIdealRing

Co-authored-by: Junyan Xu <junyanxu.math@gmail.com> Co-authored-by: Oliver Nash <github@olivernash.org>

Diff
@@ -244,7 +244,7 @@ theorem cardQuot_mul [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ
         cardQuot_pow_of_prime hI.ne_zero)
       fun {I J} hIJ => cardQuot_mul_of_coprime <| Ideal.isCoprime_iff_sup_eq.mpr
         (Ideal.isUnit_iff.mp
-          (hIJ _ (Ideal.dvd_iff_le.mpr le_sup_left) (Ideal.dvd_iff_le.mpr le_sup_right)))
+          (hIJ (Ideal.dvd_iff_le.mpr le_sup_left) (Ideal.dvd_iff_le.mpr le_sup_right)))
 #align card_quot_mul cardQuot_mul
 
 /-- The absolute norm of the ideal `I : Ideal R` is the cardinality of the quotient `R ⧸ I`. -/
feat: Add exists_ideal_in_class_of_norm_le (#9084)

Prove that each class of the classgroup of a number field contains an integral ideal of small norm.

Diff
@@ -408,6 +408,9 @@ theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := b
   · rintro rfl
     exact absNorm_bot
 
+theorem absNorm_ne_zero_of_nonZeroDivisors (I : (Ideal S)⁰) : Ideal.absNorm (I : Ideal S) ≠ 0 :=
+  Ideal.absNorm_eq_zero_iff.not.mpr <| nonZeroDivisors.coe_ne_zero _
+
 theorem irreducible_of_irreducible_absNorm {I : Ideal S} (hI : Irreducible (Ideal.absNorm I)) :
     Irreducible I :=
   irreducible_iff.mpr
refactor(Data/FunLike): use unbundled inheritance from FunLike (#8386)

The FunLike hierarchy is very big and gets scanned through each time we need a coercion (via the CoeFun instance). It looks like unbundled inheritance suits Lean 4 better here. The only class that still extends FunLike is EquivLike, since that has a custom coe_injective' field that is easier to implement. All other classes should take FunLike or EquivLike as a parameter.

Zulip thread

Important changes

Previously, morphism classes would be Type-valued and extend FunLike:

/-- `MyHomClass F A B` states that `F` is a type of `MyClass.op`-preserving morphisms.
You should extend this class when you extend `MyHom`. -/
class MyHomClass (F : Type*) (A B : outParam <| Type*) [MyClass A] [MyClass B]
  extends FunLike F A B :=
(map_op : ∀ (f : F) (x y : A), f (MyClass.op x y) = MyClass.op (f x) (f y))

After this PR, they should be Prop-valued and take FunLike as a parameter:

/-- `MyHomClass F A B` states that `F` is a type of `MyClass.op`-preserving morphisms.
You should extend this class when you extend `MyHom`. -/
class MyHomClass (F : Type*) (A B : outParam <| Type*) [MyClass A] [MyClass B]
  [FunLike F A B] : Prop :=
(map_op : ∀ (f : F) (x y : A), f (MyClass.op x y) = MyClass.op (f x) (f y))

(Note that A B stay marked as outParam even though they are not purely required to be so due to the FunLike parameter already filling them in. This is required to see through type synonyms, which is important in the category theory library. Also, I think keeping them as outParam is slightly faster.)

Similarly, MyEquivClass should take EquivLike as a parameter.

As a result, every mention of [MyHomClass F A B] should become [FunLike F A B] [MyHomClass F A B].

Remaining issues

Slower (failing) search

While overall this gives some great speedups, there are some cases that are noticeably slower. In particular, a failing application of a lemma such as map_mul is more expensive. This is due to suboptimal processing of arguments. For example:

variable [FunLike F M N] [Mul M] [Mul N] (f : F) (x : M) (y : M)

theorem map_mul [MulHomClass F M N] : f (x * y) = f x * f y

example [AddHomClass F A B] : f (x * y) = f x * f y := map_mul f _ _

Before this PR, applying map_mul f gives the goals [Mul ?M] [Mul ?N] [MulHomClass F ?M ?N]. Since M and N are out_params, [MulHomClass F ?M ?N] is synthesized first, supplies values for ?M and ?N and then the Mul M and Mul N instances can be found.

After this PR, the goals become [FunLike F ?M ?N] [Mul ?M] [Mul ?N] [MulHomClass F ?M ?N]. Now [FunLike F ?M ?N] is synthesized first, supplies values for ?M and ?N and then the Mul M and Mul N instances can be found, before trying MulHomClass F M N which fails. Since the Mul hierarchy is very big, this can be slow to fail, especially when there is no such Mul instance.

A long-term but harder to achieve solution would be to specify the order in which instance goals get solved. For example, we'd like to change the arguments to map_mul to look like [FunLike F M N] [Mul M] [Mul N] [highPriority <| MulHomClass F M N] because MulHomClass fails or succeeds much faster than the others.

As a consequence, the simpNF linter is much slower since by design it tries and fails to apply many map_ lemmas. The same issue occurs a few times in existing calls to simp [map_mul], where map_mul is tried "too soon" and fails. Thanks to the speedup of leanprover/lean4#2478 the impact is very limited, only in files that already were close to the timeout.

simp not firing sometimes

This affects map_smulₛₗ and related definitions. For simp lemmas Lean apparently uses a slightly different mechanism to find instances, so that rw can find every argument to map_smulₛₗ successfully but simp can't: leanprover/lean4#3701.

Missing instances due to unification failing

Especially in the category theory library, we might sometimes have a type A which is also accessible as a synonym (Bundled A hA).1. Instance synthesis doesn't always work if we have f : A →* B but x * y : (Bundled A hA).1 or vice versa. This seems to be mostly fixed by keeping A B as outParams in MulHomClass F A B. (Presumably because Lean will do a definitional check A =?= (Bundled A hA).1 instead of using the syntax in the discrimination tree.)

Workaround for issues

The timeouts can be worked around for now by specifying which map_mul we mean, either as map_mul f for some explicit f, or as e.g. MonoidHomClass.map_mul.

map_smulₛₗ not firing as simp lemma can be worked around by going back to the pre-FunLike situation and making LinearMap.map_smulₛₗ a simp lemma instead of the generic map_smulₛₗ. Writing simp [map_smulₛₗ _] also works.

Co-authored-by: Matthew Ballard <matt@mrb.email> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Scott Morrison <scott@tqft.net> Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>

Diff
@@ -286,7 +286,7 @@ theorem absNorm_ne_zero_iff (I : Ideal S) : Ideal.absNorm I ≠ 0 ↔ Finite (S
 /-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
 Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
 See `natAbs_det_basis_change` for a more familiar formulation of this result. -/
-theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [AddEquivClass E S I] (e : E) :
+theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [EquivLike E S I] [AddEquivClass E S I] (e : E) :
     Int.natAbs
         (LinearMap.det
           ((Submodule.subtype I).restrictScalars ℤ ∘ₗ AddMonoidHom.toIntLinearMap (e : S →+ I))) =
chore: reduce imports (#9830)

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

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

Diff
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
 -/
 import Mathlib.Algebra.CharP.Quotient
+import Mathlib.Algebra.GroupWithZero.NonZeroDivisors
 import Mathlib.Data.Finsupp.Fintype
 import Mathlib.Data.Int.AbsoluteValue
 import Mathlib.Data.Int.Associated
chore: cleanup spaces (#9745)
Diff
@@ -253,7 +253,7 @@ noncomputable def Ideal.absNorm [Nontrivial S] [IsDedekindDomain S] [Module.Free
   map_mul' I J := by dsimp only; rw [cardQuot_mul]
   map_one' := by dsimp only; rw [Ideal.one_eq_top, cardQuot_top]
   map_zero' := by
-    have : Infinite S :=  Module.Free.infinite ℤ S
+    have : Infinite S := Module.Free.infinite ℤ S
     rw [Ideal.zero_eq_bot, cardQuot_bot]
 #align ideal.abs_norm Ideal.absNorm
 
chore: replace Infinite assumption by Nontrivial in Ideal.absNorm (#9684)

Also fix a typo and remove a now useless maxHeartbeats in Mathlib.NumberTheory.NumberField.Units.

Diff
@@ -247,17 +247,19 @@ theorem cardQuot_mul [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ
 #align card_quot_mul cardQuot_mul
 
 /-- The absolute norm of the ideal `I : Ideal R` is the cardinality of the quotient `R ⧸ I`. -/
-noncomputable def Ideal.absNorm [Infinite S] [IsDedekindDomain S] [Module.Free ℤ S]
+noncomputable def Ideal.absNorm [Nontrivial S] [IsDedekindDomain S] [Module.Free ℤ S]
     [Module.Finite ℤ S] : Ideal S →*₀ ℕ where
   toFun := Submodule.cardQuot
   map_mul' I J := by dsimp only; rw [cardQuot_mul]
   map_one' := by dsimp only; rw [Ideal.one_eq_top, cardQuot_top]
-  map_zero' := by rw [Ideal.zero_eq_bot, cardQuot_bot]
+  map_zero' := by
+    have : Infinite S :=  Module.Free.infinite ℤ S
+    rw [Ideal.zero_eq_bot, cardQuot_bot]
 #align ideal.abs_norm Ideal.absNorm
 
 namespace Ideal
 
-variable [Infinite S] [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ S]
+variable [Nontrivial S] [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ S]
 
 theorem absNorm_apply (I : Ideal S) : absNorm I = cardQuot I := rfl
 #align ideal.abs_norm_apply Ideal.absNorm_apply
chore: remove unused cases' names (#9451)

These unused names will soon acquire a linter warning. Easiest to clean them up pre-emptively.

(Thanks to @nomeata for fixing these on nightly-testing.)

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

Diff
@@ -553,7 +553,7 @@ theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S
     [Algebra Rₘ Sₘ] [Algebra R Sₘ] [IsScalarTower R Rₘ Sₘ] [IsScalarTower R S Sₘ]
     [IsLocalization M Rₘ] [IsLocalization (Algebra.algebraMapSubmonoid S M) Sₘ] :
     spanNorm Rₘ (I.map (algebraMap S Sₘ)) = (spanNorm R I).map (algebraMap R Rₘ) := by
-  cases h : subsingleton_or_nontrivial R
+  cases subsingleton_or_nontrivial R
   · haveI := IsLocalization.unique R Rₘ M
     simp [eq_iff_true_of_subsingleton]
   let b := Module.Free.chooseBasis R S
refactor(*): change definition of Set.image2 etc (#9275)
  • Redefine Set.image2 to use ∃ a ∈ s, ∃ b ∈ t, f a b = c instead of ∃ a b, a ∈ s ∧ b ∈ t ∧ f a b = c.
  • Redefine Set.seq as Set.image2. The new definition is equal to the old one but rw [Set.seq] gives a different result.
  • Redefine Filter.map₂ to use ∃ u ∈ f, ∃ v ∈ g, image2 m u v ⊆ s instead of ∃ u v, u ∈ f ∧ v ∈ g ∧ ...
  • Update lemmas like Set.mem_image2, Finset.mem_image₂, Set.mem_mul, Finset.mem_div etc

The two reasons to make the change are:

  • ∃ a ∈ s, ∃ b ∈ t, _ is a simp-normal form, and
  • it looks a bit nicer.
Diff
@@ -580,7 +580,7 @@ theorem spanNorm_mul_spanNorm_le (I J : Ideal S) :
     spanNorm R I * spanNorm R J ≤ spanNorm R (I * J) := by
   rw [spanNorm, spanNorm, spanNorm, Ideal.span_mul_span', ← Set.image_mul]
   refine Ideal.span_mono (Set.monotone_image ?_)
-  rintro _ ⟨x, y, hxI, hyJ, rfl⟩
+  rintro _ ⟨x, hxI, y, hyJ, rfl⟩
   exact Ideal.mul_mem_mul hxI hyJ
 #align ideal.span_norm_mul_span_norm_le Ideal.spanNorm_mul_spanNorm_le
 
fix: attribute [simp] ... in -> attribute [local simp] ... in (#7678)

Mathlib.Logic.Unique contains the line attribute [simp] eq_iff_true_of_subsingleton in ...:

https://github.com/leanprover-community/mathlib4/blob/96a11c7aac574c00370c2b3dab483cb676405c5d/Mathlib/Logic/Unique.lean#L255-L256

Despite what the in part may imply, this adds the lemma to the simp set "globally", including for downstream files; it is likely that attribute [local simp] eq_iff_true_of_subsingleton in ... was meant instead (or maybe scoped simp, but I think "scoped" refers to the current namespace). Indeed, the relevant lemma is not marked with @[simp] for possible slowness: https://github.com/leanprover/std4/blob/846e9e1d6bb534774d1acd2dc430e70987da3c18/Std/Logic.lean#L749. Adding it to the simp set causes the example at https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Regression.20in.20simp to slow down.

This PR changes this and fixes the relevant downstream simps. There was also one ocurrence of attribute [simp] FullSubcategory.comp_def FullSubcategory.id_def in in Mathlib.CategoryTheory.Monoidal.Subcategory but that was much easier to fix.

https://github.com/leanprover-community/mathlib4/blob/bc49eb9ba756a233370b4b68bcdedd60402f71ed/Mathlib/CategoryTheory/Monoidal/Subcategory.lean#L118-L119

Diff
@@ -555,7 +555,7 @@ theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S
     spanNorm Rₘ (I.map (algebraMap S Sₘ)) = (spanNorm R I).map (algebraMap R Rₘ) := by
   cases h : subsingleton_or_nontrivial R
   · haveI := IsLocalization.unique R Rₘ M
-    simp
+    simp [eq_iff_true_of_subsingleton]
   let b := Module.Free.chooseBasis R S
   rw [map_spanNorm]
   refine span_eq_span (Set.image_subset_iff.mpr ?_) (Set.image_subset_iff.mpr ?_)
chore: Use IsCoprime for ideals. (#7523)

Make IsCoprime I J the preferred way to say that two ideals are coprime, provide lemmas translating to other formulations.

Diff
@@ -107,7 +107,7 @@ open Submodule
 This is essentially just a repackaging of the Chinese Remainder Theorem.
 -/
 theorem cardQuot_mul_of_coprime [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ S]
-    {I J : Ideal S} (coprime : I ⊔ J = ⊤) : cardQuot (I * J) = cardQuot I * cardQuot J := by
+    {I J : Ideal S} (coprime : IsCoprime I J) : cardQuot (I * J) = cardQuot I * cardQuot J := by
   let b := Module.Free.chooseBasis ℤ S
   cases isEmpty_or_nonempty (Module.Free.ChooseBasisIndex ℤ S)
   · haveI : Subsingleton S := Function.Surjective.subsingleton b.repr.toEquiv.symm.surjective
@@ -241,7 +241,7 @@ theorem cardQuot_mul [IsDedekindDomain S] [Module.Free ℤ S] [Module.Finite ℤ
       (fun {I} i hI =>
         have : Ideal.IsPrime I := Ideal.isPrime_of_prime hI
         cardQuot_pow_of_prime hI.ne_zero)
-      fun {I J} hIJ => cardQuot_mul_of_coprime
+      fun {I J} hIJ => cardQuot_mul_of_coprime <| Ideal.isCoprime_iff_sup_eq.mpr
         (Ideal.isUnit_iff.mp
           (hIJ _ (Ideal.dvd_iff_le.mpr le_sup_left) (Ideal.dvd_iff_le.mpr le_sup_right)))
 #align card_quot_mul cardQuot_mul
feat: add some ring theory lemmas (#7466)

From flt-regular.

Co-authored-by: Andrew Yang <the.erd.one@gmail.com>

Diff
@@ -393,6 +393,18 @@ theorem absNorm_span_insert (r : S) (s : Set S) :
         (by rw [absNorm_span_singleton])⟩
 #align ideal.abs_norm_span_insert Ideal.absNorm_span_insert
 
+theorem absNorm_eq_zero_iff {I : Ideal S} : Ideal.absNorm I = 0 ↔ I = ⊥ := by
+  constructor
+  · intro hI
+    rw [← le_bot_iff]
+    intros x hx
+    rw [mem_bot, ← Algebra.norm_eq_zero_iff (R := ℤ), ← Int.natAbs_eq_zero,
+      ← Ideal.absNorm_span_singleton, ← zero_dvd_iff, ← hI]
+    apply Ideal.absNorm_dvd_absNorm_of_le
+    rwa [Ideal.span_singleton_le_iff_mem]
+  · rintro rfl
+    exact absNorm_bot
+
 theorem irreducible_of_irreducible_absNorm {I : Ideal S} (hI : Irreducible (Ideal.absNorm I)) :
     Irreducible I :=
   irreducible_iff.mpr
@@ -424,6 +436,18 @@ theorem span_singleton_absNorm_le (I : Ideal S) : Ideal.span {(Ideal.absNorm I :
   simp only [Ideal.span_le, Set.singleton_subset_iff, SetLike.mem_coe, Ideal.absNorm_mem I]
 #align ideal.span_singleton_abs_norm_le Ideal.span_singleton_absNorm_le
 
+theorem span_singleton_absNorm {I : Ideal S} (hI : (Ideal.absNorm I).Prime) :
+    Ideal.span (singleton (Ideal.absNorm I : ℤ)) = I.comap (algebraMap ℤ S) := by
+  have : Ideal.IsPrime (Ideal.span (singleton (Ideal.absNorm I : ℤ))) := by
+    rwa [Ideal.span_singleton_prime (Int.ofNat_ne_zero.mpr hI.ne_zero), ← Nat.prime_iff_prime_int]
+  apply (this.isMaximal _).eq_of_le
+  · exact ((isPrime_of_irreducible_absNorm
+      ((Nat.irreducible_iff_nat_prime _).mpr hI)).comap (algebraMap ℤ S)).ne_top
+  · rw [span_singleton_le_iff_mem, mem_comap, algebraMap_int_eq, map_natCast]
+    exact absNorm_mem I
+  · rw [Ne.def, span_singleton_eq_bot]
+    exact Int.ofNat_ne_zero.mpr hI.ne_zero
+
 theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
     {I : Ideal S | Ideal.absNorm I = n}.Finite := by
   let f := fun I : Ideal S => Ideal.map (Ideal.Quotient.mk (@Ideal.span S _ {↑n})) I
@@ -441,6 +465,13 @@ theorem finite_setOf_absNorm_eq [CharZero S] {n : ℕ} (hn : 0 < n) :
     congr
 #align ideal.finite_set_of_abs_norm_eq Ideal.finite_setOf_absNorm_eq
 
+theorem norm_dvd_iff {x : S} (hx : Prime (Algebra.norm ℤ x)) {y : ℤ} :
+    Algebra.norm ℤ x ∣ y ↔ x ∣ y := by
+  rw [← Ideal.mem_span_singleton (y := x), ← eq_intCast (algebraMap ℤ S), ← Ideal.mem_comap,
+    ← Ideal.span_singleton_absNorm, Ideal.mem_span_singleton, Ideal.absNorm_span_singleton,
+    Int.natAbs_dvd]
+  rwa [Ideal.absNorm_span_singleton, ← Int.prime_iff_natAbs_prime]
+
 end Ideal
 
 end RingOfIntegers
chore: drop MulZeroClass. in mul_zero/zero_mul (#6682)

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

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

Diff
@@ -116,9 +116,9 @@ theorem cardQuot_mul_of_coprime [IsDedekindDomain S] [Module.Free ℤ S] [Module
     exact not_nontrivial_iff_subsingleton.mpr ‹Subsingleton S› ‹Nontrivial S›
   haveI : Infinite S := Infinite.of_surjective _ b.repr.toEquiv.surjective
   by_cases hI : I = ⊥
-  · rw [hI, Submodule.bot_mul, cardQuot_bot, MulZeroClass.zero_mul]
+  · rw [hI, Submodule.bot_mul, cardQuot_bot, zero_mul]
   by_cases hJ : J = ⊥
-  · rw [hJ, Submodule.mul_bot, cardQuot_bot, MulZeroClass.mul_zero]
+  · rw [hJ, Submodule.mul_bot, cardQuot_bot, mul_zero]
   have hIJ : I * J ≠ ⊥ := mt Ideal.mul_eq_bot.mp (not_or_of_not hI hJ)
   letI := Classical.decEq (Module.Free.ChooseBasisIndex ℤ S)
   letI := I.fintypeQuotientOfFreeOfNeBot hI
feat: add Algebra.discr_localizationLocalization (#6422)

We prove

theorem Algebra.discr_localizationLocalization (b : Basis ι R S) :
  Algebra.discr Rₘ (b.localizationLocalization Rₘ M Aₘ) = algebraMap R Rₘ (Algebra.discr R b) 

We need for that to prove the analogue for the trace of Algebra.norm_localization (that was the only result in RingTheory.Localization.Norm). Since the results are added to this file, it is renamed to RingTheory.Localization.NormTrace (not sure about the name though).

Diff
@@ -11,7 +11,7 @@ import Mathlib.LinearAlgebra.FreeModule.Determinant
 import Mathlib.LinearAlgebra.FreeModule.IdealQuotient
 import Mathlib.RingTheory.DedekindDomain.PID
 import Mathlib.RingTheory.LocalProperties
-import Mathlib.RingTheory.Localization.Norm
+import Mathlib.RingTheory.Localization.NormTrace
 
 #align_import ring_theory.ideal.norm from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
 
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -55,7 +55,7 @@ section abs_norm
 
 namespace Submodule
 
-variable {R M : Type _} [Ring R] [AddCommGroup M] [Module R M]
+variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M]
 
 section
 
@@ -99,7 +99,7 @@ end Submodule
 
 section RingOfIntegers
 
-variable {S : Type _} [CommRing S] [IsDomain S]
+variable {S : Type*} [CommRing S] [IsDomain S]
 
 open Submodule
 
@@ -283,7 +283,7 @@ theorem absNorm_ne_zero_iff (I : Ideal S) : Ideal.absNorm I ≠ 0 ↔ Finite (S
 /-- Let `e : S ≃ I` be an additive isomorphism (therefore a `ℤ`-linear equiv).
 Then an alternative way to compute the norm of `I` is given by taking the determinant of `e`.
 See `natAbs_det_basis_change` for a more familiar formulation of this result. -/
-theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E) :
+theorem natAbs_det_equiv (I : Ideal S) {E : Type*} [AddEquivClass E S I] (e : E) :
     Int.natAbs
         (LinearMap.det
           ((Submodule.subtype I).restrictScalars ℤ ∘ₗ AddMonoidHom.toIntLinearMap (e : S →+ I))) =
@@ -348,7 +348,7 @@ theorem natAbs_det_equiv (I : Ideal S) {E : Type _} [AddEquivClass E S I] (e : E
 /-- Let `b` be a basis for `S` over `ℤ` and `bI` a basis for `I` over `ℤ` of the same dimension.
 Then an alternative way to compute the norm of `I` is given by taking the determinant of `bI`
 over `b`. -/
-theorem natAbs_det_basis_change {ι : Type _} [Fintype ι] [DecidableEq ι] (b : Basis ι ℤ S)
+theorem natAbs_det_basis_change {ι : Type*} [Fintype ι] [DecidableEq ι] (b : Basis ι ℤ S)
     (I : Ideal S) (bI : Basis ι ℤ I) : (b.det ((↑) ∘ bI)).natAbs = Ideal.absNorm I := by
   let e := b.equiv bI (Equiv.refl _)
   calc
@@ -453,7 +453,7 @@ namespace Ideal
 
 open Submodule
 
-variable (R : Type _) [CommRing R] {S : Type _} [CommRing S] [Algebra R S]
+variable (R : Type*) [CommRing R] {S : Type*} [CommRing S] [Algebra R S]
 
 /-- `Ideal.spanNorm R (I : Ideal S)` is the ideal generated by mapping `Algebra.norm R` over `I`.
 
@@ -505,7 +505,7 @@ theorem spanNorm_top : spanNorm R (⊤ : Ideal S) = ⊤ := by
   simp
 #align ideal.span_norm_top Ideal.spanNorm_top
 
-theorem map_spanNorm (I : Ideal S) {T : Type _} [CommRing T] (f : R →+* T) :
+theorem map_spanNorm (I : Ideal S) {T : Type*} [CommRing T] (f : R →+* T) :
     map f (spanNorm R I) = span (f ∘ Algebra.norm R '' (I : Set S)) := by
   rw [spanNorm, map_span, Set.image_image]
   -- Porting note: `Function.comp` reducibility
@@ -518,7 +518,7 @@ theorem spanNorm_mono {I J : Ideal S} (h : I ≤ J) : spanNorm R I ≤ spanNorm
 #align ideal.span_norm_mono Ideal.spanNorm_mono
 
 theorem spanNorm_localization (I : Ideal S) [Module.Finite R S] [Module.Free R S] (M : Submonoid R)
-    {Rₘ : Type _} (Sₘ : Type _) [CommRing Rₘ] [Algebra R Rₘ] [CommRing Sₘ] [Algebra S Sₘ]
+    {Rₘ : Type*} (Sₘ : Type*) [CommRing Rₘ] [Algebra R Rₘ] [CommRing Sₘ] [Algebra S Sₘ]
     [Algebra Rₘ Sₘ] [Algebra R Sₘ] [IsScalarTower R Rₘ Sₘ] [IsScalarTower R S Sₘ]
     [IsLocalization M Rₘ] [IsLocalization (Algebra.algebraMapSubmonoid S M) Sₘ] :
     spanNorm Rₘ (I.map (algebraMap S Sₘ)) = (spanNorm R I).map (algebraMap R Rₘ) := by
@@ -571,7 +571,7 @@ theorem spanNorm_mul_of_bot_or_top [IsDomain R] [IsDomain S] [Module.Free R S] [
 #align ideal.span_norm_mul_of_bot_or_top Ideal.spanNorm_mul_of_bot_or_top
 
 @[simp]
-theorem spanNorm_mul_of_field {K : Type _} [Field K] [Algebra K S] [IsDomain S] [Module.Finite K S]
+theorem spanNorm_mul_of_field {K : Type*} [Field K] [Algebra K S] [IsDomain S] [Module.Finite K S]
     (I J : Ideal S) : spanNorm K (I * J) = spanNorm K I * spanNorm K J :=
   spanNorm_mul_of_bot_or_top K eq_bot_or_top I J
 #align ideal.span_norm_mul_of_field Ideal.spanNorm_mul_of_field
@@ -660,7 +660,7 @@ theorem relNorm_singleton (r : S) : relNorm R (span ({r} : Set S)) = span {Algeb
   spanNorm_singleton R
 #align ideal.rel_norm_singleton Ideal.relNorm_singleton
 
-theorem map_relNorm (I : Ideal S) {T : Type _} [CommRing T] (f : R →+* T) :
+theorem map_relNorm (I : Ideal S) {T : Type*} [CommRing T] (f : R →+* T) :
     map f (relNorm R I) = span (f ∘ Algebra.norm R '' (I : Set S)) :=
   map_spanNorm R I f
 #align ideal.map_rel_norm Ideal.map_relNorm
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,11 +2,6 @@
 Copyright (c) 2022 Anne Baanen. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Anne Baanen, Alex J. Best
-
-! This file was ported from Lean 3 source module ring_theory.ideal.norm
-! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Algebra.CharP.Quotient
 import Mathlib.Data.Finsupp.Fintype
@@ -18,6 +13,8 @@ import Mathlib.RingTheory.DedekindDomain.PID
 import Mathlib.RingTheory.LocalProperties
 import Mathlib.RingTheory.Localization.Norm
 
+#align_import ring_theory.ideal.norm from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
+
 /-!
 
 # Ideal norms
chore: tidy various files (#5449)
Diff
@@ -557,7 +557,7 @@ theorem spanNorm_mul_spanNorm_le (I J : Ideal S) :
 #align ideal.span_norm_mul_span_norm_le Ideal.spanNorm_mul_spanNorm_le
 
 /-- This condition `eq_bot_or_top` is equivalent to being a field.
-However, `span_norm_mul_of_field` is harder to apply since we'd need to upgrade a `CommRing R`
+However, `Ideal.spanNorm_mul_of_field` is harder to apply since we'd need to upgrade a `CommRing R`
 instance to a `Field R` instance. -/
 theorem spanNorm_mul_of_bot_or_top [IsDomain R] [IsDomain S] [Module.Free R S] [Module.Finite R S]
     (eq_bot_or_top : ∀ I : Ideal R, I = ⊥ ∨ I = ⊤) (I J : Ideal S) :
feat: port RingTheory.Ideal.Norm (#5311)

Co-authored-by: Xavier-François Roblot <46200072+xroblot@users.noreply.github.com>

Dependencies 11 + 901

902 files ported (98.8%)
358960 lines ported (98.5%)
Show graph

The unported dependencies are