l3lab/ntp-mathlib huggingface dataset:
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; 

Proof state:
case a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
ξ : ↥(rootsOfUnity n R)
⊢ ↑(unitOfInvertible (σ ↑↑ξ) ^ ↑n) = ↑1

Next tactic:
rw [Units.val_pow_eq_pow_val]
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; rw [Units.val_pow_eq_pow_val]; 

Proof state:
case a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
ξ : ↥(rootsOfUnity n R)
⊢ ↑(unitOfInvertible (σ ↑↑ξ)) ^ ↑n = ↑1

Next tactic:
exact h ξ
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; rw [Units.val_pow_eq_pow_val]; exact h ξ⟩
    map_one' := by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
⊢ (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1 = 1

Next tactic:
ext
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; rw [Units.val_pow_eq_pow_val]; exact h ξ⟩
    map_one' := by ext; 

Proof state:
case a.a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
⊢ ↑↑((fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1) = ↑↑1

Next tactic:
exact map_one σ
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; rw [Units.val_pow_eq_pow_val]; exact h ξ⟩
    map_one' := by ext; exact map_one σ
    map_mul' := fun ξ₁ ξ₂ => by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
ξ₁ ξ₂ : ↥(rootsOfUnity n R)
⊢ OneHom.toFun
      { toFun := fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
        map_one' :=
          (_ :
            (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1 = 1) }
      (ξ₁ * ξ₂) =
    OneHom.toFun
        { toFun := fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
          map_one' :=
            (_ :
              (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1 =
                1) }
        ξ₁ *
      OneHom.toFun
        { toFun := fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
          map_one' :=
            (_ :
              (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1 =
                1) }
        ξ₂

Next tactic:
ext
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; rw [Units.val_pow_eq_pow_val]; exact h ξ⟩
    map_one' := by ext; exact map_one σ
    map_mul' := fun ξ₁ ξ₂ => by ext; 

Proof state:
case a.a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
ξ₁ ξ₂ : ↥(rootsOfUnity n R)
⊢ ↑↑(OneHom.toFun
          { toFun := fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
            map_one' :=
              (_ :
                (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1 =
                  1) }
          (ξ₁ * ξ₂)) =
    ↑↑(OneHom.toFun
            {
              toFun := fun ξ =>
                { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
              map_one' :=
                (_ :
                  (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) })
                      1 =
                    1) }
            ξ₁ *
          OneHom.toFun
            {
              toFun := fun ξ =>
                { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
              map_one' :=
                (_ :
                  (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) })
                      1 =
                    1) }
            ξ₂)

Next tactic:
rw [Subgroup.coe_mul, Units.val_mul]
/-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [RingHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S :=
  let h : ∀ ξ : rootsOfUnity n R, (σ (ξ : Rˣ)) ^ (n : ℕ) = 1 := fun ξ => by
    rw [← map_pow, ← Units.val_pow_eq_pow_val, show (ξ : Rˣ) ^ (n : ℕ) = 1 from ξ.2, Units.val_one,
      map_one σ]
  { toFun := fun ξ =>
      ⟨@unitOfInvertible _ _ _ (invertibleOfPowEqOne _ _ (h ξ) n.ne_zero), by
        ext; rw [Units.val_pow_eq_pow_val]; exact h ξ⟩
    map_one' := by ext; exact map_one σ
    map_mul' := fun ξ₁ ξ₂ => by ext; rw [Subgroup.coe_mul, Units.val_mul]; 

Proof state:
case a.a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁵ : CommMonoid M
inst✝⁴ : CommMonoid N
inst✝³ : DivisionCommMonoid G
k l : ℕ+
inst✝² : CommSemiring R
inst✝¹ : CommSemiring S
inst✝ : RingHomClass F R S
σ : F
n : ℕ+
h : ∀ (ξ : ↥(rootsOfUnity n R)), σ ↑↑ξ ^ ↑n = 1 :=
  fun ξ =>
    Eq.mpr (id ((map_pow σ ↑↑ξ ↑n).symm ▸ Eq.refl (σ ↑↑ξ ^ ↑n = 1)))
      (Eq.mpr (id ((Units.val_pow_eq_pow_val ↑ξ ↑n).symm ▸ Eq.refl (σ (↑↑ξ ^ ↑n) = 1)))
        (Eq.mpr
          (id
            ((let_fun this := ξ.property;
              this) ▸
              Eq.refl (σ ↑(↑ξ ^ ↑n) = 1)))
          (Eq.mpr (id (Units.val_one ▸ Eq.refl (σ ↑1 = 1))) (Eq.mpr (id (map_one σ ▸ Eq.refl (σ 1 = 1))) (Eq.refl 1)))))
ξ₁ ξ₂ : ↥(rootsOfUnity n R)
⊢ ↑↑(OneHom.toFun
          { toFun := fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
            map_one' :=
              (_ :
                (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) }) 1 =
                  1) }
          (ξ₁ * ξ₂)) =
    ↑↑(OneHom.toFun
            {
              toFun := fun ξ =>
                { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
              map_one' :=
                (_ :
                  (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) })
                      1 =
                    1) }
            ξ₁) *
      ↑↑(OneHom.toFun
            {
              toFun := fun ξ =>
                { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) },
              map_one' :=
                (_ :
                  (fun ξ => { val := unitOfInvertible (σ ↑↑ξ), property := (_ : unitOfInvertible (σ ↑↑ξ) ^ ↑n = 1) })
                      1 =
                    1) }
            ξ₂)

Next tactic:
exact map_mul σ _ _
/-- Restrict a ring isomorphism to the nth roots of unity. -/
nonrec def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) :
    rootsOfUnity n R ≃* rootsOfUnity n S where
  toFun := restrictRootsOfUnity σ.toRingHom n
  invFun := restrictRootsOfUnity σ.symm.toRingHom n
  left_inv ξ := by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S
σ : R ≃+* S
n : ℕ+
ξ : ↥(rootsOfUnity n R)
⊢ (_root_.restrictRootsOfUnity (toRingHom (RingEquiv.symm σ)) n) ((_root_.restrictRootsOfUnity (toRingHom σ) n) ξ) = ξ

Next tactic:
ext
/-- Restrict a ring isomorphism to the nth roots of unity. -/
nonrec def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) :
    rootsOfUnity n R ≃* rootsOfUnity n S where
  toFun := restrictRootsOfUnity σ.toRingHom n
  invFun := restrictRootsOfUnity σ.symm.toRingHom n
  left_inv ξ := by ext; 

