File: Mathlib/Data/ZMod/Basic.lean

full_name: ZMod.charZero
code: instance charZero : CharZero (ZMod 0) 
goal: CharZero (ZMod 0)

full_name: ZMod.val
code: /-- `val a` is a natural number defined as:
  - for `a : ZMod 0` it is the absolute value of `a`
  - for `a : ZMod n` with `0 < n` it is the least natural number in the equivalence class

See `ZMod.valMinAbs` for a variant that takes values in the integers.
-/
def val : ∀ {n : ℕ}, ZMod n → ℕ
  
goal: ZMod n → ℕ

full_name: ZMod.val_lt
code: theorem val_lt {n : ℕ} [NeZero n] (a : ZMod n) : a.val < n 
goal: a.val < n

full_name: ZMod.val_le
code: theorem val_le {n : ℕ} [NeZero n] (a : ZMod n) : a.val ≤ n 
goal: a.val ≤ n

full_name: ZMod.val_zero
code: @[simp]
theorem val_zero : ∀ {n}, (0 : ZMod n).val = 0
  
goal: ZMod.val 0 = 0

full_name: ZMod.val_one'
code: @[simp]
theorem val_one' : (1 : ZMod 0).val = 1 
goal: ZMod.val 1 = 1

full_name: ZMod.val_neg'
code: @[simp]
theorem val_neg' {n : ZMod 0} : (-n).val = n.val 
goal: (-n).val = n.val

full_name: ZMod.val_mul'
code: @[simp]
theorem val_mul' {m n : ZMod 0} : (m * n).val = m.val * n.val 
goal: (m * n).val = m.val * n.val

full_name: ZMod.val_natCast
code: @[simp]
theorem val_natCast {n : ℕ} (a : ℕ) : (a : ZMod n).val = a % n 
goal: (↑a).val = a % n

full_name: ZMod.val_unit'
code: theorem val_unit' {n : ZMod 0} : IsUnit n ↔ n.val = 1 
goal: IsUnit n ↔ n.val = 1

full_name: ZMod.eq_one_of_isUnit_natCast
code: lemma eq_one_of_isUnit_natCast {n : ℕ} (h : IsUnit (n : ZMod 0)) : n = 1 
goal: n = 1

full_name: ZMod.val_natCast_of_lt
code: theorem val_natCast_of_lt {n a : ℕ} (h : a < n) : (a : ZMod n).val = a 
goal: (↑a).val = a

full_name: ZMod.charP
code: instance charP (n : ℕ) : CharP (ZMod n) n 
goal: CharP (ZMod n) n

full_name: ZMod.addOrderOf_one
code: @[simp]
theorem addOrderOf_one (n : ℕ) : addOrderOf (1 : ZMod n) = n 
goal: addOrderOf 1 = n

full_name: ZMod.addOrderOf_coe
code: /-- This lemma works in the case in which `ZMod n` is not infinite, i.e. `n ≠ 0`.  The version
where `a ≠ 0` is `addOrderOf_coe'`. -/
@[simp]
theorem addOrderOf_coe (a : ℕ) {n : ℕ} (n0 : n ≠ 0) : addOrderOf (a : ZMod n) = n / n.gcd a 
goal: addOrderOf ↑a = n / n.gcd a

full_name: ZMod.addOrderOf_coe'
code: /-- This lemma works in the case in which `a ≠ 0`.  The version where
 `ZMod n` is not infinite, i.e. `n ≠ 0`, is `addOrderOf_coe`. -/
@[simp]
theorem addOrderOf_coe' {a : ℕ} (n : ℕ) (a0 : a ≠ 0) : addOrderOf (a : ZMod n) = n / n.gcd a 
goal: addOrderOf ↑a = n / n.gcd a

full_name: ZMod.ringChar_zmod_n
code: /-- We have that `ringChar (ZMod n) = n`. -/
theorem ringChar_zmod_n (n : ℕ) : ringChar (ZMod n) = n 
goal: ringChar (ZMod n) = n

full_name: ZMod.natCast_self
code: theorem natCast_self (n : ℕ) : (n : ZMod n) = 0 
goal: ↑n = 0

full_name: ZMod.natCast_self'
code: @[simp]
theorem natCast_self' (n : ℕ) : (n + 1 : ZMod (n + 1)) = 0 
goal: ↑n + 1 = 0

full_name: ZMod.cast
code: /-- Cast an integer modulo `n` to another semiring.
This function is a morphism if the characteristic of `R` divides `n`.
See `ZMod.castHom` for a bundled version. -/
def cast : ∀ {n : ℕ}, ZMod n → R
  
goal: ZMod n → R

full_name: ZMod.cast_zero
code: @[simp]
theorem cast_zero : (cast (0 : ZMod n) : R) = 0 
goal: ZMod.cast 0 = 0

full_name: ZMod.cast_eq_val
code: theorem cast_eq_val [NeZero n] (a : ZMod n) : (cast a : R) = a.val 
goal: a.cast = ↑a.val

full_name: Prod.fst_zmod_cast
code: @[simp]
theorem _root_.Prod.fst_zmod_cast (a : ZMod n) : (cast a : R × S).fst = cast a 
goal: a.cast.1 = a.cast

full_name: Prod.snd_zmod_cast
code: @[simp]
theorem _root_.Prod.snd_zmod_cast (a : ZMod n) : (cast a : R × S).snd = cast a 
goal: a.cast.2 = a.cast

full_name: ZMod.natCast_zmod_val
code: /-- So-named because the coercion is `Nat.cast` into `ZMod`. For `Nat.cast` into an arbitrary ring,
see `ZMod.natCast_val`. -/
theorem natCast_zmod_val {n : ℕ} [NeZero n] (a : ZMod n) : (a.val : ZMod n) = a 
goal: ↑a.val = a

full_name: ZMod.natCast_rightInverse
code: theorem natCast_rightInverse [NeZero n] : Function.RightInverse val ((↑) : ℕ → ZMod n) 
goal: Function.RightInverse ZMod.val Nat.cast

full_name: ZMod.natCast_zmod_surjective
code: theorem natCast_zmod_surjective [NeZero n] : Function.Surjective ((↑) : ℕ → ZMod n) 
goal: Function.Surjective Nat.cast

