|
| 1 | +/- |
| 2 | +Copyright (c) 2016 Jeremy Avigad. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Jeremy Avigad |
| 5 | +-/ |
| 6 | +import Mathlib.Data.Nat.Units |
| 7 | +import Mathlib.Data.Int.Basic |
| 8 | +import Mathlib.Algebra.Ring.Units |
| 9 | + |
| 10 | +/-! |
| 11 | +# Lemmas about units in `ℤ`. |
| 12 | +-/ |
| 13 | + |
| 14 | + |
| 15 | +namespace Int |
| 16 | + |
| 17 | +/-! ### units -/ |
| 18 | + |
| 19 | +@[simp] |
| 20 | +theorem units_natAbs (u : ℤˣ) : natAbs u = 1 := |
| 21 | + Units.ext_iff.1 <| |
| 22 | + Nat.units_eq_one |
| 23 | + ⟨natAbs u, natAbs ↑u⁻¹, by rw [← natAbs_mul, Units.mul_inv]; rfl, by |
| 24 | + rw [← natAbs_mul, Units.inv_mul]; rfl⟩ |
| 25 | +#align int.units_nat_abs Int.units_natAbs |
| 26 | + |
| 27 | +theorem units_eq_one_or (u : ℤˣ) : u = 1 ∨ u = -1 := by |
| 28 | + simpa only [Units.ext_iff, units_natAbs] using natAbs_eq u |
| 29 | +#align int.units_eq_one_or Int.units_eq_one_or |
| 30 | + |
| 31 | +theorem isUnit_eq_one_or {a : ℤ} : IsUnit a → a = 1 ∨ a = -1 |
| 32 | + | ⟨_, hx⟩ => hx ▸ (units_eq_one_or _).imp (congr_arg Units.val) (congr_arg Units.val) |
| 33 | +#align int.is_unit_eq_one_or Int.isUnit_eq_one_or |
| 34 | + |
| 35 | +theorem isUnit_iff {a : ℤ} : IsUnit a ↔ a = 1 ∨ a = -1 := by |
| 36 | + refine' ⟨fun h => isUnit_eq_one_or h, fun h => _⟩ |
| 37 | + rcases h with (rfl | rfl) |
| 38 | + · exact isUnit_one |
| 39 | + · exact isUnit_one.neg |
| 40 | +#align int.is_unit_iff Int.isUnit_iff |
| 41 | + |
| 42 | +theorem isUnit_eq_or_eq_neg {a b : ℤ} (ha : IsUnit a) (hb : IsUnit b) : a = b ∨ a = -b := by |
| 43 | + rcases isUnit_eq_one_or hb with (rfl | rfl) |
| 44 | + · exact isUnit_eq_one_or ha |
| 45 | + · rwa [or_comm, neg_neg, ← isUnit_iff] |
| 46 | +#align int.is_unit_eq_or_eq_neg Int.isUnit_eq_or_eq_neg |
| 47 | + |
| 48 | +theorem eq_one_or_neg_one_of_mul_eq_one {z w : ℤ} (h : z * w = 1) : z = 1 ∨ z = -1 := |
| 49 | + isUnit_iff.mp (isUnit_of_mul_eq_one z w h) |
| 50 | +#align int.eq_one_or_neg_one_of_mul_eq_one Int.eq_one_or_neg_one_of_mul_eq_one |
| 51 | + |
| 52 | +-- Porting note: this was proven in mathlib3 with `tauto` which hasn't been ported yet |
| 53 | +theorem eq_one_or_neg_one_of_mul_eq_one' {z w : ℤ} (h : z * w = 1) : |
| 54 | + z = 1 ∧ w = 1 ∨ z = -1 ∧ w = -1 := by |
| 55 | + have h' : w * z = 1 := mul_comm z w ▸ h |
| 56 | + rcases eq_one_or_neg_one_of_mul_eq_one h with (rfl | rfl) <;> |
| 57 | + rcases eq_one_or_neg_one_of_mul_eq_one h' with (rfl | rfl) <;> |
| 58 | + try cases h |
| 59 | + · exact Or.inl ⟨rfl, rfl⟩ |
| 60 | + · exact Or.inr ⟨rfl, rfl⟩ |
| 61 | +#align int.eq_one_or_neg_one_of_mul_eq_one' Int.eq_one_or_neg_one_of_mul_eq_one' |
| 62 | + |
| 63 | +theorem mul_eq_one_iff_eq_one_or_neg_one {z w : ℤ} : z * w = 1 ↔ z = 1 ∧ w = 1 ∨ z = -1 ∧ w = -1 := |
| 64 | + by |
| 65 | + refine' ⟨eq_one_or_neg_one_of_mul_eq_one', fun h => Or.elim h (fun H => _) fun H => _⟩ <;> |
| 66 | + rcases H with ⟨rfl, rfl⟩ <;> |
| 67 | + rfl |
| 68 | +#align int.mul_eq_one_iff_eq_one_or_neg_one Int.mul_eq_one_iff_eq_one_or_neg_one |
| 69 | + |
| 70 | +theorem eq_one_or_neg_one_of_mul_eq_neg_one' {z w : ℤ} (h : z * w = -1) : |
| 71 | + z = 1 ∧ w = -1 ∨ z = -1 ∧ w = 1 := by |
| 72 | + rcases isUnit_eq_one_or (IsUnit.mul_iff.mp (Int.isUnit_iff.mpr (Or.inr h))).1 with (rfl | rfl) |
| 73 | + · exact Or.inl ⟨rfl, one_mul w ▸ h⟩ |
| 74 | + · exact Or.inr ⟨rfl, neg_inj.mp (neg_one_mul w ▸ h)⟩ |
| 75 | +#align int.eq_one_or_neg_one_of_mul_eq_neg_one' Int.eq_one_or_neg_one_of_mul_eq_neg_one' |
| 76 | + |
| 77 | +theorem mul_eq_neg_one_iff_eq_one_or_neg_one {z w : ℤ} : |
| 78 | + z * w = -1 ↔ z = 1 ∧ w = -1 ∨ z = -1 ∧ w = 1 := by |
| 79 | + refine' ⟨eq_one_or_neg_one_of_mul_eq_neg_one', fun h => Or.elim h (fun H => _) fun H => _⟩ <;> |
| 80 | + rcases H with ⟨rfl, rfl⟩ <;> |
| 81 | + rfl |
| 82 | +#align int.mul_eq_neg_one_iff_eq_one_or_neg_one Int.mul_eq_neg_one_iff_eq_one_or_neg_one |
| 83 | + |
| 84 | +theorem isUnit_iff_natAbs_eq {n : ℤ} : IsUnit n ↔ n.natAbs = 1 := by |
| 85 | + simp [natAbs_eq_iff, isUnit_iff, Nat.cast_zero] |
| 86 | +#align int.is_unit_iff_nat_abs_eq Int.isUnit_iff_natAbs_eq |
| 87 | + |
| 88 | +alias isUnit_iff_natAbs_eq ↔ isUnit.natAbs_eq _ |
| 89 | + |
| 90 | +-- Porting note: `rw` didn't work on `natAbs_ofNat`, so had to change to `simp`, |
| 91 | +-- presumably because `(n : ℤ)` is `Nat.cast` and not just `ofNat` |
| 92 | +@[norm_cast] |
| 93 | +theorem ofNat_isUnit {n : ℕ} : IsUnit (n : ℤ) ↔ IsUnit n := by |
| 94 | + simp [isUnit_iff_natAbs_eq] |
| 95 | +#align int.of_nat_is_unit Int.ofNat_isUnit |
| 96 | + |
| 97 | +theorem isUnit_mul_self {a : ℤ} (ha : IsUnit a) : a * a = 1 := |
| 98 | + (isUnit_eq_one_or ha).elim (fun h => h.symm ▸ rfl) fun h => h.symm ▸ rfl |
| 99 | +#align int.is_unit_mul_self Int.isUnit_mul_self |
| 100 | + |
| 101 | +-- Porting note: this was proven in mathlib3 with `tidy` which hasn't been ported yet |
| 102 | +theorem isUnit_add_isUnit_eq_isUnit_add_isUnit {a b c d : ℤ} (ha : IsUnit a) (hb : IsUnit b) |
| 103 | + (hc : IsUnit c) (hd : IsUnit d) : a + b = c + d ↔ a = c ∧ b = d ∨ a = d ∧ b = c := by |
| 104 | + rw [isUnit_iff] at ha hb hc hd |
| 105 | + cases ha <;> cases hb <;> cases hc <;> cases hd <;> |
| 106 | + subst a <;> subst b <;> subst c <;> subst d <;> |
| 107 | + simp |
| 108 | +#align int.is_unit_add_is_unit_eq_is_unit_add_is_unit Int.isUnit_add_isUnit_eq_isUnit_add_isUnit |
| 109 | + |
| 110 | +theorem eq_one_or_neg_one_of_mul_eq_neg_one {z w : ℤ} (h : z * w = -1) : z = 1 ∨ z = -1 := |
| 111 | + Or.elim (eq_one_or_neg_one_of_mul_eq_neg_one' h) (fun H => Or.inl H.1) fun H => Or.inr H.1 |
| 112 | +#align int.eq_one_or_neg_one_of_mul_eq_neg_one Int.eq_one_or_neg_one_of_mul_eq_neg_one |
| 113 | + |
| 114 | +end Int |
0 commit comments