l3lab/ntp-mathlib huggingface dataset:
/-- If `p` is a prime in the Dedekind domain `R`, `S` an extension of `R` and `Sₚ` the localization
of `S` at `p`, then all primes in `Sₚ` are factors of the image of `p` in `Sₚ`. -/
theorem IsLocalization.OverPrime.mem_normalizedFactors_of_isPrime [DecidableEq (Ideal Sₚ)]
    {P : Ideal Sₚ} (hP : IsPrime P) (hP0 : P ≠ ⊥) :
    P ∈ normalizedFactors (Ideal.map (algebraMap R Sₚ) p) := by
  have non_zero_div : Algebra.algebraMapSubmonoid S p.primeCompl ≤ S⁰ :=
    map_le_nonZeroDivisors_of_injective _ (NoZeroSMulDivisors.algebraMap_injective _ _)
      p.primeCompl_le_nonZeroDivisors
  letI : Algebra (Localization.AtPrime p) Sₚ := localizationAlgebra p.primeCompl S
  haveI : IsScalarTower R (Localization.AtPrime p) Sₚ :=
    IsScalarTower.of_algebraMap_eq fun x => by
      -- Porting note: replaced `erw` with a `rw` followed by `exact` to help infer implicits
      rw [IsScalarTower.algebraMap_apply R S]
      exact (IsLocalization.map_eq (T := Algebra.algebraMapSubmonoid S (primeCompl p))
        (Submonoid.le_comap_map _) x).symm
  obtain ⟨pid, p', ⟨hp'0, hp'p⟩, hpu⟩ :=
    (DiscreteValuationRing.iff_pid_with_one_nonzero_prime (Localization.AtPrime p)).mp
      (IsLocalization.AtPrime.discreteValuationRing_of_dedekind_domain R hp0 _)
  have : LocalRing.maximalIdeal (Localization.AtPrime p) ≠ ⊥ := by
    rw [Submodule.ne_bot_iff] at hp0 ⊢
    obtain ⟨x, x_mem, x_ne⟩ := hp0
    

Proof state:
case intro.intro
R : Type u_1
inst✝¹⁶ : CommRing R
inst✝¹⁵ : IsDomain R
inst✝¹⁴ : IsDedekindDomain R
S : Type u_2
inst✝¹³ : CommRing S
inst✝¹² : IsDomain S
inst✝¹¹ : Algebra R S
inst✝¹⁰ : Module.Free R S
inst✝⁹ : Module.Finite R S
p : Ideal R
inst✝⁸ : IsPrime p
Sₚ : Type u_3
inst✝⁷ : CommRing Sₚ
inst✝⁶ : Algebra S Sₚ
inst✝⁵ : IsLocalization (Algebra.algebraMapSubmonoid S (primeCompl p)) Sₚ
inst✝⁴ : Algebra R Sₚ
inst✝³ : IsScalarTower R S Sₚ
inst✝² : IsDomain Sₚ
inst✝¹ : IsDedekindDomain Sₚ
inst✝ : DecidableEq (Ideal Sₚ)
P : Ideal Sₚ
hP : IsPrime P
hP0 : P ≠ ⊥
non_zero_div : Algebra.algebraMapSubmonoid S (primeCompl p) ≤ S⁰
this✝ : Algebra (Localization.AtPrime p) Sₚ := localizationAlgebra (primeCompl p) S
this : IsScalarTower R (Localization.AtPrime p) Sₚ
pid : IsPrincipalIdealRing (Localization.AtPrime p)
p' : Ideal (Localization.AtPrime p)
hpu : ∀ (y : Ideal (Localization.AtPrime p)), (fun P => P ≠ ⊥ ∧ IsPrime P) y → y = p'
hp'0 : p' ≠ ⊥
hp'p : IsPrime p'
x : R
x_mem : x ∈ p
x_ne : x ≠ 0
⊢ ∃ x ∈ LocalRing.maximalIdeal (Localization.AtPrime p), x ≠ 0

