l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem finprod_curry₃ {γ : Type*} (f : α × β × γ → M) (h : (mulSupport f).Finite) :
    ∏ᶠ abc, f abc = ∏ᶠ (a) (b) (c), f (a, b, c) := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝¹ : CommMonoid M
inst✝ : CommMonoid N
f✝ g : α → M
a b : α
s t : Set α
γ : Type u_7
f : α × β × γ → M
h : Set.Finite (mulSupport f)
⊢ ∏ᶠ (abc : α × β × γ), f abc = ∏ᶠ (a : α) (b : β) (c : γ), f (a, b, c)

Next tactic:
rw [finprod_curry f h]
@[to_additive]
theorem finprod_curry₃ {γ : Type*} (f : α × β × γ → M) (h : (mulSupport f).Finite) :
    ∏ᶠ abc, f abc = ∏ᶠ (a) (b) (c), f (a, b, c) := by
  rw [finprod_curry f h]
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝¹ : CommMonoid M
inst✝ : CommMonoid N
f✝ g : α → M
a b : α
s t : Set α
γ : Type u_7
f : α × β × γ → M
h : Set.Finite (mulSupport f)
⊢ ∏ᶠ (a : α) (b : β × γ), f (a, b) = ∏ᶠ (a : α) (b : β) (c : γ), f (a, b, c)

Next tactic:
congr
@[to_additive]
theorem finprod_curry₃ {γ : Type*} (f : α × β × γ → M) (h : (mulSupport f).Finite) :
    ∏ᶠ abc, f abc = ∏ᶠ (a) (b) (c), f (a, b, c) := by
  rw [finprod_curry f h]
  congr
  

Proof state:
case e_f
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝¹ : CommMonoid M
inst✝ : CommMonoid N
f✝ g : α → M
a b : α
s t : Set α
γ : Type u_7
f : α × β × γ → M
h : Set.Finite (mulSupport f)
⊢ (fun a => ∏ᶠ (b : β × γ), f (a, b)) = fun a => ∏ᶠ (b : β) (c : γ), f (a, b, c)

Next tactic:
ext a
@[to_additive]
theorem finprod_curry₃ {γ : Type*} (f : α × β × γ → M) (h : (mulSupport f).Finite) :
    ∏ᶠ abc, f abc = ∏ᶠ (a) (b) (c), f (a, b, c) := by
  rw [finprod_curry f h]
  congr
  ext a
  

Proof state:
case e_f.h
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝¹ : CommMonoid M
inst✝ : CommMonoid N
f✝ g : α → M
a✝ b : α
s t : Set α
γ : Type u_7
f : α × β × γ → M
h : Set.Finite (mulSupport f)
a : α
⊢ ∏ᶠ (b : β × γ), f (a, b) = ∏ᶠ (b : β) (c : γ), f (a, b, c)

Next tactic:
rw [finprod_curry]
@[to_additive]
theorem finprod_curry₃ {γ : Type*} (f : α × β × γ → M) (h : (mulSupport f).Finite) :
    ∏ᶠ abc, f abc = ∏ᶠ (a) (b) (c), f (a, b, c) := by
  rw [finprod_curry f h]
  congr
  ext a
  rw [finprod_curry]
  

Proof state:
case e_f.h.hf
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝¹ : CommMonoid M
inst✝ : CommMonoid N
f✝ g : α → M
a✝ b : α
s t : Set α
γ : Type u_7
f : α × β × γ → M
h : Set.Finite (mulSupport f)
a : α
⊢ Set.Finite (mulSupport fun b => f (a, b))

Next tactic:
simp [h]
@[to_additive]
theorem finprod_emb_domain' {f : α → β} (hf : Injective f) [DecidablePred (· ∈ Set.range f)]
    (g : α → M) :
    (∏ᶠ b : β, if h : b ∈ Set.range f then g (Classical.choose h) else 1) = ∏ᶠ a : α, g a := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝² : CommMonoid M
