l3lab/ntp-mathlib huggingface dataset:
theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n := by
  simp_rw [valMinAbs_def_pos, Nat.le_div_two_iff_mul_two_le]; split_ifs with h
  · 

Proof state:
case pos
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : ↑(val x) * 2 ≤ ↑n
⊢ ↑(val x) * 2 ∈ Set.Ioc (-↑n) ↑n

Next tactic:
refine' ⟨(neg_lt_zero.2 <| mod_cast NeZero.pos n).trans_le (mul_nonneg _ _), h⟩
theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n := by
  simp_rw [valMinAbs_def_pos, Nat.le_div_two_iff_mul_two_le]; split_ifs with h
  · refine' ⟨(neg_lt_zero.2 <| mod_cast NeZero.pos n).trans_le (mul_nonneg _ _), h⟩
    

Proof state:
case pos.refine'_1
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : ↑(val x) * 2 ≤ ↑n
⊢ 0 ≤ ↑(val x)
case pos.refine'_2 n : ℕ inst✝ : NeZero n x : ZMod n h : ↑(val x) * 2 ≤ ↑n ⊢ 0 ≤ 2

Next tactic:
exacts [Nat.cast_nonneg _, zero_le_two]
theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n := by
  simp_rw [valMinAbs_def_pos, Nat.le_div_two_iff_mul_two_le]; split_ifs with h
  · refine' ⟨(neg_lt_zero.2 <| mod_cast NeZero.pos n).trans_le (mul_nonneg _ _), h⟩
    exacts [Nat.cast_nonneg _, zero_le_two]
  · 

Proof state:
case neg
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : ¬↑(val x) * 2 ≤ ↑n
⊢ (↑(val x) - ↑n) * 2 ∈ Set.Ioc (-↑n) ↑n

Next tactic:
refine' ⟨_, le_trans (mul_nonpos_of_nonpos_of_nonneg _ zero_le_two) <| Nat.cast_nonneg _⟩
theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n := by
  simp_rw [valMinAbs_def_pos, Nat.le_div_two_iff_mul_two_le]; split_ifs with h
  · refine' ⟨(neg_lt_zero.2 <| mod_cast NeZero.pos n).trans_le (mul_nonneg _ _), h⟩
    exacts [Nat.cast_nonneg _, zero_le_two]
  · refine' ⟨_, le_trans (mul_nonpos_of_nonpos_of_nonneg _ zero_le_two) <| Nat.cast_nonneg _⟩
    · 

Proof state:
case neg.refine'_1
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : ¬↑(val x) * 2 ≤ ↑n
⊢ -↑n < (↑(val x) - ↑n) * 2

Next tactic:
linarith only [h]
theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n := by
  simp_rw [valMinAbs_def_pos, Nat.le_div_two_iff_mul_two_le]; split_ifs with h
  · refine' ⟨(neg_lt_zero.2 <| mod_cast NeZero.pos n).trans_le (mul_nonneg _ _), h⟩
    exacts [Nat.cast_nonneg _, zero_le_two]
  · refine' ⟨_, le_trans (mul_nonpos_of_nonpos_of_nonneg _ zero_le_two) <| Nat.cast_nonneg _⟩
    · linarith only [h]
    · 

Proof state:
case neg.refine'_2
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : ¬↑(val x) * 2 ≤ ↑n
⊢ ↑(val x) - ↑n ≤ 0

Next tactic:
rw [sub_nonpos, Int.ofNat_le]
theorem valMinAbs_mem_Ioc {n : ℕ} [NeZero n] (x : ZMod n) :
    x.valMinAbs * 2 ∈ Set.Ioc (-n : ℤ) n := by
  simp_rw [valMinAbs_def_pos, Nat.le_div_two_iff_mul_two_le]; split_ifs with h
  · refine' ⟨(neg_lt_zero.2 <| mod_cast NeZero.pos n).trans_le (mul_nonneg _ _), h⟩
    exacts [Nat.cast_nonneg _, zero_le_two]
  · refine' ⟨_, le_trans (mul_nonpos_of_nonpos_of_nonneg _ zero_le_two) <| Nat.cast_nonneg _⟩
    · linarith only [h]
    · rw [sub_nonpos, Int.ofNat_le]
      

Proof state:
case neg.refine'_2
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : ¬↑(val x) * 2 ≤ ↑n
⊢ val x ≤ n