Next tactic:
exact
      ⟨algebraMap _ _ x, (IsLocalization.AtPrime.to_map_mem_maximal_iff _ _ _).mpr x_mem,
        IsLocalization.to_map_ne_zero_of_mem_nonZeroDivisors _ p.primeCompl_le_nonZeroDivisors
          (mem_nonZeroDivisors_of_ne_zero x_ne)⟩
/-- Let `p` be a prime in the Dedekind domain `R` and `S` be an integral extension of `R`,
then the localization `Sₚ` of `S` at `p` is a PID. -/
theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime :
    IsPrincipalIdealRing Sₚ := by
  

Proof state:
R : Type u_1
inst✝¹⁵ : CommRing R
inst✝¹⁴ : IsDomain R
inst✝¹³ : IsDedekindDomain R
S : Type u_2
inst✝¹² : CommRing S
inst✝¹¹ : IsDomain S
inst✝¹⁰ : Algebra R S
inst✝⁹ : Module.Free R S
inst✝⁸ : Module.Finite R S
p : Ideal R
hp0 : p ≠ ⊥
inst✝⁷ : IsPrime p
Sₚ : Type u_3
inst✝⁶ : CommRing Sₚ
inst✝⁵ : Algebra S Sₚ
inst✝⁴ : IsLocalization (Algebra.algebraMapSubmonoid S (primeCompl p)) Sₚ
inst✝³ : Algebra R Sₚ
inst✝² : IsScalarTower R S Sₚ
inst✝¹ : IsDomain Sₚ
inst✝ : IsDedekindDomain Sₚ
⊢ IsPrincipalIdealRing Sₚ

Next tactic:
letI := Classical.decEq (Ideal Sₚ)
/-- Let `p` be a prime in the Dedekind domain `R` and `S` be an integral extension of `R`,
then the localization `Sₚ` of `S` at `p` is a PID. -/
theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime :
    IsPrincipalIdealRing Sₚ := by
  letI := Classical.decEq (Ideal Sₚ)
  

Proof state:
R : Type u_1
inst✝¹⁵ : CommRing R
inst✝¹⁴ : IsDomain R
inst✝¹³ : IsDedekindDomain R
S : Type u_2
inst✝¹² : CommRing S
inst✝¹¹ : IsDomain S
inst✝¹⁰ : Algebra R S
inst✝⁹ : Module.Free R S
inst✝⁸ : Module.Finite R S
p : Ideal R
hp0 : p ≠ ⊥
inst✝⁷ : IsPrime p
Sₚ : Type u_3
inst✝⁶ : CommRing Sₚ
inst✝⁵ : Algebra S Sₚ
inst✝⁴ : IsLocalization (Algebra.algebraMapSubmonoid S (primeCompl p)) Sₚ
inst✝³ : Algebra R Sₚ
inst✝² : IsScalarTower R S Sₚ
inst✝¹ : IsDomain Sₚ
inst✝ : IsDedekindDomain Sₚ
this : DecidableEq (Ideal Sₚ) := Classical.decEq (Ideal Sₚ)
⊢ IsPrincipalIdealRing Sₚ

Next tactic:
letI := Classical.decPred fun P : Ideal Sₚ => P.IsPrime
/-- Let `p` be a prime in the Dedekind domain `R` and `S` be an integral extension of `R`,
then the localization `Sₚ` of `S` at `p` is a PID. -/
theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime :
    IsPrincipalIdealRing Sₚ := by
  letI := Classical.decEq (Ideal Sₚ)
  letI := Classical.decPred fun P : Ideal Sₚ => P.IsPrime
  