inst✝¹ : CommMonoid N
f✝ g✝ : α → M
a b : α
s t : Set α
f : α → β
hf : Injective f
inst✝ : DecidablePred fun x => x ∈ range f
g : α → M
⊢ (∏ᶠ (b : β), if h : b ∈ range f then g (Classical.choose h) else 1) = ∏ᶠ (a : α), g a

Next tactic:
simp_rw [← finprod_eq_dif]
@[to_additive]
theorem finprod_emb_domain' {f : α → β} (hf : Injective f) [DecidablePred (· ∈ Set.range f)]
    (g : α → M) :
    (∏ᶠ b : β, if h : b ∈ Set.range f then g (Classical.choose h) else 1) = ∏ᶠ a : α, g a := by
  simp_rw [← finprod_eq_dif]
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝² : CommMonoid M
inst✝¹ : CommMonoid N
f✝ g✝ : α → M
a b : α
s t : Set α
f : α → β
hf : Injective f
inst✝ : DecidablePred fun x => x ∈ range f
g : α → M
⊢ ∏ᶠ (b : β) (h : b ∈ range f), g (Classical.choose h) = ∏ᶠ (a : α), g a

Next tactic:
rw [finprod_dmem, finprod_mem_range hf, finprod_congr fun a => _]
@[to_additive]
theorem finprod_emb_domain' {f : α → β} (hf : Injective f) [DecidablePred (· ∈ Set.range f)]
    (g : α → M) :
    (∏ᶠ b : β, if h : b ∈ Set.range f then g (Classical.choose h) else 1) = ∏ᶠ a : α, g a := by
  simp_rw [← finprod_eq_dif]
  rw [finprod_dmem, finprod_mem_range hf, finprod_congr fun a => _]
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝² : CommMonoid M
inst✝¹ : CommMonoid N
f✝ g✝ : α → M
a b : α
s t : Set α
f : α → β
hf : Injective f
inst✝ : DecidablePred fun x => x ∈ range f
g : α → M
⊢ ∀ (a : α), (if h' : f a ∈ range f then g (Classical.choose h') else 1) = g a

Next tactic:
intro a
@[to_additive]
theorem finprod_emb_domain' {f : α → β} (hf : Injective f) [DecidablePred (· ∈ Set.range f)]
    (g : α → M) :
    (∏ᶠ b : β, if h : b ∈ Set.range f then g (Classical.choose h) else 1) = ∏ᶠ a : α, g a := by
  simp_rw [← finprod_eq_dif]
  rw [finprod_dmem, finprod_mem_range hf, finprod_congr fun a => _]
  intro a
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
G : Type u_4
M : Type u_5
N : Type u_6
inst✝² : CommMonoid M
inst✝¹ : CommMonoid N
f✝ g✝ : α → M
a✝ b : α
s t : Set α
f : α → β
hf : Injective f
inst✝ : DecidablePred fun x => x ∈ range f
g : α → M
a : α
⊢ (if h' : f a ∈ range f then g (Classical.choose h') else 1) = g a

Next tactic:
rw [dif_pos (Set.mem_range_self a), hf (Classical.choose_spec (Set.mem_range_self a))]
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}

Next tactic:
haveI := Fintype.ofFinite ι
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}

Next tactic:
let a := I.smithCoeffs b hI
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}

Next tactic:
let b' := I.ringBasis b hI
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}

Next tactic:
let ab := I.selfBasis b hI
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}

Next tactic:
have ab_eq := I.selfBasis_def b hI
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}

