l3lab/ntp-mathlib huggingface dataset:
/-- A general version of **Dirichlet's approximation theorem**.

See also `AddCircle.exists_norm_nsmul_le`. -/
lemma _root_.NormedAddCommGroup.exists_norm_nsmul_le {A : Type*}
    [NormedAddCommGroup A] [CompactSpace A] [ConnectedSpace A]
    [MeasurableSpace A] [BorelSpace A] {μ : Measure A} [μ.IsAddHaarMeasure]
    (ξ : A) {n : ℕ} (hn : 0 < n) (δ : ℝ) (hδ : μ univ ≤ (n + 1) • μ (closedBall (0 : A) (δ/2))) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ δ := by
  have : IsFiniteMeasure μ := CompactSpace.isFiniteMeasure
  let B : Icc 0 n → Set A := fun j ↦ closedBall ((j : ℕ) • ξ) (δ/2)
  have hB : ∀ j, IsClosed (B j) := fun j ↦ isClosed_ball
  suffices : ¬ Pairwise (Disjoint on B)
  · obtain ⟨i, j, hij, x, hx⟩ := exists_lt_mem_inter_of_not_pairwise_disjoint this
    refine' ⟨j - i, ⟨le_tsub_of_add_le_left hij, _⟩, _⟩
    · simpa only [tsub_le_iff_right] using j.property.2.trans le_self_add
    · rw [sub_nsmul _ (Subtype.coe_le_coe.mpr hij.le), ← sub_eq_add_neg, ← dist_eq_norm]
      refine' (dist_triangle (↑j • ξ) x (↑i • ξ)).trans _
      linarith [mem_closedBall.mp hx.1, mem_closedBall'.mp hx.2]
  by_contra h
  apply hn.ne'
  have h' : ⋃ j, B j = univ := by
    rw [← (isClosed_iUnion_of_finite hB).measure_eq_univ_iff_eq (μ := μ)]
    refine' le_antisymm (μ.mono (subset_univ _)) _
    simp_rw [measure_iUnion h (fun _ ↦ measurableSet_closedBall), tsum_fintype,
      μ.addHaar_closedBall_center, Finset.sum_const, Finset.card_univ, Nat.card_fintypeIcc,
      tsub_zero]
    exact hδ
  replace hδ : 0 ≤ δ/2 := by
    by_contra contra
    suffices : μ (closedBall 0 (δ/2)) = 0
    · apply isOpen_univ.measure_ne_zero μ univ_nonempty $ le_zero_iff.mp $ le_trans hδ _
      simp [this]
    rw [not_le, ← closedBall_eq_empty (x := (0 : A))] at contra
    

Proof state:
case this
T : ℝ
hT : Fact (0 < T)
A : Type u_1
inst✝⁵ : NormedAddCommGroup A
inst✝⁴ : CompactSpace A
inst✝³ : ConnectedSpace A
inst✝² : MeasurableSpace A
inst✝¹ : BorelSpace A
μ : Measure A
inst✝ : Measure.IsAddHaarMeasure μ
ξ : A
n : ℕ
hn : 0 < n
δ : ℝ
hδ : ↑↑μ univ ≤ (n + 1) • ↑↑μ (closedBall 0 (δ / 2))
this : IsFiniteMeasure μ
B : ↑(Icc 0 n) → Set A := fun j => closedBall (↑j • ξ) (δ / 2)
hB : ∀ (j : ↑(Icc 0 n)), IsClosed (B j)
h : Pairwise (Disjoint on B)
h' : ⋃ j, B j = univ
contra : closedBall 0 (δ / 2) = ∅
⊢ ↑↑μ (closedBall 0 (δ / 2)) = 0

Next tactic:
simp [contra]
/-- A general version of **Dirichlet's approximation theorem**.

See also `AddCircle.exists_norm_nsmul_le`. -/
lemma _root_.NormedAddCommGroup.exists_norm_nsmul_le {A : Type*}
    [NormedAddCommGroup A] [CompactSpace A] [ConnectedSpace A]
    [MeasurableSpace A] [BorelSpace A] {μ : Measure A} [μ.IsAddHaarMeasure]
    (ξ : A) {n : ℕ} (hn : 0 < n) (δ : ℝ) (hδ : μ univ ≤ (n + 1) • μ (closedBall (0 : A) (δ/2))) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ δ := by
  have : IsFiniteMeasure μ := CompactSpace.isFiniteMeasure
  let B : Icc 0 n → Set A := fun j ↦ closedBall ((j : ℕ) • ξ) (δ/2)
  have hB : ∀ j, IsClosed (B j) := fun j ↦ isClosed_ball
  suffices : ¬ Pairwise (Disjoint on B)
  · obtain ⟨i, j, hij, x, hx⟩ := exists_lt_mem_inter_of_not_pairwise_disjoint this
    refine' ⟨j - i, ⟨le_tsub_of_add_le_left hij, _⟩, _⟩
    · simpa only [tsub_le_iff_right] using j.property.2.trans le_self_add
    · rw [sub_nsmul _ (Subtype.coe_le_coe.mpr hij.le), ← sub_eq_add_neg, ← dist_eq_norm]
      refine' (dist_triangle (↑j • ξ) x (↑i • ξ)).trans _
      linarith [mem_closedBall.mp hx.1, mem_closedBall'.mp hx.2]
  by_contra h
  apply hn.ne'
  have h' : ⋃ j, B j = univ := by
    rw [← (isClosed_iUnion_of_finite hB).measure_eq_univ_iff_eq (μ := μ)]
    refine' le_antisymm (μ.mono (subset_univ _)) _
    simp_rw [measure_iUnion h (fun _ ↦ measurableSet_closedBall), tsum_fintype,
      μ.addHaar_closedBall_center, Finset.sum_const, Finset.card_univ, Nat.card_fintypeIcc,
      tsub_zero]
    exact hδ
  replace hδ : 0 ≤ δ/2 := by
    by_contra contra
    suffices : μ (closedBall 0 (δ/2)) = 0
    · apply isOpen_univ.measure_ne_zero μ univ_nonempty $ le_zero_iff.mp $ le_trans hδ _
      simp [this]
    rw [not_le, ← closedBall_eq_empty (x := (0 : A))] at contra
    simp [contra]
  

Proof state:
case this
T : ℝ
hT : Fact (0 < T)
A : Type u_1
inst✝⁵ : NormedAddCommGroup A
inst✝⁴ : CompactSpace A
inst✝³ : ConnectedSpace A
inst✝² : MeasurableSpace A
inst✝¹ : BorelSpace A
μ : Measure A
inst✝ : Measure.IsAddHaarMeasure μ
ξ : A
n : ℕ
hn : 0 < n
δ : ℝ
this : IsFiniteMeasure μ
B : ↑(Icc 0 n) → Set A := fun j => closedBall (↑j • ξ) (δ / 2)
hB : ∀ (j : ↑(Icc 0 n)), IsClosed (B j)
h : Pairwise (Disjoint on B)
h' : ⋃ j, B j = univ
hδ : 0 ≤ δ / 2
⊢ n = 0

Next tactic:
have h'' : ∀ j, (B j).Nonempty := by intro j; rwa [nonempty_closedBall]
/-- A general version of **Dirichlet's approximation theorem**.

See also `AddCircle.exists_norm_nsmul_le`. -/
lemma _root_.NormedAddCommGroup.exists_norm_nsmul_le {A : Type*}
    [NormedAddCommGroup A] [CompactSpace A] [ConnectedSpace A]
    [MeasurableSpace A] [BorelSpace A] {μ : Measure A} [μ.IsAddHaarMeasure]
    (ξ : A) {n : ℕ} (hn : 0 < n) (δ : ℝ) (hδ : μ univ ≤ (n + 1) • μ (closedBall (0 : A) (δ/2))) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ δ := by
  have : IsFiniteMeasure μ := CompactSpace.isFiniteMeasure
  let B : Icc 0 n → Set A := fun j ↦ closedBall ((j : ℕ) • ξ) (δ/2)
  have hB : ∀ j, IsClosed (B j) := fun j ↦ isClosed_ball
  suffices : ¬ Pairwise (Disjoint on B)
  · obtain ⟨i, j, hij, x, hx⟩ := exists_lt_mem_inter_of_not_pairwise_disjoint this
    refine' ⟨j - i, ⟨le_tsub_of_add_le_left hij, _⟩, _⟩
    · simpa only [tsub_le_iff_right] using j.property.2.trans le_self_add
    · rw [sub_nsmul _ (Subtype.coe_le_coe.mpr hij.le), ← sub_eq_add_neg, ← dist_eq_norm]
      refine' (dist_triangle (↑j • ξ) x (↑i • ξ)).trans _
      linarith [mem_closedBall.mp hx.1, mem_closedBall'.mp hx.2]
  by_contra h
  apply hn.ne'
  have h' : ⋃ j, B j = univ := by
    rw [← (isClosed_iUnion_of_finite hB).measure_eq_univ_iff_eq (μ := μ)]
    refine' le_antisymm (μ.mono (subset_univ _)) _
    simp_rw [measure_iUnion h (fun _ ↦ measurableSet_closedBall), tsum_fintype,
      μ.addHaar_closedBall_center, Finset.sum_const, Finset.card_univ, Nat.card_fintypeIcc,
      tsub_zero]
    exact hδ
  replace hδ : 0 ≤ δ/2 := by
    by_contra contra
    suffices : μ (closedBall 0 (δ/2)) = 0
    · apply isOpen_univ.measure_ne_zero μ univ_nonempty $ le_zero_iff.mp $ le_trans hδ _
      simp [this]
    rw [not_le, ← closedBall_eq_empty (x := (0 : A))] at contra
    simp [contra]
  have h'' : ∀ j, (B j).Nonempty := by 

Proof state:
T : ℝ
hT : Fact (0 < T)
A : Type u_1
inst✝⁵ : NormedAddCommGroup A
inst✝⁴ : CompactSpace A
inst✝³ : ConnectedSpace A
inst✝² : MeasurableSpace A
inst✝¹ : BorelSpace A
μ : Measure A
inst✝ : Measure.IsAddHaarMeasure μ
ξ : A
n : ℕ
hn : 0 < n
δ : ℝ
this : IsFiniteMeasure μ
B : ↑(Icc 0 n) → Set A := fun j => closedBall (↑j • ξ) (δ / 2)
hB : ∀ (j : ↑(Icc 0 n)), IsClosed (B j)
h : Pairwise (Disjoint on B)
h' : ⋃ j, B j = univ
hδ : 0 ≤ δ / 2
⊢ ∀ (j : ↑(Icc 0 n)), Set.Nonempty (B j)

Next tactic:
intro j
/-- A general version of **Dirichlet's approximation theorem**.

See also `AddCircle.exists_norm_nsmul_le`. -/
lemma _root_.NormedAddCommGroup.exists_norm_nsmul_le {A : Type*}
    [NormedAddCommGroup A] [CompactSpace A] [ConnectedSpace A]
    [MeasurableSpace A] [BorelSpace A] {μ : Measure A} [μ.IsAddHaarMeasure]
    (ξ : A) {n : ℕ} (hn : 0 < n) (δ : ℝ) (hδ : μ univ ≤ (n + 1) • μ (closedBall (0 : A) (δ/2))) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ δ := by
  have : IsFiniteMeasure μ := CompactSpace.isFiniteMeasure
  let B : Icc 0 n → Set A := fun j ↦ closedBall ((j : ℕ) • ξ) (δ/2)
  have hB : ∀ j, IsClosed (B j) := fun j ↦ isClosed_ball
  suffices : ¬ Pairwise (Disjoint on B)
  · obtain ⟨i, j, hij, x, hx⟩ := exists_lt_mem_inter_of_not_pairwise_disjoint this
    refine' ⟨j - i, ⟨le_tsub_of_add_le_left hij, _⟩, _⟩
    · simpa only [tsub_le_iff_right] using j.property.2.trans le_self_add
    · rw [sub_nsmul _ (Subtype.coe_le_coe.mpr hij.le), ← sub_eq_add_neg, ← dist_eq_norm]
      refine' (dist_triangle (↑j • ξ) x (↑i • ξ)).trans _
      linarith [mem_closedBall.mp hx.1, mem_closedBall'.mp hx.2]
  by_contra h
  apply hn.ne'
  have h' : ⋃ j, B j = univ := by
    rw [← (isClosed_iUnion_of_finite hB).measure_eq_univ_iff_eq (μ := μ)]
    refine' le_antisymm (μ.mono (subset_univ _)) _
    simp_rw [measure_iUnion h (fun _ ↦ measurableSet_closedBall), tsum_fintype,
      μ.addHaar_closedBall_center, Finset.sum_const, Finset.card_univ, Nat.card_fintypeIcc,
      tsub_zero]
    exact hδ
  replace hδ : 0 ≤ δ/2 := by
    by_contra contra
    suffices : μ (closedBall 0 (δ/2)) = 0
    · apply isOpen_univ.measure_ne_zero μ univ_nonempty $ le_zero_iff.mp $ le_trans hδ _
      simp [this]
    rw [not_le, ← closedBall_eq_empty (x := (0 : A))] at contra
    simp [contra]
  have h'' : ∀ j, (B j).Nonempty := by intro j; 

Proof state:
T : ℝ
hT : Fact (0 < T)
A : Type u_1
inst✝⁵ : NormedAddCommGroup A
inst✝⁴ : CompactSpace A
inst✝³ : ConnectedSpace A
inst✝² : MeasurableSpace A
inst✝¹ : BorelSpace A
μ : Measure A
inst✝ : Measure.IsAddHaarMeasure μ
ξ : A
n : ℕ
hn : 0 < n
δ : ℝ
this : IsFiniteMeasure μ
B : ↑(Icc 0 n) → Set A := fun j => closedBall (↑j • ξ) (δ / 2)
hB : ∀ (j : ↑(Icc 0 n)), IsClosed (B j)
h : Pairwise (Disjoint on B)
h' : ⋃ j, B j = univ
hδ : 0 ≤ δ / 2
j : ↑(Icc 0 n)
⊢ Set.Nonempty (B j)

Next tactic:
rwa [nonempty_closedBall]
/-- A general version of **Dirichlet's approximation theorem**.

See also `AddCircle.exists_norm_nsmul_le`. -/
lemma _root_.NormedAddCommGroup.exists_norm_nsmul_le {A : Type*}
    [NormedAddCommGroup A] [CompactSpace A] [ConnectedSpace A]
    [MeasurableSpace A] [BorelSpace A] {μ : Measure A} [μ.IsAddHaarMeasure]
    (ξ : A) {n : ℕ} (hn : 0 < n) (δ : ℝ) (hδ : μ univ ≤ (n + 1) • μ (closedBall (0 : A) (δ/2))) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ δ := by
  have : IsFiniteMeasure μ := CompactSpace.isFiniteMeasure
  let B : Icc 0 n → Set A := fun j ↦ closedBall ((j : ℕ) • ξ) (δ/2)
  have hB : ∀ j, IsClosed (B j) := fun j ↦ isClosed_ball
  suffices : ¬ Pairwise (Disjoint on B)
  · obtain ⟨i, j, hij, x, hx⟩ := exists_lt_mem_inter_of_not_pairwise_disjoint this
    refine' ⟨j - i, ⟨le_tsub_of_add_le_left hij, _⟩, _⟩
    · simpa only [tsub_le_iff_right] using j.property.2.trans le_self_add
    · rw [sub_nsmul _ (Subtype.coe_le_coe.mpr hij.le), ← sub_eq_add_neg, ← dist_eq_norm]
      refine' (dist_triangle (↑j • ξ) x (↑i • ξ)).trans _
      linarith [mem_closedBall.mp hx.1, mem_closedBall'.mp hx.2]
  by_contra h
  apply hn.ne'
  have h' : ⋃ j, B j = univ := by
    rw [← (isClosed_iUnion_of_finite hB).measure_eq_univ_iff_eq (μ := μ)]
    refine' le_antisymm (μ.mono (subset_univ _)) _
    simp_rw [measure_iUnion h (fun _ ↦ measurableSet_closedBall), tsum_fintype,
      μ.addHaar_closedBall_center, Finset.sum_const, Finset.card_univ, Nat.card_fintypeIcc,
      tsub_zero]
    exact hδ
  replace hδ : 0 ≤ δ/2 := by
    by_contra contra
    suffices : μ (closedBall 0 (δ/2)) = 0
    · apply isOpen_univ.measure_ne_zero μ univ_nonempty $ le_zero_iff.mp $ le_trans hδ _
      simp [this]
    rw [not_le, ← closedBall_eq_empty (x := (0 : A))] at contra
    simp [contra]
  have h'' : ∀ j, (B j).Nonempty := by intro j; rwa [nonempty_closedBall]
  

Proof state:
case this
T : ℝ
hT : Fact (0 < T)
A : Type u_1
inst✝⁵ : NormedAddCommGroup A
inst✝⁴ : CompactSpace A
inst✝³ : ConnectedSpace A
inst✝² : MeasurableSpace A
inst✝¹ : BorelSpace A
μ : Measure A
inst✝ : Measure.IsAddHaarMeasure μ
ξ : A
n : ℕ
hn : 0 < n
δ : ℝ
this : IsFiniteMeasure μ
B : ↑(Icc 0 n) → Set A := fun j => closedBall (↑j • ξ) (δ / 2)
hB : ∀ (j : ↑(Icc 0 n)), IsClosed (B j)
h : Pairwise (Disjoint on B)
h' : ⋃ j, B j = univ
hδ : 0 ≤ δ / 2
h'' : ∀ (j : ↑(Icc 0 n)), Set.Nonempty (B j)
⊢ n = 0

Next tactic:
simpa using subsingleton_of_disjoint_isClosed_iUnion_eq_univ h'' h hB h'
/-- **Dirichlet's approximation theorem**

See also `Real.exists_rat_abs_sub_le_and_den_le`. -/
lemma exists_norm_nsmul_le (ξ : 𝕊) {n : ℕ} (hn : 0 < n) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ T / ↑(n + 1) := by
  

Proof state:
T : ℝ
hT : Fact (0 < T)
ξ : 𝕊
n : ℕ
hn : 0 < n
⊢ ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ T / ↑(n + 1)

Next tactic:
apply NormedAddCommGroup.exists_norm_nsmul_le (μ := volume) ξ hn
/-- **Dirichlet's approximation theorem**

See also `Real.exists_rat_abs_sub_le_and_den_le`. -/
lemma exists_norm_nsmul_le (ξ : 𝕊) {n : ℕ} (hn : 0 < n) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ T / ↑(n + 1) := by
  apply NormedAddCommGroup.exists_norm_nsmul_le (μ := volume) ξ hn
  

Proof state:
case hδ
T : ℝ
hT : Fact (0 < T)
ξ : 𝕊
n : ℕ
hn : 0 < n
⊢ ↑↑volume univ ≤ (n + 1) • ↑↑volume (closedBall 0 (T / ↑(n + 1) / 2))

Next tactic:
rw [AddCircle.measure_univ, volume_closedBall, ← ENNReal.ofReal_nsmul,
    mul_div_cancel' _ two_ne_zero, min_eq_right (div_le_self hT.out.le $ by simp), nsmul_eq_mul,
    mul_div_cancel' _ (Nat.cast_ne_zero.mpr n.succ_ne_zero)]
/-- **Dirichlet's approximation theorem**

See also `Real.exists_rat_abs_sub_le_and_den_le`. -/
lemma exists_norm_nsmul_le (ξ : 𝕊) {n : ℕ} (hn : 0 < n) :
    ∃ j ∈ Icc 1 n, ‖j • ξ‖ ≤ T / ↑(n + 1) := by
  apply NormedAddCommGroup.exists_norm_nsmul_le (μ := volume) ξ hn
  rw [AddCircle.measure_univ, volume_closedBall, ← ENNReal.ofReal_nsmul,
    mul_div_cancel' _ two_ne_zero, min_eq_right (div_le_self hT.out.le $ by 

Proof state:
T : ℝ
hT : Fact (0 < T)
ξ : 𝕊
n : ℕ
hn : 0 < n
⊢ 1 ≤ ↑(n + 1)

Next tactic:
simp
instance charZero : CharZero (ZMod 0) :=
  (by 

Proof state:
⊢ CharZero ℤ

Next tactic:
infer_instance
theorem val_lt {n : ℕ} [NeZero n] (a : ZMod n) : a.val < n := by
  

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
⊢ val a < n

Next tactic:
cases n
theorem val_lt {n : ℕ} [NeZero n] (a : ZMod n) : a.val < n := by
  cases n
  · 

Proof state:
case zero
inst✝ : NeZero Nat.zero
a : ZMod Nat.zero
⊢ val a < Nat.zero

Next tactic:
cases NeZero.ne 0 rfl
theorem val_lt {n : ℕ} [NeZero n] (a : ZMod n) : a.val < n := by
  cases n
  · cases NeZero.ne 0 rfl
  

Proof state:
case succ
n✝ : ℕ
inst✝ : NeZero (Nat.succ n✝)
a : ZMod (Nat.succ n✝)
⊢ val a < Nat.succ n✝

Next tactic:
exact Fin.is_lt a
@[simp]
theorem val_nat_cast {n : ℕ} (a : ℕ) : (a : ZMod n).val = a % n := by
  

Proof state:
n a : ℕ
⊢ val ↑a = a % n

Next tactic:
cases n
@[simp]
theorem val_nat_cast {n : ℕ} (a : ℕ) : (a : ZMod n).val = a % n := by
  cases n
  · 

Proof state:
case zero
a : ℕ
⊢ val ↑a = a % Nat.zero

Next tactic:
rw [Nat.mod_zero]
@[simp]
theorem val_nat_cast {n : ℕ} (a : ℕ) : (a : ZMod n).val = a % n := by
  cases n
  · rw [Nat.mod_zero]
    

Proof state:
case zero
a : ℕ
⊢ val ↑a = a

Next tactic:
exact Int.natAbs_ofNat a
@[simp]
theorem val_nat_cast {n : ℕ} (a : ℕ) : (a : ZMod n).val = a % n := by
  cases n
  · rw [Nat.mod_zero]
    exact Int.natAbs_ofNat a
  · 

Proof state:
case succ
a n✝ : ℕ
⊢ val ↑a = a % Nat.succ n✝

Next tactic:
apply Fin.val_nat_cast
theorem val_nat_cast_of_lt {n a : ℕ} (h : a < n) : (a : ZMod n).val = a := by
  

Proof state:
n a : ℕ
h : a < n
⊢ val ↑a = a

Next tactic:
rwa [val_nat_cast, Nat.mod_eq_of_lt]
instance charP (n : ℕ) : CharP (ZMod n) n where
  cast_eq_zero_iff' := by
    

Proof state:
n : ℕ
⊢ ∀ (x : ℕ), ↑x = 0 ↔ n ∣ x

Next tactic:
intro k
instance charP (n : ℕ) : CharP (ZMod n) n where
  cast_eq_zero_iff' := by
    intro k
    

Proof state:
n k : ℕ
⊢ ↑k = 0 ↔ n ∣ k

Next tactic:
cases' n with n
instance charP (n : ℕ) : CharP (ZMod n) n where
  cast_eq_zero_iff' := by
    intro k
    cases' n with n
    · 

Proof state:
case zero
k : ℕ
⊢ ↑k = 0 ↔ Nat.zero ∣ k

Next tactic:
simp [zero_dvd_iff, Int.coe_nat_eq_zero, Nat.zero_eq]
instance charP (n : ℕ) : CharP (ZMod n) n where
  cast_eq_zero_iff' := by
    intro k
    cases' n with n
    · simp [zero_dvd_iff, Int.coe_nat_eq_zero, Nat.zero_eq]
    · 

Proof state:
case succ
k n : ℕ
⊢ ↑k = 0 ↔ Nat.succ n ∣ k

Next tactic:
exact Fin.nat_cast_eq_zero
/-- 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 := by
  

Proof state:
a n : ℕ
n0 : n ≠ 0
⊢ addOrderOf ↑a = n / Nat.gcd n a

Next tactic:
cases' a with a
/-- 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 := by
  cases' a with a
  

Proof state:
case zero
n : ℕ
n0 : n ≠ 0
⊢ addOrderOf ↑Nat.zero = n / Nat.gcd n Nat.zero
case succ n : ℕ n0 : n ≠ 0 a : ℕ ⊢ addOrderOf ↑(Nat.succ a) = n / Nat.gcd n (Nat.succ a)

Next tactic:
simp only [Nat.zero_eq, Nat.cast_zero, addOrderOf_zero, Nat.gcd_zero_right, Nat.pos_of_ne_zero n0,
    Nat.div_self]
/-- 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 := by
  cases' a with a
  simp only [Nat.zero_eq, Nat.cast_zero, addOrderOf_zero, Nat.gcd_zero_right, Nat.pos_of_ne_zero n0,
    Nat.div_self]
  

Proof state:
case succ
n : ℕ
n0 : n ≠ 0
a : ℕ
⊢ addOrderOf ↑(Nat.succ a) = n / Nat.gcd n (Nat.succ a)

Next tactic:
rw [← Nat.smul_one_eq_coe, addOrderOf_nsmul' _ a.succ_ne_zero, ZMod.addOrderOf_one]
/-- 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 := by
  

Proof state:
a n : ℕ
a0 : a ≠ 0
⊢ addOrderOf ↑a = n / Nat.gcd n a

Next tactic:
rw [← Nat.smul_one_eq_coe, addOrderOf_nsmul' _ a0, ZMod.addOrderOf_one]
/-- We have that `ringChar (ZMod n) = n`. -/
theorem ringChar_zmod_n (n : ℕ) : ringChar (ZMod n) = n := by
  

Proof state:
n : ℕ
⊢ ringChar (ZMod n) = n

Next tactic:
rw [ringChar.eq_iff]
/-- We have that `ringChar (ZMod n) = n`. -/
theorem ringChar_zmod_n (n : ℕ) : ringChar (ZMod n) = n := by
  rw [ringChar.eq_iff]
  

Proof state:
n : ℕ
⊢ CharP (ZMod n) n

Next tactic:
exact ZMod.charP n
@[simp]
theorem nat_cast_self' (n : ℕ) : (n + 1 : ZMod (n + 1)) = 0 := by
  

Proof state:
n : ℕ
⊢ ↑n + 1 = 0

Next tactic:
rw [← Nat.cast_add_one, nat_cast_self (n + 1)]
@[simp]
theorem cast_zero : ((0 : ZMod n) : R) = 0 := by
  

Proof state:
n : ℕ
R : Type u_1
inst✝ : AddGroupWithOne R
⊢ ↑0 = 0

Next tactic:
delta ZMod.cast
@[simp]
theorem cast_zero : ((0 : ZMod n) : R) = 0 := by
  delta ZMod.cast
  

Proof state:
n : ℕ
R : Type u_1
inst✝ : AddGroupWithOne R
⊢ (match (motive := (x : ℕ) → ZMod x → R) n with
      | 0 => Int.cast
      | Nat.succ n => fun i => ↑(val i))
      0 =
    0

Next tactic:
cases n
@[simp]
theorem cast_zero : ((0 : ZMod n) : R) = 0 := by
  delta ZMod.cast
  cases n
  · 

Proof state:
case zero
R : Type u_1
inst✝ : AddGroupWithOne R
⊢ (match (motive := (x : ℕ) → ZMod x → R) Nat.zero with
      | 0 => Int.cast
      | Nat.succ n => fun i => ↑(val i))
      0 =
    0

Next tactic:
exact Int.cast_zero
@[simp]
theorem cast_zero : ((0 : ZMod n) : R) = 0 := by
  delta ZMod.cast
  cases n
  · exact Int.cast_zero
  · 

Proof state:
case succ
R : Type u_1
inst✝ : AddGroupWithOne R
n✝ : ℕ
⊢ (match (motive := (x : ℕ) → ZMod x → R) Nat.succ n✝ with
      | 0 => Int.cast
      | Nat.succ n => fun i => ↑(val i))
      0 =
    0

Next tactic:
simp
theorem cast_eq_val [NeZero n] (a : ZMod n) : (a : R) = a.val := by
  

Proof state:
n : ℕ
R : Type u_1
inst✝¹ : AddGroupWithOne R
inst✝ : NeZero n
a : ZMod n
⊢ ↑a = ↑(val a)

Next tactic:
cases n
theorem cast_eq_val [NeZero n] (a : ZMod n) : (a : R) = a.val := by
  cases n
  · 

Proof state:
case zero
R : Type u_1
inst✝¹ : AddGroupWithOne R
inst✝ : NeZero Nat.zero
a : ZMod Nat.zero
⊢ ↑a = ↑(val a)

Next tactic:
cases NeZero.ne 0 rfl
theorem cast_eq_val [NeZero n] (a : ZMod n) : (a : R) = a.val := by
  cases n
  · cases NeZero.ne 0 rfl
  

Proof state:
case succ
R : Type u_1
inst✝¹ : AddGroupWithOne R
n✝ : ℕ
inst✝ : NeZero (Nat.succ n✝)
a : ZMod (Nat.succ n✝)
⊢ ↑a = ↑(val a)

Next tactic:
rfl
@[simp]
theorem _root_.Prod.fst_zmod_cast (a : ZMod n) : (a : R × S).fst = a := by
  

Proof state:
n : ℕ
R : Type u_1
inst✝¹ : AddGroupWithOne R
S : Type u_2
inst✝ : AddGroupWithOne S
a : ZMod n
⊢ (↑a).1 = ↑a

Next tactic:
cases n
@[simp]
theorem _root_.Prod.fst_zmod_cast (a : ZMod n) : (a : R × S).fst = a := by
  cases n
  · 

Proof state:
case zero
R : Type u_1
inst✝¹ : AddGroupWithOne R
S : Type u_2
inst✝ : AddGroupWithOne S
a : ZMod Nat.zero
⊢ (↑a).1 = ↑a

Next tactic:
rfl
@[simp]
theorem _root_.Prod.fst_zmod_cast (a : ZMod n) : (a : R × S).fst = a := by
  cases n
  · rfl
  · 

Proof state:
case succ
R : Type u_1
inst✝¹ : AddGroupWithOne R
S : Type u_2
inst✝ : AddGroupWithOne S
n✝ : ℕ
a : ZMod (Nat.succ n✝)
⊢ (↑a).1 = ↑a

Next tactic:
simp [ZMod.cast]
@[simp]
theorem _root_.Prod.snd_zmod_cast (a : ZMod n) : (a : R × S).snd = a := by
  

Proof state:
n : ℕ
R : Type u_1
inst✝¹ : AddGroupWithOne R
S : Type u_2
inst✝ : AddGroupWithOne S
a : ZMod n
⊢ (↑a).2 = ↑a

Next tactic:
cases n
@[simp]
theorem _root_.Prod.snd_zmod_cast (a : ZMod n) : (a : R × S).snd = a := by
  cases n
  · 

Proof state:
case zero
R : Type u_1
inst✝¹ : AddGroupWithOne R
S : Type u_2
inst✝ : AddGroupWithOne S
a : ZMod Nat.zero
⊢ (↑a).2 = ↑a

Next tactic:
rfl
@[simp]
theorem _root_.Prod.snd_zmod_cast (a : ZMod n) : (a : R × S).snd = a := by
  cases n
  · rfl
  · 

Proof state:
case succ
R : Type u_1
inst✝¹ : AddGroupWithOne R
S : Type u_2
inst✝ : AddGroupWithOne S
n✝ : ℕ
a : ZMod (Nat.succ n✝)
⊢ (↑a).2 = ↑a

Next tactic:
simp [ZMod.cast]
/-- So-named because the coercion is `Nat.cast` into `ZMod`. For `Nat.cast` into an arbitrary ring,
see `ZMod.nat_cast_val`. -/
theorem nat_cast_zmod_val {n : ℕ} [NeZero n] (a : ZMod n) : (a.val : ZMod n) = a := by
  

Proof state:
n✝ : ℕ
R : Type u_1
n : ℕ
inst✝ : NeZero n
a : ZMod n
⊢ ↑(val a) = a

Next tactic:
cases n
/-- So-named because the coercion is `Nat.cast` into `ZMod`. For `Nat.cast` into an arbitrary ring,
see `ZMod.nat_cast_val`. -/
theorem nat_cast_zmod_val {n : ℕ} [NeZero n] (a : ZMod n) : (a.val : ZMod n) = a := by
  cases n
  · 

Proof state:
case zero
n : ℕ
R : Type u_1
inst✝ : NeZero Nat.zero
a : ZMod Nat.zero
⊢ ↑(val a) = a

Next tactic:
cases NeZero.ne 0 rfl
/-- So-named because the coercion is `Nat.cast` into `ZMod`. For `Nat.cast` into an arbitrary ring,
see `ZMod.nat_cast_val`. -/
theorem nat_cast_zmod_val {n : ℕ} [NeZero n] (a : ZMod n) : (a.val : ZMod n) = a := by
  cases n
  · cases NeZero.ne 0 rfl
  · 

Proof state:
case succ
n : ℕ
R : Type u_1
n✝ : ℕ
inst✝ : NeZero (Nat.succ n✝)
a : ZMod (Nat.succ n✝)
⊢ ↑(val a) = a

Next tactic:
apply Fin.cast_val_eq_self
/-- So-named because the outer coercion is `Int.cast` into `ZMod`. For `Int.cast` into an arbitrary
ring, see `ZMod.int_cast_cast`. -/
@[norm_cast]
theorem int_cast_zmod_cast (a : ZMod n) : ((a : ℤ) : ZMod n) = a := by
  

Proof state:
n : ℕ
R : Type u_1
a : ZMod n
⊢ ↑↑a = a

Next tactic:
cases n
/-- So-named because the outer coercion is `Int.cast` into `ZMod`. For `Int.cast` into an arbitrary
ring, see `ZMod.int_cast_cast`. -/
@[norm_cast]
theorem int_cast_zmod_cast (a : ZMod n) : ((a : ℤ) : ZMod n) = a := by
  cases n
  · 

Proof state:
case zero
R : Type u_1
a : ZMod Nat.zero
⊢ ↑↑a = a

Next tactic:
simp [ZMod.cast, ZMod]
/-- So-named because the outer coercion is `Int.cast` into `ZMod`. For `Int.cast` into an arbitrary
ring, see `ZMod.int_cast_cast`. -/
@[norm_cast]
theorem int_cast_zmod_cast (a : ZMod n) : ((a : ℤ) : ZMod n) = a := by
  cases n
  · simp [ZMod.cast, ZMod]
  · 

Proof state:
case succ
R : Type u_1
n✝ : ℕ
a : ZMod (Nat.succ n✝)
⊢ ↑↑a = a

Next tactic:
dsimp [ZMod.cast, ZMod]
/-- So-named because the outer coercion is `Int.cast` into `ZMod`. For `Int.cast` into an arbitrary
ring, see `ZMod.int_cast_cast`. -/
@[norm_cast]
theorem int_cast_zmod_cast (a : ZMod n) : ((a : ℤ) : ZMod n) = a := by
  cases n
  · simp [ZMod.cast, ZMod]
  · dsimp [ZMod.cast, ZMod]
    

Proof state:
case succ
R : Type u_1
n✝ : ℕ
a : ZMod (Nat.succ n✝)
⊢ ↑↑(val a) = a

Next tactic:
erw [Int.cast_ofNat, Fin.cast_val_eq_self]
/-- The coercions are respectively `Nat.cast` and `ZMod.cast`. -/
@[simp]
theorem nat_cast_comp_val [NeZero n] : ((↑) : ℕ → R) ∘ (val : ZMod n → ℕ) = (↑) := by
  

Proof state:
n : ℕ
R : Type u_1
inst✝¹ : Ring R
inst✝ : NeZero n
⊢ Nat.cast ∘ val = cast

Next tactic:
cases n