Proof state:
R : Type u_1
inst✝¹⁵ : CommRing R
inst✝¹⁴ : IsDomain R
inst✝¹³ : IsDedekindDomain R
S : Type u_2
inst✝¹² : CommRing S
inst✝¹¹ : IsDomain S
inst✝¹⁰ : Algebra R S
inst✝⁹ : Module.Free R S
inst✝⁸ : Module.Finite R S
p : Ideal R
hp0 : p ≠ ⊥
inst✝⁷ : IsPrime p
Sₚ : Type u_3
inst✝⁶ : CommRing Sₚ
inst✝⁵ : Algebra S Sₚ
inst✝⁴ : IsLocalization (Algebra.algebraMapSubmonoid S (primeCompl p)) Sₚ
inst✝³ : Algebra R Sₚ
inst✝² : IsScalarTower R S Sₚ
inst✝¹ : IsDomain Sₚ
inst✝ : IsDedekindDomain Sₚ
this✝ : DecidableEq (Ideal Sₚ) := Classical.decEq (Ideal Sₚ)
this : DecidablePred fun P => IsPrime P := Classical.decPred fun P => IsPrime P
⊢ IsPrincipalIdealRing Sₚ

Next tactic:
refine'
    IsPrincipalIdealRing.of_finite_primes
      (Set.Finite.ofFinset
        (Finset.filter (fun P => P.IsPrime)
          ({⊥} ∪ (normalizedFactors (Ideal.map (algebraMap R Sₚ) p)).toFinset))
        fun P => _)
/-- Let `p` be a prime in the Dedekind domain `R` and `S` be an integral extension of `R`,
then the localization `Sₚ` of `S` at `p` is a PID. -/
theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime :
    IsPrincipalIdealRing Sₚ := by
  letI := Classical.decEq (Ideal Sₚ)
  letI := Classical.decPred fun P : Ideal Sₚ => P.IsPrime
  refine'
    IsPrincipalIdealRing.of_finite_primes
      (Set.Finite.ofFinset
        (Finset.filter (fun P => P.IsPrime)
          ({⊥} ∪ (normalizedFactors (Ideal.map (algebraMap R Sₚ) p)).toFinset))
        fun P => _)
  

Proof state:
R : Type u_1
inst✝¹⁵ : CommRing R
inst✝¹⁴ : IsDomain R
inst✝¹³ : IsDedekindDomain R
S : Type u_2
inst✝¹² : CommRing S
inst✝¹¹ : IsDomain S
inst✝¹⁰ : Algebra R S
inst✝⁹ : Module.Free R S
inst✝⁸ : Module.Finite R S
p : Ideal R
hp0 : p ≠ ⊥
inst✝⁷ : IsPrime p
Sₚ : Type u_3
inst✝⁶ : CommRing Sₚ
inst✝⁵ : Algebra S Sₚ
inst✝⁴ : IsLocalization (Algebra.algebraMapSubmonoid S (primeCompl p)) Sₚ
inst✝³ : Algebra R Sₚ
inst✝² : IsScalarTower R S Sₚ
inst✝¹ : IsDomain Sₚ
inst✝ : IsDedekindDomain Sₚ
this✝ : DecidableEq (Ideal Sₚ) := Classical.decEq (Ideal Sₚ)
this : DecidablePred fun P => IsPrime P := Classical.decPred fun P => IsPrime P
P : Ideal Sₚ
⊢ P ∈ Finset.filter (fun P => IsPrime P) ({⊥} ∪ Multiset.toFinset (normalizedFactors (map (algebraMap R Sₚ) p))) ↔
    P ∈ {I | IsPrime I}

Next tactic:
rw [Finset.mem_filter, Finset.mem_union, Finset.mem_singleton, Set.mem_setOf,
    Multiset.mem_toFinset]
/-- Let `p` be a prime in the Dedekind domain `R` and `S` be an integral extension of `R`,
then the localization `Sₚ` of `S` at `p` is a PID. -/
theorem IsDedekindDomain.isPrincipalIdealRing_localization_over_prime :
    IsPrincipalIdealRing Sₚ := by
  letI := Classical.decEq (Ideal Sₚ)
  letI := Classical.decPred fun P : Ideal Sₚ => P.IsPrime
  refine'
    IsPrincipalIdealRing.of_finite_primes
      (Set.Finite.ofFinset
        (Finset.filter (fun P => P.IsPrime)
          ({⊥} ∪ (normalizedFactors (Ideal.map (algebraMap R Sₚ) p)).toFinset))
        fun P => _)
  rw [Finset.mem_filter, Finset.mem_union, Finset.mem_singleton, Set.mem_setOf,
    Multiset.mem_toFinset]
  