full_name: ZMod.intCast_zmod_cast
code: /-- So-named because the outer coercion is `Int.cast` into `ZMod`. For `Int.cast` into an arbitrary
ring, see `ZMod.intCast_cast`. -/
@[norm_cast]
theorem intCast_zmod_cast (a : ZMod n) : ((cast a : ℤ) : ZMod n) = a 
goal: ↑a.cast = a

full_name: ZMod.intCast_rightInverse
code: theorem intCast_rightInverse : Function.RightInverse (cast : ZMod n → ℤ) ((↑) : ℤ → ZMod n) 
goal: Function.RightInverse ZMod.cast Int.cast

full_name: ZMod.intCast_surjective
code: theorem intCast_surjective : Function.Surjective ((↑) : ℤ → ZMod n) 
goal: Function.Surjective Int.cast

full_name: ZMod.cast_id
code: theorem cast_id : ∀ (n) (i : ZMod n), (ZMod.cast i : ZMod n) = i
  
goal: i.cast = i

full_name: ZMod.cast_id'
code: @[simp]
theorem cast_id' : (ZMod.cast : ZMod n → ZMod n) = id 
goal: ZMod.cast = id

full_name: ZMod.natCast_comp_val
code: /-- The coercions are respectively `Nat.cast` and `ZMod.cast`. -/
@[simp]
theorem natCast_comp_val [NeZero n] : ((↑) : ℕ → R) ∘ (val : ZMod n → ℕ) = cast 
goal: Nat.cast ∘ ZMod.val = ZMod.cast

full_name: ZMod.intCast_comp_cast
code: /-- The coercions are respectively `Int.cast`, `ZMod.cast`, and `ZMod.cast`. -/
@[simp]
theorem intCast_comp_cast : ((↑) : ℤ → R) ∘ (cast : ZMod n → ℤ) = cast 
goal: Int.cast ∘ ZMod.cast = ZMod.cast

full_name: ZMod.natCast_val
code: @[simp]
theorem natCast_val [NeZero n] (i : ZMod n) : (i.val : R) = cast i 
goal: ↑i.val = i.cast

full_name: ZMod.intCast_cast
code: @[simp]
theorem intCast_cast (i : ZMod n) : ((cast i : ℤ) : R) = cast i 
goal: ↑i.cast = i.cast

full_name: ZMod.cast_add_eq_ite
code: theorem cast_add_eq_ite {n : ℕ} (a b : ZMod n) :
    (cast (a + b) : ℤ) =
      if (n : ℤ) ≤ cast a + cast b then (cast a + cast b - n : ℤ) else cast a + cast b 
goal: (a + b).cast = if ↑n ≤ a.cast + b.cast then a.cast + b.cast - ↑n else a.cast + b.cast

full_name: ZMod.cast_one
code: @[simp]
theorem cast_one (h : m ∣ n) : (cast (1 : ZMod n) : R) = 1 
goal: ZMod.cast 1 = 1

full_name: ZMod.cast_add
code: theorem cast_add (h : m ∣ n) (a b : ZMod n) : (cast (a + b : ZMod n) : R) = cast a + cast b 
goal: (a + b).cast = a.cast + b.cast

full_name: ZMod.cast_mul
code: theorem cast_mul (h : m ∣ n) (a b : ZMod n) : (cast (a * b : ZMod n) : R) = cast a * cast b 
goal: (a * b).cast = a.cast * b.cast

full_name: ZMod.castHom
code: /-- The canonical ring homomorphism from `ZMod n` to a ring of characteristic dividing `n`.

See also `ZMod.lift` for a generalized version working in `AddGroup`s.
-/
def castHom (h : m ∣ n) (R : Type*) [Ring R] [CharP R m] : ZMod n →+* R 
goal: ZMod n →+* R

full_name: ZMod.castHom_apply
code: @[simp]
theorem castHom_apply {h : m ∣ n} (i : ZMod n) : castHom h R i = cast i 
goal: (ZMod.castHom h R) i = i.cast

full_name: ZMod.cast_sub
code: @[simp]
theorem cast_sub (h : m ∣ n) (a b : ZMod n) : (cast (a - b : ZMod n) : R) = cast a - cast b 
goal: (a - b).cast = a.cast - b.cast

full_name: ZMod.cast_neg
code: @[simp]
theorem cast_neg (h : m ∣ n) (a : ZMod n) : (cast (-a : ZMod n) : R) = -(cast a) 
goal: (-a).cast = -a.cast

full_name: ZMod.cast_pow
code: @[simp]
theorem cast_pow (h : m ∣ n) (a : ZMod n) (k : ℕ) : (cast (a ^ k : ZMod n) : R) = (cast a) ^ k 
goal: (a ^ k).cast = a.cast ^ k

full_name: ZMod.cast_natCast
code: @[simp, norm_cast]
theorem cast_natCast (h : m ∣ n) (k : ℕ) : (cast (k : ZMod n) : R) = k 
goal: (↑k).cast = ↑k

full_name: ZMod.cast_intCast
code: @[simp, norm_cast]
theorem cast_intCast (h : m ∣ n) (k : ℤ) : (cast (k : ZMod n) : R) = k 
goal: (↑k).cast = ↑k

full_name: ZMod.cast_one'
code: @[simp]
theorem cast_one' : (cast (1 : ZMod n) : R) = 1 
goal: ZMod.cast 1 = 1

full_name: ZMod.cast_add'
code: @[simp]
theorem cast_add' (a b : ZMod n) : (cast (a + b : ZMod n) : R) = cast a + cast b 
goal: (a + b).cast = a.cast + b.cast

full_name: ZMod.cast_mul'
code: @[simp]
theorem cast_mul' (a b : ZMod n) : (cast (a * b : ZMod n) : R) = cast a * cast b 
goal: (a * b).cast = a.cast * b.cast

full_name: ZMod.cast_sub'
code: @[simp]
theorem cast_sub' (a b : ZMod n) : (cast (a - b : ZMod n) : R) = cast a - cast b 
goal: (a - b).cast = a.cast - b.cast

full_name: ZMod.cast_pow'
code: @[simp]
theorem cast_pow' (a : ZMod n) (k : ℕ) : (cast (a ^ k : ZMod n) : R) = (cast a : R) ^ k 
goal: (a ^ k).cast = a.cast ^ k