Next tactic:
exact x.val_lt.le
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    

Proof state:
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
⊢ valMinAbs x = y → x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n

Next tactic:
rintro rfl
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    

Proof state:
n : ℕ
inst✝ : NeZero n
x : ZMod n
⊢ x = ↑(valMinAbs x) ∧ valMinAbs x * 2 ∈ Set.Ioc (-↑n) ↑n

Next tactic:
exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        

Proof state:
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ valMinAbs x = y

Next tactic:
rw [← sub_eq_zero]
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        

Proof state:
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ valMinAbs x - y = 0

Next tactic:
apply @Int.eq_zero_of_abs_lt_dvd n
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · 

Proof state:
case h1
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ ↑n ∣ valMinAbs x - y

Next tactic:
rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
        

Proof state:
case h2
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ |valMinAbs x - y| < ↑n

Next tactic:
rw [← mul_lt_mul_right (@zero_lt_two ℤ _ _ _ _ _)]
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
        rw [← mul_lt_mul_right (@zero_lt_two ℤ _ _ _ _ _)]
        

Proof state:
case h2
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ |valMinAbs x - y| * 2 < ↑n * 2

Next tactic:
nth_rw 1 [← abs_eq_self.2 (@zero_le_two ℤ _ _ _ _)]
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
        rw [← mul_lt_mul_right (@zero_lt_two ℤ _ _ _ _ _)]
        nth_rw 1 [← abs_eq_self.2 (@zero_le_two ℤ _ _ _ _)]
        

Proof state:
case h2
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ |valMinAbs x - y| * |2| < ↑n * 2

Next tactic:
rw [← abs_mul, sub_mul, abs_lt]
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
        rw [← mul_lt_mul_right (@zero_lt_two ℤ _ _ _ _ _)]
        nth_rw 1 [← abs_eq_self.2 (@zero_le_two ℤ _ _ _ _)]
        rw [← abs_mul, sub_mul, abs_lt]
        

Proof state:
case h2
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ -(↑n * 2) < valMinAbs x * 2 - y * 2 ∧ valMinAbs x * 2 - y * 2 < ↑n * 2

Next tactic:
constructor
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
        rw [← mul_lt_mul_right (@zero_lt_two ℤ _ _ _ _ _)]
        nth_rw 1 [← abs_eq_self.2 (@zero_le_two ℤ _ _ _ _)]
        rw [← abs_mul, sub_mul, abs_lt]
        constructor <;> 

Proof state:
case h2.left
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ -(↑n * 2) < valMinAbs x * 2 - y * 2

Next tactic:
linarith only [x.valMinAbs_mem_Ioc.1, x.valMinAbs_mem_Ioc.2, h.2.1, h.2.2]
theorem valMinAbs_spec {n : ℕ} [NeZero n] (x : ZMod n) (y : ℤ) :
    x.valMinAbs = y ↔ x = y ∧ y * 2 ∈ Set.Ioc (-n : ℤ) n :=
  ⟨by
    rintro rfl
    exact ⟨x.coe_valMinAbs.symm, x.valMinAbs_mem_Ioc⟩, fun h =>
      by
        rw [← sub_eq_zero]
        apply @Int.eq_zero_of_abs_lt_dvd n
        · rw [← int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub, coe_valMinAbs, h.1, sub_self]
        rw [← mul_lt_mul_right (@zero_lt_two ℤ _ _ _ _ _)]
        nth_rw 1 [← abs_eq_self.2 (@zero_le_two ℤ _ _ _ _)]
        rw [← abs_mul, sub_mul, abs_lt]
        constructor <;> 

Proof state:
case h2.right
n : ℕ
inst✝ : NeZero n
x : ZMod n
y : ℤ
h : x = ↑y ∧ y * 2 ∈ Set.Ioc (-↑n) ↑n
⊢ valMinAbs x * 2 - y * 2 < ↑n * 2

Next tactic:
linarith only [x.valMinAbs_mem_Ioc.1, x.valMinAbs_mem_Ioc.2, h.2.1, h.2.2]
theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 := by
  

Proof state:
n : ℕ
inst✝ : NeZero n
x : ZMod n
⊢ Int.natAbs (valMinAbs x) ≤ n / 2

