/*======================================================================== Copyright (C) 1996-2002 by Jorn Lind-Nielsen All rights reserved Permission is hereby granted, without written agreement and without license or royalty fees, to use, reproduce, prepare derivative works, distribute, and display this software and its documentation for any purpose, provided that (1) the above copyright notice and the following two paragraphs appear in all copies of the source code and (2) redistributions, including without limitation binaries, reproduce these notices in the supporting documentation. Substantial modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated in all files where they apply. IN NO EVENT SHALL JORN LIND-NIELSEN, OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. JORN LIND-NIELSEN SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ========================================================================*/ /************************************************************************* $Header: /cvsroot/buddy/buddy/src/bvec.c,v 1.1.1.1 2004/06/25 13:22:34 haimcohen Exp $ FILE: bvec.c DESCR: Boolean vector arithmetics using BDDs AUTH: Jorn Lind DATE: (C) may 1999 *************************************************************************/ #include #include "kernel.h" #include "bvec.h" #define DEFAULT(v) { v.bitnum=0; v.bitvec=NULL; } /************************************************************************* *************************************************************************/ static bvec bvec_build(int bitnum, int isTrue) { bvec vec; int n; vec.bitvec = NEW(BDD,bitnum); vec.bitnum = bitnum; if (!vec.bitvec) { bdd_error(BDD_MEMORY); vec.bitnum = 0; return vec; } for (n=0 ; n 0) { val >>= 1; bitnum++; } return bitnum; } #endif /* NAME {* bvec\_copy *} SECTION {* bvec *} SHORT {* create a copy of a bvec *} PROTO {* bvec bvec_copy(bvec src) *} DESCR {* Returns a copy of {\tt src}. The result is reference counted. *} ALSO {* bvec\_con *} */ bvec bvec_copy(bvec src) { bvec dst; int n; if (src.bitnum == 0) { DEFAULT(dst); return dst; } dst = bvec_build(src.bitnum,0); for (n=0 ; n> 1; } return v; } /* NAME {* bvec\_var *} SECTION {* bvec *} SHORT {* build a boolean vector with BDD variables *} PROTO {* bvec bvec_var(int bitnum, int offset, int step) *} DESCR {* Builds a boolean vector with the BDD variables $v_1, \ldots, v_n$ as the elements. Each variable will be the the variabled numbered {\tt offset + N*step} where {\tt N} ranges from 0 to {\tt bitnum}-1.*} RETURN {* The boolean vector (which is already reference counted) *} ALSO {* bvec\_true, bvec\_false, bvec\_con *} */ bvec bvec_var(int bitnum, int offset, int step) { bvec v; int n; v = bvec_build(bitnum,0); for (n=0 ; n=0 ; n--) if (ISONE(e.bitvec[n])) val = (val << 1) | 1; else if (ISZERO(e.bitvec[n])) val = val << 1; else return 0; return val; } /*======================================================================*/ /* NAME {* bvec\_free *} SECTION {* bvec *} SHORT {* frees all memory used by a boolean vector *} PROTO {* void bvec_free(bvec v) *} DESCR {* Use this function to release any unused boolean vectors. The decrease of the reference counts on the BDDs in {\tt v} is done by {\tt bvec\_free}. *} */ void bvec_free(bvec v) { bvec_delref(v); free(v.bitvec); } /* NAME {* bvec\_addref *} SECTION {* bvec *} SHORT {* increase reference count of a boolean vector *} PROTO {* bvec bvec_addref(bvec v) *} DESCR {* Use this function to increase the reference count of all BDDs in a {\tt v}. Please note that all boolean vectors returned from BuDDy are reference counted from the beginning. *} RETURN {* The boolean vector {\tt v} *} ALSO {* bvec\_delref *} */ bvec bvec_addref(bvec v) { int n; for (n=0 ; n>1); if (c & 0x1) { res = bvec_add(e, rest); bvec_free(rest); } else res = rest; bvec_free(next); return res; } /* NAME {* bvec\_mul *} SECTION {* bvec *} SHORT {* builds a boolean vector for multiplication *} PROTO {* bvec bvec_mul(bvec l, bvec r) *} DESCR {* Builds a boolean vector representing the multiplication of {\tt l} and {\tt r}. *} RETURN {* The result of the multiplication (which is already reference counted) *} ALSO {* bvec\_mulfixed, bvec\_div, bvec\_add, bvec\_shl *} */ bvec bvec_mul(bvec left, bvec right) { int n; int bitnum = left.bitnum + right.bitnum; bvec res; bvec leftshifttmp; bvec leftshift; if (left.bitnum == 0 || right.bitnum == 0) { DEFAULT(res); return res; } res = bvec_false(bitnum); leftshifttmp = bvec_copy(left); leftshift = bvec_coerce(bitnum, leftshifttmp); /*bvec_delref(leftshifttmp);*/ bvec_free(leftshifttmp); for (n=0 ; n=1 ; m--) leftshift.bitvec[m] = leftshift.bitvec[m-1]; leftshift.bitvec[0] = bddfalse; /*bvec_delref(added);*/ bvec_free(added); } /*bvec_delref(leftshift);*/ bvec_free(leftshift); return res; } static void bvec_div_rec(bvec divisor, bvec *remainder, bvec *result, int step) { int n; BDD isSmaller = bdd_addref( bvec_lte(divisor, *remainder) ); bvec newResult = bvec_shlfixed( *result, 1, isSmaller ); bvec zero = bvec_build(divisor.bitnum, bddfalse); bvec newRemainder, tmp, sub = bvec_build(divisor.bitnum, bddfalse); for (n=0 ; nbitvec[divisor.bitnum-1]); if (step > 1) bvec_div_rec( divisor, &newRemainder, &newResult, step-1 ); bvec_free(tmp); bvec_free(sub); bvec_free(zero); bdd_delref(isSmaller); bvec_free(*remainder); bvec_free(*result); *result = newResult; *remainder = newRemainder; } /* NAME {* bvec\_divfixed *} SECTION {* bvec *} SHORT {* builds a boolean vector for division by a constant *} PROTO {* int bvec_div(bvec e, int c, bvec *res, bvec *rem) *} DESCR {* Builds a new boolean vector representing the integer division of {\tt e} with {\tt c}. The result of the division will be stored in {\tt res} and the remainder of the division will be stored in {\tt rem}. Both vectors should be initialized as the function will try to release the nodes used by them. If an error occurs then the nodes will {\em not} be freed. *} RETURN {* Zero on success or a negative error code on error. *} ALSO {* bvec\_div, bvec\_mul, bvec\_add, bvec\_shl *} */ int bvec_divfixed(bvec e, int c, bvec *res, bvec *rem) { if (c > 0) { bvec divisor = bvec_con(e.bitnum, c); bvec tmp = bvec_build(e.bitnum, 0); bvec tmpremainder = bvec_shlfixed(tmp, 1, e.bitvec[e.bitnum-1]); bvec result = bvec_shlfixed(e, 1, bddfalse); bvec remainder; bvec_div_rec(divisor, &tmpremainder, &result, divisor.bitnum); remainder = bvec_shrfixed(tmpremainder, 1, bddfalse); bvec_free(tmp); bvec_free(tmpremainder); bvec_free(divisor); *res = result; *rem = remainder; return 0; } return bdd_error(BVEC_DIVZERO); } #if 0 void p(bvec x) { int n; for (n=0 ; n 0) res.bitvec[right.bitnum-n] = divLteRem; /* Shift 'div' one bit right */ bdd_delref(div.bitvec[0]); for (m=0 ; m= 0) tmp1 = bdd_addref( bdd_and(rEquN, l.bitvec[m-n]) ); else tmp1 = bdd_addref( bdd_and(rEquN, c) ); tmp2 = bdd_addref( bdd_or(res.bitvec[m], tmp1) ); bdd_delref(tmp1); bdd_delref(res.bitvec[m]); res.bitvec[m] = tmp2; } bdd_delref(rEquN); /*bvec_delref(val);*/ bvec_free(val); } /* At last make sure 'c' is shiftet in for r-values > l-bitnum */ val = bvec_con(r.bitnum, l.bitnum); rEquN = bvec_gth(r, val); tmp1 = bdd_addref( bdd_and(rEquN, c) ); for (m=0 ; m l-bitnum */ val = bvec_con(r.bitnum, l.bitnum); rEquN = bvec_gth(r, val); tmp1 = bdd_addref( bdd_and(rEquN, c) ); for (m=0 ; m y$ *} PROTO {* bdd bvec_gth(bvec l, bvec r) *} DESCR {* Returns the BDD representing {\tt l > r} ({\em not} reference counted). Both vectors must have the same number of bits. *} ALSO {* bvec\_lth, bvec\_lte, bvec\_gte, bvec\_equ, bvec\_neq *} */ bdd bvec_gth(bvec l, bvec r) { BDD tmp = bdd_addref( bvec_lte(l,r) ); BDD p = bdd_not(tmp); bdd_delref(tmp); return p; } /* NAME {* bvec\_gte *} SECTION {* bvec *} SHORT {* calculates the truth value of $x \geq y$ *} PROTO {* bdd bvec_gte(bvec l, bvec r) *} DESCR {* Returns the BDD representing {\tt l}$\geq${\tt r} ({\em not} reference counted). Both vectors must have the same number of bits. *} ALSO {* bvec\_lth, bvec\_gth, bvec\_gth, bvec\_equ, bvec\_neq *} */ bdd bvec_gte(bvec l, bvec r) { BDD tmp = bdd_addref( bvec_lth(l,r) ); BDD p = bdd_not(tmp); bdd_delref(tmp); return p; } /* NAME {* bvec\_equ *} SECTION {* bvec *} SHORT {* calculates the truth value of $x = y$ *} PROTO {* bdd bvec_equ(bvec l, bvec r) *} DESCR {* Returns the BDD representing {\tt l = r} ({\em not} reference counted). Both vectors must have the same number of bits. *} ALSO {* bvec\_lth, bvec\_lte, bvec\_gth, bvec\_gte, bvec\_neq *} */ bdd bvec_equ(bvec l, bvec r) { BDD p = bddtrue; int n; if (l.bitnum == 0 || r.bitnum == 0) return bddfalse; if (l.bitnum != r.bitnum) { bdd_error(BVEC_SIZE); return p; } for (n=0 ; n