full_name: ZMod.cast_natCast'
code: @[simp, norm_cast]
theorem cast_natCast' (k : ℕ) : (cast (k : ZMod n) : R) = k 
goal: (↑k).cast = ↑k

full_name: ZMod.cast_intCast'
code: @[simp, norm_cast]
theorem cast_intCast' (k : ℤ) : (cast (k : ZMod n) : R) = k 
goal: (↑k).cast = ↑k

full_name: ZMod.castHom_injective
code: theorem castHom_injective : Function.Injective (ZMod.castHom (dvd_refl n) R) 
goal: Function.Injective ⇑(ZMod.castHom ⋯ R)

full_name: ZMod.castHom_bijective
code: theorem castHom_bijective [Fintype R] (h : Fintype.card R = n) :
    Function.Bijective (ZMod.castHom (dvd_refl n) R) 
goal: Function.Bijective ⇑(ZMod.castHom ⋯ R)

full_name: ZMod.ringEquiv
code: /-- The unique ring isomorphism between `ZMod n` and a ring `R`
of characteristic `n` and cardinality `n`. -/
noncomputable def ringEquiv [Fintype R] (h : Fintype.card R = n) : ZMod n ≃+* R 
goal: ZMod n ≃+* R

full_name: ZMod.ringEquivOfPrime
code: /-- The unique ring isomorphism between `ZMod p` and a ring `R` of cardinality a prime `p`.

If you need any property of this isomorphism, first of all use `ringEquivOfPrime_eq_ringEquiv`
below (after `have : CharP R p := ...`) and deduce it by the results about `ZMod.ringEquiv`.  -/
noncomputable def ringEquivOfPrime [Fintype R] {p : ℕ} (hp : p.Prime) (hR : Fintype.card R = p) :
    ZMod p ≃+* R 
goal: ZMod p ≃+* R

full_name: ZMod.ringEquivOfPrime_eq_ringEquiv
code: @[simp]
lemma ringEquivOfPrime_eq_ringEquiv [Fintype R] {p : ℕ} [CharP R p] (hp : p.Prime)
    (hR : Fintype.card R = p) : ringEquivOfPrime R hp hR = ringEquiv R hR 
goal: ZMod.ringEquivOfPrime R hp hR = ZMod.ringEquiv R hR

full_name: ZMod.ringEquivCongr
code: /-- The identity between `ZMod m` and `ZMod n` when `m = n`, as a ring isomorphism. -/
def ringEquivCongr {m n : ℕ} (h : m = n) : ZMod m ≃+* ZMod n 
goal: ZMod m ≃+* ZMod n

full_name: ZMod.ringEquivCongr_refl
code: @[simp] lemma ringEquivCongr_refl (a : ℕ) : ringEquivCongr (rfl : a = a) = .refl _ 
goal: ZMod.ringEquivCongr ⋯ = RingEquiv.refl (ZMod a)

full_name: ZMod.ringEquivCongr_refl_apply
code: lemma ringEquivCongr_refl_apply {a : ℕ} (x : ZMod a) : ringEquivCongr rfl x = x 
goal: (ZMod.ringEquivCongr ⋯) x = x

full_name: ZMod.ringEquivCongr_symm
code: lemma ringEquivCongr_symm {a b : ℕ} (hab : a = b) :
    (ringEquivCongr hab).symm = ringEquivCongr hab.symm 
goal: (ZMod.ringEquivCongr hab).symm = ZMod.ringEquivCongr ⋯

full_name: ZMod.ringEquivCongr_trans
code: lemma ringEquivCongr_trans {a b c : ℕ} (hab : a = b) (hbc : b = c) :
    (ringEquivCongr hab).trans (ringEquivCongr hbc) = ringEquivCongr (hab.trans hbc) 
goal: (ZMod.ringEquivCongr hab).trans (ZMod.ringEquivCongr hbc) = ZMod.ringEquivCongr ⋯

full_name: ZMod.ringEquivCongr_ringEquivCongr_apply
code: lemma ringEquivCongr_ringEquivCongr_apply {a b c : ℕ} (hab : a = b) (hbc : b = c) (x : ZMod a) :
    ringEquivCongr hbc (ringEquivCongr hab x) = ringEquivCongr (hab.trans hbc) x 
goal: (ZMod.ringEquivCongr hbc) ((ZMod.ringEquivCongr hab) x) = (ZMod.ringEquivCongr ⋯) x

full_name: ZMod.ringEquivCongr_val
code: lemma ringEquivCongr_val {a b : ℕ} (h : a = b) (x : ZMod a) :
    ZMod.val ((ZMod.ringEquivCongr h) x) = ZMod.val x 
goal: ((ZMod.ringEquivCongr h) x).val = x.val

full_name: ZMod.ringEquivCongr_intCast
code: lemma ringEquivCongr_intCast {a b : ℕ} (h : a = b) (z : ℤ) :
    ZMod.ringEquivCongr h z = z 
goal: (ZMod.ringEquivCongr h) ↑z = ↑z

full_name: ZMod.intCast_eq_intCast_iff
code: theorem intCast_eq_intCast_iff (a b : ℤ) (c : ℕ) : (a : ZMod c) = (b : ZMod c) ↔ a ≡ b [ZMOD c] 
goal: ↑a = ↑b ↔ a ≡ b [ZMOD ↑c]

full_name: ZMod.intCast_eq_intCast_iff'
code: theorem intCast_eq_intCast_iff' (a b : ℤ) (c : ℕ) : (a : ZMod c) = (b : ZMod c) ↔ a % c = b % c 
goal: ↑a = ↑b ↔ a % ↑c = b % ↑c

full_name: ZMod.natCast_eq_natCast_iff
code: theorem natCast_eq_natCast_iff (a b c : ℕ) : (a : ZMod c) = (b : ZMod c) ↔ a ≡ b [MOD c] 
goal: ↑a = ↑b ↔ a ≡ b [MOD c]

full_name: ZMod.natCast_eq_natCast_iff'
code: theorem natCast_eq_natCast_iff' (a b c : ℕ) : (a : ZMod c) = (b : ZMod c) ↔ a % c = b % c 
goal: ↑a = ↑b ↔ a % c = b % c

full_name: ZMod.intCast_zmod_eq_zero_iff_dvd
code: theorem intCast_zmod_eq_zero_iff_dvd (a : ℤ) (b : ℕ) : (a : ZMod b) = 0 ↔ (b : ℤ) ∣ a 
goal: ↑a = 0 ↔ ↑b ∣ a

