Skip to content

Commit 3913a5e

Browse files
committed
feat(NNRat): More basic lemmas (#15047)
From LeanAPAP
1 parent a6b7481 commit 3913a5e

File tree

10 files changed

+223
-78
lines changed

10 files changed

+223
-78
lines changed

Mathlib/Algebra/Algebra/Rat.lean

Lines changed: 82 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ Copyright (c) 2018 Kenny Lau. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Kenny Lau, Yury Kudryashov
55
-/
6-
import Mathlib.Data.Rat.Cast.CharZero
76
import Mathlib.Algebra.Algebra.Defs
7+
import Mathlib.Algebra.GroupWithZero.Action.Basic
8+
import Mathlib.Data.Rat.Cast.CharZero
89

910
/-!
1011
# Further basic results about `Algebra`'s over `ℚ`.
1112
1213
This file could usefully be split further.
1314
-/
1415

15-
namespace RingHom
16+
variable {F R S : Type*}
1617

17-
variable {R S : Type*}
18+
namespace RingHom
1819

1920
-- Porting note: changed `[Ring R] [Ring S]` to `[Semiring R] [Semiring S]`
2021
-- otherwise, Lean failed to find a `Subsingleton (ℚ →+* S)` instance
@@ -25,26 +26,89 @@ theorem map_rat_algebraMap [Semiring R] [Semiring S] [Algebra ℚ R] [Algebra
2526

2627
end RingHom
2728

28-
section Rat
29+
namespace NNRat
30+
variable [DivisionSemiring R] [CharZero R]
31+
32+
section Semiring
33+
variable [Semiring S] [Module ℚ≥0 S]
34+
35+
variable (R) in
36+
/-- `nnqsmul` is equal to any other module structure via a cast. -/
37+
lemma cast_smul_eq_nnqsmul [Module R S] (q : ℚ≥0) (a : S) : (q : R) • a = q • a := by
38+
refine MulAction.injective₀ (G₀ := ℚ≥0) (Nat.cast_ne_zero.2 q.den_pos.ne') ?_
39+
dsimp
40+
rw [← mul_smul, den_mul_eq_num, Nat.cast_smul_eq_nsmul, Nat.cast_smul_eq_nsmul, ← smul_assoc,
41+
nsmul_eq_mul q.den, ← cast_natCast, ← cast_mul, den_mul_eq_num, cast_natCast,
42+
Nat.cast_smul_eq_nsmul]
43+
44+
end Semiring
45+
46+
section DivisionSemiring
47+
variable [DivisionSemiring S] [CharZero S]
48+
49+
instance _root_.DivisionSemiring.toNNRatAlgebra : Algebra ℚ≥0 R where
50+
smul_def' := smul_def
51+
toRingHom := castHom _
52+
commutes' := cast_commute
53+
54+
instance _root_.RingHomClass.toLinearMapClassNNRat [FunLike F R S] [RingHomClass F R S] :
55+
LinearMapClass F ℚ≥0 R S where
56+
map_smulₛₗ f q a := by simp [smul_def, cast_id]
57+
58+
variable [SMul R S]
59+
60+
instance instSMulCommClass [SMulCommClass R S S] : SMulCommClass ℚ≥0 R S where
61+
smul_comm q a b := by simp [smul_def, mul_smul_comm]
62+
63+
instance instSMulCommClass' [SMulCommClass S R S] : SMulCommClass R ℚ≥0 S :=
64+
have := SMulCommClass.symm S R S; SMulCommClass.symm _ _ _
65+
66+
end DivisionSemiring
67+
end NNRat
68+
69+
namespace Rat
70+
variable [DivisionRing R] [CharZero R]
71+
72+
section Ring
73+
variable [Ring S] [Module ℚ S]
74+
75+
variable (R) in
76+
/-- `nnqsmul` is equal to any other module structure via a cast. -/
77+
lemma cast_smul_eq_qsmul [Module R S] (q : ℚ) (a : S) : (q : R) • a = q • a := by
78+
refine MulAction.injective₀ (G₀ := ℚ) (Nat.cast_ne_zero.2 q.den_pos.ne') ?_
79+
dsimp
80+
rw [← mul_smul, den_mul_eq_num, Nat.cast_smul_eq_nsmul, Int.cast_smul_eq_zsmul, ← smul_assoc,
81+
nsmul_eq_mul q.den, ← cast_natCast, ← cast_mul, den_mul_eq_num, cast_intCast,
82+
Int.cast_smul_eq_zsmul]
83+
84+
end Ring
85+
86+
section DivisionRing
87+
variable [DivisionRing S] [CharZero S]
88+
89+
instance _root_.DivisionRing.toRatAlgebra : Algebra ℚ R where
90+
smul_def' := smul_def
91+
toRingHom := castHom _
92+
commutes' := cast_commute
93+
94+
instance _root_.RingHomClass.toLinearMapClassRat [FunLike F R S] [RingHomClass F R S] :
95+
LinearMapClass F ℚ R S where
96+
map_smulₛₗ f q a := by simp [smul_def, cast_id]
97+
98+
variable [SMul R S]
2999

30-
/-- Every division ring of characteristic zero is an algebra over the rationals. -/
31-
instance DivisionRing.toRatAlgebra {α} [DivisionRing α] [CharZero α] : Algebra ℚ α where
32-
smul := (· • ·)
33-
smul_def' := Rat.smul_def
34-
toRingHom := Rat.castHom α
35-
commutes' := Rat.cast_commute
100+
instance instSMulCommClass [SMulCommClass R S S] : SMulCommClass ℚ R S where
101+
smul_comm q a b := by simp [smul_def, mul_smul_comm]
36102

37-
/-- The rational numbers are an algebra over the non-negative rationals. -/
38-
instance : Algebra NNRat ℚ :=
39-
NNRat.coeHom.toAlgebra
103+
instance instSMulCommClass' [SMulCommClass S R S] : SMulCommClass R ℚ S :=
104+
have := SMulCommClass.symm S R S; SMulCommClass.symm _ _ _
40105

41-
/-- The two `Algebra ℚ ℚ` instances should coincide. -/
42-
example : DivisionRing.toRatAlgebra = Algebra.id ℚ :=
43-
rfl
106+
end DivisionRing
44107

45-
@[simp] theorem algebraMap_rat_rat : algebraMap ℚ ℚ = RingHom.id ℚ := rfl
108+
@[deprecated Algebra.id.map_eq_id (since := "2024-07-30")]
109+
lemma _root_.algebraMap_rat_rat : algebraMap ℚ ℚ = RingHom.id ℚ := rfl
46110

47-
instance algebra_rat_subsingleton {α} [Semiring α] : Subsingleton (Algebra ℚ α) :=
111+
instance algebra_rat_subsingleton {R} [Semiring R] : Subsingleton (Algebra ℚ R) :=
48112
fun x y => Algebra.algebra_ext x y <| RingHom.congr_fun <| Subsingleton.elim _ _⟩
49113

50114
end Rat

Mathlib/Analysis/SpecialFunctions/Log/Basic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Chris Hughes, Abhimanyu Pallavi Sudhir, Jean Lo, Calle Sönne
66
import Mathlib.Analysis.SpecialFunctions.Exp
77
import Mathlib.Data.Nat.Factorization.Defs
88
import Mathlib.Analysis.NormedSpace.Real
9+
import Mathlib.Data.Rat.Cast.CharZero
910

1011
/-!
1112
# Real logarithm

Mathlib/Data/NNRat/Defs.lean

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ Whenever you state a lemma about the coercion `ℚ≥0 → ℚ`, check that Lean
3030
`Subtype.val`. Else your lemma will never apply.
3131
-/
3232

33+
library_note "specialised high priority simp lemma" /--
34+
It sometimes happens that a `@[simp]` lemma declared early in the library can be proved by `simp`
35+
using later, more general simp lemmas. In that case, the following reasons might be arguments for
36+
the early lemma to be tagged `@[simp high]` (rather than `@[simp, nolint simpNF]` or
37+
un``@[simp]``ed):
38+
1. There is a significant portion of the library which needs the early lemma to be available via
39+
`simp` and which doesn't have access to the more general lemmas.
40+
2. The more general lemmas have more complicated typeclass assumptions, causing rewrites with them
41+
to be slower.
42+
-/
43+
3344
open Function
3445

3546
deriving instance CanonicallyOrderedCommSemiring for NNRat
@@ -56,7 +67,8 @@ theorem ext : (p : ℚ) = (q : ℚ) → p = q :=
5667
protected theorem coe_injective : Injective ((↑) : ℚ≥0 → ℚ) :=
5768
Subtype.coe_injective
5869

59-
@[simp, norm_cast]
70+
-- See note [specialised high priority simp lemma]
71+
@[simp high, norm_cast]
6072
theorem coe_inj : (p : ℚ) = q ↔ p = q :=
6173
Subtype.coe_inj
6274

@@ -109,7 +121,8 @@ theorem coe_mul (p q : ℚ≥0) : ((p * q : ℚ≥0) : ℚ) = p * q :=
109121
theorem coe_sub (h : q ≤ p) : ((p - q : ℚ≥0) : ℚ) = p - q :=
110122
max_eq_left <| le_sub_comm.2 <| by rwa [sub_zero]
111123

112-
@[simp]
124+
-- See note [specialised high priority simp lemma]
125+
@[simp high]
113126
theorem coe_eq_zero : (q : ℚ) = 0 ↔ q = 0 := by norm_cast
114127

115128
theorem coe_ne_zero : (q : ℚ) ≠ 0 ↔ q ≠ 0 :=

Mathlib/Data/Rat/Cast/CharZero.lean

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,15 @@ import Mathlib.Data.Rat.Cast.Defs
1010
# Casts of rational numbers into characteristic zero fields (or division rings).
1111
-/
1212

13+
open Function
1314

1415
variable {F ι α β : Type*}
1516

1617
namespace Rat
18+
variable [DivisionRing α] [CharZero α] {p q : ℚ}
1719

18-
open Rat
19-
20-
section WithDivRing
21-
22-
variable [DivisionRing α]
23-
24-
@[simp, norm_cast]
25-
theorem cast_inj [CharZero α] : ∀ {m n : ℚ}, (m : α) = n ↔ m = n
26-
| ⟨n₁, d₁, d₁0, c₁⟩, ⟨n₂, d₂, d₂0, c₂⟩ => by
27-
refine ⟨fun h => ?_, congr_arg _⟩
20+
lemma cast_injective : Injective ((↑) : ℚ → α)
21+
| ⟨n₁, d₁, d₁0, c₁⟩, ⟨n₂, d₂, d₂0, c₂⟩, h => by
2822
have d₁a : (d₁ : α) ≠ 0 := Nat.cast_ne_zero.2 d₁0
2923
have d₂a : (d₂ : α) ≠ 0 := Nat.cast_ne_zero.2 d₂0
3024
rw [mk'_eq_divInt, mk'_eq_divInt] at h ⊢
@@ -34,30 +28,21 @@ theorem cast_inj [CharZero α] : ∀ {m n : ℚ}, (m : α) = n ↔ m = n
3428
Int.cast_mul, ← Int.cast_natCast d₂, ← Int.cast_mul, Int.cast_inj, ← mkRat_eq_iff d₁0 d₂0]
3529
at h
3630

37-
theorem cast_injective [CharZero α] : Function.Injective ((↑) : ℚ → α)
38-
| _, _ => cast_inj.1
31+
@[simp, norm_cast] lemma cast_inj : (p : α) = q ↔ p = q := cast_injective.eq_iff
3932

40-
@[simp]
41-
theorem cast_eq_zero [CharZero α] {n : ℚ} : (n : α) = 0 ↔ n = 0 := by rw [← cast_zero, cast_inj]
42-
43-
theorem cast_ne_zero [CharZero α] {n : ℚ} : (n : α) ≠ 0 ↔ n ≠ 0 :=
44-
not_congr cast_eq_zero
45-
46-
@[simp, norm_cast]
47-
theorem cast_add [CharZero α] (m n) : ((m + n : ℚ) : α) = m + n :=
48-
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)
33+
@[simp, norm_cast] lemma cast_eq_zero : (p : α) = 0 ↔ p = 0 := cast_injective.eq_iff' cast_zero
34+
lemma cast_ne_zero : (p : α) ≠ 0 ↔ p ≠ 0 := cast_eq_zero.ne
4935

50-
@[simp, norm_cast]
51-
theorem cast_sub [CharZero α] (m n) : ((m - n : ℚ) : α) = m - n :=
52-
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)
36+
@[simp, norm_cast] lemma cast_add (p q : ℚ) : ↑(p + q) = (p + q : α) :=
37+
cast_add_of_ne_zero (Nat.cast_ne_zero.2 p.pos.ne') (Nat.cast_ne_zero.2 q.pos.ne')
5338

54-
@[simp, norm_cast]
55-
theorem cast_mul [CharZero α] (m n) : ((m * n : ℚ) : α) = m * n :=
56-
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)
39+
@[simp, norm_cast] lemma cast_sub (p q : ℚ) : ↑(p - q) = (p - q : α) :=
40+
cast_sub_of_ne_zero (Nat.cast_ne_zero.2 p.pos.ne') (Nat.cast_ne_zero.2 q.pos.ne')
5741

58-
variable (α)
59-
variable [CharZero α]
42+
@[simp, norm_cast] lemma cast_mul (p q : ℚ) : ↑(p * q) = (p * q : α) :=
43+
cast_mul_of_ne_zero (Nat.cast_ne_zero.2 p.pos.ne') (Nat.cast_ne_zero.2 q.pos.ne')
6044

45+
variable (α) in
6146
/-- Coercion `ℚ → α` as a `RingHom`. -/
6247
def castHom : ℚ →+* α where
6348
toFun := (↑)
@@ -66,32 +51,67 @@ def castHom : ℚ →+* α where
6651
map_zero' := cast_zero
6752
map_add' := cast_add
6853

69-
variable {α}
70-
71-
@[simp]
72-
theorem coe_cast_hom : ⇑(castHom α) = ((↑) : ℚ → α) :=
73-
rfl
54+
@[simp] lemma coe_castHom : ⇑(castHom α) = ((↑) : ℚ → α) := rfl
7455

75-
@[simp, norm_cast]
76-
theorem cast_inv (n) : ((n⁻¹ : ℚ) : α) = (n : α)⁻¹ :=
77-
map_inv₀ (castHom α) _
56+
@[deprecated (since := "2024-07-22")] alias coe_cast_hom := coe_castHom
7857

79-
@[simp, norm_cast]
80-
theorem cast_div (m n) : ((m / n : ℚ) : α) = m / n :=
81-
map_div₀ (castHom α) _ _
58+
@[simp, norm_cast] lemma cast_inv (p : ℚ) : ↑(p⁻¹) = (p⁻¹ : α) := map_inv₀ (castHom α) _
59+
@[simp, norm_cast] lemma cast_div (p q : ℚ) : ↑(p / q) = (p / q : α) := map_div₀ (castHom α) ..
8260

8361
@[simp, norm_cast]
84-
theorem cast_zpow (q : ℚ) (n : ℤ) : ((q ^ n : ℚ) : α) = (q : α) ^ n :=
85-
map_zpow₀ (castHom α) q n
62+
lemma cast_zpow (p : ℚ) (n : ℤ) : ↑(p ^ n) = (p ^ n : α) := map_zpow₀ (castHom α) ..
8663

8764
@[norm_cast]
8865
theorem cast_mk (a b : ℤ) : (a /. b : α) = a / b := by
8966
simp only [divInt_eq_div, cast_div, cast_intCast]
9067

68+
end Rat
69+
70+
namespace NNRat
71+
variable [DivisionSemiring α] [CharZero α] {p q : ℚ≥0}
72+
73+
lemma cast_injective : Injective ((↑) : ℚ≥0 → α) := by
74+
rintro p q hpq
75+
rw [NNRat.cast_def, NNRat.cast_def, Commute.div_eq_div_iff] at hpq
76+
rw [← p.num_div_den, ← q.num_div_den, div_eq_div_iff]
77+
norm_cast at hpq ⊢
78+
any_goals norm_cast
79+
any_goals apply den_ne_zero
80+
exact Nat.cast_commute ..
81+
82+
@[simp, norm_cast] lemma cast_inj : (p : α) = q ↔ p = q := cast_injective.eq_iff
83+
84+
@[simp, norm_cast] lemma cast_eq_zero : (q : α) = 0 ↔ q = 0 := by rw [← cast_zero, cast_inj]
85+
lemma cast_ne_zero : (q : α) ≠ 0 ↔ q ≠ 0 := cast_eq_zero.not
86+
87+
@[simp, norm_cast] lemma cast_add (p q : ℚ≥0) : ↑(p + q) = (p + q : α) :=
88+
cast_add_of_ne_zero (Nat.cast_ne_zero.2 p.den_pos.ne') (Nat.cast_ne_zero.2 q.den_pos.ne')
89+
90+
@[simp, norm_cast] lemma cast_mul (p q) : (p * q : ℚ≥0) = (p * q : α) :=
91+
cast_mul_of_ne_zero (Nat.cast_ne_zero.2 p.den_pos.ne') (Nat.cast_ne_zero.2 q.den_pos.ne')
92+
93+
variable (α) in
94+
/-- Coercion `ℚ≥0 → α` as a `RingHom`. -/
95+
def castHom : ℚ≥0 →+* α where
96+
toFun := (↑)
97+
map_one' := cast_one
98+
map_mul' := cast_mul
99+
map_zero' := cast_zero
100+
map_add' := cast_add
101+
102+
@[simp, norm_cast] lemma coe_castHom : ⇑(castHom α) = (↑) := rfl
103+
104+
@[simp, norm_cast] lemma cast_inv (p) : (p⁻¹ : ℚ≥0) = (p : α)⁻¹ := map_inv₀ (castHom α) _
105+
@[simp, norm_cast] lemma cast_div (p q) : (p / q : ℚ≥0) = (p / q : α) := map_div₀ (castHom α) ..
106+
91107
@[simp, norm_cast]
92-
theorem cast_pow (q : ℚ) (k : ℕ) : ↑(q ^ k) = (q : α) ^ k :=
93-
(castHom α).map_pow q k
108+
lemma cast_zpow (q : ℚ≥0) (p : ℤ) : ↑(q ^ p) = ((q : α) ^ p : α) := map_zpow₀ (castHom α) ..
94109

95-
end WithDivRing
110+
@[simp]
111+
lemma cast_divNat (a b : ℕ) : (divNat a b : α) = a / b := by
112+
rw [← cast_natCast, ← cast_natCast b, ← cast_div]
113+
congr
114+
ext
115+
apply Rat.mkRat_eq_div
96116

97-
end Rat
117+
end NNRat

0 commit comments

Comments
 (0)