I made a few choices so far that can probably be discussed: - got rid of `modn` on `UInt`, nobody seems to use it apart from the definition of `shift` which can use normal `mod` - removed the previous defeq optimized definition of `USize.size` in favor for a normal one. The motivation was to allow `OfNat` to work which doesn't seem to be necessary anymore afaict. - Minimized uses of `.val`, should we maybe mark it deprecated? - Mostly got rid of `.val` in basically all theorems as the proper next level of API would now be `.toBitVec`. We could probably re-prove them but it would be more annoying given the change of definition. - Did not yet redefine `log2` in terms of `BitVec` as this would require a `log2` in `BitVec` as well, do we want this? - I added a couple of theorems around the relation of `<` on `UInt` and `Nat`. These were previously not needed because defeq was used all over the place to save us. I did not yet generalize these to all types as I wasn't sure if they are the appropriate lemma that we want to have.
52 lines
1.3 KiB
Text
52 lines
1.3 KiB
Text
/-
|
|
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
|
|
|
|
set_option linter.missingDocs true
|
|
|
|
/-!
|
|
This module exists to provide the very basic `BitVec` definitions required for
|
|
`Init.Data.UInt.BasicAux`.
|
|
-/
|
|
|
|
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
|