Proof state:
case a.a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S
σ : R ≃+* S
n : ℕ+
ξ : ↥(rootsOfUnity n R)
⊢ ↑↑((_root_.restrictRootsOfUnity (toRingHom (RingEquiv.symm σ)) n) ((_root_.restrictRootsOfUnity (toRingHom σ) n) ξ)) =
    ↑↑ξ

Next tactic:
exact σ.symm_apply_apply (ξ : Rˣ)
/-- Restrict a ring isomorphism to the nth roots of unity. -/
nonrec def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) :
    rootsOfUnity n R ≃* rootsOfUnity n S where
  toFun := restrictRootsOfUnity σ.toRingHom n
  invFun := restrictRootsOfUnity σ.symm.toRingHom n
  left_inv ξ := by ext; exact σ.symm_apply_apply (ξ : Rˣ)
  right_inv ξ := by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S
σ : R ≃+* S
n : ℕ+
ξ : ↥(rootsOfUnity n S)
⊢ (_root_.restrictRootsOfUnity (toRingHom σ) n) ((_root_.restrictRootsOfUnity (toRingHom (RingEquiv.symm σ)) n) ξ) = ξ

Next tactic:
ext
/-- Restrict a ring isomorphism to the nth roots of unity. -/
nonrec def RingEquiv.restrictRootsOfUnity (σ : R ≃+* S) (n : ℕ+) :
    rootsOfUnity n R ≃* rootsOfUnity n S where
  toFun := restrictRootsOfUnity σ.toRingHom n
  invFun := restrictRootsOfUnity σ.symm.toRingHom n
  left_inv ξ := by ext; exact σ.symm_apply_apply (ξ : Rˣ)
  right_inv ξ := by ext; 

