[GOAL]
ι : 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}
[PROOFSTEP]
haveI := Fintype.ofFinite ι
[GOAL]
ι : 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}
[PROOFSTEP]
let a := I.smithCoeffs b hI
[GOAL]
ι : 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}
[PROOFSTEP]
let b' := I.ringBasis b hI
[GOAL]
ι : 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}
[PROOFSTEP]
let ab := I.selfBasis b hI
[GOAL]
ι : 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 { x // x ∈ I } := selfBasis b I hI
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
have ab_eq := I.selfBasis_def b hI
[GOAL]
ι : 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 { x // x ∈ 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}
[PROOFSTEP]
have mem_I_iff : ∀ x, x ∈ I ↔ ∀ i, a i ∣ b'.repr x i := by
  intro x
  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⟩
        -- Now we map everything through the linear equiv `S ≃ₗ (ι → R)`,
          -- which maps `I` to `I' := Π i, a i ℤ`.
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
intro x
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
rw [ab.mem_ideal_iff']
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
simp_rw [ab_eq]
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
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]
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
intro c i
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
simp only [← MulAction.mul_smul, b'.repr_sum_self, mul_comm]
[GOAL]
ι : 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 { x // x ∈ 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
[PROOFSTEP]
constructor
[GOAL]
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 { x // x ∈ 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
[PROOFSTEP]
rintro ⟨c, rfl⟩ i
[GOAL]
case mp.intro
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
this : ∀ (c : ι → R) (i : ι), ↑(↑b'.repr (∑ j : ι, c j • a j • ↑b' j)) i = a i * c i
c : ι → R
i : ι
⊢ smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr (∑ x : ι, c x • smithCoeffs b I hI x • ↑(ringBasis b I hI) x)) i
[PROOFSTEP]
exact ⟨c i, this c i⟩
[GOAL]
case mpr
ι : 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 { x // x ∈ 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
⊢ (∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr x) i) →
    ∃ c, x = ∑ x : ι, c x • smithCoeffs b I hI x • ↑(ringBasis b I hI) x
[PROOFSTEP]
rintro ha
[GOAL]
case mpr
ι : 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 { x // x ∈ 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
ha : ∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr x) i
⊢ ∃ c, x = ∑ x : ι, c x • smithCoeffs b I hI x • ↑(ringBasis b I hI) x
[PROOFSTEP]
choose c hc using ha
[GOAL]
case mpr
ι : 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 { x // x ∈ 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 : ι → R
hc : ∀ (i : ι), ↑(↑(ringBasis b I hI).repr x) i = smithCoeffs b I hI i * c i
⊢ ∃ c, x = ∑ x : ι, c x • smithCoeffs b I hI x • ↑(ringBasis b I hI) x
[PROOFSTEP]
exact
  ⟨c, b'.ext_elem fun i => Eq.trans (hc i) (this c i).symm⟩
    -- Now we map everything through the linear equiv `S ≃ₗ (ι → R)`,
      -- which maps `I` to `I' := Π i, a i ℤ`.
[GOAL]
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
let I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span ({a i} : Set R)
[GOAL]
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
have : Submodule.map (b'.equivFun : S →ₗ[R] ι → R) (I.restrictScalars R) = I' :=
  by
  ext x
  simp only [Submodule.mem_map, Submodule.mem_pi, mem_span_singleton, Set.mem_univ, Submodule.restrictScalars_mem,
    mem_I_iff, smul_eq_mul, forall_true_left, LinearEquiv.coe_coe, Basis.equivFun_apply]
  constructor
  · rintro ⟨y, hy, rfl⟩ i
    exact hy i
  · rintro hdvd
    refine' ⟨∑ i, x i • b' i, fun i => _, _⟩ <;> rw [b'.repr_sum_self]
    · exact hdvd i
[GOAL]
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
⊢ Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
[PROOFSTEP]
ext x
[GOAL]
case h
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
⊢ x ∈ Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) ↔ x ∈ I'
[PROOFSTEP]
simp only [Submodule.mem_map, Submodule.mem_pi, mem_span_singleton, Set.mem_univ, Submodule.restrictScalars_mem,
  mem_I_iff, smul_eq_mul, forall_true_left, LinearEquiv.coe_coe, Basis.equivFun_apply]
[GOAL]
case h
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
⊢ (∃ y, (∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr y) i) ∧ ↑(↑(ringBasis b I hI).repr y) = x) ↔
    ∀ (i : ι), smithCoeffs b I hI i ∣ x i
[PROOFSTEP]
constructor
[GOAL]
case h.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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
⊢ (∃ y, (∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr y) i) ∧ ↑(↑(ringBasis b I hI).repr y) = x) →
    ∀ (i : ι), smithCoeffs b I hI i ∣ x i
[PROOFSTEP]
rintro ⟨y, hy, rfl⟩ i
[GOAL]
case h.mp.intro.intro
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
y : S
hy : ∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr y) i
i : ι
⊢ smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr y) i
[PROOFSTEP]
exact hy i
[GOAL]
case h.mpr
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
⊢ (∀ (i : ι), smithCoeffs b I hI i ∣ x i) →
    ∃ y, (∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr y) i) ∧ ↑(↑(ringBasis b I hI).repr y) = x