full_name: ZMod.intCast_eq_intCast_iff_dvd_sub
code: theorem intCast_eq_intCast_iff_dvd_sub (a b : ℤ) (c : ℕ) : (a : ZMod c) = ↑b ↔ ↑c ∣ b - a 
goal: ↑a = ↑b ↔ ↑c ∣ b - a

full_name: ZMod.natCast_zmod_eq_zero_iff_dvd
code: theorem natCast_zmod_eq_zero_iff_dvd (a b : ℕ) : (a : ZMod b) = 0 ↔ b ∣ a 
goal: ↑a = 0 ↔ b ∣ a

full_name: ZMod.val_intCast
code: theorem val_intCast {n : ℕ} (a : ℤ) [NeZero n] : ↑(a : ZMod n).val = a % n 
goal: ↑(↑a).val = a % ↑n

full_name: ZMod.coe_intCast
code: theorem coe_intCast (a : ℤ) : cast (a : ZMod n) = a % n 
goal: (↑a).cast = a % ↑n

full_name: ZMod.intCast_cast_add
code: lemma intCast_cast_add (x y : ZMod n) : (cast (x + y) : ℤ) = (cast x + cast y) % n 
goal: (x + y).cast = (x.cast + y.cast) % ↑n

full_name: ZMod.intCast_cast_mul
code: lemma intCast_cast_mul (x y : ZMod n) : (cast (x * y) : ℤ) = cast x * cast y % n 
goal: (x * y).cast = x.cast * y.cast % ↑n

full_name: ZMod.intCast_cast_sub
code: lemma intCast_cast_sub (x y : ZMod n) : (cast (x - y) : ℤ) = (cast x - cast y) % n 
goal: (x - y).cast = (x.cast - y.cast) % ↑n

full_name: ZMod.intCast_cast_neg
code: lemma intCast_cast_neg (x : ZMod n) : (cast (-x) : ℤ) = -cast x % n 
goal: (-x).cast = -x.cast % ↑n

full_name: ZMod.val_neg_one
code: @[simp]
theorem val_neg_one (n : ℕ) : (-1 : ZMod n.succ).val = n 
goal: (-1).val = n

full_name: ZMod.cast_neg_one
code: /-- `-1 : ZMod n` lifts to `n - 1 : R`. This avoids the characteristic assumption in `cast_neg`. -/
theorem cast_neg_one {R : Type*} [Ring R] (n : ℕ) : cast (-1 : ZMod n) = (n - 1 : R) 
goal: (-1).cast = ↑n - 1

full_name: ZMod.cast_sub_one
code: theorem cast_sub_one {R : Type*} [Ring R] {n : ℕ} (k : ZMod n) :
    (cast (k - 1 : ZMod n) : R) = (if k = 0 then (n : R) else cast k) - 1 
goal: (k - 1).cast = (if k = 0 then ↑n else k.cast) - 1

full_name: ZMod.natCast_eq_iff
code: theorem natCast_eq_iff (p : ℕ) (n : ℕ) (z : ZMod p) [NeZero p] :
    ↑n = z ↔ ∃ k, n = z.val + p * k 
goal: ↑n = z ↔ ∃ k, n = z.val + p * k

full_name: ZMod.intCast_eq_iff
code: theorem intCast_eq_iff (p : ℕ) (n : ℤ) (z : ZMod p) [NeZero p] :
    ↑n = z ↔ ∃ k, n = z.val + p * k 
goal: ↑n = z ↔ ∃ k, n = ↑z.val + ↑p * k

full_name: ZMod.intCast_mod
code: @[push_cast, simp]
theorem intCast_mod (a : ℤ) (b : ℕ) : ((a % b : ℤ) : ZMod b) = (a : ZMod b) 
goal: ↑(a % ↑b) = ↑a

full_name: ZMod.ker_intCastAddHom
code: theorem ker_intCastAddHom (n : ℕ) :
    (Int.castAddHom (ZMod n)).ker = AddSubgroup.zmultiples (n : ℤ) 
goal: (Int.castAddHom (ZMod n)).ker = AddSubgroup.zmultiples ↑n

full_name: ZMod.cast_injective_of_le
code: theorem cast_injective_of_le {m n : ℕ} [nzm : NeZero m] (h : m ≤ n) :
    Function.Injective (@cast (ZMod n) _ m) 
goal: Function.Injective ZMod.cast

full_name: ZMod.cast_zmod_eq_zero_iff_of_le
code: theorem cast_zmod_eq_zero_iff_of_le {m n : ℕ} [NeZero m] (h : m ≤ n) (a : ZMod m) :
    (cast a : ZMod n) = 0 ↔ a = 0 
goal: a.cast = 0 ↔ a = 0

full_name: ZMod.natCast_toNat
code: @[simp]
theorem natCast_toNat (p : ℕ) : ∀ {z : ℤ} (_h : 0 ≤ z), (z.toNat : ZMod p) = z
  
goal: ↑z.toNat = ↑z

full_name: ZMod.val_injective
code: theorem val_injective (n : ℕ) [NeZero n] : Function.Injective (val : ZMod n → ℕ) 
goal: Function.Injective ZMod.val

full_name: ZMod.val_one_eq_one_mod
code: theorem val_one_eq_one_mod (n : ℕ) : (1 : ZMod n).val = 1 % n 
goal: ZMod.val 1 = 1 % n

full_name: ZMod.val_one
code: theorem val_one (n : ℕ) [Fact (1 < n)] : (1 : ZMod n).val = 1 
goal: ZMod.val 1 = 1

full_name: ZMod.val_one''
code: lemma val_one'' : ∀ {n}, n ≠ 1 → (1 : ZMod n).val = 1
  
goal: n ≠ 1 → ZMod.val 1 = 1

full_name: ZMod.val_add
code: theorem val_add {n : ℕ} [NeZero n] (a b : ZMod n) : (a + b).val = (a.val + b.val) % n 
goal: (a + b).val = (a.val + b.val) % n

full_name: ZMod.val_add_of_lt
code: theorem val_add_of_lt {n : ℕ} {a b : ZMod n} (h : a.val + b.val < n) :
    (a + b).val = a.val + b.val 
goal: (a + b).val = a.val + b.val