Next tactic:
rw [Nat.le_div_two_iff_mul_two_le]
theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 := by
  rw [Nat.le_div_two_iff_mul_two_le]
  

Proof state:
n : ℕ
inst✝ : NeZero n
x : ZMod n
⊢ ↑(Int.natAbs (valMinAbs x)) * 2 ≤ ↑n

Next tactic:
cases' x.valMinAbs.natAbs_eq with h h
theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 := by
  rw [Nat.le_div_two_iff_mul_two_le]
  cases' x.valMinAbs.natAbs_eq with h h
  · 

Proof state:
case inl
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : valMinAbs x = ↑(Int.natAbs (valMinAbs x))
⊢ ↑(Int.natAbs (valMinAbs x)) * 2 ≤ ↑n

Next tactic:
rw [← h]
theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 := by
  rw [Nat.le_div_two_iff_mul_two_le]
  cases' x.valMinAbs.natAbs_eq with h h
  · rw [← h]
    

Proof state:
case inl
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : valMinAbs x = ↑(Int.natAbs (valMinAbs x))
⊢ valMinAbs x * 2 ≤ ↑n

Next tactic:
exact x.valMinAbs_mem_Ioc.2
theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 := by
  rw [Nat.le_div_two_iff_mul_two_le]
  cases' x.valMinAbs.natAbs_eq with h h
  · rw [← h]
    exact x.valMinAbs_mem_Ioc.2
  · 

Proof state:
case inr
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : valMinAbs x = -↑(Int.natAbs (valMinAbs x))
⊢ ↑(Int.natAbs (valMinAbs x)) * 2 ≤ ↑n

Next tactic:
rw [← neg_le_neg_iff, ← neg_mul, ← h]
theorem natAbs_valMinAbs_le {n : ℕ} [NeZero n] (x : ZMod n) : x.valMinAbs.natAbs ≤ n / 2 := by
  rw [Nat.le_div_two_iff_mul_two_le]
  cases' x.valMinAbs.natAbs_eq with h h
  · rw [← h]
    exact x.valMinAbs_mem_Ioc.2
  · rw [← neg_le_neg_iff, ← neg_mul, ← h]
    

Proof state:
case inr
n : ℕ
inst✝ : NeZero n
x : ZMod n
h : valMinAbs x = -↑(Int.natAbs (valMinAbs x))
⊢ -↑n ≤ valMinAbs x * 2

Next tactic:
exact x.valMinAbs_mem_Ioc.1.le
@[simp]
theorem valMinAbs_zero : ∀ n, (0 : ZMod n).valMinAbs = 0
  | 0 => by 

Proof state:
⊢ valMinAbs 0 = 0

Next tactic:
simp only [valMinAbs_def_zero]
@[simp]
theorem valMinAbs_zero : ∀ n, (0 : ZMod n).valMinAbs = 0
  | 0 => by simp only [valMinAbs_def_zero]
  | n + 1 => by 

Proof state:
n : ℕ
⊢ valMinAbs 0 = 0

Next tactic:
simp only [valMinAbs_def_pos, if_true, Int.ofNat_zero, zero_le, val_zero]
@[simp]
theorem valMinAbs_eq_zero {n : ℕ} (x : ZMod n) : x.valMinAbs = 0 ↔ x = 0 := by
  

Proof state:
n : ℕ
x : ZMod n
⊢ valMinAbs x = 0 ↔ x = 0

Next tactic:
cases' n with n
@[simp]
theorem valMinAbs_eq_zero {n : ℕ} (x : ZMod n) : x.valMinAbs = 0 ↔ x = 0 := by
  cases' n with n
  · 

Proof state:
case zero
x : ZMod Nat.zero
⊢ valMinAbs x = 0 ↔ x = 0

Next tactic:
simp
@[simp]
theorem valMinAbs_eq_zero {n : ℕ} (x : ZMod n) : x.valMinAbs = 0 ↔ x = 0 := by
  cases' n with n
  · simp
  

Proof state:
case succ
n : ℕ
x : ZMod (Nat.succ n)
⊢ valMinAbs x = 0 ↔ x = 0

Next tactic:
rw [← valMinAbs_zero n.succ]
@[simp]
theorem valMinAbs_eq_zero {n : ℕ} (x : ZMod n) : x.valMinAbs = 0 ↔ x = 0 := by
  cases' n with n
  · simp
  rw [← valMinAbs_zero n.succ]
  