Next tactic:
have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    simp_rw [ab_eq]
    have : ∀ (c : ι → R) (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 ha
      choose c hc using ha
      exact ⟨c, b'.ext_elem fun i => Eq.trans (hc i) (this c i).symm⟩
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
⊢ ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ (b'.repr x) i

Next tactic:
intro x
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
⊢ x ∈ I ↔ ∀ (i : ι), a i ∣ (b'.repr x) i

Next tactic:
rw [ab.mem_ideal_iff']
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
⊢ (∃ c, x = ∑ i : ι, c i • ↑(ab i)) ↔ ∀ (i : ι), a i ∣ (b'.repr x) i

Next tactic:
simp_rw [ab_eq]
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    simp_rw [ab_eq]
    

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
⊢ (∃ c, x = ∑ x : ι, c x • smithCoeffs b I hI x • (ringBasis b I hI) x) ↔
    ∀ (i : ι), smithCoeffs b I hI i ∣ ((ringBasis b I hI).repr x) i

Next tactic:
have : ∀ (c : ι → R) (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]
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    simp_rw [ab_eq]
    have : ∀ (c : ι → R) (i), b'.repr (∑ j : ι, c j • a j • b' j) i = a i * c i := by
      

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
⊢ ∀ (c : ι → R) (i : ι), (b'.repr (∑ j : ι, c j • a j • b' j)) i = a i * c i

Next tactic:
intro c i
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    simp_rw [ab_eq]
    have : ∀ (c : ι → R) (i), b'.repr (∑ j : ι, c j • a j • b' j) i = a i * c i := by
      intro c i
      

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
c : ι → R
i : ι
⊢ (b'.repr (∑ j : ι, c j • a j • b' j)) i = a i * c i

Next tactic:
simp only [← MulAction.mul_smul, b'.repr_sum_self, mul_comm]
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    simp_rw [ab_eq]
    have : ∀ (c : ι → R) (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]
    

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this✝ : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
this : ∀ (c : ι → R) (i : ι), (b'.repr (∑ j : ι, c j • a j • b' j)) i = a i * c i
⊢ (∃ c, x = ∑ x : ι, c x • smithCoeffs b I hI x • (ringBasis b I hI) x) ↔
    ∀ (i : ι), smithCoeffs b I hI i ∣ ((ringBasis b I hI).repr x) i

Next tactic:
constructor
/-- We can write the quotient of an ideal over a PID as a product of quotients by principal ideals.
-/
noncomputable def quotientEquivPiSpan (I : Ideal S) (b : Basis ι R S) (hI : I ≠ ⊥) :
    (S ⧸ I) ≃ₗ[R] ∀ i, R ⧸ span ({I.smithCoeffs b hI i} : Set R) := by
  haveI := Fintype.ofFinite ι
  -- Choose `e : S ≃ₗ I` and a basis `b'` for `S` that turns the map
  -- `f := ((Submodule.subtype I).restrictScalars R).comp e` into a diagonal matrix:
  -- there is an `a : ι → ℤ` such that `f (b' i) = a i • b' i`.
  let a := I.smithCoeffs b hI
  let b' := I.ringBasis b hI
  let ab := I.selfBasis b hI
  have ab_eq := I.selfBasis_def b hI
  have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
    intro x
    -- Porting note: these lines used to be `simp_rw [ab.mem_ideal_iff', ab_eq]`
    rw [ab.mem_ideal_iff']
    simp_rw [ab_eq]
    have : ∀ (c : ι → R) (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
    · 

Proof state:
case mp
ι : Type u_1
R : Type u_2
S : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
inst✝¹ : IsDomain S
inst✝ : Finite ι
I : Ideal S
b : Basis ι R S
hI : I ≠ ⊥
this✝ : Fintype ι
a : ι → R := smithCoeffs b I hI
b' : Basis ι R S := ringBasis b I hI
ab : Basis ι R ↥I := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑((selfBasis b I hI) i) = smithCoeffs b I hI i • (ringBasis b I hI) i
x : S
this : ∀ (c : ι → R) (i : ι), (b'.repr (∑ j : ι, c j • a j • b' j)) i = a i * c i
⊢ (∃ c, x = ∑ x : ι, c x • smithCoeffs b I hI x • (ringBasis b I hI) x) →
    ∀ (i : ι), smithCoeffs b I hI i ∣ ((ringBasis b I hI).repr x) i

Next tactic:
rintro ⟨c, rfl⟩ i