diff options
Diffstat (limited to 'books/workshops/2004/sawada/support/bv.lisp')
-rw-r--r-- | books/workshops/2004/sawada/support/bv.lisp | 942 |
1 files changed, 942 insertions, 0 deletions
diff --git a/books/workshops/2004/sawada/support/bv.lisp b/books/workshops/2004/sawada/support/bv.lisp new file mode 100644 index 0000000..ed39966 --- /dev/null +++ b/books/workshops/2004/sawada/support/bv.lisp @@ -0,0 +1,942 @@ +;; ********************************************************************** +;; Originally published as a supplemental material of ACL2 2004 paper +;; Created by Jun Sawada at IBM Austin Research Lab, 2003, 2004. +;; ********************************************************************** +(in-package "BV") + +(include-book "ihs") +(include-book "../../../../arithmetic-2/pass1/top") +(local (include-book "../../../../ihs/quotient-remainder-lemmas")) + +(deflabel begin-bv) +(defun bvp (bv) + (declare (xargs :guard t)) + (and (listp bv) + (equal (len bv) 3) + (integerp (caddr bv)) + (<= 0 (caddr bv)) + (integerp (cadr bv)) + (<= 0 (cadr bv)) + (< (cadr bv) (expt 2 (caddr bv))))) + + + +(defun bv (val size) + (declare (xargs :guard (and (integerp val) + (integerp size) + (<= 0 size)))) + (list 'bv (mod val (expt 2 size)) size)) + +(defthm bvp-bv + (implies (and (integerp s) (<= 0 s) (integerp v)) + (bvp (bv v s)))) + + +(defun bv-val (bv) + (declare (xargs :guard (bvp bv))) + (cadr bv)) + +(defun bv-size (bv) + (declare (xargs :guard (bvp bv))) + (caddr bv)) + +(defthm type-bv-val + (implies (bvp v) (and (integerp (bv-val v)) (<= 0 (bv-val v)))) + :rule-classes ((:type-prescription) (:rewrite))) + +(defthm acl2-numberp-bv-val + (implies (bvp v) (acl2-numberp (bv-val v))) + :rule-classes ((:type-prescription) (:rewrite))) + +(defthm type-bv-size + (implies (bvp v) (and (integerp (bv-size v)) (<= 0 (bv-size v)))) + :rule-classes ((:type-prescription) (:rewrite))) + + +(defthm bv-size-bv (equal (bv-size (bv val size)) size)) + +(defthm bv-val-bv (equal (bv-val (bv val size)) (mod val (expt 2 size)))) + +(in-theory (disable bv bv-size bv-val bvp)) + +(defconst *b0* '(bit 0)) +(defconst *b1* '(bit 1)) + +(defun bitp (b) + (declare (xargs :guard t)) + (or (equal b *b1*) (equal b *b0*))) + +(defun make-bit (val) + (declare (xargs :guard (or (equal val 0) (equal val 1)))) + (if (zp val) *b0* *b1*)) + +(defun bit-val (b) + (declare (xargs :guard (bitp b))) + (cadr b)) + +(defun b-not (b) + (declare (xargs :guard (bitp b))) + (make-bit (acl2::b-not (bit-val b)))) +(defun b-ior (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-ior (bit-val b0) (bit-val b1)))) +(defun b-nor (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-nor (bit-val b0) (bit-val b1)))) +(defun b-and (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-and (bit-val b0) (bit-val b1)))) +(defun b-nand (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-nand (bit-val b0) (bit-val b1)))) +(defun b-xor (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-xor (bit-val b0) (bit-val b1)))) +(defun b-andc1 (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-andc1 (bit-val b0) (bit-val b1)))) +(defun b-andc2 (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-andc2 (bit-val b0) (bit-val b1)))) +(defun b-orc1 (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-orc1 (bit-val b0) (bit-val b1)))) +(defun b-orc2 (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-orc2 (bit-val b0) (bit-val b1)))) +(defun b-eqv (b0 b1) + (declare (xargs :guard (and (bitp b0) (bitp b1)))) + (make-bit (acl2::b-eqv (bit-val b0) (bit-val b1)))) + + +(defun b2bv (b) + (declare (xargs :guard (bitp b))) + (bv (bit-val b) 1)) + +(defthm bvp-b2bv + (implies (bitp b) (bvp (b2bv b)))) + +(defthm bv-size-b2bv + (equal (bv-size (b2bv b)) 1)) + +;(defconst *b0* (b2bv 0)) +;(defconst *b1* (b2bv 1)) +(defconst *bv-nil* (bv 0 0)) + +(defun bv-null? (bv) + (declare (xargs :guard (bvp bv))) + (zp (bv-size bv))) + +(defthm bv-null-bv-size + (implies (bvp v) + (iff (bv-null? v) (>= 0 (bv-size v))))) + +(defun lsb (bv) + (declare (xargs :guard (and (bvp bv) (< 0 (bv-size bv))) + :verify-guards nil)) + (if (equal (bv-size bv) 0) + *b0* + (make-bit (logcar (bv-val bv))))) + +(verify-guards lsb + :hints (("goal" :use ((:instance logcar-type (acl2::i (bv-val bv)))) + :in-theory (e/d (acl2::bitp) (LOGCAR-TYPE))))) + +(defun msb (bv) + (declare (xargs :guard (and (bvp bv) (< 0 (bv-size bv))) + :verify-guards nil)) + (if (equal (bv-size bv) 0) + *b0* + (make-bit (logbit (1- (bv-size bv)) (bv-val bv))))) + +(verify-guards msb + :hints (("goal" :use ((:instance logbit-type + (acl2::pos (+ -1 (BV-SIZE BV))) + (acl2::i (bv-val bv)))) + :in-theory (e/d (acl2::bitp) (LOGBIT-TYPE))))) + +(defthm bitp-lsb (bitp (lsb bv))) + +(defthm bitp-msb (bitp (msb bv))) + +(in-theory (disable lsb msb)) + +;; suggested name msbv, lbv +(defun msbits (bv) + (declare (xargs :guard (and (bvp bv) (< 0 (bv-size bv))) + :verify-guards nil)) + (if (equal (bv-size bv) 0) + (bv 0 0) + (bv (logcdr (bv-val bv)) (1- (bv-size bv))))) + +(verify-guards msbits) + +(defun lsbits (bv) + (declare (xargs :guard (and (bvp bv) (< 0 (bv-size bv))))) + (if (equal (bv-size bv) 0) + (bv 0 0) + (bv (loghead (1- (bv-size bv)) (bv-val bv)) + (1- (bv-size bv))))) + +(defthm bvp-msbits + (implies (and (bvp bv) (not (bv-null? bv))) (bvp (msbits bv)))) + +(defthm bv-size-msbits + (implies (and (bvp bv) (not (bv-null? bv))) + (equal (bv-size (msbits bv)) (1- (bv-size bv))))) + +(defthm bvp-lsbits + (implies (and (bvp bv) (not (bv-null? bv))) (bvp (lsbits bv)))) + +(defthm bv-size-lsbits + (implies (and (bvp bv) (not (bv-null? bv))) + (equal (bv-size (lsbits bv)) (1- (bv-size bv))))) + + +(defun bitn (n bv) + (declare (xargs :guard (and (integerp n) (bvp bv) + (<= 0 n) (< n (bv-size bv))) + :verify-guards nil)) + (make-bit (logbit (- (bv-size bv) (1+ n)) (bv-val bv)))) + +(verify-guards bitn + :hints (("goal" :use ((:instance logbit-type + (acl2::pos (+ -1 (- N) (BV-SIZE BV))) + (acl2::i (bv-val bv)))) + :in-theory (e/d (acl2::bitp) (LOGBIT-TYPE))))) + + +(defthm bitp-bitn (bitp (bitn n bv))) + +;; A possible improved name is bv&b +(defun bv&b (bv b) + (declare (xargs :guard (and (bvp bv) (bitp b)))) + (bv (logcons (bit-val b) (bv-val bv)) (1+ (bv-size bv)))) + +(defthm bvp-bv&b + (implies (and (bvp bv) (bitp b)) + (bvp (bv&b bv b)))) + +(defthm bv-size-bv&b + (implies (and (bvp bv) (bitp b)) + (equal (bv-size (bv&b bv b)) (1+ (bv-size bv))))) + +;; A possible improved name is b&bv +(defun b&bv (b bv) + (declare (xargs :guard (and (bvp bv) (bitp b)))) + (bv (logapp (bv-size bv) (bv-val bv) (bit-val b)) (1+ (bv-size bv)))) + + +(defthm bvp-b&bv + (implies (and (bvp bv) (bitp b)) + (bvp (b&bv b bv)))) + +(defthm bv-size-b&bv + (implies (and (bvp bv) (bitp b)) + (equal (bv-size (b&bv b bv)) (1+ (bv-size bv))))) + +(defun bits (bv i j) + (declare (xargs :guard (and (bvp bv) (integerp i) + (integerp j) (>= j 0) (>= j i) + (>= i 0) + (> (bv-size bv) j)))) + (bv (loghead (1+ (- j i)) (logtail (1- (- (bv-size bv) j)) (bv-val bv))) + (1+ (- j i)))) + +(defthm bvp-bits + (implies (and (bvp bv) (integerp i) (integerp j) (>= j i)) + (bvp (bits bv i j)))) + +(defthm bv-size-bits + (implies (and (bvp bv) (integerp i) (integerp j) (> j i)) + (equal (bv-size (bits bv i j)) (1+ (- j i))))) + +; suggested name rbits +(defun bv-right (n bv) + (declare (xargs :guard (and (integerp n) (<= 0 n) (bvp bv)))) + (bv (loghead n (bv-val bv)) n)) + + +(defthm bvp-bv-right + (implies (and (bvp bv) (integerp n) (<= 0 n)) + (bvp (bv-right n bv)))) + +(defthm bv-size-bv-right + (implies (and (bvp bv) (integerp n) (<= 0 n)) + (equal (bv-size (bv-right n bv)) n))) + +; suggested name lbits +(defun bv-left (n bv) + (declare (xargs :guard (and (integerp n) (<= 0 n) (bvp bv) + (<= n (bv-size bv))) + :verify-guards nil)) + (bv (logtail (- (bv-size bv) n) (bv-val bv)) n)) + +(verify-guards bv-left + :hints (("subgoal 1" :in-theory (enable logtail ifloor expt)))) + + +(defthm bvp-bv-left + (implies (and (bvp bv) (integerp n) (<= 0 n) + (<= n (bv-size bv))) + (bvp (bv-left n bv)))) + +(defthm bv-size-bv-left + (implies (and (bvp bv) (integerp n) (<= 0 n) + (<= n (bv-size bv))) + (equal (bv-size (bv-left n bv)) n))) + + +(defun bv& (a b) + (declare (xargs :guard (and (bvp a) (bvp b)))) + (bv (logapp (bv-size b) (bv-val b) (bv-val a)) + (+ (bv-size a) (bv-size b)))) + +(defthm bvp-bv& + (implies (and (bvp a) (bvp b)) (bvp (bv& a b)))) + +(defthm bv-size-bv& + (implies (and (bvp a) (bvp b)) + (equal (bv-size (bv& a b)) + (+ (bv-size a) (bv-size b))))) + +(defun b&-rec (arglist) + (if (endp arglist) + (bv 0 0) + (if (endp (cdr arglist)) + `(b2bv ,(car arglist)) + `(b&bv ,(car arglist) ,(b&-rec (cdr arglist)))))) + +;; (log&& a b c) appends all arguments to one vector +(defmacro b&& (&rest arglist) + (b&-rec arglist)) + + + +(defun bv&-rec (arglist) + (if (endp arglist) + (bv 0 0) + (if (endp (cdr arglist)) + (car arglist) + `(bv& ,(car arglist) ,(bv&-rec (cdr arglist)))))) + +;; (log&& a b c) appends all arguments to one vector +(defmacro bv&& (&rest arglist) + (bv&-rec arglist)) + + + + +(defun ones (n) + (declare (xargs :guard (and (integerp n) (<= 0 n)))) + (bv (- (expt 2 n) 1) n)) + +(defun zeros (n) + (declare (xargs :guard (and (integerp n) (<= 0 n)))) + (bv 0 n)) + + +(defun pad1 (n) + (declare (xargs :guard (and (integerp n) (<= 0 n)))) + (ones n)) + +(defun pad0 (n) + (declare (xargs :guard (and (integerp n) (<= 0 n)))) + (zeros n)) + + +;; fill0 fill0_at zeros_from_to fill_zero fill_0 fill_1 +(defun fill-0 (m n) + (declare (xargs :guard (and (integerp n) (<= 0 n) (integerp m) (<= 0 m) (<= m n)))) + (zeros (1+ (- n m)))) + +(defun fill-1 (m n) + (declare (xargs :guard (and (integerp n) (<= 0 n) (integerp m) (<= 0 m) (<= m n)))) + (ones (1+ (- n m)))) + + +(defthm bvp-zeros + (implies (and (integerp n) (<= 0 n)) + (bvp (zeros n)))) +(defthm bv-size-zeros + (implies (and (integerp n) (<= 0 n)) + (equal (bv-size (zeros n)) n))) + +(defthm bvp-ones + (implies (and (integerp n) (<= 0 n)) + (bvp (ones n)))) + +(defthm bv-size-ones + (implies (and (integerp n) (<= 0 n)) + (equal (bv-size (ones n)) n))) + + +(defthm bvp-pad0 + (implies (and (integerp n) (<= 0 n)) + (bvp (pad0 n)))) + +(defthm bv-size-pad0 + (implies (and (integerp n) (<= 0 n)) + (equal (bv-size (pad0 n)) n))) + +(defthm bvp-pad1 + (implies (and (integerp n) (<= 0 n)) + (bvp (pad1 n)))) + +(defthm bv-size-pad1 + (implies (and (integerp n) (<= 0 n)) + (equal (bv-size (pad1 n)) n))) + +(defthm bvp-fill-0 + (implies (and (integerp n) (integerp m) (<= n m)) + (bvp (fill-0 n m)))) + +(defthm bv-size-fill-0 + (implies (and (integerp n) (integerp m) (<= n m)) + (equal (bv-size (fill-0 n m)) (1+ (- m n))))) + +(defthm bvp-fill-1 + (implies (and (integerp n) (integerp m) (<= n m)) + (bvp (fill-1 n m))) + :hints (("goal" :in-theory (disable ones)))) + +(defthm bv-size-fill-1 + (implies (and (integerp n) (integerp m) (<= n m)) + (equal (bv-size (fill-1 n m)) (1+ (- m n))))) + + +(defun b1p (b) + (declare (xargs :guard (bitp b))) + (not (equal b *b0*))) + +(defun b-if (a b c) + (declare (xargs :guard (and (bitp a) (bitp b) (bitp c)))) + (if (b1p a) b c)) + + +(defthm bitp-b-if + (implies (and (bitp a) (bitp b) (bitp c)) + (bitp (b-if a b c)))) + +(defun bv-if (a b c) + (declare (xargs :guard (and (bitp a) (bvp b) (bvp c)))) + (if (b1p a) b c)) + +(defthm bvp-bv-if + (implies (and (bitp a) (bvp b) (bvp c)) + (bvp (bv-if a b c)))) + +(defthm bv-size-bv-if + (implies (and (bitp a) (bvp b) (bvp c) (equal (bv-size b) (bv-size c))) + (equal (bv-size (bv-if a b c)) (bv-size b)))) + + +(defmacro b-cond (&rest clause) + (if (endp clause) + 0 + (let ((cnd (caar clause)) + (first (cadar clause)) + (rest (cdr clause))) + `(b-if ,cnd ,first (b-cond ,@rest))))) + + + +(defmacro bv-cond (&rest clause) + (if (endp clause) + *bv-nil* + (if (and (endp (cdr clause)) + (equal (caar clause) 1)) + (cadar clause) + (let ((cnd (caar clause)) + (first (cadar clause)) + (rest (cdr clause))) + `(bv-if ,cnd ,first (bv-cond ,@rest)))))) + + +(defun bv-not (bv) + (declare (xargs :guard (bvp bv))) + (bv (lognotu (bv-size bv) (bv-val bv)) + (bv-size bv))) + +(defthm bvp-bv-not + (implies (bvp bv) + (bvp (bv-not bv)))) + +(defthm bv-size-bv-not + (implies (bvp bv) + (equal (bv-size (bv-not bv)) (bv-size bv)))) + +(defun bv-and (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2) + (equal (bv-size bv1) (bv-size bv2))))) + (bv (logand (bv-val bv1) (bv-val bv2)) + (bv-size bv1))) + + +(defun bv-ior (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2) + (equal (bv-size bv1) (bv-size bv2))))) + (bv (logior (bv-val bv1) (bv-val bv2)) + (bv-size bv1))) + +(defun bv-xor (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2) + (equal (bv-size bv1) (bv-size bv2))))) + (bv (logxor (bv-val bv1) (bv-val bv2)) + (bv-size bv1))) + +(defthm bvp-bv-and + (implies (and (bvp bv1) (bvp bv2) + (equal (bv-size bv1) (bv-size bv2))) + (bvp (bv-and bv1 bv2)))) + +(defthm bv-size-bv-and + (implies (and (bvp bv1) (bvp bv2) (equal (bv-size bv1) (bv-size bv2))) + (equal (bv-size (bv-and bv1 bv2)) + (bv-size bv1)))) + + +(defthm bvp-bv-ior + (implies (and (bvp bv1) (bvp bv2) (equal (bv-size bv1) (bv-size bv2))) + (bvp (bv-ior bv1 bv2)))) + +(defthm bv-size-bv-ior + (implies (and (bvp bv1) (bvp bv2) (equal (bv-size bv1) (bv-size bv2))) + (equal (bv-size (bv-ior bv1 bv2)) + (bv-size bv1)))) + + +(defthm bvp-bv-xor + (implies (and (bvp bv1) (bvp bv2)) + (bvp (bv-xor bv1 bv2)))) + +(defthm bv-size-bv-xor + (implies (and (bvp bv1) (bvp bv2) (equal (bv-size bv1) (bv-size bv2))) + (equal (bv-size (bv-xor bv1 bv2)) + (bv-size bv1)))) + +(defun b-maj (a b c) + (declare (xargs :guard (and (bitp a) (bitp b) (bitp c)))) + (b-and (b-ior a b) (b-and (b-ior b c) (b-ior c a)))) + +(defthm bitp-b-maj + (implies (and (bitp a) (bitp b) (bitp c)) + (bitp (b-maj a b c)))) + +(defun bv-uextend (a n) + (declare (xargs :guard (and (bvp a) (integerp n) (<= 0 n)))) + (bv (bv-val a) n)) + +(defthm bvp-bv-uextend + (implies (and (bvp bv1) (integerp n) (<= 0 n)) + (bvp (bv-uextend bv1 n)))) + +(defthm bv-size-bv-uextend + (implies (and (bvp a) (integerp n) (<= 0 n)) + (equal (bv-size (bv-uextend a n)) n))) + +(defun bv-sextend (a n) + (declare (xargs :guard (and (bvp a) (< 0 (bv-size a)) + (integerp n) (<= 0 n)))) + (bv (logextu n (bv-size a) (bv-val a)) n)) + +(defthm bvp-bv-sextend + (implies (and (bvp bv1) (integerp n) (<= 0 n)) + (bvp (bv-sextend bv1 n)))) + +(defthm bv-size-bv-sextend + (implies (and (bvp a) (integerp n) (<= 0 n)) + (equal (bv-size (bv-sextend a n)) n))) + + +(defun bv-lsh (n a) + (declare (xargs :guard (and (bvp a) (integerp n)))) + (bv (lshu (bv-size a) (bv-val a) n) (bv-size a))) + +(defthm bvp-bv-lsh + (implies (and (bvp bv1) (integerp n)) + (bvp (bv-lsh n bv1)))) + +(defthm bv-size-bv-lsh + (implies (and (bvp bv1) (integerp n)) + (equal (bv-size (bv-lsh n bv1)) (bv-size bv1)))) + + +(defun bv-ash (n a) + (declare (xargs :guard (and (bvp a) (integerp n) + (< 0 (bv-size a))))) + (bv (ashu (bv-size a) (bv-val a) n) (bv-size a))) + +(defthm bvp-bv-ash + (implies (and (bvp bv1) (integerp n)) + (bvp (bv-ash n bv1)))) + +(defthm bv-size-bv-ash + (implies (and (bvp bv1) (integerp n)) + (equal (bv-size (bv-ash n bv1)) (bv-size bv1)))) + + +(defun bv-<< (bv sa) + (declare (xargs :guard (and (bvp sa) (bvp bv)))) + (bv-lsh (bv-val sa) bv)) + +(defthm bvp-bv-<< + (implies (and (bvp sa) (bvp bv)) + (bvp (bv-<< bv sa)))) + +(defthm bv-size-bv-<< + (implies (and (bvp sa) (bvp bv)) + (equal (bv-size (bv-<< bv sa)) (bv-size bv)))) + +(defun bv->> (bv sa) + (declare (xargs :guard (and (bvp sa) (bvp bv)))) + (bv-lsh (- (bv-val sa)) bv)) + +(defthm bvp-bv->> + (implies (and (bvp sa) (bvp bv)) + (bvp (bv->> bv sa)))) + + +(defthm bv-size-bv->> + (implies (and (bvp sa) (bvp bv)) + (equal (bv-size (bv->> bv sa)) (bv-size bv)))) + + +(defun bv-*>> (bv sa) + (declare (xargs :guard (and (bvp sa) (bvp bv) (< 0 (bv-size bv))))) + (bv-ash (- (bv-val sa)) bv)) + +(defthm bvp-bv-*>> + (implies (and (bvp sa) (bvp bv)) + (bvp (bv-*>> bv sa)))) + +(defthm bv-size-bv-*>> + (implies (and (bvp sa) (bvp bv)) + (equal (bv-size (bv-*>> bv sa)) (bv-size bv)))) + + +(defun adder (a b c) + (declare (xargs :measure (nfix (bv-size a)) + :guard (and (bvp a) (bvp b) (bitp c)) + :verify-guards nil)) + (if (bv-null? a) + (b2bv c) + (if (bv-null? b) + (b2bv c) + (bv&b (adder (msbits a) (msbits b) (b-maj (lsb a) (lsb b) c)) + (b-xor (b-xor (lsb a) (lsb b)) c))))) + +(defthm bvp-adder + (implies (and (bvp a) (bvp b) (bitp c)) + (bvp (adder a b c)))) + +(defthm bv-size-adder + (implies (and (bvp a) (bvp b) (bitp c) + (equal (bv-size a) (bv-size b))) + (equal (bv-size (adder a b c)) + (1+ (bv-size a))))) + + +(verify-guards adder + :hints (("goal" :in-theory (disable msbits b-maj bitp)))) + +;; There are two versions of bv+ that can be thought of as a natural +;; definition. One returns the bit-vector of the same size as the +;; original input and the other returns a bit vector of size +;; incremented by one. There are pro and conses between these design +;; choices. Let us list the advantage of the implementation. +;; Advantage of the fixed size +;; The commutative rule applies. +;; Most of the microprocessor instruction implements fixed sized +;; add. +;; Carry output is defined as a separate function. +;; Adding arbitrary number of vectors can be described naturally. +;; Incremented width subtract operation is not natural to define, +;; because carry is inverted. +;; Advantage of the incremented width. +;; Does not overflow. +;; May save explicit padding. +;; Currently we implment fixed with sum and subtract operation. +;; When overflow should be avoided, bit vector should be extended +;; before the operations. +(defun bv+ (a b) + (declare (xargs :guard (and (bvp a) (bvp b)))) + (bv (+ (bv-val a) (bv-val b)) (bv-size a))) + +(defthm bvp-bv+ + (implies (and (bvp a) (bvp b)) + (bvp (bv+ a b)))) + +(defthm bv-size-bv+ + (implies (and (bvp a) (bvp b) (equal (bv-size a) (bv-size b))) + (equal (bv-size (bv+ a b)) + (bv-size a)))) + +(defun bv+carry (a b) + (declare (xargs :guard (and (bvp a) (bvp b) + (equal (bv-size a) (bv-size b))) )) + (msb (bv+ (b&bv *b0* a) (b&bv *b0* b)))) + +(defthm bitp-bv+carry (bitp (bv+carry a b))) + +;; Bit vector multiply. +;; I put a strong guard because a or b is not bvp, this function +;; may return an incorrect value. Consider (bv* (bv 7 2) (bv 7 2)) +(defun bv* (a b) + (declare (xargs :guard (and (bvp a) (bvp b)))) + (bv (* (bv-val a) (bv-val b)) (+ (bv-size a) (bv-size b)))) + +(defthm bvp-bv* + (implies (and (bvp a) (bvp b)) + (bvp (bv* a b)))) + +(defthm bv-size-bv* + (implies (and (bvp a) (bvp b)) + (equal (bv-size (bv* a b)) (+ (bv-size a) (bv-size b))))) + + +(defun bv-eq? (a b) + (declare (xargs :guard (and (bvp a) (bvp b)))) + (if (equal a b) *b1* *b0*)) + +(defthm bitp-eq? + (bitp (bv-eq? a b))) + +(defun bv-neq? (a b) + (declare (xargs :guard (and (bvp a) (bvp b)))) + (b-not (bv-eq? a b))) + +(defthm bitp-bv-neq? + (bitp (bv-neq? a b))) + +(defun bv-all-ones? (bv) + (declare (xargs :guard (bvp bv))) + (bv-eq? bv (ones (bv-size bv)))) + +(defthm bitp-all-ones? + (bitp (bv-all-ones? bv))) + +(defun bv-all-zeros? (bv) + (declare (xargs :guard (bvp bv))) + (bv-eq? bv (zeros (bv-size bv)))) + +(defthm bitp-all-zeros? + (bitp (bv-all-zeros? bv))) + +(defun bv-and-all (bv) + (declare (xargs :guard (bvp bv))) + (bv-all-ones? bv)) + +(defthm bitp-bv-and-all + (bitp (bv-and-all bv))) + +(defun bv-ior-all (bv) + (declare (xargs :guard (bvp bv))) + (b-not (bv-all-zeros? bv))) + +(defthm bitp-bv-ior-all + (bitp (bv-ior-all bv))) + +(defun bv-some-zeros? (bv) + (declare (xargs :guard (bvp bv))) + (b-not (bv-all-ones? bv))) + +(defthm bitp-some-zeros? + (bitp (bv-some-zeros? bv))) + +(defun bv-some-ones? (bv) + (declare (xargs :guard (bvp bv))) + (b-not (bv-all-zeros? bv))) + +(defthm bitp-some-ones? + (bitp (bv-some-ones? bv))) + +(defun bv-right-ior (bv sa) + (declare (xargs :guard (and (bvp bv) (bvp sa)))) + (let ((w (expt 2 (bv-size sa)))) + (bv-some-ones? (bv-right w (bv->> (bv& bv (bv 0 w)) sa))))) + +(defthm bitp-bv-right-ior (bitp (bv-right-ior bv sa))) + +(defun bv-left-ior (bv sa) + (declare (xargs :guard (and (bvp bv) (bvp sa)))) + (let ((w (expt 2 (bv-size sa)))) + (bv-some-ones? (bv-left w (bv-<< (bv& (bv 0 w) bv) sa))))) + +(defthm bitp-bv-left-ior (bitp (bv-left-ior bv sa))) + + +(defun bv-inc (bv c) + (declare (xargs :guard (and (bvp bv) (bitp c)))) + (bv (+ (bv-val bv) (bit-val c)) (bv-size bv))) + +(defthm bvp-bv-inc + (implies (and (bvp bv) (bitp c)) + (bvp (bv-inc bv c)))) + +(defthm bv-size-bv-inc + (implies (and (bvp bv) (bitp c)) + (equal (bv-size (bv-inc bv c)) (bv-size bv)))) + +(defun bv++ (bv) + (declare (xargs :guard (and (bvp bv)))) + (bv (1+ (bv-val bv)) (bv-size bv))) + +(defthm bvp-bv++ + (implies (bvp bv) (bvp (bv++ bv)))) + + +(defthm bv-size-bv++ + (implies (bvp bv) + (equal (bv-size (bv++ bv)) (bv-size bv)))) + +(defun bv-- (bv) + (declare (xargs :guard (and (bvp bv)))) + (bv (1- (bv-val bv)) (bv-size bv))) + +(defthm bvp-bv-- + (implies (bvp bv) (bvp (bv-- bv)))) + + +(defthm bv-size-bv-- + (implies (bvp bv) + (equal (bv-size (bv-- bv)) (bv-size bv)))) + +(defun bv- (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2)))) + (bv (- (bv-val bv1) (bv-val bv2)) (bv-size bv1))) + +(defthm bvp-bv- + (implies (and (bvp bv1) (bvp bv2)) (bvp (bv- bv1 bv2)))) + +(defthm bv-size-bv- + (implies (and (bvp bv1) (bvp bv2) (equal (bv-size bv1) (bv-size bv2))) + (equal (bv-size (bv- bv1 bv2)) (bv-size bv1)))) + + +(defun bv-neg (bv1) + (declare (xargs :guard (bvp bv1))) + (bv++ (bv-not bv1))) + +(defun bv-carry (bv1 bv2) + (msb (bv++ (bv+ (b&bv *b0* bv1) (b&bv *b0* (bv-not bv2)))))) + +(defthm bitp-bv-carry + (bitp (bv-carry bv1 bv2))) + +(defun bv-gt? (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2)))) + (if (> (bv-val bv1) (bv-val bv2)) *b1* *b0*)) + +(defthm bitp-bv-gt? (bitp (bv-gt? bv1 bv2))) + +(defun bv-ge? (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2)))) + (if (>= (bv-val bv1) (bv-val bv2)) *b1* *b0*)) + +(defthm bitp-bv-ge? (bitp (bv-ge? bv1 bv2))) + +(defun bv-lt? (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2)))) + (if (< (bv-val bv1) (bv-val bv2)) *b1* *b0*)) + +(defthm bitp-bv-lt? (bitp (bv-lt? bv1 bv2))) + +(defun bv-le? (bv1 bv2) + (declare (xargs :guard (and (bvp bv1) (bvp bv2)))) + (if (<= (bv-val bv1) (bv-val bv2)) *b1* *b0*)) + +(defthm bitp-bv-le? (bitp (bv-le? bv1 bv2))) + +(defun bv-lz (bv w) + (declare (xargs :guard (and (bvp bv) (integerp w) (<= 0 w)) + :measure (nfix (bv-size bv)) + :verify-guards nil)) + (if (bv-null? bv) + (bv 0 w) + (if (b1p (bitn 0 bv)) + (bv 0 w) + (bv++ (bv-lz (lsbits bv) w))))) + +(defthm bvp-bv-lz + (implies (and (bvp bv) (integerp w) (<= 0 w)) + (bvp (bv-lz bv w)))) + +(defthm bv-size-bv-lz + (implies (and (bvp bv) (integerp w) (<= 0 w)) + (equal (bv-size (bv-lz bv w)) w))) + +(verify-guards bv-lz) + +(deflabel end-bv) + +;; auxiliary functions for integer expressions. +(defun fixint32 (a) + (- (mod (+ (nfix a) (expt 2 31)) (expt 2 32)) + (expt 2 31))) + +(defun int32p (a) (and (integerp a) (<= (- (expt 2 31)) a) (< a (expt 2 31)))) +(defun int32+ (a b) (fixint32 (+ a b))) +(defun int32- (a b) (fixint32 (- a b))) +(defun int32* (a b) (fixint32 (* a b))) +(defun int32** (a b) (fixint32 (expt a b))) + +(deftheory bv-theory (set-difference-theories (function-theory 'end-bv) + (function-theory 'begin-bv))) + + +(defthm bitp-b-not + (implies (bitp b) (bitp (b-not b))) + :rule-classes (:rewrite :type-prescription)) + +(defthm bitp-b-and + (implies (and (bitp a) (bitp b)) + (bitp (b-and a b))) + :rule-classes (:rewrite :type-prescription)) + +(defthm bitp-b-and + (implies (and (bitp a) (bitp b)) + (bitp (b-and a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-ior + (implies (and (bitp a) (bitp b)) + (bitp (b-ior a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-xor + (implies (and (bitp a) (bitp b)) + (bitp (b-xor a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-nor + (implies (and (bitp a) (bitp b)) + (bitp (b-nor a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-nand + (implies (and (bitp a) (bitp b)) + (bitp (b-nand a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-andc1 + (implies (and (bitp a) (bitp b)) + (bitp (b-andc1 a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-andc2 + (implies (and (bitp a) (bitp b)) + (bitp (b-andc2 a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-orc1 + (implies (and (bitp a) (bitp b)) + (bitp (b-orc1 a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-orc2 + (implies (and (bitp a) (bitp b)) + (bitp (b-orc2 a b))) + :rule-classes (:rewrite :type-prescription)) +(defthm bitp-b-eqv + (implies (and (bitp a) (bitp b)) + (bitp (b-eqv a b))) + :rule-classes (:rewrite :type-prescription)) + +(defthm bitn-type-prescription + (bitp (bitn n bv)) + :rule-classes (:rewrite :type-prescription)) + +(in-theory (disable bv-theory))
\ No newline at end of file |