Proof state:
case succ
n : ℕ
x : ZMod (Nat.succ n)
⊢ valMinAbs x = valMinAbs 0 ↔ x = 0

Next tactic:
apply injective_valMinAbs.eq_iff
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
⊢ ↑(Int.natAbs (valMinAbs a)) = if val a ≤ n / 2 then a else -a

Next tactic:
have : (a.val : ℤ) - n ≤ 0 := by
    erw [sub_nonpos, Int.ofNat_le]
    exact a.val_le
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  have : (a.val : ℤ) - n ≤ 0 := by
    

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
⊢ ↑(val a) - ↑n ≤ 0

Next tactic:
erw [sub_nonpos, Int.ofNat_le]
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  have : (a.val : ℤ) - n ≤ 0 := by
    erw [sub_nonpos, Int.ofNat_le]
    

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

Next tactic:
exact a.val_le
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  have : (a.val : ℤ) - n ≤ 0 := by
    erw [sub_nonpos, Int.ofNat_le]
    exact a.val_le
  

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
this : ↑(val a) - ↑n ≤ 0
⊢ ↑(Int.natAbs (valMinAbs a)) = if val a ≤ n / 2 then a else -a

Next tactic:
rw [valMinAbs_def_pos]
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  have : (a.val : ℤ) - n ≤ 0 := by
    erw [sub_nonpos, Int.ofNat_le]
    exact a.val_le
  rw [valMinAbs_def_pos]
  

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
this : ↑(val a) - ↑n ≤ 0
⊢ ↑(Int.natAbs (if val a ≤ n / 2 then ↑(val a) else ↑(val a) - ↑n)) = if val a ≤ n / 2 then a else -a

Next tactic:
split_ifs
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  have : (a.val : ℤ) - n ≤ 0 := by
    erw [sub_nonpos, Int.ofNat_le]
    exact a.val_le
  rw [valMinAbs_def_pos]
  split_ifs
  · 

Proof state:
case pos
n : ℕ
inst✝ : NeZero n
a : ZMod n
this : ↑(val a) - ↑n ≤ 0
h✝ : val a ≤ n / 2
⊢ ↑(Int.natAbs ↑(val a)) = a

Next tactic:
rw [Int.natAbs_ofNat, nat_cast_zmod_val]
theorem nat_cast_natAbs_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.valMinAbs.natAbs : ZMod n) = if a.val ≤ (n : ℕ) / 2 then a else -a := by
  have : (a.val : ℤ) - n ≤ 0 := by
    erw [sub_nonpos, Int.ofNat_le]
    exact a.val_le
  rw [valMinAbs_def_pos]
  split_ifs
  · rw [Int.natAbs_ofNat, nat_cast_zmod_val]
  · 

Proof state:
case neg
n : ℕ
inst✝ : NeZero n
a : ZMod n
this : ↑(val a) - ↑n ≤ 0
h✝ : ¬val a ≤ n / 2
⊢ ↑(Int.natAbs (↑(val a) - ↑n)) = -a

Next tactic:
rw [← Int.cast_ofNat, Int.ofNat_natAbs_of_nonpos this, Int.cast_neg, Int.cast_sub,
      Int.cast_ofNat, Int.cast_ofNat, nat_cast_self, sub_zero, nat_cast_zmod_val]
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  

Proof state:
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
⊢ valMinAbs (-a) = -valMinAbs a

Next tactic:
cases' eq_zero_or_neZero n with h h
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · 

Proof state:
case inl
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
h : n = 0
⊢ valMinAbs (-a) = -valMinAbs a

Next tactic:
subst h
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · subst h
    

Proof state:
case inl
a : ZMod 0
ha : 2 * val a ≠ 0
⊢ valMinAbs (-a) = -valMinAbs a

Next tactic:
rfl
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · subst h
    rfl
  

Proof state:
case inr
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
h : NeZero n
⊢ valMinAbs (-a) = -valMinAbs a

Next tactic:
refine' (valMinAbs_spec _ _).2 ⟨_, _, _⟩
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · subst h
    rfl
  refine' (valMinAbs_spec _ _).2 ⟨_, _, _⟩
  · 

Proof state:
case inr.refine'_1
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
h : NeZero n
⊢ -a = ↑(-valMinAbs a)