full_name: ZMod.val_add_val_of_le
code: theorem val_add_val_of_le {n : ℕ} [NeZero n] {a b : ZMod n} (h : n ≤ a.val + b.val) :
    a.val + b.val = (a + b).val + n 
goal: a.val + b.val = (a + b).val + n

full_name: ZMod.val_add_of_le
code: theorem val_add_of_le {n : ℕ} [NeZero n] {a b : ZMod n} (h : n ≤ a.val + b.val) :
    (a + b).val = a.val + b.val - n 
goal: (a + b).val = a.val + b.val - n

full_name: ZMod.val_add_le
code: theorem val_add_le {n : ℕ} (a b : ZMod n) : (a + b).val ≤ a.val + b.val 
goal: (a + b).val ≤ a.val + b.val

full_name: ZMod.val_mul
code: theorem val_mul {n : ℕ} (a b : ZMod n) : (a * b).val = a.val * b.val % n 
goal: (a * b).val = a.val * b.val % n

full_name: ZMod.val_mul_le
code: theorem val_mul_le {n : ℕ} (a b : ZMod n) : (a * b).val ≤ a.val * b.val 
goal: (a * b).val ≤ a.val * b.val

full_name: ZMod.val_mul_of_lt
code: theorem val_mul_of_lt {n : ℕ} {a b : ZMod n} (h : a.val * b.val < n) :
    (a * b).val = a.val * b.val 
goal: (a * b).val = a.val * b.val

full_name: ZMod.nontrivial
code: instance nontrivial (n : ℕ) [Fact (1 < n)] : Nontrivial (ZMod n) 
goal: Nontrivial (ZMod n)

full_name: ZMod.nontrivial'
code: instance nontrivial' : Nontrivial (ZMod 0) 
goal: Nontrivial (ZMod 0)

full_name: ZMod.inv
code: /-- The inversion on `ZMod n`.
It is setup in such a way that `a * a⁻¹` is equal to `gcd a.val n`.
In particular, if `a` is coprime to `n`, and hence a unit, `a * a⁻¹ = 1`. -/
def inv : ∀ n : ℕ, ZMod n → ZMod n
  
goal: ZMod n → ZMod n

full_name: ZMod.instInv
code: instance (n : ℕ) : Inv (ZMod n) 
goal: Inv (ZMod n)

full_name: ZMod.inv_zero
code: @[nolint unusedHavesSuffices]
theorem inv_zero : ∀ n : ℕ, (0 : ZMod n)⁻¹ = 0
  
goal: 0⁻¹ = 0

full_name: ZMod.mul_inv_eq_gcd
code: theorem mul_inv_eq_gcd {n : ℕ} (a : ZMod n) : a * a⁻¹ = Nat.gcd a.val n 
goal: a * a⁻¹ = ↑(a.val.gcd n)

full_name: ZMod.inv_one
code: @[simp] protected lemma inv_one (n : ℕ) : (1⁻¹ : ZMod n) = 1 
goal: 1⁻¹ = 1

full_name: ZMod.natCast_mod
code: @[simp]
theorem natCast_mod (a : ℕ) (n : ℕ) : ((a % n : ℕ) : ZMod n) = a 
goal: ↑(a % n) = ↑a

full_name: ZMod.eq_iff_modEq_nat
code: theorem eq_iff_modEq_nat (n : ℕ) {a b : ℕ} : (a : ZMod n) = b ↔ a ≡ b [MOD n] 
goal: ↑a = ↑b ↔ a ≡ b [MOD n]

full_name: ZMod.coe_mul_inv_eq_one
code: theorem coe_mul_inv_eq_one {n : ℕ} (x : ℕ) (h : Nat.Coprime x n) :
    ((x : ZMod n) * (x : ZMod n)⁻¹) = 1 
goal: ↑x * (↑x)⁻¹ = 1

full_name: ZMod.mul_val_inv
code: lemma mul_val_inv (hmn : m.Coprime n) : (m * (m⁻¹ : ZMod n).val : ZMod n) = 1 
goal: ↑m * ↑(↑m)⁻¹.val = 1

full_name: ZMod.val_inv_mul
code: lemma val_inv_mul (hmn : m.Coprime n) : ((m⁻¹ : ZMod n).val * m : ZMod n) = 1 
goal: ↑(↑m)⁻¹.val * ↑m = 1

full_name: ZMod.unitOfCoprime
code: /-- `unitOfCoprime` makes an element of `(ZMod n)ˣ` given
  a natural number `x` and a proof that `x` is coprime to `n`  -/
def unitOfCoprime {n : ℕ} (x : ℕ) (h : Nat.Coprime x n) : (ZMod n)ˣ 
goal: (ZMod n)ˣ

full_name: ZMod.coe_unitOfCoprime
code: @[simp]
theorem coe_unitOfCoprime {n : ℕ} (x : ℕ) (h : Nat.Coprime x n) :
    (unitOfCoprime x h : ZMod n) = x 
goal: ↑(ZMod.unitOfCoprime x h) = ↑x

full_name: ZMod.val_coe_unit_coprime
code: theorem val_coe_unit_coprime {n : ℕ} (u : (ZMod n)ˣ) : Nat.Coprime (u : ZMod n).val n 
goal: (↑u).val.Coprime n

full_name: ZMod.isUnit_iff_coprime
code: lemma isUnit_iff_coprime (m n : ℕ) : IsUnit (m : ZMod n) ↔ m.Coprime n 
goal: IsUnit ↑m ↔ m.Coprime n

full_name: ZMod.isUnit_prime_iff_not_dvd
code: lemma isUnit_prime_iff_not_dvd {n p : ℕ} (hp : p.Prime) : IsUnit (p : ZMod n) ↔ ¬p ∣ n 
goal: IsUnit ↑p ↔ ¬p ∣ n

full_name: ZMod.isUnit_prime_of_not_dvd
code: lemma isUnit_prime_of_not_dvd {n p : ℕ} (hp : p.Prime) (h : ¬ p ∣ n) : IsUnit (p : ZMod n) 
goal: IsUnit ↑p

full_name: ZMod.inv_coe_unit
code: @[simp]
theorem inv_coe_unit {n : ℕ} (u : (ZMod n)ˣ) : (u : ZMod n)⁻¹ = (u⁻¹ : (ZMod n)ˣ) 
goal: (↑u)⁻¹ = ↑u⁻¹