[PROOFSTEP]
rintro hdvd
[GOAL]
case h.mpr
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
hdvd : ∀ (i : ι), smithCoeffs b I hI i ∣ x i
⊢ ∃ y, (∀ (i : ι), smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr y) i) ∧ ↑(↑(ringBasis b I hI).repr y) = x
[PROOFSTEP]
refine' ⟨∑ i, x i • b' i, fun i => _, _⟩
[GOAL]
case h.mpr.refine'_1
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
hdvd : ∀ (i : ι), smithCoeffs b I hI i ∣ x i
i : ι
⊢ smithCoeffs b I hI i ∣ ↑(↑(ringBasis b I hI).repr (∑ i : ι, x i • ↑b' i)) i
[PROOFSTEP]
rw [b'.repr_sum_self]
[GOAL]
case h.mpr.refine'_2
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
hdvd : ∀ (i : ι), smithCoeffs b I hI i ∣ x i
⊢ ↑(↑(ringBasis b I hI).repr (∑ i : ι, x i • ↑b' i)) = x
[PROOFSTEP]
rw [b'.repr_sum_self]
[GOAL]
case h.mpr.refine'_1
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
x : ι → R
hdvd : ∀ (i : ι), smithCoeffs b I hI i ∣ x i
i : ι
⊢ smithCoeffs b I hI i ∣ x i
[PROOFSTEP]
exact hdvd i
[GOAL]
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ (S ⧸ I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
refine'
  ((Submodule.Quotient.restrictScalarsEquiv R I).restrictScalars R).symm.trans (σ₁₂ := RingHom.id R) (σ₃₂ :=
    RingHom.id R) _
[GOAL]
case refine'_1
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ RingHomInvPair (RingHom.id R) (RingHom.id R)
[PROOFSTEP]
infer_instance
[GOAL]
case refine'_2
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ RingHomInvPair (RingHom.id R) (RingHom.id R)
[PROOFSTEP]
infer_instance
[GOAL]
case refine'_3
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ (S ⧸ Submodule.restrictScalars R I) ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
refine'
  (Submodule.Quotient.equiv (I.restrictScalars R) I' b'.equivFun this).trans (σ₁₂ := RingHom.id R) (σ₃₂ := RingHom.id R)
    _
[GOAL]
case refine'_3.refine'_1
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ RingHomInvPair (RingHom.id R) (RingHom.id R)
[PROOFSTEP]
infer_instance
[GOAL]
case refine'_3.refine'_2
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ RingHomInvPair (RingHom.id R) (RingHom.id R)
[PROOFSTEP]
infer_instance
[GOAL]
case refine'_3.refine'_3
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ ((ι → R) ⧸ I') ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
classical
let this := Submodule.quotientPi (show ∀ _, Submodule R R from fun i => span ({a i} : Set R))
exact this
[GOAL]
case refine'_3.refine'_3
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
⊢ ((ι → R) ⧸ I') ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
let this := Submodule.quotientPi (show ∀ _, Submodule R R from fun i => span ({a i} : Set R))
[GOAL]
case refine'_3.refine'_3
ι : 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 { x // x ∈ I } := selfBasis b I hI
ab_eq : ∀ (i : ι), ↑(↑(selfBasis b I hI) i) = smithCoeffs b I hI i • ↑(ringBasis b I hI) i
mem_I_iff : ∀ (x : S), x ∈ I ↔ ∀ (i : ι), a i ∣ ↑(↑b'.repr x) i
I' : Submodule R (ι → R) := Submodule.pi Set.univ fun i => span {a i}
this✝ : Submodule.map (↑(Basis.equivFun b')) (Submodule.restrictScalars R I) = I'
this : ((ι → R) ⧸
    Submodule.pi Set.univ
      (let_fun this := fun i => span {a i};
      this)) ≃ₗ[R]
  (i : ι) → R ⧸ (fun this => this) (fun i => span {a i}) i :=
  Submodule.quotientPi
    (let_fun this := fun i => span {a i};
    this)
⊢ ((ι → R) ⧸ I') ≃ₗ[R] (i : ι) → R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
exact this
[GOAL]
ι : 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 ι
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : I ≠ ⊥
⊢ Fintype (S ⧸ I)
[PROOFSTEP]
let b := Module.Free.chooseBasis ℤ S
[GOAL]
ι : 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 ι
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : I ≠ ⊥
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ Fintype (S ⧸ I)
[PROOFSTEP]
let a := I.smithCoeffs b hI
[GOAL]
ι : 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 ι
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : I ≠ ⊥
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
⊢ Fintype (S ⧸ I)
[PROOFSTEP]
let e := I.quotientEquivPiZMod b hI
[GOAL]
ι : 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 ι
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : I ≠ ⊥
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
e : S ⧸ I ≃+ ((i : Module.Free.ChooseBasisIndex ℤ S) → ZMod (Int.natAbs (smithCoeffs b I hI i))) :=
  quotientEquivPiZMod I b hI
⊢ Fintype (S ⧸ I)
[PROOFSTEP]
haveI : ∀ i, NeZero (a i).natAbs := fun i => ⟨Int.natAbs_ne_zero.mpr (smithCoeffs_ne_zero b I hI i)⟩
[GOAL]
ι : 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 ι
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : I ≠ ⊥
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
e : S ⧸ I ≃+ ((i : Module.Free.ChooseBasisIndex ℤ S) → ZMod (Int.natAbs (smithCoeffs b I hI i))) :=
  quotientEquivPiZMod I b hI
this : ∀ (i : Module.Free.ChooseBasisIndex ℤ S), NeZero (Int.natAbs (a i))
⊢ Fintype (S ⧸ I)
[PROOFSTEP]
classical exact Fintype.ofEquiv (∀ i, ZMod (a i).natAbs) e.symm
[GOAL]
ι : 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 ι
inst✝¹ : Module.Free ℤ S
inst✝ : Module.Finite ℤ S
I : Ideal S
hI : I ≠ ⊥
b : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
a : Module.Free.ChooseBasisIndex ℤ S → ℤ := smithCoeffs b I hI
e : S ⧸ I ≃+ ((i : Module.Free.ChooseBasisIndex ℤ S) → ZMod (Int.natAbs (smithCoeffs b I hI i))) :=
  quotientEquivPiZMod I b hI
this : ∀ (i : Module.Free.ChooseBasisIndex ℤ S), NeZero (Int.natAbs (a i))
⊢ Fintype (S ⧸ I)
[PROOFSTEP]
exact Fintype.ofEquiv (∀ i, ZMod (a i).natAbs) e.symm
[GOAL]
ι : 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 ι
F : Type u_4
inst✝³ : CommRing F
inst✝² : Algebra F R
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F R S
b : Basis ι R S
I : Ideal S
hI : I ≠ ⊥
⊢ (S ⧸ I) ≃ₗ[F] ⨁ (i : ι), R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
haveI := Fintype.ofFinite ι
[GOAL]
ι : 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 ι
F : Type u_4
inst✝³ : CommRing F
inst✝² : Algebra F R
inst✝¹ : Algebra F S
inst✝ : IsScalarTower F R S
b : Basis ι R S
I : Ideal S
hI : I ≠ ⊥
this : Fintype ι
⊢ (S ⧸ I) ≃ₗ[F] ⨁ (i : ι), R ⧸ span {smithCoeffs b I hI i}
[PROOFSTEP]
exact ((I.quotientEquivPiSpan b _).restrictScalars F).trans (DirectSum.linearEquivFunOnFintype _ _ _).symm
[GOAL]
ι✝ : 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 ι✝
F : Type u_4
inst✝⁷ : CommRing F
inst✝⁶ : Algebra F R
inst✝⁵ : Algebra F S
inst✝⁴ : IsScalarTower F R S
b✝ : Basis ι✝ R S
I : Ideal S
hI : I ≠ ⊥
ι : Type u_5
inst✝³ : Fintype ι
b : Basis ι R S
inst✝² : Nontrivial F
inst✝¹ : ∀ (i : ι), Module.Free F (R ⧸ span {smithCoeffs b I hI i})
inst✝ : ∀ (i : ι), Module.Finite F (R ⧸ span {smithCoeffs b I hI i})
⊢ FiniteDimensional.finrank F (S ⧸ I) = ∑ i : ι, FiniteDimensional.finrank F (R ⧸ span {smithCoeffs b I hI i})
[PROOFSTEP]
rw [LinearEquiv.finrank_eq <| quotientEquivDirectSum F b hI, FiniteDimensional.finrank_directSum]


[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf : a✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
hg : b✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
i : ℕ
⊢ coeff (a✝ * b✝) i ∈ I ^ i
[PROOFSTEP]
rw [coeff_mul]
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf : a✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
hg : b✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
i : ℕ
⊢ ∑ x in Finset.Nat.antidiagonal i, coeff a✝ x.fst * coeff b✝ x.snd ∈ I ^ i
[PROOFSTEP]
apply Ideal.sum_mem
[GOAL]
case a
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf : a✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
hg : b✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
i : ℕ
⊢ ∀ (c : ℕ × ℕ), c ∈ Finset.Nat.antidiagonal i → coeff a✝ c.fst * coeff b✝ c.snd ∈ I ^ i
[PROOFSTEP]
rintro ⟨j, k⟩ e
[GOAL]
case a.mk
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf : a✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
hg : b✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
i j k : ℕ
e : (j, k) ∈ Finset.Nat.antidiagonal i
⊢ coeff a✝ (j, k).fst * coeff b✝ (j, k).snd ∈ I ^ i
[PROOFSTEP]
rw [← Finset.Nat.mem_antidiagonal.mp e, pow_add]
[GOAL]
case a.mk
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf : a✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
hg : b✝ ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i}
i j k : ℕ
e : (j, k) ∈ Finset.Nat.antidiagonal i
⊢ coeff a✝ (j, k).fst * coeff b✝ (j, k).snd ∈ I ^ (j, k).fst * I ^ (j, k).snd
[PROOFSTEP]
exact Ideal.mul_mem_mul (hf j) (hg k)
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
i : ℕ
⊢ coeff 1 i ∈ I ^ i
[PROOFSTEP]
rw [coeff_one]
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
i : ℕ
⊢ (if 0 = i then 1 else 0) ∈ I ^ i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
i : ℕ
h : 0 = i
⊢ 1 ∈ I ^ i
[PROOFSTEP]
subst h
[GOAL]
case pos
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ 1 ∈ I ^ 0
[PROOFSTEP]
simp
[GOAL]
case neg
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
i : ℕ
h : ¬0 = i
⊢ 0 ∈ I ^ i
[PROOFSTEP]
simp
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf :
  a✝ ∈
    {
          toSubsemigroup :=
            { carrier := {f | ∀ (i : ℕ), coeff f i ∈ I ^ i},
              mul_mem' :=
                (_ :
                  ∀ {a b : R[X]},
                    a ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} →
                      b ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} → ∀ (i : ℕ), coeff (a * b) i ∈ I ^ i) },
          one_mem' := (_ : ∀ (i : ℕ), coeff 1 i ∈ I ^ i) }.toSubsemigroup.carrier
hg :
  b✝ ∈
    {
          toSubsemigroup :=
            { carrier := {f | ∀ (i : ℕ), coeff f i ∈ I ^ i},
              mul_mem' :=
                (_ :
                  ∀ {a b : R[X]},
                    a ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} →
                      b ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} → ∀ (i : ℕ), coeff (a * b) i ∈ I ^ i) },
          one_mem' := (_ : ∀ (i : ℕ), coeff 1 i ∈ I ^ i) }.toSubsemigroup.carrier
i : ℕ
⊢ coeff (a✝ + b✝) i ∈ I ^ i
[PROOFSTEP]
rw [coeff_add]
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
a✝ b✝ : R[X]
hf :
  a✝ ∈
    {
          toSubsemigroup :=
            { carrier := {f | ∀ (i : ℕ), coeff f i ∈ I ^ i},
              mul_mem' :=
                (_ :
                  ∀ {a b : R[X]},
                    a ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} →
                      b ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} → ∀ (i : ℕ), coeff (a * b) i ∈ I ^ i) },
          one_mem' := (_ : ∀ (i : ℕ), coeff 1 i ∈ I ^ i) }.toSubsemigroup.carrier
hg :
  b✝ ∈
    {
          toSubsemigroup :=
            { carrier := {f | ∀ (i : ℕ), coeff f i ∈ I ^ i},
              mul_mem' :=
                (_ :
                  ∀ {a b : R[X]},
                    a ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} →
                      b ∈ {f | ∀ (i : ℕ), coeff f i ∈ I ^ i} → ∀ (i : ℕ), coeff (a * b) i ∈ I ^ i) },
          one_mem' := (_ : ∀ (i : ℕ), coeff 1 i ∈ I ^ i) }.toSubsemigroup.carrier
i : ℕ
⊢ coeff a✝ i + coeff b✝ i ∈ I ^ i
[PROOFSTEP]
exact Ideal.add_mem _ (hf i) (hg i)
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
i : ℕ
⊢ coeff (↑(algebraMap R R[X]) r) i ∈ I ^ i
[PROOFSTEP]
rw [algebraMap_apply, coeff_C]
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
i : ℕ
⊢ (if i = 0 then ↑(algebraMap R R) r else 0) ∈ I ^ i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
i : ℕ
h : i = 0
⊢ ↑(algebraMap R R) r ∈ I ^ i
[PROOFSTEP]
subst h
[GOAL]
case pos
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
⊢ ↑(algebraMap R R) r ∈ I ^ 0
[PROOFSTEP]
simp
[GOAL]
case neg
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
i : ℕ
h : ¬i = 0
⊢ 0 ∈ I ^ i
[PROOFSTEP]
simp
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
f : R[X]
⊢ f ∈ reesAlgebra I ↔ ∀ (i : ℕ), i ∈ support f → coeff f i ∈ I ^ i
[PROOFSTEP]
apply forall_congr'
[GOAL]
case h
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
f : R[X]
⊢ ∀ (a : ℕ), coeff f a ∈ I ^ a ↔ a ∈ support f → coeff f a ∈ I ^ a
[PROOFSTEP]
intro a
[GOAL]
case h
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
f : R[X]
a : ℕ
⊢ coeff f a ∈ I ^ a ↔ a ∈ support f → coeff f a ∈ I ^ a
[PROOFSTEP]
rw [mem_support_iff, Iff.comm, imp_iff_right_iff, Ne.def, ← imp_iff_not_or]
[GOAL]
case h
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
f : R[X]
a : ℕ
⊢ coeff f a = 0 → coeff f a ∈ I ^ a
[PROOFSTEP]
exact fun e => e.symm ▸ (I ^ a).zero_mem
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
i : ℕ
r : R
⊢ ↑(monomial i) r ∈ reesAlgebra I ↔ r ∈ I ^ i
[PROOFSTEP]
simp (config := { contextual := true }) [mem_reesAlgebra_iff_support, coeff_monomial, ← imp_iff_not_or]
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n : ℕ
r : R
hr : r ∈ I ^ n
⊢ ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
induction' n with n hn generalizing r
[GOAL]
case zero
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n
r : R
hr : r ∈ I ^ Nat.zero
⊢ ↑(monomial Nat.zero) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
exact Subalgebra.algebraMap_mem _ _
[GOAL]
case succ
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r : R
hr : r ∈ I ^ Nat.succ n
⊢ ↑(monomial (Nat.succ n)) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
rw [pow_succ] at hr
[GOAL]
case succ
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r : R
hr : r ∈ I * I ^ n
⊢ ↑(monomial (Nat.succ n)) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
apply
  Submodule.smul_induction_on (p := fun r =>
    (monomial (Nat.succ n)) r ∈ Algebra.adjoin R (Submodule.map (monomial 1) I)) hr
[GOAL]
case succ.Hb
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r : R
hr : r ∈ I * I ^ n
⊢ ∀ (r : R),
    r ∈ I →
      ∀ (n_1 : R), n_1 ∈ I ^ n → ↑(monomial (Nat.succ n)) (r • n_1) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
intro r hr s hs
[GOAL]
case succ.Hb
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝¹ : R
hr✝¹ : r✝¹ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r✝ : R
hr✝ : r✝ ∈ I * I ^ n
r : R
hr : r ∈ I
s : R
hs : s ∈ I ^ n
⊢ ↑(monomial (Nat.succ n)) (r • s) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
rw [Nat.succ_eq_one_add, smul_eq_mul, ← monomial_mul_monomial]
[GOAL]
case succ.Hb
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝¹ : R
hr✝¹ : r✝¹ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r✝ : R
hr✝ : r✝ ∈ I * I ^ n
r : R
hr : r ∈ I
s : R
hs : s ∈ I ^ n
⊢ ↑(monomial 1) r * ↑(monomial n) s ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
exact Subalgebra.mul_mem _ (Algebra.subset_adjoin (Set.mem_image_of_mem _ hr)) (hn hs)
[GOAL]
case succ.H1
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r : R
hr : r ∈ I * I ^ n
⊢ ∀ (x y : R),
    ↑(monomial (Nat.succ n)) x ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I) →
      ↑(monomial (Nat.succ n)) y ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I) →
        ↑(monomial (Nat.succ n)) (x + y) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
intro x y hx hy
[GOAL]
case succ.H1
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r : R
hr : r ∈ I * I ^ n
x y : R
hx : ↑(monomial (Nat.succ n)) x ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
hy : ↑(monomial (Nat.succ n)) y ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
⊢ ↑(monomial (Nat.succ n)) (x + y) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
rw [monomial_add]
[GOAL]
case succ.H1
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I✝ I : Ideal R
n✝ : ℕ
r✝ : R
hr✝ : r✝ ∈ I ^ n✝
n : ℕ
hn : ∀ {r : R}, r ∈ I ^ n → ↑(monomial n) r ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
r : R
hr : r ∈ I * I ^ n
x y : R
hx : ↑(monomial (Nat.succ n)) x ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
hy : ↑(monomial (Nat.succ n)) y ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
⊢ ↑(monomial (Nat.succ n)) x + ↑(monomial (Nat.succ n)) y ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
exact Subalgebra.add_mem _ hx hy
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ Algebra.adjoin R ↑(Submodule.map (monomial 1) I) = reesAlgebra I
[PROOFSTEP]
apply le_antisymm
[GOAL]
case a
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ Algebra.adjoin R ↑(Submodule.map (monomial 1) I) ≤ reesAlgebra I
[PROOFSTEP]
apply Algebra.adjoin_le _
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ ↑(Submodule.map (monomial 1) I) ⊆ ↑(reesAlgebra I)
[PROOFSTEP]
rintro _ ⟨r, hr, rfl⟩
[GOAL]
case intro.intro
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
hr : r ∈ ↑I
⊢ ↑(monomial 1) r ∈ ↑(reesAlgebra I)
[PROOFSTEP]
exact reesAlgebra.monomial_mem.mpr (by rwa [pow_one])
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
r : R
hr : r ∈ ↑I
⊢ r ∈ I ^ 1
[PROOFSTEP]
rwa [pow_one]
[GOAL]
case a
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ reesAlgebra I ≤ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
intro p hp
[GOAL]
case a
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
p : R[X]
hp : p ∈ reesAlgebra I
⊢ p ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
rw [p.as_sum_support]
[GOAL]
case a
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
p : R[X]
hp : p ∈ reesAlgebra I
⊢ ∑ i in support p, ↑(monomial i) (coeff p i) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
apply Subalgebra.sum_mem _ _
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
p : R[X]
hp : p ∈ reesAlgebra I
⊢ ∀ (x : ℕ), x ∈ support p → ↑(monomial x) (coeff p x) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
rintro i -
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
p : R[X]
hp : p ∈ reesAlgebra I
i : ℕ
⊢ ↑(monomial i) (coeff p i) ∈ Algebra.adjoin R ↑(Submodule.map (monomial 1) I)
[PROOFSTEP]
exact monomial_mem_adjoin_monomial (hp i)
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
hI : Ideal.FG I
⊢ Subalgebra.FG (reesAlgebra I)
[PROOFSTEP]
classical
obtain ⟨s, hs⟩ := hI
rw [← adjoin_monomial_eq_reesAlgebra, ← hs]
use s.image (monomial 1)
rw [Finset.coe_image]
change _ = Algebra.adjoin R (Submodule.map (monomial 1 : R →ₗ[R] R[X]) (Submodule.span R ↑s) : Set R[X])
rw [Submodule.map_span, Algebra.adjoin_span]
[GOAL]
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
hI : Ideal.FG I
⊢ Subalgebra.FG (reesAlgebra I)
[PROOFSTEP]
obtain ⟨s, hs⟩ := hI
[GOAL]
case intro
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
s : Finset R
hs : Ideal.span ↑s = I
⊢ Subalgebra.FG (reesAlgebra I)
[PROOFSTEP]
rw [← adjoin_monomial_eq_reesAlgebra, ← hs]
[GOAL]
case intro
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
s : Finset R
hs : Ideal.span ↑s = I
⊢ Subalgebra.FG (Algebra.adjoin R ↑(Submodule.map (monomial 1) (Ideal.span ↑s)))
[PROOFSTEP]
use s.image (monomial 1)
[GOAL]
case h
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
s : Finset R
hs : Ideal.span ↑s = I
⊢ Algebra.adjoin R ↑(Finset.image (↑(monomial 1)) s) = Algebra.adjoin R ↑(Submodule.map (monomial 1) (Ideal.span ↑s))
[PROOFSTEP]
rw [Finset.coe_image]
[GOAL]
case h
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
s : Finset R
hs : Ideal.span ↑s = I
⊢ Algebra.adjoin R (↑(monomial 1) '' ↑s) = Algebra.adjoin R ↑(Submodule.map (monomial 1) (Ideal.span ↑s))
[PROOFSTEP]
change _ = Algebra.adjoin R (Submodule.map (monomial 1 : R →ₗ[R] R[X]) (Submodule.span R ↑s) : Set R[X])
[GOAL]
case h
R M : Type u
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
s : Finset R
hs : Ideal.span ↑s = I
⊢ Algebra.adjoin R (↑(monomial 1) '' ↑s) = Algebra.adjoin R ↑(Submodule.map (monomial 1) (Submodule.span R ↑s))
[PROOFSTEP]
rw [Submodule.map_span, Algebra.adjoin_span]


[GOAL]
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
⊢ IsCoatomic α
[PROOFSTEP]
refine ⟨fun x => le_top.eq_or_lt.imp_right fun hx => ?_⟩
[GOAL]
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
⊢ ∃ a, IsCoatom a ∧ x ≤ a
[PROOFSTEP]
have : ∃ y ∈ Ico x ⊤, x ≤ y ∧ ∀ z ∈ Ico x ⊤, y ≤ z → z = y :=
  by
  refine zorn_nonempty_partialOrder₀ (Ico x ⊤) (fun c hxc hc y hy => ?_) x (left_mem_Ico.2 hx)
  rcases h c hc ⟨y, hy⟩ fun h => (hxc h).2.ne rfl with ⟨z, hz, hcz⟩
  exact ⟨z, ⟨le_trans (hxc hy).1 (hcz hy), hz.lt_top⟩, hcz⟩
[GOAL]
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
⊢ ∃ y, y ∈ Ico x ⊤ ∧ x ≤ y ∧ ∀ (z : α), z ∈ Ico x ⊤ → y ≤ z → z = y
[PROOFSTEP]
refine zorn_nonempty_partialOrder₀ (Ico x ⊤) (fun c hxc hc y hy => ?_) x (left_mem_Ico.2 hx)
[GOAL]
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
c : Set α
hxc : c ⊆ Ico x ⊤
hc : IsChain (fun x x_1 => x ≤ x_1) c
y : α
hy : y ∈ c
⊢ ∃ ub, ub ∈ Ico x ⊤ ∧ ∀ (z : α), z ∈ c → z ≤ ub
[PROOFSTEP]
rcases h c hc ⟨y, hy⟩ fun h => (hxc h).2.ne rfl with ⟨z, hz, hcz⟩
[GOAL]
case intro.intro
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
c : Set α
hxc : c ⊆ Ico x ⊤
hc : IsChain (fun x x_1 => x ≤ x_1) c
y : α
hy : y ∈ c
z : α
hz : z ≠ ⊤
hcz : z ∈ upperBounds c
⊢ ∃ ub, ub ∈ Ico x ⊤ ∧ ∀ (z : α), z ∈ c → z ≤ ub
[PROOFSTEP]
exact ⟨z, ⟨le_trans (hxc hy).1 (hcz hy), hz.lt_top⟩, hcz⟩
[GOAL]
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
this : ∃ y, y ∈ Ico x ⊤ ∧ x ≤ y ∧ ∀ (z : α), z ∈ Ico x ⊤ → y ≤ z → z = y
⊢ ∃ a, IsCoatom a ∧ x ≤ a
[PROOFSTEP]
rcases this with ⟨y, ⟨hxy, hy⟩, -, hy'⟩
[GOAL]
case intro.intro.intro.intro
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
y : α
hxy : x ≤ y
hy : y < ⊤
hy' : ∀ (z : α), z ∈ Ico x ⊤ → y ≤ z → z = y
⊢ ∃ a, IsCoatom a ∧ x ≤ a
[PROOFSTEP]
refine ⟨y, ⟨hy.ne, fun z hyz => le_top.eq_or_lt.resolve_right fun hz => ?_⟩, hxy⟩
[GOAL]
case intro.intro.intro.intro
α : Type u_1
inst✝¹ : PartialOrder α
inst✝ : OrderTop α
h : ∀ (c : Set α), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ¬⊤ ∈ c → ∃ x x_1, x ∈ upperBounds c
x : α
hx : x < ⊤
y : α
hxy : x ≤ y
hy : y < ⊤
hy' : ∀ (z : α), z ∈ Ico x ⊤ → y ≤ z → z = y
z : α
hyz : y < z
hz : z < ⊤
⊢ False
[PROOFSTEP]
exact hyz.ne' (hy' z ⟨hxy.trans hyz.le, hz⟩ hyz.le)


[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
⊢ IsPrimitiveRoot (exp (2 * ↑π * I * (↑i / ↑n))) n
[PROOFSTEP]
rw [IsPrimitiveRoot.iff_def]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
⊢ exp (2 * ↑π * I * (↑i / ↑n)) ^ n = 1 ∧ ∀ (l : ℕ), exp (2 * ↑π * I * (↑i / ↑n)) ^ l = 1 → n ∣ l
[PROOFSTEP]
simp only [← exp_nat_mul, exp_eq_one_iff]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
⊢ (∃ n_1, ↑n * (2 * ↑π * I * (↑i / ↑n)) = ↑n_1 * (2 * ↑π * I)) ∧
    ∀ (l : ℕ), (∃ n_1, ↑l * (2 * ↑π * I * (↑i / ↑n)) = ↑n_1 * (2 * ↑π * I)) → n ∣ l
[PROOFSTEP]
have hn0 : (n : ℂ) ≠ 0 := by exact_mod_cast h0
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
⊢ ↑n ≠ 0
[PROOFSTEP]
exact_mod_cast h0
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
⊢ (∃ n_1, ↑n * (2 * ↑π * I * (↑i / ↑n)) = ↑n_1 * (2 * ↑π * I)) ∧
    ∀ (l : ℕ), (∃ n_1, ↑l * (2 * ↑π * I * (↑i / ↑n)) = ↑n_1 * (2 * ↑π * I)) → n ∣ l
[PROOFSTEP]
constructor
[GOAL]
case left
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
⊢ ∃ n_1, ↑n * (2 * ↑π * I * (↑i / ↑n)) = ↑n_1 * (2 * ↑π * I)
[PROOFSTEP]
use i
[GOAL]
case h
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
⊢ ↑n * (2 * ↑π * I * (↑i / ↑n)) = ↑↑i * (2 * ↑π * I)
[PROOFSTEP]
field_simp [hn0, mul_comm (i : ℂ), mul_comm (n : ℂ)]
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
⊢ ∀ (l : ℕ), (∃ n_1, ↑l * (2 * ↑π * I * (↑i / ↑n)) = ↑n_1 * (2 * ↑π * I)) → n ∣ l
[PROOFSTEP]
simp only [hn0, mul_right_comm _ _ ↑n, mul_left_inj' two_pi_I_ne_zero, Ne.def, not_false_iff, mul_comm _ (i : ℂ), ←
  mul_assoc _ (i : ℂ), exists_imp, field_simps]
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
⊢ ∀ (l : ℕ) (x : ℤ), ↑i * ↑l * (2 * ↑π * I) = ↑x * (2 * ↑π * I) * ↑n → n ∣ l
[PROOFSTEP]
norm_cast
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
⊢ ∀ (l : ℕ) (x : ℤ), ↑(i * l) * (↑(2 * π) * I) = ↑x * (↑(2 * π) * I) * ↑n → n ∣ l
[PROOFSTEP]
rintro l k hk
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑k * (↑(2 * π) * I) * ↑n
⊢ n ∣ l
[PROOFSTEP]
conv_rhs at hk => rw [mul_comm, ← mul_assoc]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑k * (↑(2 * π) * I) * ↑n
| ↑k * (↑(2 * π) * I) * ↑n
[PROOFSTEP]
rw [mul_comm, ← mul_assoc]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑k * (↑(2 * π) * I) * ↑n
| ↑k * (↑(2 * π) * I) * ↑n
[PROOFSTEP]
rw [mul_comm, ← mul_assoc]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑k * (↑(2 * π) * I) * ↑n
| ↑k * (↑(2 * π) * I) * ↑n
[PROOFSTEP]
rw [mul_comm, ← mul_assoc]
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑n * ↑k * (↑(2 * π) * I)
⊢ n ∣ l
[PROOFSTEP]
have hz : 2 * ↑π * I ≠ 0 := by simp [pi_pos.ne.symm, I_ne_zero]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑n * ↑k * (↑(2 * π) * I)
⊢ 2 * ↑π * I ≠ 0
[PROOFSTEP]
simp [pi_pos.ne.symm, I_ne_zero]
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hk : ↑(i * l) * (↑(2 * π) * I) = ↑n * ↑k * (↑(2 * π) * I)
hz : 2 * ↑π * I ≠ 0
⊢ n ∣ l
[PROOFSTEP]
field_simp [hz] at hk
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hz : 2 * ↑π * I ≠ 0
hk : ↑i * ↑l = ↑n * ↑k
⊢ n ∣ l
[PROOFSTEP]
norm_cast at hk
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hz : 2 * ↑π * I ≠ 0
hk : ↑(i * l) = ↑n * k
⊢ n ∣ l
[PROOFSTEP]
have : n ∣ i * l := by rw [← Int.coe_nat_dvd, hk, mul_comm]; apply dvd_mul_left
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hz : 2 * ↑π * I ≠ 0
hk : ↑(i * l) = ↑n * k
⊢ n ∣ i * l
[PROOFSTEP]
rw [← Int.coe_nat_dvd, hk, mul_comm]
[GOAL]
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hz : 2 * ↑π * I ≠ 0
hk : ↑(i * l) = ↑n * k
⊢ ↑n ∣ k * ↑n
[PROOFSTEP]
apply dvd_mul_left
[GOAL]
case right
i n : ℕ
h0 : n ≠ 0
hi : Nat.coprime i n
hn0 : ↑n ≠ 0
l : ℕ
k : ℤ
hz : 2 * ↑π * I ≠ 0
hk : ↑(i * l) = ↑n * k
this : n ∣ i * l
⊢ n ∣ l
[PROOFSTEP]
exact hi.symm.dvd_of_dvd_mul_left this
[GOAL]
n : ℕ
h0 : n ≠ 0
⊢ IsPrimitiveRoot (exp (2 * ↑π * I / ↑n)) n
[PROOFSTEP]
simpa only [Nat.cast_one, one_div] using isPrimitiveRoot_exp_of_coprime 1 n h0 n.coprime_one_left
[GOAL]
ζ : ℂ
n : ℕ
hn : n ≠ 0
⊢ IsPrimitiveRoot ζ n ↔ ∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ
[PROOFSTEP]
have hn0 : (n : ℂ) ≠ 0 := by exact_mod_cast hn
[GOAL]
ζ : ℂ
n : ℕ
hn : n ≠ 0
⊢ ↑n ≠ 0
[PROOFSTEP]
exact_mod_cast hn
[GOAL]
ζ : ℂ
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
⊢ IsPrimitiveRoot ζ n ↔ ∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ
[PROOFSTEP]
constructor
[GOAL]
case mp
ζ : ℂ
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
⊢ IsPrimitiveRoot ζ n → ∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ
case mpr
ζ : ℂ
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
⊢ (∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ) → IsPrimitiveRoot ζ n
[PROOFSTEP]
swap
[GOAL]
case mpr
ζ : ℂ
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
⊢ (∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ) → IsPrimitiveRoot ζ n
[PROOFSTEP]
rintro ⟨i, -, hi, rfl⟩
[GOAL]
case mpr.intro.intro.intro
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
i : ℕ
hi : Nat.coprime i n
⊢ IsPrimitiveRoot (exp (2 * ↑π * I * (↑i / ↑n))) n
[PROOFSTEP]
exact isPrimitiveRoot_exp_of_coprime i n hn hi
[GOAL]
case mp
ζ : ℂ
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
⊢ IsPrimitiveRoot ζ n → ∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ
[PROOFSTEP]
intro h
[GOAL]
case mp
ζ : ℂ
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
h : IsPrimitiveRoot ζ n
⊢ ∃ i, i < n ∧ ∃ x, exp (2 * ↑π * I * (↑i / ↑n)) = ζ
[PROOFSTEP]
obtain ⟨i, hi, rfl⟩ := (isPrimitiveRoot_exp n hn).eq_pow_of_pow_eq_one h.pow_eq_one (Nat.pos_of_ne_zero hn)
[GOAL]
case mp.intro.intro
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
i : ℕ
hi : i < n
h : IsPrimitiveRoot (exp (2 * ↑π * I / ↑n) ^ i) n
⊢ ∃ i_1, i_1 < n ∧ ∃ x, exp (2 * ↑π * I * (↑i_1 / ↑n)) = exp (2 * ↑π * I / ↑n) ^ i
[PROOFSTEP]
refine' ⟨i, hi, ((isPrimitiveRoot_exp n hn).pow_iff_coprime (Nat.pos_of_ne_zero hn) i).mp h, _⟩
[GOAL]
case mp.intro.intro
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
i : ℕ
hi : i < n
h : IsPrimitiveRoot (exp (2 * ↑π * I / ↑n) ^ i) n
⊢ exp (2 * ↑π * I * (↑i / ↑n)) = exp (2 * ↑π * I / ↑n) ^ i
[PROOFSTEP]
rw [← exp_nat_mul]
[GOAL]
case mp.intro.intro
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
i : ℕ
hi : i < n
h : IsPrimitiveRoot (exp (2 * ↑π * I / ↑n) ^ i) n
⊢ exp (2 * ↑π * I * (↑i / ↑n)) = exp (↑i * (2 * ↑π * I / ↑n))
[PROOFSTEP]
congr 1
[GOAL]
case mp.intro.intro.e_z
n : ℕ
hn : n ≠ 0
hn0 : ↑n ≠ 0
i : ℕ
hi : i < n
h : IsPrimitiveRoot (exp (2 * ↑π * I / ↑n) ^ i) n
⊢ 2 * ↑π * I * (↑i / ↑n) = ↑i * (2 * ↑π * I / ↑n)
[PROOFSTEP]
field_simp [hn0, mul_comm (i : ℂ)]
[GOAL]
n : ℕ+
x : ℂˣ
⊢ x ∈ rootsOfUnity n ℂ ↔ ∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
rw [mem_rootsOfUnity, Units.ext_iff, Units.val_pow_eq_pow_val, Units.val_one]
[GOAL]
n : ℕ+
x : ℂˣ
⊢ ↑x ^ ↑n = 1 ↔ ∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
have hn0 : (n : ℂ) ≠ 0 := by exact_mod_cast n.ne_zero
[GOAL]
n : ℕ+
x : ℂˣ
⊢ ↑↑n ≠ 0
[PROOFSTEP]
exact_mod_cast n.ne_zero
[GOAL]
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
⊢ ↑x ^ ↑n = 1 ↔ ∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
constructor
[GOAL]
case mp
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
⊢ ↑x ^ ↑n = 1 → ∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
intro h
[GOAL]
case mp
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
h : ↑x ^ ↑n = 1
⊢ ∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
obtain ⟨i, hi, H⟩ : ∃ i < (n : ℕ), exp (2 * π * I / n) ^ i = x := by
  simpa only using (isPrimitiveRoot_exp n n.ne_zero).eq_pow_of_pow_eq_one h n.pos
[GOAL]
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
h : ↑x ^ ↑n = 1
⊢ ∃ i, i < ↑n ∧ exp (2 * ↑π * I / ↑↑n) ^ i = ↑x
[PROOFSTEP]
simpa only using (isPrimitiveRoot_exp n n.ne_zero).eq_pow_of_pow_eq_one h n.pos
[GOAL]
case mp.intro.intro
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
h : ↑x ^ ↑n = 1
i : ℕ
hi : i < ↑n
H : exp (2 * ↑π * I / ↑↑n) ^ i = ↑x
⊢ ∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
refine' ⟨i, hi, _⟩
[GOAL]
case mp.intro.intro
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
h : ↑x ^ ↑n = 1
i : ℕ
hi : i < ↑n
H : exp (2 * ↑π * I / ↑↑n) ^ i = ↑x
⊢ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
[PROOFSTEP]
rw [← H, ← exp_nat_mul]
[GOAL]
case mp.intro.intro
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
h : ↑x ^ ↑n = 1
i : ℕ
hi : i < ↑n
H : exp (2 * ↑π * I / ↑↑n) ^ i = ↑x
⊢ exp (2 * ↑π * I * (↑i / ↑↑n)) = exp (↑i * (2 * ↑π * I / ↑↑n))
[PROOFSTEP]
congr 1
[GOAL]
case mp.intro.intro.e_z
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
h : ↑x ^ ↑n = 1
i : ℕ
hi : i < ↑n
H : exp (2 * ↑π * I / ↑↑n) ^ i = ↑x
⊢ 2 * ↑π * I * (↑i / ↑↑n) = ↑i * (2 * ↑π * I / ↑↑n)
[PROOFSTEP]
field_simp [hn0, mul_comm (i : ℂ)]
[GOAL]
case mpr
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
⊢ (∃ i, i < ↑n ∧ exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x) → ↑x ^ ↑n = 1
[PROOFSTEP]
rintro ⟨i, _, H⟩
[GOAL]
case mpr.intro.intro
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
i : ℕ
left✝ : i < ↑n
H : exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
⊢ ↑x ^ ↑n = 1
[PROOFSTEP]
rw [← H, ← exp_nat_mul, exp_eq_one_iff]
[GOAL]
case mpr.intro.intro
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
i : ℕ
left✝ : i < ↑n
H : exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
⊢ ∃ n_1, ↑↑n * (2 * ↑π * I * (↑i / ↑↑n)) = ↑n_1 * (2 * ↑π * I)
[PROOFSTEP]
use i
[GOAL]
case h
n : ℕ+
x : ℂˣ
hn0 : ↑↑n ≠ 0
i : ℕ
left✝ : i < ↑n
H : exp (2 * ↑π * I * (↑i / ↑↑n)) = ↑x
⊢ ↑↑n * (2 * ↑π * I * (↑i / ↑↑n)) = ↑↑i * (2 * ↑π * I)
[PROOFSTEP]
field_simp [hn0, mul_comm ((n : ℕ) : ℂ), mul_comm (i : ℂ)]
[GOAL]
k : ℕ
⊢ Finset.card (primitiveRoots k ℂ) = φ k
[PROOFSTEP]
by_cases h : k = 0
[GOAL]
case pos
k : ℕ
h : k = 0
⊢ Finset.card (primitiveRoots k ℂ) = φ k
[PROOFSTEP]
simp [h]
[GOAL]
case neg
k : ℕ
h : ¬k = 0
⊢ Finset.card (primitiveRoots k ℂ) = φ k
[PROOFSTEP]
exact (isPrimitiveRoot_exp k h).card_primitiveRoots
[GOAL]
n : ℕ
ζ : ℂ
h : IsPrimitiveRoot ζ n
hn : n ≠ 0
⊢ ∃ i, Complex.arg ζ = ↑i / ↑n * (2 * Real.pi) ∧ IsCoprime i ↑n ∧ Int.natAbs i < n
[PROOFSTEP]
rw [Complex.isPrimitiveRoot_iff _ _ hn] at h
[GOAL]
n : ℕ
ζ : ℂ
h : ∃ i, i < n ∧ ∃ x, Complex.exp (2 * ↑Real.pi * Complex.I * (↑i / ↑n)) = ζ
hn : n ≠ 0
⊢ ∃ i, Complex.arg ζ = ↑i / ↑n * (2 * Real.pi) ∧ IsCoprime i ↑n ∧ Int.natAbs i < n
[PROOFSTEP]
obtain ⟨i, h, hin, rfl⟩ := h
[GOAL]
case intro.intro.intro
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ ∃ i_1,
    Complex.arg (Complex.exp (2 * ↑Real.pi * Complex.I * (↑i / ↑n))) = ↑i_1 / ↑n * (2 * Real.pi) ∧
      IsCoprime i_1 ↑n ∧ Int.natAbs i_1 < n
[PROOFSTEP]
rw [mul_comm, ← mul_assoc, Complex.exp_mul_I]
[GOAL]
case intro.intro.intro
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ ∃ i_1,
    Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
        ↑i_1 / ↑n * (2 * Real.pi) ∧
      IsCoprime i_1 ↑n ∧ Int.natAbs i_1 < n
[PROOFSTEP]
refine' ⟨if i * 2 ≤ n then i else i - n, _, _, _⟩
[GOAL]
case intro.intro.intro.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑(if i * 2 ≤ n then ↑i else ↑i - ↑n) / ↑n * (2 * Real.pi)
case intro.intro.intro.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ IsCoprime (if i * 2 ≤ n then ↑i else ↑i - ↑n) ↑n
case intro.intro.intro.refine'_3
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Int.natAbs (if i * 2 ≤ n then ↑i else ↑i - ↑n) < n
[PROOFSTEP]
on_goal 2 =>
  replace hin := Nat.isCoprime_iff_coprime.mpr hin
  split_ifs
  · exact hin
  · convert hin.add_mul_left_left (-1) using 1
    rw [mul_neg_one, sub_eq_add_neg]
[GOAL]
case intro.intro.intro.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑(if i * 2 ≤ n then ↑i else ↑i - ↑n) / ↑n * (2 * Real.pi)
case intro.intro.intro.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ IsCoprime (if i * 2 ≤ n then ↑i else ↑i - ↑n) ↑n
case intro.intro.intro.refine'_3
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Int.natAbs (if i * 2 ≤ n then ↑i else ↑i - ↑n) < n
[PROOFSTEP]
on_goal 2 =>
  replace hin := Nat.isCoprime_iff_coprime.mpr hin
  split_ifs
  · exact hin
  · convert hin.add_mul_left_left (-1) using 1
    rw [mul_neg_one, sub_eq_add_neg]
[GOAL]
case intro.intro.intro.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ IsCoprime (if i * 2 ≤ n then ↑i else ↑i - ↑n) ↑n
[PROOFSTEP]
replace hin := Nat.isCoprime_iff_coprime.mpr hin
[GOAL]
case intro.intro.intro.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : IsCoprime ↑i ↑n
⊢ IsCoprime (if i * 2 ≤ n then ↑i else ↑i - ↑n) ↑n
[PROOFSTEP]
split_ifs
[GOAL]
case pos
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : IsCoprime ↑i ↑n
h✝ : i * 2 ≤ n
⊢ IsCoprime ↑i ↑n
[PROOFSTEP]
exact hin
[GOAL]
case neg
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : IsCoprime ↑i ↑n
h✝ : ¬i * 2 ≤ n
⊢ IsCoprime (↑i - ↑n) ↑n
[PROOFSTEP]
convert hin.add_mul_left_left (-1) using 1
[GOAL]
case h.e'_3
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : IsCoprime ↑i ↑n
h✝ : ¬i * 2 ≤ n
⊢ ↑i - ↑n = ↑i + ↑n * -1
[PROOFSTEP]
rw [mul_neg_one, sub_eq_add_neg]
[GOAL]
case intro.intro.intro.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑(if i * 2 ≤ n then ↑i else ↑i - ↑n) / ↑n * (2 * Real.pi)
case intro.intro.intro.refine'_3
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Int.natAbs (if i * 2 ≤ n then ↑i else ↑i - ↑n) < n
[PROOFSTEP]
on_goal 2 =>
  split_ifs with h₂
  · exact_mod_cast h
  suffices (i - n : ℤ).natAbs = n - i by
    rw [this]
    apply tsub_lt_self hn.bot_lt
    contrapose! h₂
    rw [Nat.eq_zero_of_le_zero h₂, zero_mul]
    exact zero_le _
  rw [← Int.natAbs_neg, neg_sub, Int.natAbs_eq_iff]
  exact Or.inl (Int.ofNat_sub h.le).symm
[GOAL]
case intro.intro.intro.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑(if i * 2 ≤ n then ↑i else ↑i - ↑n) / ↑n * (2 * Real.pi)
case intro.intro.intro.refine'_3
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Int.natAbs (if i * 2 ≤ n then ↑i else ↑i - ↑n) < n
[PROOFSTEP]
on_goal 2 =>
  split_ifs with h₂
  · exact_mod_cast h
  suffices (i - n : ℤ).natAbs = n - i by
    rw [this]
    apply tsub_lt_self hn.bot_lt
    contrapose! h₂
    rw [Nat.eq_zero_of_le_zero h₂, zero_mul]
    exact zero_le _
  rw [← Int.natAbs_neg, neg_sub, Int.natAbs_eq_iff]
  exact Or.inl (Int.ofNat_sub h.le).symm
[GOAL]
case intro.intro.intro.refine'_3
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Int.natAbs (if i * 2 ≤ n then ↑i else ↑i - ↑n) < n
[PROOFSTEP]
split_ifs with h₂
[GOAL]
case pos
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ Int.natAbs ↑i < n
[PROOFSTEP]
exact_mod_cast h
[GOAL]
case neg
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ Int.natAbs (↑i - ↑n) < n
[PROOFSTEP]
suffices (i - n : ℤ).natAbs = n - i by
  rw [this]
  apply tsub_lt_self hn.bot_lt
  contrapose! h₂
  rw [Nat.eq_zero_of_le_zero h₂, zero_mul]
  exact zero_le _
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
this : Int.natAbs (↑i - ↑n) = n - i
⊢ Int.natAbs (↑i - ↑n) < n
[PROOFSTEP]
rw [this]
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
this : Int.natAbs (↑i - ↑n) = n - i
⊢ n - i < n
[PROOFSTEP]
apply tsub_lt_self hn.bot_lt
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
this : Int.natAbs (↑i - ↑n) = n - i
⊢ 0 < i
[PROOFSTEP]
contrapose! h₂
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
this : Int.natAbs (↑i - ↑n) = n - i
h₂ : i ≤ 0
⊢ i * 2 ≤ n
[PROOFSTEP]
rw [Nat.eq_zero_of_le_zero h₂, zero_mul]
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
this : Int.natAbs (↑i - ↑n) = n - i
h₂ : i ≤ 0
⊢ 0 ≤ n
[PROOFSTEP]
exact zero_le _
[GOAL]
case neg
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ Int.natAbs (↑i - ↑n) = n - i
[PROOFSTEP]
rw [← Int.natAbs_neg, neg_sub, Int.natAbs_eq_iff]
[GOAL]
case neg
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑n - ↑i = ↑(n - i) ∨ ↑n - ↑i = -↑(n - i)
[PROOFSTEP]
exact Or.inl (Int.ofNat_sub h.le).symm
[GOAL]
case intro.intro.intro.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑(if i * 2 ≤ n then ↑i else ↑i - ↑n) / ↑n * (2 * Real.pi)
[PROOFSTEP]
split_ifs with h₂
[GOAL]
case pos
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑↑i / ↑n * (2 * Real.pi)
[PROOFSTEP]
convert Complex.arg_cos_add_sin_mul_I _
[GOAL]
case h.e'_2.h.e'_1.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) = ↑(↑↑i / ↑n * (2 * Real.pi))
[PROOFSTEP]
push_cast
[GOAL]
case h.e'_2.h.e'_1.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) = ↑i / ↑n * (2 * ↑Real.pi)
[PROOFSTEP]
rfl
[GOAL]
case h.e'_2.h.e'_1.h.e'_6.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) = ↑(↑↑i / ↑n * (2 * Real.pi))
[PROOFSTEP]
push_cast
[GOAL]
case h.e'_2.h.e'_1.h.e'_6.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) = ↑i / ↑n * (2 * ↑Real.pi)
[PROOFSTEP]
rfl
[GOAL]
case pos.convert_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ ↑↑i / ↑n * (2 * Real.pi) ∈ Set.Ioc (-Real.pi) Real.pi
[PROOFSTEP]
field_simp [hn]
[GOAL]
case pos.convert_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ -Real.pi < ↑i * (2 * Real.pi) / ↑n ∧ ↑i * (2 * Real.pi) / ↑n ≤ Real.pi
[PROOFSTEP]
refine' ⟨(neg_lt_neg Real.pi_pos).trans_le _, _⟩
[GOAL]
case pos.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ -0 ≤ ↑i * (2 * Real.pi) / ↑n
[PROOFSTEP]
rw [neg_zero]
[GOAL]
case pos.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ 0 ≤ ↑i * (2 * Real.pi) / ↑n
[PROOFSTEP]
exact
  mul_nonneg (mul_nonneg i.cast_nonneg <| by simp [Real.pi_pos.le]) (by rw [inv_nonneg]; simp only [Nat.cast_nonneg])
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ 0 ≤ 2 * Real.pi
[PROOFSTEP]
simp [Real.pi_pos.le]
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ 0 ≤ (↑n)⁻¹
[PROOFSTEP]
rw [inv_nonneg]
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ 0 ≤ ↑n
[PROOFSTEP]
simp only [Nat.cast_nonneg]
[GOAL]
case pos.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ ↑i * (2 * Real.pi) / ↑n ≤ Real.pi
[PROOFSTEP]
rw [← mul_rotate', mul_div_assoc]
[GOAL]
case pos.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n
⊢ Real.pi * (↑i * 2 / ↑n) ≤ Real.pi
[PROOFSTEP]
rw [← mul_one n] at h₂
[GOAL]
case pos.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n * 1
⊢ Real.pi * (↑i * 2 / ↑n) ≤ Real.pi
[PROOFSTEP]
exact mul_le_of_le_one_right Real.pi_pos.le ((div_le_iff' <| by exact_mod_cast pos_of_gt h).mpr <| by exact_mod_cast h₂)
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n * 1
⊢ 0 < ↑n
[PROOFSTEP]
exact_mod_cast pos_of_gt h
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : i * 2 ≤ n * 1
⊢ ↑i * 2 ≤ ↑n * 1
[PROOFSTEP]
exact_mod_cast h₂
[GOAL]
case neg
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ Complex.arg (Complex.cos (↑i / ↑n * (2 * ↑Real.pi)) + Complex.sin (↑i / ↑n * (2 * ↑Real.pi)) * Complex.I) =
    ↑(↑i - ↑n) / ↑n * (2 * Real.pi)
[PROOFSTEP]
rw [← Complex.cos_sub_two_pi, ← Complex.sin_sub_two_pi]
[GOAL]
case neg
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ Complex.arg
      (Complex.cos (↑i / ↑n * (2 * ↑Real.pi) - 2 * ↑Real.pi) +
        Complex.sin (↑i / ↑n * (2 * ↑Real.pi) - 2 * ↑Real.pi) * Complex.I) =
    ↑(↑i - ↑n) / ↑n * (2 * Real.pi)
[PROOFSTEP]
convert Complex.arg_cos_add_sin_mul_I _
[GOAL]
case h.e'_2.h.e'_1.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) - 2 * ↑Real.pi = ↑(↑(↑i - ↑n) / ↑n * (2 * Real.pi))
[PROOFSTEP]
push_cast
[GOAL]
case h.e'_2.h.e'_1.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) - 2 * ↑Real.pi = (↑i - ↑n) / ↑n * (2 * ↑Real.pi)
[PROOFSTEP]
rw [← sub_one_mul, sub_div, div_self]
[GOAL]
case h.e'_2.h.e'_1.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑n ≠ 0
[PROOFSTEP]
exact_mod_cast hn
[GOAL]
case h.e'_2.h.e'_1.h.e'_6.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) - 2 * ↑Real.pi = ↑(↑(↑i - ↑n) / ↑n * (2 * Real.pi))
[PROOFSTEP]
push_cast
[GOAL]
case h.e'_2.h.e'_1.h.e'_6.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑i / ↑n * (2 * ↑Real.pi) - 2 * ↑Real.pi = (↑i - ↑n) / ↑n * (2 * ↑Real.pi)
[PROOFSTEP]
rw [← sub_one_mul, sub_div, div_self]
[GOAL]
case h.e'_2.h.e'_1.h.e'_6.h.e'_5.h.e'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑n ≠ 0
[PROOFSTEP]
exact_mod_cast hn
[GOAL]
case neg.convert_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑(↑i - ↑n) / ↑n * (2 * Real.pi) ∈ Set.Ioc (-Real.pi) Real.pi
[PROOFSTEP]
field_simp [hn]
[GOAL]
case neg.convert_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ -Real.pi < (↑i - ↑n) * (2 * Real.pi) / ↑n ∧ (↑i - ↑n) * (2 * Real.pi) / ↑n ≤ Real.pi
[PROOFSTEP]
refine' ⟨_, le_trans _ Real.pi_pos.le⟩
[GOAL]
case neg.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ -Real.pi < (↑i - ↑n) * (2 * Real.pi) / ↑n
case neg.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ (↑i - ↑n) * (2 * Real.pi) / ↑n ≤ 0
[PROOFSTEP]
on_goal 2 =>
  rw [mul_div_assoc]
  exact
    mul_nonpos_of_nonpos_of_nonneg (sub_nonpos.mpr <| by exact_mod_cast h.le)
      (div_nonneg (by simp [Real.pi_pos.le]) <| by simp)
[GOAL]
case neg.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ -Real.pi < (↑i - ↑n) * (2 * Real.pi) / ↑n
case neg.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ (↑i - ↑n) * (2 * Real.pi) / ↑n ≤ 0
[PROOFSTEP]
on_goal 2 =>
  rw [mul_div_assoc]
  exact
    mul_nonpos_of_nonpos_of_nonneg (sub_nonpos.mpr <| by exact_mod_cast h.le)
      (div_nonneg (by simp [Real.pi_pos.le]) <| by simp)
[GOAL]
case neg.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ (↑i - ↑n) * (2 * Real.pi) / ↑n ≤ 0
[PROOFSTEP]
rw [mul_div_assoc]
[GOAL]
case neg.convert_2.refine'_2
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ (↑i - ↑n) * (2 * Real.pi / ↑n) ≤ 0
[PROOFSTEP]
exact
  mul_nonpos_of_nonpos_of_nonneg (sub_nonpos.mpr <| by exact_mod_cast h.le)
    (div_nonneg (by simp [Real.pi_pos.le]) <| by simp)
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑i ≤ ↑n
[PROOFSTEP]
exact_mod_cast h.le
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ 0 ≤ 2 * Real.pi
[PROOFSTEP]
simp [Real.pi_pos.le]
[GOAL]
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ 0 ≤ ↑n
[PROOFSTEP]
simp
[GOAL]
case neg.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ -Real.pi < (↑i - ↑n) * (2 * Real.pi) / ↑n
[PROOFSTEP]
rw [← mul_rotate', mul_div_assoc, neg_lt, ← mul_neg, mul_lt_iff_lt_one_right Real.pi_pos, ← neg_div, ← neg_mul, neg_sub,
  div_lt_iff, one_mul, sub_mul, sub_lt_comm, ← mul_sub_one]
[GOAL]
case neg.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑n * (2 - 1) < ↑i * 2
case neg.convert_2.refine'_1 n : ℕ hn : n ≠ 0 i : ℕ h : i < n hin : Nat.coprime i n h₂ : ¬i * 2 ≤ n ⊢ 0 < ↑n
[PROOFSTEP]
norm_num
[GOAL]
case neg.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ ↑n < ↑i * 2
case neg.convert_2.refine'_1 n : ℕ hn : n ≠ 0 i : ℕ h : i < n hin : Nat.coprime i n h₂ : ¬i * 2 ≤ n ⊢ 0 < ↑n
[PROOFSTEP]
exact_mod_cast not_le.mp h₂
[GOAL]
case neg.convert_2.refine'_1
n : ℕ
hn : n ≠ 0
i : ℕ
h : i < n
hin : Nat.coprime i n
h₂ : ¬i * 2 ≤ n
⊢ 0 < ↑n
[PROOFSTEP]
exact Nat.cast_pos.mpr hn.bot_lt


[GOAL]
α : Type u_1
β : Type u_2
f : α → β
inst✝¹ : Preorder α
inst✝ : Preorder β
a b : α
h : Monotone f
x✝¹ : α
x✝ : x✝¹ ∈ Icc a b
⊢ f x✝¹ ∈ Icc (f a) (f b)
[PROOFSTEP]
aesop
[GOAL]
α : Type u_1
β : Type u_2
f : α → β
inst✝¹ : Preorder α
inst✝ : Preorder β
a b : α
h : StrictMono f
x✝¹ : α
x✝ : x✝¹ ∈ Ioo a b
⊢ f x✝¹ ∈ Ioo (f a) (f b)
[PROOFSTEP]
aesop
[GOAL]
α : Type u_1
β : Type u_2
f : α → β
inst✝¹ : Preorder α
inst✝ : Preorder β
a : α
h : Monotone f
x✝¹ : α
x✝ : x✝¹ ∈ Ici a
⊢ f x✝¹ ∈ Ici (f a)
[PROOFSTEP]
aesop
[GOAL]
α : Type u_1
β : Type u_2
f : α → β
inst✝¹ : Preorder α
inst✝ : Preorder β
a : α
h : Monotone f
x✝¹ : α
x✝ : x✝¹ ∈ Iic a
⊢ f x✝¹ ∈ Iic (f a)
[PROOFSTEP]
aesop
[GOAL]
α : Type u_1
β : Type u_2
f : α → β
inst✝¹ : Preorder α
inst✝ : Preorder β
a : α
h : StrictMono f
x✝¹ : α
x✝ : x✝¹ ∈ Ioi a
⊢ f x✝¹ ∈ Ioi (f a)
[PROOFSTEP]
aesop
[GOAL]
α : Type u_1
β : Type u_2
f : α → β
inst✝¹ : Preorder α
inst✝ : Preorder β
a : α
h : StrictMono f
x✝¹ : α
x✝ : x✝¹ ∈ Iio a
⊢ f x✝¹ ∈ Iio (f a)
[PROOFSTEP]
aesop