Proof state:
R : Type u_1
inst✝¹⁵ : CommRing R
inst✝¹⁴ : IsDomain R
inst✝¹³ : IsDedekindDomain R
S : Type u_2
inst✝¹² : CommRing S
inst✝¹¹ : IsDomain S
inst✝¹⁰ : Algebra R S
inst✝⁹ : Module.Free R S
inst✝⁸ : Module.Finite R S
p : Ideal R
hp0 : p ≠ ⊥
inst✝⁷ : IsPrime p
Sₚ : Type u_3
inst✝⁶ : CommRing Sₚ
inst✝⁵ : Algebra S Sₚ
inst✝⁴ : IsLocalization (Algebra.algebraMapSubmonoid S (primeCompl p)) Sₚ
inst✝³ : Algebra R Sₚ
inst✝² : IsScalarTower R S Sₚ
inst✝¹ : IsDomain Sₚ
inst✝ : IsDedekindDomain Sₚ
this✝ : DecidableEq (Ideal Sₚ) := Classical.decEq (Ideal Sₚ)
this : DecidablePred fun P => IsPrime P := Classical.decPred fun P => IsPrime P
P : Ideal Sₚ
⊢ (P = ⊥ ∨ P ∈ normalizedFactors (map (algebraMap R Sₚ) p)) ∧ IsPrime P ↔ IsPrime P

Next tactic:
exact
    and_iff_right_of_imp fun hP =>
      or_iff_not_imp_left.mpr (IsLocalization.OverPrime.mem_normalizedFactors_of_isPrime S p hp0 hP)
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
⊢ IsIdempotentElem I ↔ ∃ e, IsIdempotentElem e ∧ I = Submodule.span R {e}

Next tactic:
constructor
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · 

Proof state:
case mp
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
⊢ IsIdempotentElem I → ∃ e, IsIdempotentElem e ∧ I = Submodule.span R {e}

Next tactic:
intro e
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    

Proof state:
case mp
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
⊢ ∃ e, IsIdempotentElem e ∧ I = Submodule.span R {e}

Next tactic:
obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          

Proof state:
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
⊢ I ≤ I • I

Next tactic:
rw [smul_eq_mul]
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          

Proof state:
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
⊢ I ≤ I * I

Next tactic:
exact e.ge
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
r : R
hr : r ∈ I
hr' : ∀ n ∈ I, r • n = n
⊢ ∃ e, IsIdempotentElem e ∧ I = Submodule.span R {e}

Next tactic:
simp_rw [smul_eq_mul] at hr'
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    simp_rw [smul_eq_mul] at hr'
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
r : R
hr : r ∈ I
hr' : ∀ n ∈ I, r * n = n
⊢ ∃ e, IsIdempotentElem e ∧ I = Submodule.span R {e}

Next tactic:
refine' ⟨r, hr' r hr, antisymm _ ((Submodule.span_singleton_le_iff_mem _ _).mpr hr)⟩
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    simp_rw [smul_eq_mul] at hr'
    refine' ⟨r, hr' r hr, antisymm _ ((Submodule.span_singleton_le_iff_mem _ _).mpr hr)⟩
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
r : R
hr : r ∈ I
hr' : ∀ n ∈ I, r * n = n
⊢ I ≤ Submodule.span R {r}

Next tactic:
intro x hx
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    simp_rw [smul_eq_mul] at hr'
    refine' ⟨r, hr' r hr, antisymm _ ((Submodule.span_singleton_le_iff_mem _ _).mpr hr)⟩
    intro x hx
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
r : R
hr : r ∈ I
hr' : ∀ n ∈ I, r * n = n
x : R
hx : x ∈ I
⊢ x ∈ Submodule.span R {r}

