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
    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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] 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
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:
replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
/-- 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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
        replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
        

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
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
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
hxy : x (↑↑μ' ^ Exists.choose hy') = ↑↑μ' ^ Exists.choose hxy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
rw [x.map_pow] at hxy
/-- 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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
        replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
        rw [x.map_pow] at hxy
        

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
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
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
hxy : x ↑↑μ' ^ Exists.choose hy' = ↑↑μ' ^ Exists.choose hxy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
replace hxy : (((μ' : Sˣ) : S) ^ hx'.choose) ^ hy'.choose = ((μ' : Sˣ) : S) ^ hxy'.choose :=
          hx ▸ hxy
/-- 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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
        replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
        rw [x.map_pow] at hxy
        replace hxy : (((μ' : Sˣ) : S) ^ hx'.choose) ^ hy'.choose = ((μ' : Sˣ) : S) ^ hxy'.choose :=
          hx ▸ hxy
        

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
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
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
hxy : (↑↑μ' ^ Exists.choose hx') ^ Exists.choose hy' = ↑↑μ' ^ Exists.choose hxy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
rw [← pow_mul] at hxy
/-- 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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
        replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
        rw [x.map_pow] at hxy
        replace hxy : (((μ' : Sˣ) : S) ^ hx'.choose) ^ hy'.choose = ((μ' : Sˣ) : S) ^ hxy'.choose :=
          hx ▸ hxy
        rw [← pow_mul] at hxy
        

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
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
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
hxy : ↑↑μ' ^ (Exists.choose hx' * Exists.choose hy') = ↑↑μ' ^ Exists.choose hxy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
replace hxy : μ' ^ (hx'.choose * hy'.choose) = μ' ^ hxy'.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
/-- 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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
        replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
        rw [x.map_pow] at hxy
        replace hxy : (((μ' : Sˣ) : S) ^ hx'.choose) ^ hy'.choose = ((μ' : Sˣ) : S) ^ hxy'.choose :=
          hx ▸ hxy
        rw [← pow_mul] at hxy
        replace hxy : μ' ^ (hx'.choose * hy'.choose) = μ' ^ hxy'.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
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
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
hxy : ↑↑μ' ^ (Exists.choose hx' * Exists.choose hy') = ↑↑μ' ^ Exists.choose hxy'
⊢ (fun x => ↑↑x) (μ' ^ (Exists.choose hx' * Exists.choose hy')) = (fun x => ↑↑x) (μ' ^ Exists.choose hxy')

Next tactic:
simpa only [rootsOfUnity.coe_pow] using hxy
/-- 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
        dsimp only [AlgEquiv.toRingEquiv_eq_coe, RingEquiv.toRingHom_eq_coe,
          RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.mul_apply] at *
        replace hxy : x (((μ' : Sˣ) : S) ^ hy'.choose) = ((μ' : Sˣ) : S) ^ hxy'.choose := hy ▸ hxy
        rw [x.map_pow] at hxy
        replace hxy : (((μ' : Sˣ) : S) ^ hx'.choose) ^ hy'.choose = ((μ' : Sˣ) : S) ^ hxy'.choose :=
          hx ▸ hxy
        rw [← pow_mul] at hxy
        replace hxy : μ' ^ (hx'.choose * hy'.choose) = μ' ^ hxy'.choose :=
          rootsOfUnity.coe_injective (by simpa only [rootsOfUnity.coe_pow] using hxy)
        

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
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
hx : ↑x ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hx'
hy : ↑y ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose hy'
hxy : μ' ^ (Exists.choose hx' * Exists.choose hy') = μ' ^ Exists.choose hxy'
⊢ ↑(Exists.choose hxy') = ↑(Exists.choose hx') * ↑(Exists.choose hy')

Next tactic:
rw [← Nat.cast_mul, ZMod.nat_cast_eq_nat_cast_iff, ← ho, ← pow_eq_pow_iff_modEq, hxy]
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := 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
f : S ≃ₐ[R] S
⊢ μ ^ ZMod.val ↑((autToPow R hμ) f) = f μ

Next tactic:
rw [IsPrimitiveRoot.coe_autToPow_apply]
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  

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
f : S ≃ₐ[R] S
⊢ μ ^ ZMod.val ↑(Exists.choose (_ : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m)) = f μ

Next tactic:
generalize_proofs h
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  generalize_proofs 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
f : S ≃ₐ[R] S
h : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
⊢ μ ^ ZMod.val ↑(Exists.choose h) = f μ

Next tactic:
have := h.choose_spec
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  generalize_proofs h
  have := h.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
f : S ≃ₐ[R] S
h : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
this : f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h
⊢ μ ^ ZMod.val ↑(Exists.choose h) = f μ

Next tactic:
refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  generalize_proofs h
  have := h.choose_spec
  refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
  

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
f : S ≃ₐ[R] S
h : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
this : f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h
⊢ ↑↑(toRootsOfUnity hμ) ^ ZMod.val ↑(Exists.choose h) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h

Next tactic:
rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  generalize_proofs h
  have := h.choose_spec
  refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
  rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
  

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
f : S ≃ₐ[R] S
h : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
this : f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h
⊢ ↑↑(toRootsOfUnity hμ ^ ZMod.val ↑(Exists.choose h)) = ↑↑(toRootsOfUnity hμ ^ Exists.choose h)

Next tactic:
congr 2
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  generalize_proofs h
  have := h.choose_spec
  refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
  rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
  congr 2
  

Proof state:
case e_self.e_self
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
f : S ≃ₐ[R] S
h : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
this : f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h
⊢ toRootsOfUnity hμ ^ ZMod.val ↑(Exists.choose h) = toRootsOfUnity hμ ^ Exists.choose h

Next tactic:
rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ← Subgroup.orderOf_coe,
    ← orderOf_units]
@[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ := by
  rw [IsPrimitiveRoot.coe_autToPow_apply]
  generalize_proofs h
  have := h.choose_spec
  refine' (_ : ((hμ.toRootsOfUnity : Sˣ) : S) ^ _ = _).trans this.symm
  rw [← rootsOfUnity.coe_pow, ← rootsOfUnity.coe_pow]
  congr 2
  rw [pow_eq_pow_iff_modEq, ZMod.val_nat_cast, hμ.eq_orderOf, ← Subgroup.orderOf_coe,
    ← orderOf_units]
  

Proof state:
case e_self.e_self
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
f : S ≃ₐ[R] S
h : ∃ m, f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ m
this : f ↑↑(toRootsOfUnity hμ) = ↑↑(toRootsOfUnity hμ) ^ Exists.choose h
⊢ Exists.choose h % orderOf μ ≡ Exists.choose h [MOD orderOf ↑↑(toRootsOfUnity hμ)]

Next tactic:
exact Nat.mod_modEq _ _
instance : ConcreteCategory ωCPO := by 

Proof state:
⊢ ConcreteCategory ωCPO

Next tactic:
unfold ωCPO
instance : ConcreteCategory ωCPO := by unfold ωCPO; 

Proof state:
⊢ ConcreteCategory (Bundled OmegaCompletePartialOrder)

Next tactic:
infer_instance