Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 2da9bef

Browse files
committed
feat(data/nat/cast,...): add char_zero typeclass for cast_inj
As pointed out by @kbuzzard, the complex numbers are an important example of an unordered characteristic zero field for which we will want cast_inj to be available.
1 parent 2883c1b commit 2da9bef

File tree

3 files changed

+88
-35
lines changed

3 files changed

+88
-35
lines changed

data/int/basic.lean

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,19 @@ end
862862
theorem cast_sub [add_group α] [has_one α] (m n) : ((m - n : ℤ) : α) = m - n :=
863863
by simp
864864

865+
@[simp] theorem cast_eq_zero [add_group α] [has_one α] [char_zero α] {n : ℤ} : (n : α) = 0 ↔ n = 0 :=
866+
⟨λ h, begin cases n,
867+
{ exact congr_arg coe (nat.cast_eq_zero.1 h) },
868+
{ rw [cast_neg_succ_of_nat, neg_eq_zero, ← cast_succ, nat.cast_eq_zero] at h,
869+
contradiction }
870+
end, λ h, by rw [h, cast_zero]⟩
871+
872+
@[simp] theorem cast_inj [add_group α] [has_one α] [char_zero α] {m n : ℤ} : (m : α) = n ↔ m = n :=
873+
by rw [← sub_eq_zero, ← cast_sub, cast_eq_zero, sub_eq_zero]
874+
875+
@[simp] theorem cast_ne_zero [add_group α] [has_one α] [char_zero α] {n : ℤ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
876+
not_congr cast_eq_zero
877+
865878
@[simp] theorem cast_mul [ring α] : ∀ m n, ((m * n : ℤ) : α) = m * n
866879
| (m : ℕ) (n : ℕ) := nat.cast_mul _ _
867880
| (m : ℕ) -[1+ n] := (cast_neg_of_nat _).trans $
@@ -901,15 +914,6 @@ by rw [← cast_zero, cast_lt]
901914
@[simp] theorem cast_lt_zero [linear_ordered_ring α] {n : ℤ} : (n : α) < 0 ↔ n < 0 :=
902915
by rw [← cast_zero, cast_lt]
903916

904-
@[simp] theorem cast_inj [linear_ordered_ring α] {m n : ℤ} : (m : α) = n ↔ m = n :=
905-
by simp [le_antisymm_iff]
906-
907-
@[simp] theorem cast_eq_zero [linear_ordered_ring α] {n : ℤ} : (n : α) = 0 ↔ n = 0 :=
908-
by rw [← cast_zero, cast_inj]
909-
910-
@[simp] theorem cast_ne_zero [linear_ordered_ring α] {n : ℤ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
911-
not_congr cast_eq_zero
912-
913917
@[simp] theorem cast_id : ∀ n : ℤ, ↑n = n
914918
| (n : ℕ) := (cast_coe_nat n).trans (nat_cast_eq_coe_nat n)
915919
| -[1+ n] := eq.trans (by rw ← nat_cast_eq_coe_nat; refl) (neg_succ_of_nat_eq _).symm

data/nat/cast.lean

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,6 @@ by simpa [-cast_le] using not_congr (@cast_le α _ n m)
6767
@[simp] theorem cast_pos [linear_ordered_ring α] {n : ℕ} : (0 : α) < n ↔ 0 < n :=
6868
by rw [← cast_zero, cast_lt]
6969

70-
@[simp] theorem cast_inj [linear_ordered_semiring α] {m n : ℕ} : (m : α) = n ↔ m = n :=
71-
by simp [le_antisymm_iff]
72-
73-
@[simp] theorem cast_eq_zero [linear_ordered_semiring α] {n : ℕ} : (n : α) = 0 ↔ n = 0 :=
74-
by rw [← cast_zero, cast_inj]
75-
76-
@[simp] theorem cast_ne_zero [linear_ordered_semiring α] {n : ℕ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
77-
not_congr cast_eq_zero
78-
7970
@[simp] theorem cast_id : ∀ n : ℕ, ↑n = n
8071
| 0 := rfl
8172
| (n+1) := congr_arg (+1) (cast_id n)
@@ -87,3 +78,48 @@ by by_cases a ≤ b; simp [h, min]
8778
by by_cases a ≤ b; simp [h, max]
8879

8980
end nat
81+
82+
class char_zero (α : Type*) [add_monoid α] [has_one α] : Prop :=
83+
(cast_inj : ∀ {m n : ℕ}, (m : α) = n ↔ m = n)
84+
85+
theorem char_zero_of_inj_zero {α : Type*} [add_monoid α] [has_one α]
86+
(add_left_cancel : ∀ a b c : α, a + b = a + c → b = c)
87+
(H : ∀ n:ℕ, (n:α) = 0 → n = 0) : char_zero α :=
88+
⟨λ m n, ⟨suffices ∀ {m n : ℕ}, (m:α) = n → m ≤ n,
89+
from λ h, le_antisymm (this h) (this h.symm),
90+
λ m n h, (le_total m n).elim id $ λ h2, le_of_eq $ begin
91+
cases nat.le.dest h2 with k e,
92+
suffices : k = 0, {simp [this] at e, rw e},
93+
apply H, apply add_left_cancel n,
94+
rw [← nat.cast_add, e, add_zero, h]
95+
end,
96+
congr_arg _⟩⟩
97+
98+
theorem add_group.char_zero_of_inj_zero {α : Type*} [add_group α] [has_one α]
99+
(H : ∀ n:ℕ, (n:α) = 0 → n = 0) : char_zero α :=
100+
char_zero_of_inj_zero (@add_left_cancel _ _) H
101+
102+
theorem ordered_cancel_comm_monoid.char_zero_of_inj_zero {α : Type*}
103+
[ordered_cancel_comm_monoid α] [has_one α]
104+
(H : ∀ n:ℕ, (n:α) = 0 → n = 0) : char_zero α :=
105+
char_zero_of_inj_zero (@add_left_cancel _ _) H
106+
107+
instance linear_ordered_semiring.to_char_zero {α : Type*}
108+
[linear_ordered_semiring α] : char_zero α :=
109+
ordered_cancel_comm_monoid.char_zero_of_inj_zero $
110+
λ n h, nat.eq_zero_of_le_zero $
111+
(@nat.cast_le α _ _ _).1 (by simp [h])
112+
113+
namespace nat
114+
variables {α : Type*} [add_monoid α] [has_one α] [char_zero α]
115+
116+
@[simp] theorem cast_inj {m n : ℕ} : (m : α) = n ↔ m = n :=
117+
char_zero.cast_inj _
118+
119+
@[simp] theorem cast_eq_zero {n : ℕ} : (n : α) = 0 ↔ n = 0 :=
120+
by rw [← cast_zero, cast_inj]
121+
122+
@[simp] theorem cast_ne_zero {n : ℕ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
123+
not_congr cast_eq_zero
124+
125+
end nat

data/rat.lean

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -723,32 +723,54 @@ have (n⁻¹.denom : α) = 0 → (n.num : α) = 0, from
723723
rwa [int.cast_mul, int.cast_coe_nat, h, zero_mul] at this,
724724
by rw [division_def, cast_mul_of_ne_zero md (mt this nn), cast_inv_of_ne_zero nn nd, division_def]
725725

726+
@[simp] theorem cast_inj [char_zero α] : ∀ {m n : ℚ}, (m : α) = n ↔ m = n
727+
| ⟨n₁, d₁, h₁, c₁⟩ ⟨n₂, d₂, h₂, c₂⟩ := begin
728+
refine ⟨λ h, _, congr_arg _⟩,
729+
have d₁0 : d₁ ≠ 0 := ne_of_gt h₁,
730+
have d₂0 : d₂ ≠ 0 := ne_of_gt h₂,
731+
have d₁a : (d₁:α) ≠ 0 := nat.cast_ne_zero.2 d₁0,
732+
have d₂a : (d₂:α) ≠ 0 := nat.cast_ne_zero.2 d₂0,
733+
rw [num_denom', num_denom'] at h ⊢,
734+
rw [cast_mk_of_ne_zero, cast_mk_of_ne_zero] at h; simp [d₁0, d₂0] at h ⊢,
735+
rwa [eq_div_iff_mul_eq _ _ d₂a, division_def, mul_assoc,
736+
inv_comm_of_comm d₁a (nat.mul_cast_comm _ _),
737+
← mul_assoc, ← division_def, eq_comm, eq_div_iff_mul_eq _ _ d₁a, eq_comm,
738+
← int.cast_coe_nat, ← int.cast_mul, ← int.cast_coe_nat, ← int.cast_mul,
739+
int.cast_inj, ← mk_eq (int.coe_nat_ne_zero.2 d₁0) (int.coe_nat_ne_zero.2 d₂0)] at h
726740
end
727741

728-
theorem cast_mk [discrete_linear_ordered_field α] (a b : ℤ) : ((a /. b) : α) = a / b :=
742+
@[simp] theorem cast_eq_zero [char_zero α] {n : ℚ} : (n : α) = 0 ↔ n = 0 :=
743+
by rw [← cast_zero, cast_inj]
744+
745+
@[simp] theorem cast_ne_zero [char_zero α] {n : ℚ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
746+
not_congr cast_eq_zero
747+
748+
end
749+
750+
theorem cast_mk [discrete_field α] [char_zero α] (a b : ℤ) : ((a /. b) : α) = a / b :=
729751
if b0 : b = 0 then by simp [b0, div_zero]
730752
else cast_mk_of_ne_zero a b (int.cast_ne_zero.2 b0)
731753

732-
@[simp] theorem cast_add [linear_ordered_field α] (m n) : ((m + n : ℚ) : α) = m + n :=
754+
@[simp] theorem cast_add [division_ring α] [char_zero α] (m n) : ((m + n : ℚ) : α) = m + n :=
733755
cast_add_of_ne_zero (nat.cast_ne_zero.2 $ ne_of_gt m.pos) (nat.cast_ne_zero.2 $ ne_of_gt n.pos)
734756

735-
@[simp] theorem cast_sub [linear_ordered_field α] (m n) : ((m - n : ℚ) : α) = m - n :=
757+
@[simp] theorem cast_sub [division_ring α] [char_zero α] (m n) : ((m - n : ℚ) : α) = m - n :=
736758
cast_sub_of_ne_zero (nat.cast_ne_zero.2 $ ne_of_gt m.pos) (nat.cast_ne_zero.2 $ ne_of_gt n.pos)
737759

738-
@[simp] theorem cast_mul [linear_ordered_field α] (m n) : ((m * n : ℚ) : α) = m * n :=
760+
@[simp] theorem cast_mul [division_ring α] [char_zero α] (m n) : ((m * n : ℚ) : α) = m * n :=
739761
cast_mul_of_ne_zero (nat.cast_ne_zero.2 $ ne_of_gt m.pos) (nat.cast_ne_zero.2 $ ne_of_gt n.pos)
740762

741-
@[simp] theorem cast_inv [discrete_linear_ordered_field α] (n) : ((n⁻¹ : ℚ) : α) = n⁻¹ :=
763+
@[simp] theorem cast_inv [discrete_field α] [char_zero α] (n) : ((n⁻¹ : ℚ) : α) = n⁻¹ :=
742764
if n0 : n.num = 0 then
743765
by simp [show n = 0, by rw [num_denom n, n0]; simp, inv_zero] else
744766
cast_inv_of_ne_zero (int.cast_ne_zero.2 n0) (nat.cast_ne_zero.2 $ ne_of_gt n.pos)
745767

746-
@[simp] theorem cast_div [discrete_linear_ordered_field α] (m n) : ((m / n : ℚ) : α) = m / n :=
768+
@[simp] theorem cast_div [discrete_field α] [char_zero α] (m n) : ((m / n : ℚ) : α) = m / n :=
747769
by rw [division_def, cast_mul, cast_inv, division_def]
748770

749-
@[simp] theorem cast_bit0 [linear_ordered_field α] (n : ℚ) : ((bit0 n : ℚ) : α) = bit0 n := cast_add _ _
771+
@[simp] theorem cast_bit0 [division_ring α] [char_zero α] (n : ℚ) : ((bit0 n : ℚ) : α) = bit0 n := cast_add _ _
750772

751-
@[simp] theorem cast_bit1 [linear_ordered_field α] (n : ℚ) : ((bit1 n : ℚ) : α) = bit1 n :=
773+
@[simp] theorem cast_bit1 [division_ring α] [char_zero α] (n : ℚ) : ((bit1 n : ℚ) : α) = bit1 n :=
752774
by rw [bit1, cast_add, cast_one, cast_bit0]; refl
753775

754776
@[simp] theorem cast_nonneg [linear_ordered_field α] : ∀ {n : ℚ}, 0 ≤ (n : α) ↔ 0 ≤ n
@@ -763,9 +785,6 @@ by rw [← sub_nonneg, ← cast_sub, cast_nonneg, sub_nonneg]
763785
@[simp] theorem cast_lt [linear_ordered_field α] {m n : ℚ} : (m : α) < n ↔ m < n :=
764786
by simpa [-cast_le] using not_congr (@cast_le α _ n m)
765787

766-
@[simp] theorem cast_inj [linear_ordered_field α] {m n : ℚ} : (m : α) = n ↔ m = n :=
767-
by simp [le_antisymm_iff]
768-
769788
@[simp] theorem cast_nonpos [linear_ordered_field α] {n : ℚ} : (n : α) ≤ 0 ↔ n ≤ 0 :=
770789
by rw [← cast_zero, cast_le]
771790

@@ -775,12 +794,6 @@ by rw [← cast_zero, cast_lt]
775794
@[simp] theorem cast_lt_zero [linear_ordered_field α] {n : ℚ} : (n : α) < 0 ↔ n < 0 :=
776795
by rw [← cast_zero, cast_lt]
777796

778-
@[simp] theorem cast_eq_zero [linear_ordered_field α] {n : ℚ} : (n : α) = 0 ↔ n = 0 :=
779-
by rw [← cast_zero, cast_inj]
780-
781-
@[simp] theorem cast_ne_zero [linear_ordered_field α] {n : ℚ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
782-
not_congr cast_eq_zero
783-
784797
@[simp] theorem cast_id : ∀ n : ℚ, ↑n = n
785798
| ⟨n, d, h, c⟩ := show (n / (d : ℤ) : ℚ) = _, by rw [num_denom', mk_eq_div]
786799

0 commit comments

Comments
 (0)