full_name: ZMod.mul_inv_of_unit
code: theorem mul_inv_of_unit {n : ℕ} (a : ZMod n) (h : IsUnit a) : a * a⁻¹ = 1 
goal: a * a⁻¹ = 1

full_name: ZMod.inv_mul_of_unit
code: theorem inv_mul_of_unit {n : ℕ} (a : ZMod n) (h : IsUnit a) : a⁻¹ * a = 1 
goal: a⁻¹ * a = 1

full_name: ZMod.inv_eq_of_mul_eq_one
code: protected theorem inv_eq_of_mul_eq_one (n : ℕ) (a b : ZMod n) (h : a * b = 1) : a⁻¹ = b 
goal: a⁻¹ = b

full_name: ZMod.unitsEquivCoprime
code: /-- Equivalence between the units of `ZMod n` and
the subtype of terms `x : ZMod n` for which `x.val` is coprime to `n` -/
def unitsEquivCoprime {n : ℕ} [NeZero n] : (ZMod n)ˣ ≃ { x : ZMod n // Nat.Coprime x.val n } 
goal: (ZMod n)ˣ ≃ { x // x.val.Coprime n }

full_name: ZMod.chineseRemainder
code: /-- The **Chinese remainder theorem**. For a pair of coprime natural numbers, `m` and `n`,
  the rings `ZMod (m * n)` and `ZMod m × ZMod n` are isomorphic.

See `Ideal.quotientInfRingEquivPiQuotient` for the Chinese remainder theorem for ideals in any
ring.
-/
def chineseRemainder {m n : ℕ} (h : m.Coprime n) : ZMod (m * n) ≃+* ZMod m × ZMod n 
goal: ZMod (m * n) ≃+* ZMod m × ZMod n

full_name: ZMod.subsingleton_iff
code: lemma subsingleton_iff {n : ℕ} : Subsingleton (ZMod n) ↔ n = 1 
goal: Subsingleton (ZMod n) ↔ n = 1

full_name: ZMod.nontrivial_iff
code: lemma nontrivial_iff {n : ℕ} : Nontrivial (ZMod n) ↔ n ≠ 1 
goal: Nontrivial (ZMod n) ↔ n ≠ 1

full_name: ZMod.subsingleton_units
code: instance subsingleton_units : Subsingleton (ZMod 2)ˣ 
goal: Subsingleton (ZMod 2)ˣ

full_name: ZMod.add_self_eq_zero_iff_eq_zero
code: @[simp]
theorem add_self_eq_zero_iff_eq_zero {n : ℕ} (hn : Odd n) {a : ZMod n} :
    a + a = 0 ↔ a = 0 
goal: a + a = 0 ↔ a = 0

full_name: ZMod.ne_neg_self
code: theorem ne_neg_self {n : ℕ} (hn : Odd n) {a : ZMod n} (ha : a ≠ 0) : a ≠ -a 
goal: a ≠ -a

full_name: ZMod.neg_one_ne_one
code: theorem neg_one_ne_one {n : ℕ} [Fact (2 < n)] : (-1 : ZMod n) ≠ 1 
goal: -1 ≠ 1

full_name: ZMod.neg_eq_self_mod_two
code: theorem neg_eq_self_mod_two (a : ZMod 2) : -a = a 
goal: -a = a

full_name: ZMod.natAbs_mod_two
code: @[simp]
theorem natAbs_mod_two (a : ℤ) : (a.natAbs : ZMod 2) = a 
goal: ↑a.natAbs = ↑a

full_name: ZMod.val_eq_zero
code: @[simp]
theorem val_eq_zero : ∀ {n : ℕ} (a : ZMod n), a.val = 0 ↔ a = 0
  
goal: a.val = 0 ↔ a = 0

full_name: ZMod.val_ne_zero
code: theorem val_ne_zero {n : ℕ} (a : ZMod n) : a.val ≠ 0 ↔ a ≠ 0 
goal: a.val ≠ 0 ↔ a ≠ 0

full_name: ZMod.neg_eq_self_iff
code: theorem neg_eq_self_iff {n : ℕ} (a : ZMod n) : -a = a ↔ a = 0 ∨ 2 * a.val = n 
goal: -a = a ↔ a = 0 ∨ 2 * a.val = n

full_name: ZMod.val_cast_of_lt
code: theorem val_cast_of_lt {n : ℕ} {a : ℕ} (h : a < n) : (a : ZMod n).val = a 
goal: (↑a).val = a

full_name: ZMod.neg_val'
code: theorem neg_val' {n : ℕ} [NeZero n] (a : ZMod n) : (-a).val = (n - a.val) % n 
goal: (-a).val = (n - a.val) % n

full_name: ZMod.neg_val
code: theorem neg_val {n : ℕ} [NeZero n] (a : ZMod n) : (-a).val = if a = 0 then 0 else n - a.val 
goal: (-a).val = if a = 0 then 0 else n - a.val

full_name: ZMod.val_neg_of_ne_zero
code: theorem val_neg_of_ne_zero {n : ℕ} [nz : NeZero n] (a : ZMod n) [na : NeZero a] :
    (- a).val = n - a.val 
goal: (-a).val = n - a.val

full_name: ZMod.val_sub
code: theorem val_sub {n : ℕ} [NeZero n] {a b : ZMod n} (h : b.val ≤ a.val) :
    (a - b).val = a.val - b.val 
goal: (a - b).val = a.val - b.val

full_name: ZMod.val_cast_eq_val_of_lt
code: theorem val_cast_eq_val_of_lt {m n : ℕ} [nzm : NeZero m] {a : ZMod m}
    (h : a.val < n) : (a.cast : ZMod n).val = a.val 
goal: a.cast.val = a.val

full_name: ZMod.cast_cast_zmod_of_le
code: theorem cast_cast_zmod_of_le {m n : ℕ} [hm : NeZero m] (h : m ≤ n) (a : ZMod m) :
    (cast (cast a : ZMod n) : ZMod m) = a 
goal: a.cast.cast = a

full_name: ZMod.valMinAbs
code: /-- `valMinAbs x` returns the integer in the same equivalence class as `x` that is closest to `0`,
  The result will be in the interval `(-n/2, n/2]`. -/
def valMinAbs : ∀ {n : ℕ}, ZMod n → ℤ
  
goal: ZMod n → ℤ

full_name: ZMod.valMinAbs_def_zero
code: @[simp]
theorem valMinAbs_def_zero (x : ZMod 0) : valMinAbs x = x 
goal: x.valMinAbs = x

full_name: ZMod.valMinAbs_def_pos
code: theorem valMinAbs_def_pos {n : ℕ} [NeZero n] (x : ZMod n) :
    valMinAbs x = if x.val ≤ n / 2 then (x.val : ℤ) else x.val - n 
goal: x.valMinAbs = if x.val ≤ n / 2 then ↑x.val else ↑x.val - ↑n

full_name: ZMod.coe_valMinAbs
code: @[simp, norm_cast]
theorem coe_valMinAbs : ∀ {n : ℕ} (x : ZMod n), (x.valMinAbs : ZMod n) = x
  
goal: ↑x.valMinAbs = x

full_name: ZMod.injective_valMinAbs
code: theorem injective_valMinAbs {n : ℕ} : (valMinAbs : ZMod n → ℤ).Injective 
goal: Function.Injective ZMod.valMinAbs

full_name: Nat.le_div_two_iff_mul_two_le
code: theorem _root_.Nat.le_div_two_iff_mul_two_le {n m : ℕ} : m ≤ n / 2 ↔ (m : ℤ) * 2 ≤ n 
goal: m ≤ n / 2 ↔ ↑m * 2 ≤ ↑n

full_name: ZMod.valMinAbs_nonneg_iff
code: theorem valMinAbs_nonneg_iff {n : ℕ} [NeZero n] (x : ZMod n) : 0 ≤ x.valMinAbs ↔ x.val ≤ n / 2 
goal: 0 ≤ x.valMinAbs ↔ x.val ≤ n / 2

full_name: ZMod.valMinAbs_mul_two_eq_iff
code: theorem valMinAbs_mul_two_eq_iff {n : ℕ} (a : ZMod n) : a.valMinAbs * 2 = n ↔ 2 * a.val = n 
goal: a.valMinAbs * 2 = ↑n ↔ 2 * a.val = n

full_name: ZMod.valMinAbs_mem_Ioc
code: theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n 
goal: x.valMinAbs * 2 ∈ Set.Ioc (-↑n) ↑n

full_name: ZMod.valMinAbs_spec
code: theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n 
goal: x.valMinAbs = y ↔ x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n

full_name: ZMod.natAbs_valMinAbs_le
code: theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 
goal: x.valMinAbs.natAbs ≤ n / 2

full_name: ZMod.valMinAbs_zero
code: @[simp]
theorem valMinAbs_zero : ∀ n, (0 : ZMod n).valMinAbs = 0
  
goal: ZMod.valMinAbs 0 = 0

full_name: ZMod.valMinAbs_eq_zero
code: @[simp]
theorem valMinAbs_eq_zero {n : ℕ} (x : ZMod n) : x.valMinAbs = 0 ↔ x = 0 
goal: x.valMinAbs = 0 ↔ x = 0

full_name: ZMod.natCast_natAbs_valMinAbs
code: theorem natCast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a 
goal: ↑a.valMinAbs.natAbs = if a.val ≤ n / 2 then a else -a

full_name: ZMod.valMinAbs_neg_of_ne_half
code: theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs 
goal: (-a).valMinAbs = -a.valMinAbs

full_name: ZMod.natAbs_valMinAbs_neg
code: @[simp]
theorem natAbs_valMinAbs_neg {n : ℕ} (a : ZMod n) : (-a).valMinAbs.natAbs = a.valMinAbs.natAbs 
goal: (-a).valMinAbs.natAbs = a.valMinAbs.natAbs

full_name: ZMod.val_eq_ite_valMinAbs
code: theorem val_eq_ite_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.val : ℤ) = a.valMinAbs + if a.val ≤ n / 2 then 0 else n 
goal: ↑a.val = a.valMinAbs + ↑(if a.val ≤ n / 2 then 0 else n)

full_name: ZMod.prime_ne_zero
code: theorem prime_ne_zero (p q : ℕ) [hp : Fact p.Prime] [hq : Fact q.Prime] (hpq : p ≠ q) :
    (q : ZMod p) ≠ 0 
goal: ↑q ≠ 0

full_name: ZMod.valMinAbs_natAbs_eq_min
code: theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) 
goal: a.valMinAbs.natAbs = min a.val (n - a.val)

