l3lab/ntp-mathlib huggingface dataset:
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := 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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
⊢ orderOf μ' = ↑n

Next tactic:
rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      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✝³ : CommRing S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
⊢ (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1

Next tactic:
dsimp only
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
⊢ ↑(Exists.choose (_ : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m)) = 1

Next tactic:
generalize_proofs h1
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
h1 : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
⊢ ↑(Exists.choose h1) = 1

Next tactic:
have h := h1.choose_spec
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
h1 : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
h : ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h1
⊢ ↑(Exists.choose h1) = 1

Next tactic:
dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf (toRootsOfUnity hμ) = ↑n
h1 : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
h : ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h1
⊢ ↑(Exists.choose h1) = 1

Next tactic:
replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf (toRootsOfUnity hμ) = ↑n
h1 : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
h : ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h1
⊢ (fun x => ↑↑x) μ' = (fun x => ↑↑x) (μ' ^ Exists.choose h1)

Next tactic:
simpa only [rootsOfUnity.coe_pow] using h
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf (toRootsOfUnity hμ) = ↑n
h1 : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
h : μ' = μ' ^ Exists.choose h1
⊢ ↑(Exists.choose h1) = 1

Next tactic:
nth_rw 1 [← pow_one μ'] at h
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf (toRootsOfUnity hμ) = ↑n
h1 : ∃ m, ↑1 ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
h : μ' ^ 1 = μ' ^ Exists.choose h1
⊢ ↑(Exists.choose h1) = 1

Next tactic:
rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := 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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
⊢ ∀ (x y : S ≃ₐ[R] S),
    OneHom.toFun
        { toFun := fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m)),
          map_one' := (_ : (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1) }
        (x * y) =
      OneHom.toFun
          { toFun := fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m)),
            map_one' := (_ : (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1) }
          x *
        OneHom.toFun
          { toFun := fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m)),
            map_one' := (_ : (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1) }
          y

Next tactic:
intro x y
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := by
        intro x y
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
x y : S ≃ₐ[R] S
⊢ OneHom.toFun
      { toFun := fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m)),
        map_one' := (_ : (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1) }
      (x * y) =
    OneHom.toFun
        { toFun := fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m)),
          map_one' := (_ : (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1) }
        x *
      OneHom.toFun
        { toFun := fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m)),
          map_one' := (_ : (fun σ => ↑(Exists.choose (_ : ∃ m, ↑σ ↑↑μ' = ↑↑μ' ^ m))) 1 = 1) }
        y

Next tactic:
dsimp only
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := by
        intro x y
        dsimp only
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
x y : S ≃ₐ[R] S
⊢ ↑(Exists.choose (_ : ∃ m, ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m)) =
    ↑(Exists.choose (_ : ∃ m, ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m)) *
      ↑(Exists.choose (_ : ∃ m, ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m))

Next tactic:
generalize_proofs hxy' hx' hy'
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := by
        intro x y
        dsimp only
        generalize_proofs hxy' hx' hy'
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
x y : S ≃ₐ[R] S
hxy' : ∃ m, ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hx' : ∃ m, ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hy' : ∃ m, ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
have hxy := hxy'.choose_spec
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := by
        intro x y
        dsimp only
        generalize_proofs hxy' hx' hy'
        have hxy := hxy'.choose_spec
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
x y : S ≃ₐ[R] S
hxy' : ∃ m, ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hx' : ∃ m, ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hy' : ∃ m, ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hxy : ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hxy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
have hx := hx'.choose_spec
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := by
        intro x y
        dsimp only
        generalize_proofs hxy' hx' hy'
        have hxy := hxy'.choose_spec
        have hx := hx'.choose_spec
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
x y : S ≃ₐ[R] S
hxy' : ∃ m, ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hx' : ∃ m, ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hy' : ∃ m, ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hxy : ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hxy'
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
have hy := hy'.choose_spec
/-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ :=
  let μ' := hμ.toRootsOfUnity
  have ho : orderOf μ' = n := by
    rw [hμ.eq_orderOf, ← hμ.val_toRootsOfUnity_coe, orderOf_units, Subgroup.orderOf_coe]
  MonoidHom.toHomUnits
    { toFun := fun σ => (map_rootsOfUnity_eq_pow_self σ.toAlgHom μ').choose
      map_one' := by
        dsimp only
        generalize_proofs h1
        have h := h1.choose_spec
        dsimp only [AlgEquiv.one_apply, AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv] at *
        replace h : μ' = μ' ^ h1.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using h)
        nth_rw 1 [← pow_one μ'] at h
        rw [← Nat.cast_one, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, h]
      map_mul' := by
        intro x y
        dsimp only
        generalize_proofs hxy' hx' hy'
        have hxy := hxy'.choose_spec
        have hx := hx'.choose_spec
        have hy := hy'.choose_spec
        

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 S
inst✝² : IsDomain S
μ : S
n : ℕ+
hμ : IsPrimitiveRoot μ ↑n
inst✝¹ : CommRing R
inst✝ : Algebra R S
μ' : ↥(rootsOfUnity n S) := toRootsOfUnity hμ
ho : orderOf μ' = ↑n
x y : S ≃ₐ[R] S
hxy' : ∃ m, ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hx' : ∃ m, ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hy' : ∃ m, ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
hxy : ↑(x * y) ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hxy'
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *