Skip to content

Commit 8154aaa

Browse files
authored
feat: preparation for semirings and noncommutative rings in grind (#8343)
This PR splits `Lean.Grind.CommRing` into 4 typeclasses, for semirings and noncommutative rings. This does not yet change the behaviour of `grind`, which expects to find all 4 typeclasses. Later we will make some generalizations.
1 parent abc85c2 commit 8154aaa

File tree

11 files changed

+184
-73
lines changed

11 files changed

+184
-73
lines changed

src/Init/Data/BitVec/Lemmas.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3731,6 +3731,10 @@ theorem mul_add {x y z : BitVec w} :
37313731
rw [Nat.mul_mod, Nat.mod_mod (y.toNat + z.toNat),
37323732
← Nat.mul_mod, Nat.mul_add]
37333733

3734+
theorem add_mul {x y z : BitVec w} :
3735+
(x + y) * z = x * z + y * z := by
3736+
rw [BitVec.mul_comm, mul_add, BitVec.mul_comm z, BitVec.mul_comm z]
3737+
37343738
theorem mul_succ {x y : BitVec w} : x * (y + 1#w) = x * y + x := by simp [mul_add]
37353739
theorem succ_mul {x y : BitVec w} : (x + 1#w) * y = x * y + y := by simp [BitVec.mul_comm, BitVec.mul_add]
37363740

src/Init/Grind/CommRing/Basic.lean

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,39 +30,51 @@ theorem ofNat_eq_iff_of_lt {x y : Nat} (h₁ : x < p) (h₂ : y < p) :
3030

3131
namespace Lean.Grind
3232

33-
class CommRing (α : Type u) extends Add α, Mul α, Neg α, Sub α, HPow α Nat α where
33+
class Semiring (α : Type u) extends Add α, Mul α, HPow α Nat α where
3434
[ofNat : ∀ n, OfNat α n]
3535
[natCast : NatCast α]
36-
[intCast : IntCast α]
3736
add_assoc : ∀ a b c : α, a + b + c = a + (b + c)
3837
add_comm : ∀ a b : α, a + b = b + a
3938
add_zero : ∀ a : α, a + 0 = a
40-
neg_add_cancel : ∀ a : α, -a + a = 0
4139
mul_assoc : ∀ a b c : α, a * b * c = a * (b * c)
42-
mul_comm : ∀ a b : α, a * b = b * a
4340
mul_one : ∀ a : α, a * 1 = a
41+
one_mul : ∀ a : α, 1 * a = a
4442
left_distrib : ∀ a b c : α, a * (b + c) = a * b + a * c
43+
right_distrib : ∀ a b c : α, (a + b) * c = a * c + b * c
4544
zero_mul : ∀ a : α, 0 * a = 0
46-
sub_eq_add_neg : ∀ a b : α, a - b = a + -b
45+
mul_zero : ∀ a : α, a * 0 = 0
4746
pow_zero : ∀ a : α, a ^ 0 = 1
4847
pow_succ : ∀ a : α, ∀ n : Nat, a ^ (n + 1) = (a ^ n) * a
4948
ofNat_succ : ∀ a : Nat, OfNat.ofNat (α := α) (a + 1) = OfNat.ofNat a + 1 := by intros; rfl
5049
ofNat_eq_natCast : ∀ n : Nat, OfNat.ofNat (α := α) n = Nat.cast n := by intros; rfl
50+
51+
class Ring (α : Type u) extends Semiring α, Neg α, Sub α where
52+
[intCast : IntCast α]
53+
neg_add_cancel : ∀ a : α, -a + a = 0
54+
sub_eq_add_neg : ∀ a b : α, a - b = a + -b
5155
intCast_ofNat : ∀ n : Nat, Int.cast (OfNat.ofNat (α := Int) n) = OfNat.ofNat (α := α) n := by intros; rfl
5256
intCast_neg : ∀ i : Int, Int.cast (R := α) (-i) = -Int.cast i := by intros; rfl
5357

58+
class CommSemiring (α : Type u) extends Semiring α where
59+
mul_comm : ∀ a b : α, a * b = b * a
60+
one_mul := by intro a; rw [mul_comm, mul_one]
61+
mul_zero := by intro a; rw [mul_comm, zero_mul]
62+
right_distrib := by intro a b c; rw [mul_comm, left_distrib, mul_comm c, mul_comm c]
63+
64+
class CommRing (α : Type u) extends Ring α, CommSemiring α
65+
5466
-- We reduce the priority of these parent instances,
5567
-- so that in downstream libraries with their own `CommRing` class,
5668
-- the path `CommRing -> Add` is found before `CommRing -> Lean.Grind.CommRing -> Add`.
5769
-- (And similarly for the other parents.)
58-
attribute [instance 100] CommRing.toAdd CommRing.toMul CommRing.toNeg CommRing.toSub CommRing.toHPow
70+
attribute [instance 100] Semiring.toAdd Semiring.toMul Semiring.toHPow Ring.toNeg Ring.toSub
5971

6072
-- This is a low-priority instance, to avoid conflicts with existing `OfNat`, `NatCast`, and `IntCast` instances.
61-
attribute [instance 100] CommRing.ofNat CommRing.natCast CommRing.intCast
73+
attribute [instance 100] Semiring.ofNat Semiring.natCast Ring.intCast
6274

63-
namespace CommRing
75+
namespace Semiring
6476

65-
variable {α : Type u} [CommRing α]
77+
variable {α : Type u} [Semiring α]
6678

6779
theorem natCast_zero : ((0 : Nat) : α) = 0 := (ofNat_eq_natCast 0).symm
6880
theorem natCast_one : ((1 : Nat) : α) = 1 := (ofNat_eq_natCast 1).symm
@@ -80,24 +92,9 @@ theorem natCast_succ (n : Nat) : ((n + 1 : Nat) : α) = ((n : α) + 1) := by
8092
theorem zero_add (a : α) : 0 + a = a := by
8193
rw [add_comm, add_zero]
8294

83-
theorem add_neg_cancel (a : α) : a + -a = 0 := by
84-
rw [add_comm, neg_add_cancel]
85-
8695
theorem add_left_comm (a b c : α) : a + (b + c) = b + (a + c) := by
8796
rw [← add_assoc, ← add_assoc, add_comm a]
8897

89-
theorem one_mul (a : α) : 1 * a = a := by
90-
rw [mul_comm, mul_one]
91-
92-
theorem right_distrib (a b c : α) : (a + b) * c = a * c + b * c := by
93-
rw [mul_comm, left_distrib, mul_comm c, mul_comm c]
94-
95-
theorem mul_zero (a : α) : a * 0 = 0 := by
96-
rw [mul_comm, zero_mul]
97-
98-
theorem mul_left_comm (a b c : α) : a * (b * c) = b * (a * c) := by
99-
rw [← mul_assoc, ← mul_assoc, mul_comm a]
100-
10198
theorem ofNat_mul (a b : Nat) : OfNat.ofNat (α := α) (a * b) = OfNat.ofNat a * OfNat.ofNat b := by
10299
induction b with
103100
| zero => simp [Nat.mul_zero, mul_zero]
@@ -106,6 +103,22 @@ theorem ofNat_mul (a b : Nat) : OfNat.ofNat (α := α) (a * b) = OfNat.ofNat a *
106103
theorem natCast_mul (a b : Nat) : ((a * b : Nat) : α) = ((a : α) * (b : α)) := by
107104
rw [← ofNat_eq_natCast, ofNat_mul, ofNat_eq_natCast, ofNat_eq_natCast]
108105

106+
theorem pow_add (a : α) (k₁ k₂ : Nat) : a ^ (k₁ + k₂) = a^k₁ * a^k₂ := by
107+
induction k₂
108+
next => simp [pow_zero, mul_one]
109+
next k₂ ih => rw [Nat.add_succ, pow_succ, pow_succ, ih, mul_assoc]
110+
111+
end Semiring
112+
113+
namespace Ring
114+
115+
open Semiring
116+
117+
variable {α : Type u} [Ring α]
118+
119+
theorem add_neg_cancel (a : α) : a + -a = 0 := by
120+
rw [add_comm, neg_add_cancel]
121+
109122
theorem add_left_inj {a b : α} (c : α) : a + c = b + c ↔ a = b :=
110123
fun h => by simpa [add_assoc, add_neg_cancel, add_zero] using (congrArg (· + -c) h),
111124
fun g => congrArg (· + c) g⟩
@@ -198,11 +211,17 @@ theorem neg_eq_neg_one_mul (a : α) : -a = (-1) * a := by
198211
rw [← right_distrib, ← intCast_neg_one, ← intCast_one (α := α)]
199212
simp [← intCast_add, intCast_zero, zero_mul]
200213

214+
theorem neg_eq_mul_neg_one (a : α) : -a = a * (-1) := by
215+
rw [← add_left_inj a, neg_add_cancel]
216+
conv => rhs; arg 2; rw [← mul_one a]
217+
rw [← left_distrib, ← intCast_neg_one, ← intCast_one (α := α)]
218+
simp [← intCast_add, intCast_zero, mul_zero]
219+
201220
theorem neg_mul (a b : α) : (-a) * b = -(a * b) := by
202221
rw [neg_eq_neg_one_mul a, neg_eq_neg_one_mul (a * b), mul_assoc]
203222

204223
theorem mul_neg (a b : α) : a * (-b) = -(a * b) := by
205-
rw [mul_comm, neg_mul, mul_comm]
224+
rw [neg_eq_mul_neg_one b, neg_eq_mul_neg_one (a * b), mul_assoc]
206225

207226
theorem intCast_nat_mul (x y : Nat) : ((x * y : Int) : α) = ((x : α) * (y : α)) := by
208227
rw [Int.ofNat_mul_ofNat, intCast_natCast, natCast_mul]
@@ -224,21 +243,27 @@ theorem intCast_pow (x : Int) (k : Nat) : ((x ^ k : Int) : α) = (x : α) ^ k :=
224243
next => simp [pow_zero, Int.pow_zero, intCast_one]
225244
next k ih => simp [pow_succ, Int.pow_succ, intCast_mul, *]
226245

227-
theorem pow_add (a : α) (k₁ k₂ : Nat) : a ^ (k₁ + k₂) = a^k₁ * a^k₂ := by
228-
induction k₂
229-
next => simp [pow_zero, mul_one]
230-
next k₂ ih => rw [Nat.add_succ, pow_succ, pow_succ, ih, mul_assoc]
246+
end Ring
247+
248+
namespace CommSemiring
249+
250+
open Semiring
251+
252+
variable {α : Type u} [CommSemiring α]
253+
254+
theorem mul_left_comm (a b c : α) : a * (b * c) = b * (a * c) := by
255+
rw [← mul_assoc, ← mul_assoc, mul_comm a]
231256

232-
end CommRing
257+
end CommSemiring
233258

234-
open CommRing
259+
open Semiring Ring CommSemiring CommRing
235260

236-
class IsCharP (α : Type u) [CommRing α] (p : outParam Nat) where
261+
class IsCharP (α : Type u) [Ring α] (p : outParam Nat) where
237262
ofNat_eq_zero_iff (p) : ∀ (x : Nat), OfNat.ofNat (α := α) x = 0 ↔ x % p = 0
238263

239264
namespace IsCharP
240265

241-
variable (p) {α : Type u} [CommRing α] [IsCharP α p]
266+
variable (p) {α : Type u} [Ring α] [IsCharP α p]
242267

243268
theorem natCast_eq_zero_iff (x : Nat) : (x : α) = 0 ↔ x % p = 0 := by
244269
rw [← ofNat_eq_natCast]
@@ -325,12 +350,12 @@ end IsCharP
325350
/--
326351
Special case of Mathlib's `NoZeroSMulDivisors Nat α`.
327352
-/
328-
class NoNatZeroDivisors (α : Type u) [CommRing α] where
353+
class NoNatZeroDivisors (α : Type u) [Ring α] where
329354
no_nat_zero_divisors : ∀ (k : Nat) (a : α), k ≠ 0 → OfNat.ofNat (α := α) k * a = 0 → a = 0
330355

331356
export NoNatZeroDivisors (no_nat_zero_divisors)
332357

333-
theorem no_int_zero_divisors {α : Type u} [CommRing α] [NoNatZeroDivisors α] {k : Int} {a : α}
358+
theorem no_int_zero_divisors {α : Type u} [Ring α] [NoNatZeroDivisors α] {k : Int} {a : α}
334359
: k ≠ 0 → k * a = 0 → a = 0 := by
335360
match k with
336361
| (k : Nat) =>

src/Init/Grind/CommRing/BitVec.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ instance : CommRing (BitVec w) where
1919
mul_assoc := BitVec.mul_assoc
2020
mul_comm := BitVec.mul_comm
2121
mul_one := BitVec.mul_one
22+
one_mul := BitVec.one_mul
2223
left_distrib _ _ _ := BitVec.mul_add
24+
right_distrib _ _ _ := BitVec.add_mul
2325
zero_mul _ := BitVec.zero_mul
26+
mul_zero _ := BitVec.mul_zero
2427
sub_eq_add_neg := BitVec.sub_eq_add_neg
2528
pow_zero _ := BitVec.pow_zero
2629
pow_succ _ _ := BitVec.pow_succ

src/Init/Grind/CommRing/Int.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ instance : CommRing Int where
1919
mul_assoc := Int.mul_assoc
2020
mul_comm := Int.mul_comm
2121
mul_one := Int.mul_one
22+
one_mul := Int.one_mul
2223
left_distrib := Int.mul_add
24+
right_distrib := Int.add_mul
2325
zero_mul := Int.zero_mul
26+
mul_zero := Int.mul_zero
2427
pow_zero _ := rfl
2528
pow_succ _ _ := rfl
2629
ofNat_succ _ := rfl

src/Init/Grind/CommRing/Poly.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ def NullCert.toPolyC (nc : NullCert) (c : Nat) : Poly :=
508508
Theorems for justifying the procedure for commutative rings in `grind`.
509509
-/
510510

511+
open Semiring Ring CommSemiring
512+
511513
theorem denoteInt_eq {α} [CommRing α] (k : Int) : denoteInt (α := α) k = k := by
512514
simp [denoteInt, cond_eq_if] <;> split
513515
next h => rw [ofNat_eq_natCast, ← intCast_natCast, ← intCast_neg, ← Int.eq_neg_natAbs_of_nonpos (Int.le_of_lt h)]

src/Init/Grind/CommRing/SInt.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ instance : CommRing Int8 where
2525
mul_assoc := Int8.mul_assoc
2626
mul_comm := Int8.mul_comm
2727
mul_one := Int8.mul_one
28+
one_mul := Int8.one_mul
2829
left_distrib _ _ _ := Int8.mul_add
30+
right_distrib _ _ _ := Int8.add_mul
2931
zero_mul _ := Int8.zero_mul
32+
mul_zero _ := Int8.mul_zero
3033
sub_eq_add_neg := Int8.sub_eq_add_neg
3134
pow_zero := Int8.pow_zero
3235
pow_succ := Int8.pow_succ
@@ -54,8 +57,11 @@ instance : CommRing Int16 where
5457
mul_assoc := Int16.mul_assoc
5558
mul_comm := Int16.mul_comm
5659
mul_one := Int16.mul_one
60+
one_mul := Int16.one_mul
5761
left_distrib _ _ _ := Int16.mul_add
62+
right_distrib _ _ _ := Int16.add_mul
5863
zero_mul _ := Int16.zero_mul
64+
mul_zero _ := Int16.mul_zero
5965
sub_eq_add_neg := Int16.sub_eq_add_neg
6066
pow_zero := Int16.pow_zero
6167
pow_succ := Int16.pow_succ
@@ -82,8 +88,11 @@ instance : CommRing Int32 where
8288
mul_assoc := Int32.mul_assoc
8389
mul_comm := Int32.mul_comm
8490
mul_one := Int32.mul_one
91+
one_mul := Int32.one_mul
8592
left_distrib _ _ _ := Int32.mul_add
93+
right_distrib _ _ _ := Int32.add_mul
8694
zero_mul _ := Int32.zero_mul
95+
mul_zero _ := Int32.mul_zero
8796
sub_eq_add_neg := Int32.sub_eq_add_neg
8897
pow_zero := Int32.pow_zero
8998
pow_succ := Int32.pow_succ
@@ -110,8 +119,11 @@ instance : CommRing Int64 where
110119
mul_assoc := Int64.mul_assoc
111120
mul_comm := Int64.mul_comm
112121
mul_one := Int64.mul_one
122+
one_mul := Int64.one_mul
113123
left_distrib _ _ _ := Int64.mul_add
124+
right_distrib _ _ _ := Int64.add_mul
114125
zero_mul _ := Int64.zero_mul
126+
mul_zero _ := Int64.mul_zero
115127
sub_eq_add_neg := Int64.sub_eq_add_neg
116128
pow_zero := Int64.pow_zero
117129
pow_succ := Int64.pow_succ
@@ -138,8 +150,11 @@ instance : CommRing ISize where
138150
mul_assoc := ISize.mul_assoc
139151
mul_comm := ISize.mul_comm
140152
mul_one := ISize.mul_one
153+
one_mul := ISize.one_mul
141154
left_distrib _ _ _ := ISize.mul_add
155+
right_distrib _ _ _ := ISize.add_mul
142156
zero_mul _ := ISize.zero_mul
157+
mul_zero _ := ISize.mul_zero
143158
sub_eq_add_neg := ISize.sub_eq_add_neg
144159
pow_zero := ISize.pow_zero
145160
pow_succ := ISize.pow_succ

src/Init/Grind/CommRing/UInt.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,11 @@ instance : CommRing UInt8 where
131131
mul_assoc := UInt8.mul_assoc
132132
mul_comm := UInt8.mul_comm
133133
mul_one := UInt8.mul_one
134+
one_mul := UInt8.one_mul
134135
left_distrib _ _ _ := UInt8.mul_add
136+
right_distrib _ _ _ := UInt8.add_mul
135137
zero_mul _ := UInt8.zero_mul
138+
mul_zero _ := UInt8.mul_zero
136139
sub_eq_add_neg := UInt8.sub_eq_add_neg
137140
pow_zero := UInt8.pow_zero
138141
pow_succ := UInt8.pow_succ
@@ -153,8 +156,11 @@ instance : CommRing UInt16 where
153156
mul_assoc := UInt16.mul_assoc
154157
mul_comm := UInt16.mul_comm
155158
mul_one := UInt16.mul_one
159+
one_mul := UInt16.one_mul
156160
left_distrib _ _ _ := UInt16.mul_add
161+
right_distrib _ _ _ := UInt16.add_mul
157162
zero_mul _ := UInt16.zero_mul
163+
mul_zero _ := UInt16.mul_zero
158164
sub_eq_add_neg := UInt16.sub_eq_add_neg
159165
pow_zero := UInt16.pow_zero
160166
pow_succ := UInt16.pow_succ
@@ -175,8 +181,11 @@ instance : CommRing UInt32 where
175181
mul_assoc := UInt32.mul_assoc
176182
mul_comm := UInt32.mul_comm
177183
mul_one := UInt32.mul_one
184+
one_mul := UInt32.one_mul
178185
left_distrib _ _ _ := UInt32.mul_add
186+
right_distrib _ _ _ := UInt32.add_mul
179187
zero_mul _ := UInt32.zero_mul
188+
mul_zero _ := UInt32.mul_zero
180189
sub_eq_add_neg := UInt32.sub_eq_add_neg
181190
pow_zero := UInt32.pow_zero
182191
pow_succ := UInt32.pow_succ
@@ -197,8 +206,11 @@ instance : CommRing UInt64 where
197206
mul_assoc := UInt64.mul_assoc
198207
mul_comm := UInt64.mul_comm
199208
mul_one := UInt64.mul_one
209+
one_mul := UInt64.one_mul
200210
left_distrib _ _ _ := UInt64.mul_add
211+
right_distrib _ _ _ := UInt64.add_mul
201212
zero_mul _ := UInt64.zero_mul
213+
mul_zero _ := UInt64.mul_zero
202214
sub_eq_add_neg := UInt64.sub_eq_add_neg
203215
pow_zero := UInt64.pow_zero
204216
pow_succ := UInt64.pow_succ
@@ -219,8 +231,11 @@ instance : CommRing USize where
219231
mul_assoc := USize.mul_assoc
220232
mul_comm := USize.mul_comm
221233
mul_one := USize.mul_one
234+
one_mul := USize.one_mul
222235
left_distrib _ _ _ := USize.mul_add
236+
right_distrib _ _ _ := USize.add_mul
223237
zero_mul _ := USize.zero_mul
238+
mul_zero _ := USize.mul_zero
224239
sub_eq_add_neg := USize.sub_eq_add_neg
225240
pow_zero := USize.pow_zero
226241
pow_succ := USize.pow_succ

src/Lean/Meta/Tactic/Grind/Arith/CommRing/DenoteExpr.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ variable [Monad M] [MonadGetRing M]
1717
private def denoteNum (k : Int) : M Expr := do
1818
let ring ← getRing
1919
let n := mkRawNatLit k.natAbs
20-
let ofNatInst := mkApp3 (mkConst ``Grind.CommRing.ofNat [ring.u]) ring.type ring.commRingInst n
20+
let ofNatInst := mkApp3 (mkConst ``Grind.Semiring.ofNat [ring.u]) ring.type ring.semiringInst n
2121
let n := mkApp3 (mkConst ``OfNat.ofNat [ring.u]) ring.type n ofNatInst
2222
if k < 0 then
2323
return mkApp ring.negFn n

0 commit comments

Comments
 (0)