Next tactic:
rw [← hr' x hx]
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    simp_rw [smul_eq_mul] at hr'
    refine' ⟨r, hr' r hr, antisymm _ ((Submodule.span_singleton_le_iff_mem _ _).mpr hr)⟩
    intro x hx
    rw [← hr' x hx]
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
e : IsIdempotentElem I
r : R
hr : r ∈ I
hr' : ∀ n ∈ I, r * n = n
x : R
hx : x ∈ I
⊢ r * x ∈ Submodule.span R {r}

Next tactic:
exact Ideal.mem_span_singleton'.mpr ⟨_, mul_comm _ _⟩
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    simp_rw [smul_eq_mul] at hr'
    refine' ⟨r, hr' r hr, antisymm _ ((Submodule.span_singleton_le_iff_mem _ _).mpr hr)⟩
    intro x hx
    rw [← hr' x hx]
    exact Ideal.mem_span_singleton'.mpr ⟨_, mul_comm _ _⟩
  · 

Proof state:
case mpr
R : Type u_1
inst✝ : CommRing R
I : Ideal R
h : FG I
⊢ (∃ e, IsIdempotentElem e ∧ I = Submodule.span R {e}) → IsIdempotentElem I

Next tactic:
rintro ⟨e, he, rfl⟩
/-- A finitely generated idempotent ideal is generated by an idempotent element -/
theorem isIdempotentElem_iff_of_fg {R : Type*} [CommRing R] (I : Ideal R) (h : I.FG) :
    IsIdempotentElem I ↔ ∃ e : R, IsIdempotentElem e ∧ I = R ∙ e := by
  constructor
  · intro e
    obtain ⟨r, hr, hr'⟩ :=
      Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul I I h
        (by
          rw [smul_eq_mul]
          exact e.ge)
    simp_rw [smul_eq_mul] at hr'
    refine' ⟨r, hr' r hr, antisymm _ ((Submodule.span_singleton_le_iff_mem _ _).mpr hr)⟩
    intro x hx
    rw [← hr' x hx]
    exact Ideal.mem_span_singleton'.mpr ⟨_, mul_comm _ _⟩
  · rintro ⟨e, he, rfl⟩
    

Proof state:
case mpr.intro.intro
R : Type u_1
inst✝ : CommRing R
e : R
he : IsIdempotentElem e
h : FG (Submodule.span R {e})
⊢ IsIdempotentElem (Submodule.span R {e})

Next tactic:
simp [IsIdempotentElem, Ideal.span_singleton_mul_span_singleton, he.eq]
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
I : Ideal R
h : FG I
⊢ IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤

Next tactic:
constructor
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · 

Proof state:
case mp
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
I : Ideal R
h : FG I
⊢ IsIdempotentElem I → I = ⊥ ∨ I = ⊤

Next tactic:
intro H
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    

Proof state:
case mp
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
I : Ideal R
h : FG I
H : IsIdempotentElem I
⊢ I = ⊥ ∨ I = ⊤

Next tactic:
obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
e : R
he : IsIdempotentElem e
h : FG (Submodule.span R {e})
H : IsIdempotentElem (Submodule.span R {e})
⊢ Submodule.span R {e} = ⊥ ∨ Submodule.span R {e} = ⊤

Next tactic:
simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
e : R
he : IsIdempotentElem e
h : FG (Submodule.span R {e})
H : IsIdempotentElem (Submodule.span R {e})
⊢ e = 0 ∨ span {e} = ⊤

Next tactic:
apply Or.imp id _ (IsIdempotentElem.iff_eq_zero_or_one.mp he)
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
    apply Or.imp id _ (IsIdempotentElem.iff_eq_zero_or_one.mp he)
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
e : R
he : IsIdempotentElem e
h : FG (Submodule.span R {e})
H : IsIdempotentElem (Submodule.span R {e})
⊢ e = 1 → span {e} = ⊤

Next tactic:
rintro rfl
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
    apply Or.imp id _ (IsIdempotentElem.iff_eq_zero_or_one.mp he)
    rintro rfl
    

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
he : IsIdempotentElem 1
h : FG (Submodule.span R {1})
H : IsIdempotentElem (Submodule.span R {1})
⊢ span {1} = ⊤

Next tactic:
simp
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
    apply Or.imp id _ (IsIdempotentElem.iff_eq_zero_or_one.mp he)
    rintro rfl
    simp
  · 

Proof state:
case mpr
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
I : Ideal R
h : FG I
⊢ I = ⊥ ∨ I = ⊤ → IsIdempotentElem I

Next tactic:
rintro (rfl | rfl)
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
    apply Or.imp id _ (IsIdempotentElem.iff_eq_zero_or_one.mp he)
    rintro rfl
    simp
  · rintro (rfl | rfl) <;> 

Proof state:
case mpr.inl
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
h : FG ⊥
⊢ IsIdempotentElem ⊥

Next tactic:
simp [IsIdempotentElem]
theorem isIdempotentElem_iff_eq_bot_or_top {R : Type*} [CommRing R] [IsDomain R] (I : Ideal R)
    (h : I.FG) : IsIdempotentElem I ↔ I = ⊥ ∨ I = ⊤ := by
  constructor
  · intro H
    obtain ⟨e, he, rfl⟩ := (I.isIdempotentElem_iff_of_fg h).mp H
    simp only [Ideal.submodule_span_eq, Ideal.span_singleton_eq_bot]
    apply Or.imp id _ (IsIdempotentElem.iff_eq_zero_or_one.mp he)
    rintro rfl
    simp
  · rintro (rfl | rfl) <;> 

Proof state:
case mpr.inr
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
h : FG ⊤
⊢ IsIdempotentElem ⊤

Next tactic:
simp [IsIdempotentElem]
@[simp]
theorem baseChange_add : (f + g).baseChange A = f.baseChange A + g.baseChange A := by
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁸ : CommSemiring R
inst✝⁷ : Semiring A
inst✝⁶ : Algebra R A
inst✝⁵ : Semiring B
inst✝⁴ : Algebra R B
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
r : R
f g : M →ₗ[R] N
⊢ baseChange A (f + g) = baseChange A f + baseChange A g

Next tactic:
ext
@[simp]
theorem baseChange_add : (f + g).baseChange A = f.baseChange A + g.baseChange A := by
  ext
  -- porting note: added `-baseChange_tmul`
  

Proof state:
case a.h.h
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁸ : CommSemiring R
inst✝⁷ : Semiring A
inst✝⁶ : Algebra R A
inst✝⁵ : Semiring B
inst✝⁴ : Algebra R B
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
r : R
f g : M →ₗ[R] N
x✝ : M
⊢ ((AlgebraTensorModule.curry (baseChange A (f + g))) 1) x✝ =
    ((AlgebraTensorModule.curry (baseChange A f + baseChange A g)) 1) x✝

Next tactic:
simp [baseChange_eq_ltensor, -baseChange_tmul]
@[simp]
theorem baseChange_zero : baseChange A (0 : M →ₗ[R] N) = 0 := by
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁸ : CommSemiring R
inst✝⁷ : Semiring A
inst✝⁶ : Algebra R A
inst✝⁵ : Semiring B
inst✝⁴ : Algebra R B
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
r : R
f g : M →ₗ[R] N
⊢ baseChange A 0 = 0

Next tactic:
ext
@[simp]
theorem baseChange_zero : baseChange A (0 : M →ₗ[R] N) = 0 := by
  ext
  

Proof state:
case a.h.h
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁸ : CommSemiring R
inst✝⁷ : Semiring A
inst✝⁶ : Algebra R A
inst✝⁵ : Semiring B
inst✝⁴ : Algebra R B
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
r : R
f g : M →ₗ[R] N
x✝ : M
⊢ ((AlgebraTensorModule.curry (baseChange A 0)) 1) x✝ = ((AlgebraTensorModule.curry 0) 1) x✝

Next tactic:
simp [baseChange_eq_ltensor]