Next tactic:
rw [Int.cast_neg, coe_valMinAbs]
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · subst h
    rfl
  refine' (valMinAbs_spec _ _).2 ⟨_, _, _⟩
  · rw [Int.cast_neg, coe_valMinAbs]
  · 

Proof state:
case inr.refine'_2
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
h : NeZero n
⊢ -↑n < -valMinAbs a * 2

Next tactic:
rw [neg_mul, neg_lt_neg_iff]
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · subst h
    rfl
  refine' (valMinAbs_spec _ _).2 ⟨_, _, _⟩
  · rw [Int.cast_neg, coe_valMinAbs]
  · rw [neg_mul, neg_lt_neg_iff]
    

Proof state:
case inr.refine'_2
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
h : NeZero n
⊢ valMinAbs a * 2 < ↑n

Next tactic:
exact a.valMinAbs_mem_Ioc.2.lt_of_ne (mt a.valMinAbs_mul_two_eq_iff.1 ha)
theorem valMinAbs_neg_of_ne_half {n : ℕ} {a : ZMod n} (ha : 2 * a.val ≠ n) :
    (-a).valMinAbs = -a.valMinAbs := by
  cases' eq_zero_or_neZero n with h h
  · subst h
    rfl
  refine' (valMinAbs_spec _ _).2 ⟨_, _, _⟩
  · rw [Int.cast_neg, coe_valMinAbs]
  · rw [neg_mul, neg_lt_neg_iff]
    exact a.valMinAbs_mem_Ioc.2.lt_of_ne (mt a.valMinAbs_mul_two_eq_iff.1 ha)
  · 

Proof state:
case inr.refine'_3
n : ℕ
a : ZMod n
ha : 2 * val a ≠ n
h : NeZero n
⊢ -valMinAbs a * 2 ≤ ↑n

Next tactic:
linarith only [a.valMinAbs_mem_Ioc.1]
@[simp]
theorem natAbs_valMinAbs_neg {n : ℕ} (a : ZMod n) : (-a).valMinAbs.natAbs = a.valMinAbs.natAbs := by
  

Proof state:
n : ℕ
a : ZMod n
⊢ Int.natAbs (valMinAbs (-a)) = Int.natAbs (valMinAbs a)

Next tactic:
by_cases h2a : 2 * a.val = n
@[simp]
theorem natAbs_valMinAbs_neg {n : ℕ} (a : ZMod n) : (-a).valMinAbs.natAbs = a.valMinAbs.natAbs := by
  by_cases h2a : 2 * a.val = n
  · 

Proof state:
case pos
n : ℕ
a : ZMod n
h2a : 2 * val a = n
⊢ Int.natAbs (valMinAbs (-a)) = Int.natAbs (valMinAbs a)

Next tactic:
rw [a.neg_eq_self_iff.2 (Or.inr h2a)]
@[simp]
theorem natAbs_valMinAbs_neg {n : ℕ} (a : ZMod n) : (-a).valMinAbs.natAbs = a.valMinAbs.natAbs := by
  by_cases h2a : 2 * a.val = n
  · rw [a.neg_eq_self_iff.2 (Or.inr h2a)]
  · 

Proof state:
case neg
n : ℕ
a : ZMod n
h2a : ¬2 * val a = n
⊢ Int.natAbs (valMinAbs (-a)) = Int.natAbs (valMinAbs a)

Next tactic:
rw [valMinAbs_neg_of_ne_half h2a, Int.natAbs_neg]
theorem val_eq_ite_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.val : ℤ) = a.valMinAbs + if a.val ≤ n / 2 then 0 else n := by
  

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
⊢ ↑(val a) = valMinAbs a + ↑(if val a ≤ n / 2 then 0 else n)

Next tactic:
rw [valMinAbs_def_pos]
theorem val_eq_ite_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.val : ℤ) = a.valMinAbs + if a.val ≤ n / 2 then 0 else n := by
  rw [valMinAbs_def_pos]
  

Proof state:
n : ℕ
inst✝ : NeZero n
a : ZMod n
⊢ ↑(val a) = (if val a ≤ n / 2 then ↑(val a) else ↑(val a) - ↑n) + ↑(if val a ≤ n / 2 then 0 else n)

Next tactic:
split_ifs
theorem val_eq_ite_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.val : ℤ) = a.valMinAbs + if a.val ≤ n / 2 then 0 else n := by
  rw [valMinAbs_def_pos]
  split_ifs <;> 

