-
Notifications
You must be signed in to change notification settings - Fork 406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: redefine unsigned fixed width integers in terms of BitVec #5323
base: master
Are you sure you want to change the base?
Changes from all commits
155ea33
db3bcc0
0d95335
c65e845
b1cefe9
9150feb
4ea4301
64c9e71
cf00a62
31dc764
81fa14f
1c6266d
d940cf1
458c2b9
7f345ad
f27f8d6
760cabf
cb09806
0e17624
0297212
56f6c00
0d352b1
a024370
19cf42f
89d6133
660a8e4
7ba8cc0
e62cd45
2e2b141
b44578e
78cb9f1
4137f3a
ac36985
0c7c9c9
06379fd
30b0ea9
79eda0d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -8,6 +8,7 @@ import Init.Data.Fin.Basic | |||||
import Init.Data.Nat.Bitwise.Lemmas | ||||||
import Init.Data.Nat.Power2 | ||||||
import Init.Data.Int.Bitwise | ||||||
import Init.Data.BitVec.BasicAux | ||||||
|
||||||
/-! | ||||||
We define bitvectors. We choose the `Fin` representation over others for its relative efficiency | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
@@ -22,60 +23,12 @@ of SMT-LIBv2. | |||||
|
||||||
set_option linter.missingDocs true | ||||||
|
||||||
/-- | ||||||
A bitvector of the specified width. | ||||||
|
||||||
This is represented as the underlying `Nat` number in both the runtime | ||||||
and the kernel, inheriting all the special support for `Nat`. | ||||||
-/ | ||||||
structure BitVec (w : Nat) where | ||||||
/-- Construct a `BitVec w` from a number less than `2^w`. | ||||||
O(1), because we use `Fin` as the internal representation of a bitvector. -/ | ||||||
ofFin :: | ||||||
/-- Interpret a bitvector as a number less than `2^w`. | ||||||
O(1), because we use `Fin` as the internal representation of a bitvector. -/ | ||||||
toFin : Fin (2^w) | ||||||
|
||||||
/-- | ||||||
Bitvectors have decidable equality. This should be used via the instance `DecidableEq (BitVec n)`. | ||||||
-/ | ||||||
-- We manually derive the `DecidableEq` instances for `BitVec` because | ||||||
-- we want to have builtin support for bit-vector literals, and we | ||||||
-- need a name for this function to implement `canUnfoldAtMatcher` at `WHNF.lean`. | ||||||
def BitVec.decEq (x y : BitVec n) : Decidable (x = y) := | ||||||
match x, y with | ||||||
| ⟨n⟩, ⟨m⟩ => | ||||||
if h : n = m then | ||||||
isTrue (h ▸ rfl) | ||||||
else | ||||||
isFalse (fun h' => BitVec.noConfusion h' (fun h' => absurd h' h)) | ||||||
|
||||||
instance : DecidableEq (BitVec n) := BitVec.decEq | ||||||
|
||||||
namespace BitVec | ||||||
|
||||||
section Nat | ||||||
|
||||||
/-- The `BitVec` with value `i`, given a proof that `i < 2^n`. -/ | ||||||
@[match_pattern] | ||||||
protected def ofNatLt {n : Nat} (i : Nat) (p : i < 2^n) : BitVec n where | ||||||
toFin := ⟨i, p⟩ | ||||||
|
||||||
/-- The `BitVec` with value `i mod 2^n`. -/ | ||||||
@[match_pattern] | ||||||
protected def ofNat (n : Nat) (i : Nat) : BitVec n where | ||||||
toFin := Fin.ofNat' (2^n) i | ||||||
|
||||||
instance instOfNat : OfNat (BitVec n) i where ofNat := .ofNat n i | ||||||
instance natCastInst : NatCast (BitVec w) := ⟨BitVec.ofNat w⟩ | ||||||
|
||||||
/-- Given a bitvector `x`, return the underlying `Nat`. This is O(1) because `BitVec` is a | ||||||
(zero-cost) wrapper around a `Nat`. -/ | ||||||
protected def toNat (x : BitVec n) : Nat := x.toFin.val | ||||||
|
||||||
/-- Return the bound in terms of toNat. -/ | ||||||
theorem isLt (x : BitVec w) : x.toNat < 2^w := x.toFin.isLt | ||||||
|
||||||
@[deprecated isLt (since := "2024-03-12")] | ||||||
theorem toNat_lt (x : BitVec n) : x.toNat < 2^n := x.isLt | ||||||
|
||||||
|
@@ -238,22 +191,6 @@ end repr_toString | |||||
|
||||||
section arithmetic | ||||||
|
||||||
/-- | ||||||
Addition for bit vectors. This can be interpreted as either signed or unsigned addition | ||||||
modulo `2^n`. | ||||||
|
||||||
SMT-Lib name: `bvadd`. | ||||||
-/ | ||||||
protected def add (x y : BitVec n) : BitVec n := .ofNat n (x.toNat + y.toNat) | ||||||
instance : Add (BitVec n) := ⟨BitVec.add⟩ | ||||||
|
||||||
/-- | ||||||
Subtraction for bit vectors. This can be interpreted as either signed or unsigned subtraction | ||||||
modulo `2^n`. | ||||||
-/ | ||||||
protected def sub (x y : BitVec n) : BitVec n := .ofNat n ((2^n - y.toNat) + x.toNat) | ||||||
instance : Sub (BitVec n) := ⟨BitVec.sub⟩ | ||||||
|
||||||
/-- | ||||||
Negation for bit vectors. This can be interpreted as either signed or unsigned negation | ||||||
modulo `2^n`. | ||||||
|
@@ -387,21 +324,13 @@ SMT-Lib name: `bvult`. | |||||
-/ | ||||||
protected def ult (x y : BitVec n) : Bool := x.toNat < y.toNat | ||||||
|
||||||
instance : LT (BitVec n) where lt := (·.toNat < ·.toNat) | ||||||
instance (x y : BitVec n) : Decidable (x < y) := | ||||||
inferInstanceAs (Decidable (x.toNat < y.toNat)) | ||||||
|
||||||
/-- | ||||||
Unsigned less-than-or-equal-to for bit vectors. | ||||||
|
||||||
SMT-Lib name: `bvule`. | ||||||
-/ | ||||||
protected def ule (x y : BitVec n) : Bool := x.toNat ≤ y.toNat | ||||||
|
||||||
instance : LE (BitVec n) where le := (·.toNat ≤ ·.toNat) | ||||||
instance (x y : BitVec n) : Decidable (x ≤ y) := | ||||||
inferInstanceAs (Decidable (x.toNat ≤ y.toNat)) | ||||||
|
||||||
/-- | ||||||
Signed less-than for bit vectors. | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/- | ||
Copyright (c) 2024 Lean FRO, LLC. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Joe Hendrix, Wojciech Nawrocki, Leonardo de Moura, Mario Carneiro, Alex Keizer, Harun Khan, Abdalrhman M Mohamed | ||
-/ | ||
prelude | ||
import Init.Data.Fin.Basic | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a module doc to this file explaining why the |
||
set_option linter.missingDocs true | ||
|
||
namespace BitVec | ||
|
||
section Nat | ||
|
||
/-- The `BitVec` with value `i mod 2^n`. -/ | ||
@[match_pattern] | ||
protected def ofNat (n : Nat) (i : Nat) : BitVec n where | ||
toFin := Fin.ofNat' (2^n) i | ||
|
||
instance instOfNat : OfNat (BitVec n) i where ofNat := .ofNat n i | ||
|
||
/-- Return the bound in terms of toNat. -/ | ||
theorem isLt (x : BitVec w) : x.toNat < 2^w := x.toFin.isLt | ||
|
||
end Nat | ||
|
||
section arithmetic | ||
|
||
/-- | ||
Addition for bit vectors. This can be interpreted as either signed or unsigned addition | ||
modulo `2^n`. | ||
|
||
SMT-Lib name: `bvadd`. | ||
-/ | ||
protected def add (x y : BitVec n) : BitVec n := .ofNat n (x.toNat + y.toNat) | ||
instance : Add (BitVec n) := ⟨BitVec.add⟩ | ||
|
||
/-- | ||
Subtraction for bit vectors. This can be interpreted as either signed or unsigned subtraction | ||
modulo `2^n`. | ||
-/ | ||
protected def sub (x y : BitVec n) : BitVec n := .ofNat n ((2^n - y.toNat) + x.toNat) | ||
instance : Sub (BitVec n) := ⟨BitVec.sub⟩ | ||
|
||
end arithmetic | ||
|
||
end BitVec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a sentence in this module doc which is no longer true.