Proof state:
case a.a
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S
σ : R ≃+* S
n : ℕ+
ξ : ↥(rootsOfUnity n S)
⊢ ↑↑((_root_.restrictRootsOfUnity (toRingHom σ) n) ((_root_.restrictRootsOfUnity (toRingHom (RingEquiv.symm σ)) n) ξ)) =
    ↑↑ξ

Next tactic:
exact σ.apply_symm_apply (ξ : Sˣ)
theorem mem_rootsOfUnity_iff_mem_nthRoots {ζ : Rˣ} :
    ζ ∈ rootsOfUnity k R ↔ (ζ : R) ∈ nthRoots k (1 : R) := by
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
ζ : Rˣ
⊢ ζ ∈ rootsOfUnity k R ↔ ↑ζ ∈ nthRoots (↑k) 1

Next tactic:
simp only [mem_rootsOfUnity, mem_nthRoots k.pos, Units.ext_iff, Units.val_one,
    Units.val_pow_eq_pow_val]
/-- Equivalence between the `k`-th roots of unity in `R` and the `k`-th roots of `1`.

This is implemented as equivalence of subtypes,
because `rootsOfUnity` is a subgroup of the group of units,
whereas `nthRoots` is a multiset. -/
def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1 : R) } := by
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ ↥(rootsOfUnity k R) ≃ { x // x ∈ nthRoots (↑k) 1 }

Next tactic:
refine'
    { toFun := fun x => ⟨(x : Rˣ), mem_rootsOfUnity_iff_mem_nthRoots.mp x.2⟩
      invFun := fun x => ⟨⟨x, ↑x ^ (k - 1 : ℕ), _, _⟩, _⟩
      left_inv := _
      right_inv := _ }
/-- Equivalence between the `k`-th roots of unity in `R` and the `k`-th roots of `1`.

This is implemented as equivalence of subtypes,
because `rootsOfUnity` is a subgroup of the group of units,
whereas `nthRoots` is a multiset. -/
def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1 : R) } := by
  refine'
    { toFun := fun x => ⟨(x : Rˣ), mem_rootsOfUnity_iff_mem_nthRoots.mp x.2⟩
      invFun := fun x => ⟨⟨x, ↑x ^ (k - 1 : ℕ), _, _⟩, _⟩
      left_inv := _
      right_inv := _ }
  

Proof state:
case refine'_1
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
x : { x // x ∈ nthRoots (↑k) 1 }
⊢ ↑x * ↑x ^ (↑k - 1) = 1
case refine'_2
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
x : { x // x ∈ nthRoots (↑k) 1 }
⊢ ↑x ^ (↑k - 1) * ↑x = 1
case refine'_3
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
x : { x // x ∈ nthRoots (↑k) 1 }
⊢ { val := ↑x, inv := ↑x ^ (↑k - 1), val_inv := ?refine'_1, inv_val := ?refine'_2 } ∈ rootsOfUnity k R
case refine'_4
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ Function.LeftInverse
    (fun x =>
      {
        val :=
          { val := ↑x, inv := ↑x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661189 x ^ (↑k - 1) = 1),
            inv_val := (_ : ?m.661191 x ^ (↑k - 1) * ↑x = 1) },
        property :=
          (_ :
            { val := ↑x, inv := ?m.661193 x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661194 x ^ (↑k - 1) = 1),
                inv_val := (_ : ?m.661196 x ^ (↑k - 1) * ↑x = 1) } ∈
              rootsOfUnity k R) })
    fun x => { val := ↑↑x, property := (_ : ↑↑x ∈ nthRoots (↑k) 1) }
case refine'_5
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ Function.RightInverse
    (fun x =>
      {
        val :=
          { val := ↑x, inv := ↑x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661189 x ^ (↑k - 1) = 1),
            inv_val := (_ : ?m.661191 x ^ (↑k - 1) * ↑x = 1) },
        property :=
          (_ :
            { val := ↑x, inv := ?m.661193 x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661194 x ^ (↑k - 1) = 1),
                inv_val := (_ : ?m.661196 x ^ (↑k - 1) * ↑x = 1) } ∈
              rootsOfUnity k R) })
    fun x => { val := ↑↑x, property := (_ : ↑↑x ∈ nthRoots (↑k) 1) }