full_name: ZMod.valMinAbs_natCast_of_le_half
code: theorem valMinAbs_natCast_of_le_half (ha : a ≤ n / 2) : (a : ZMod n).valMinAbs = a 
goal: (↑a).valMinAbs = ↑a

full_name: ZMod.valMinAbs_natCast_of_half_lt
code: theorem valMinAbs_natCast_of_half_lt (ha : n / 2 < a) (ha' : a < n) :
    (a : ZMod n).valMinAbs = a - n 
goal: (↑a).valMinAbs = ↑a - ↑n

full_name: ZMod.valMinAbs_natCast_eq_self
code: @[simp]
theorem valMinAbs_natCast_eq_self [NeZero n] : (a : ZMod n).valMinAbs = a ↔ a ≤ n / 2 
goal: (↑a).valMinAbs = ↑a ↔ a ≤ n / 2

full_name: ZMod.natAbs_min_of_le_div_two
code: theorem natAbs_min_of_le_div_two (n : ℕ) (x y : ℤ) (he : (x : ZMod n) = y) (hl : x.natAbs ≤ n / 2) :
    x.natAbs ≤ y.natAbs 
goal: x.natAbs ≤ y.natAbs

full_name: ZMod.natAbs_valMinAbs_add_le
code: theorem natAbs_valMinAbs_add_le {n : ℕ} (a b : ZMod n) :
    (a + b).valMinAbs.natAbs ≤ (a.valMinAbs + b.valMinAbs).natAbs 
goal: (a + b).valMinAbs.natAbs ≤ (a.valMinAbs + b.valMinAbs).natAbs

full_name: _private.Mathlib.Data.ZMod.Basic.0.ZMod.mul_inv_cancel_aux
code: private theorem mul_inv_cancel_aux (a : ZMod p) (h : a ≠ 0) : a * a⁻¹ = 1 
goal: a * a⁻¹ = 1

full_name: ZMod.instField
code: /-- Field structure on `ZMod p` if `p` is prime. -/
instance instField : Field (ZMod p) 
goal: Field (ZMod p)

full_name: ZMod.instIsDomain
code: /-- `ZMod p` is an integral domain when `p` is prime. -/
instance (p : ℕ) [hp : Fact p.Prime] : IsDomain (ZMod p) 
goal: IsDomain (ZMod p)

full_name: RingHom.ext_zmod
code: theorem RingHom.ext_zmod {n : ℕ} {R : Type*} [Semiring R] (f g : ZMod n →+* R) : f = g 
goal: f = g

full_name: ZMod.subsingleton_ringHom
code: instance subsingleton_ringHom [Semiring R] : Subsingleton (ZMod n →+* R) 
goal: Subsingleton (ZMod n →+* R)

full_name: ZMod.subsingleton_ringEquiv
code: instance subsingleton_ringEquiv [Semiring R] : Subsingleton (ZMod n ≃+* R) 
goal: Subsingleton (ZMod n ≃+* R)

full_name: ZMod.ringHom_map_cast
code: @[simp]
theorem ringHom_map_cast [Ring R] (f : R →+* ZMod n) (k : ZMod n) : f (cast k) = k 
goal: f k.cast = k

full_name: ZMod.ringHom_rightInverse
code: /-- Any ring homomorphism into `ZMod n` has a right inverse. -/
theorem ringHom_rightInverse [Ring R] (f : R →+* ZMod n) :
    Function.RightInverse (cast : ZMod n → R) f 
goal: Function.RightInverse ZMod.cast ⇑f

full_name: ZMod.ringHom_surjective
code: /-- Any ring homomorphism into `ZMod n` is surjective. -/
theorem ringHom_surjective [Ring R] (f : R →+* ZMod n) : Function.Surjective f 
goal: Function.Surjective ⇑f

full_name: ZMod.castHom_self
code: @[simp]
lemma castHom_self : ZMod.castHom dvd_rfl (ZMod n) = RingHom.id (ZMod n) 
goal: ZMod.castHom ⋯ (ZMod n) = RingHom.id (ZMod n)

full_name: ZMod.castHom_comp
code: @[simp]
lemma castHom_comp {m d : ℕ} (hm : n ∣ m) (hd : m ∣ d) :
    (castHom hm (ZMod n)).comp (castHom hd (ZMod m)) = castHom (dvd_trans hm hd) (ZMod n) 
goal: (ZMod.castHom hm (ZMod n)).comp (ZMod.castHom hd (ZMod m)) = ZMod.castHom ⋯ (ZMod n)

full_name: ZMod.lift
code: /-- The map from `ZMod n` induced by `f : ℤ →+ A` that maps `n` to `0`. -/
--@[simps] -- Porting note: removed, simplified LHS of `lift_coe` to something worse.
def lift : { f : ℤ →+ A // f n = 0 } ≃ (ZMod n →+ A) 
goal: { f // f ↑n = 0 } ≃ (ZMod n →+ A)

full_name: ZMod.lift_coe
code: @[simp]
theorem lift_coe (x : ℤ) : lift n f (x : ZMod n) = f.val x 
goal: ((ZMod.lift n) f) ↑x = ↑f x

full_name: ZMod.lift_castAddHom
code: theorem lift_castAddHom (x : ℤ) : lift n f (Int.castAddHom (ZMod n) x) = f.1 x 
goal: ((ZMod.lift n) f) ((Int.castAddHom (ZMod n)) x) = ↑f x

full_name: ZMod.lift_comp_coe
code: @[simp]
theorem lift_comp_coe : ZMod.lift n f ∘ ((↑) : ℤ → _) = f 
goal: ⇑((ZMod.lift n) f) ∘ Int.cast = ⇑↑f

full_name: ZMod.lift_comp_castAddHom
code: @[simp]
theorem lift_comp_castAddHom : (ZMod.lift n f).comp (Int.castAddHom (ZMod n)) = f 
goal: ((ZMod.lift n) f).comp (Int.castAddHom (ZMod n)) = ↑f

full_name: ZMod.lift_injective
code: lemma lift_injective {f : {f : ℤ →+ A // f n = 0}} :
    Injective (lift n f) ↔ ∀ m, f.1 m = 0 → (m : ZMod n) = 0 
goal: Function.Injective ⇑((ZMod.lift n) f) ↔ ∀ (m : ℤ), ↑f m = 0 → ↑m = 0

full_name: nsmul_zmod_val_inv_nsmul
code: @[simp]
lemma nsmul_zmod_val_inv_nsmul (hn : (Nat.card α).Coprime n) (a : α) :
    n • (n⁻¹ : ZMod (Nat.card α)).val • a = a 
goal: n • (↑n)⁻¹.val • a = a

full_name: zmod_val_inv_nsmul_nsmul
code: @[simp]
lemma zmod_val_inv_nsmul_nsmul (hn : (Nat.card α).Coprime n) (a : α) :
    (n⁻¹ : ZMod (Nat.card α)).val • n • a = a 
goal: (↑n)⁻¹.val • n • a = a

full_name: pow_zmod_val_inv_pow
code: @[to_additive (attr := simp) existing nsmul_zmod_val_inv_nsmul]
lemma pow_zmod_val_inv_pow (hn : (Nat.card α).Coprime n) (a : α) :
    (a ^ (n⁻¹ : ZMod (Nat.card α)).val) ^ n = a 
goal: (a ^ (↑n)⁻¹.val) ^ n = a

full_name: pow_pow_zmod_val_inv
code: @[to_additive (attr := simp) existing zmod_val_inv_nsmul_nsmul]
lemma pow_pow_zmod_val_inv (hn : (Nat.card α).Coprime n) (a : α) :
    (a ^ n) ^ (n⁻¹ : ZMod (Nat.card α)).val = a 
goal: (a ^ n) ^ (↑n)⁻¹.val = a

full_name: Nat.range_mul_add
code: /-- The range of `(m * · + k)` on natural numbers is the set of elements `≥ k` in the
residue class of `k` mod `m`. -/
lemma Nat.range_mul_add (m k : ℕ) :
    Set.range (fun n : ℕ ↦ m * n + k) = {n : ℕ | (n : ZMod m) = k ∧ k ≤ n} 
goal: (Set.range fun n => m * n + k) = {n | ↑n = ↑k ∧ k ≤ n}