Proof state:
case pos
n : ℕ
inst✝ : NeZero n
a : ZMod n
h✝ : val a ≤ n / 2
⊢ ↑(val a) = ↑(val a) + ↑0

Next tactic:
simp [add_zero, sub_add_cancel]
theorem val_eq_ite_valMinAbs {n : ℕ} [NeZero n] (a : ZMod n) :
    (a.val : ℤ) = a.valMinAbs + if a.val ≤ n / 2 then 0 else n := by
  rw [valMinAbs_def_pos]
  split_ifs <;> 

Proof state:
case neg
n : ℕ
inst✝ : NeZero n
a : ZMod n
h✝ : ¬val a ≤ n / 2
⊢ ↑(val a) = ↑(val a) - ↑n + ↑n

Next tactic:
simp [add_zero, sub_add_cancel]
theorem prime_ne_zero (p q : ℕ) [hp : Fact p.Prime] [hq : Fact q.Prime] (hpq : p ≠ q) :
    (q : ZMod p) ≠ 0 := by
  

Proof state:
p q : ℕ
hp : Fact (Nat.Prime p)
hq : Fact (Nat.Prime q)
hpq : p ≠ q
⊢ ↑q ≠ 0

Next tactic:
rwa [← Nat.cast_zero, Ne.def, eq_iff_modEq_nat, Nat.modEq_zero_iff_dvd, ←
    hp.1.coprime_iff_not_dvd, Nat.coprime_primes hp.1 hq.1]
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  

Proof state:
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
⊢ Int.natAbs (valMinAbs a) = min (val a) (n - val a)

Next tactic:
rw [valMinAbs_def_pos]
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  rw [valMinAbs_def_pos]
  

Proof state:
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
⊢ Int.natAbs (if val a ≤ n / 2 then ↑(val a) else ↑(val a) - ↑n) = min (val a) (n - val a)

Next tactic:
split_ifs with h
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  rw [valMinAbs_def_pos]
  split_ifs with h
  · 

Proof state:
case pos
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
h : val a ≤ n / 2
⊢ Int.natAbs ↑(val a) = min (val a) (n - val a)

Next tactic:
rw [Int.natAbs_ofNat]
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  rw [valMinAbs_def_pos]
  split_ifs with h
  · rw [Int.natAbs_ofNat]
    

Proof state:
case pos
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
h : val a ≤ n / 2
⊢ val a = min (val a) (n - val a)

Next tactic:
symm
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  rw [valMinAbs_def_pos]
  split_ifs with h
  · rw [Int.natAbs_ofNat]
    symm
    

Proof state:
case pos
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
h : val a ≤ n / 2
⊢ min (val a) (n - val a) = val a

Next tactic:
apply
      min_eq_left (le_trans h (le_trans (Nat.half_le_of_sub_le_half _) (Nat.sub_le_sub_left h n)))
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  rw [valMinAbs_def_pos]
  split_ifs with h
  · rw [Int.natAbs_ofNat]
    symm
    apply
      min_eq_left (le_trans h (le_trans (Nat.half_le_of_sub_le_half _) (Nat.sub_le_sub_left h n)))
    

Proof state:
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
h : val a ≤ n / 2
⊢ n - (n - n / 2) ≤ n / 2

Next tactic:
rw [Nat.sub_sub_self (Nat.div_le_self _ _)]
theorem valMinAbs_natAbs_eq_min {n : ℕ} [hpos : NeZero n] (a : ZMod n) :
    a.valMinAbs.natAbs = min a.val (n - a.val) := by
  rw [valMinAbs_def_pos]
  split_ifs with h
  · rw [Int.natAbs_ofNat]
    symm
    apply
      min_eq_left (le_trans h (le_trans (Nat.half_le_of_sub_le_half _) (Nat.sub_le_sub_left h n)))
    rw [Nat.sub_sub_self (Nat.div_le_self _ _)]
  · 

Proof state:
case neg
n✝ a✝ n : ℕ
hpos : NeZero n
a : ZMod n
h : ¬val a ≤ n / 2
⊢ Int.natAbs (↑(val a) - ↑n) = min (val a) (n - val a)

Next tactic:
rw [← Int.natAbs_neg, neg_sub, ← Nat.cast_sub a.val_le]