Next tactic:
pick_goal 4
/-- Equivalence between the `k`-th roots of unity in `R` and the `k`-th roots of `1`.

This is implemented as equivalence of subtypes,
because `rootsOfUnity` is a subgroup of the group of units,
whereas `nthRoots` is a multiset. -/
def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1 : R) } := by
  refine'
    { toFun := fun x => ⟨(x : Rˣ), mem_rootsOfUnity_iff_mem_nthRoots.mp x.2⟩
      invFun := fun x => ⟨⟨x, ↑x ^ (k - 1 : ℕ), _, _⟩, _⟩
      left_inv := _
      right_inv := _ }
  pick_goal 4; · 

Proof state:
case refine'_4
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
⊢ Function.LeftInverse
    (fun x =>
      {
        val :=
          { val := ↑x, inv := ↑x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661189 x ^ (↑k - 1) = 1),
            inv_val := (_ : ?m.661191 x ^ (↑k - 1) * ↑x = 1) },
        property :=
          (_ :
            { val := ↑x, inv := ?m.661193 x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661194 x ^ (↑k - 1) = 1),
                inv_val := (_ : ?m.661196 x ^ (↑k - 1) * ↑x = 1) } ∈
              rootsOfUnity k R) })
    fun x => { val := ↑↑x, property := (_ : ↑↑x ∈ nthRoots (↑k) 1) }

Next tactic:
rintro ⟨x, hx⟩
/-- Equivalence between the `k`-th roots of unity in `R` and the `k`-th roots of `1`.

This is implemented as equivalence of subtypes,
because `rootsOfUnity` is a subgroup of the group of units,
whereas `nthRoots` is a multiset. -/
def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1 : R) } := by
  refine'
    { toFun := fun x => ⟨(x : Rˣ), mem_rootsOfUnity_iff_mem_nthRoots.mp x.2⟩
      invFun := fun x => ⟨⟨x, ↑x ^ (k - 1 : ℕ), _, _⟩, _⟩
      left_inv := _
      right_inv := _ }
  pick_goal 4; · rintro ⟨x, hx⟩; 

Proof state:
case refine'_4.mk
M : Type u_1
N : Type u_2
G : Type u_3
R : Type u_4
S : Type u_5
F : Type u_6
inst✝⁴ : CommMonoid M
inst✝³ : CommMonoid N
inst✝² : DivisionCommMonoid G
k l : ℕ+
inst✝¹ : CommRing R
inst✝ : IsDomain R
x : Rˣ
hx : x ∈ rootsOfUnity k R
⊢ (fun x =>
        {
          val :=
            { val := ↑x, inv := ↑x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661189 x ^ (↑k - 1) = 1),
              inv_val := (_ : ?m.661191 x ^ (↑k - 1) * ↑x = 1) },
          property :=
            (_ :
              { val := ↑x, inv := ?m.661193 x ^ (↑k - 1), val_inv := (_ : ↑x * ?m.661194 x ^ (↑k - 1) = 1),
                  inv_val := (_ : ?m.661196 x ^ (↑k - 1) * ↑x = 1) } ∈
                rootsOfUnity k R) })
      ((fun x => { val := ↑↑x, property := (_ : ↑↑x ∈ nthRoots (↑k) 1) }) { val := x, property := hx }) =
    { val := x, property := hx }

Next tactic:
ext