// BDDBitVector.java, created Jul 14, 2003 9:50:57 PM by jwhaley // Copyright (C) 2003 John Whaley // Licensed under the terms of the GNU LGPL; see COPYING for details. package net.sf.javabdd; import java.math.BigInteger; /** * <p>Bit vector implementation for BDDs.</p> * * @author John Whaley * @version $Id: BDDBitVector.java,v 1.2 2004/10/18 09:35:20 joewhaley Exp $ */ public abstract class BDDBitVector { protected BDD[] bitvec; protected BDDBitVector(int bitnum) { bitvec = new BDD[bitnum]; } protected void initialize(boolean isTrue) { BDDFactory bdd = getFactory(); for (int n = 0; n < bitvec.length; n++) if (isTrue) bitvec[n] = bdd.one(); else bitvec[n] = bdd.zero(); } protected void initialize(int val) { BDDFactory bdd = getFactory(); for (int n = 0; n < bitvec.length; n++) { if ((val & 0x1) != 0) bitvec[n] = bdd.one(); else bitvec[n] = bdd.zero(); val >>= 1; } } protected void initialize(long val) { BDDFactory bdd = getFactory(); for (int n = 0; n < bitvec.length; n++) { if ((val & 0x1) != 0) bitvec[n] = bdd.one(); else bitvec[n] = bdd.zero(); val >>= 1; } } protected void initialize(BigInteger val) { BDDFactory bdd = getFactory(); for (int n = 0; n < bitvec.length; n++) { if (val.testBit(0)) bitvec[n] = bdd.one(); else bitvec[n] = bdd.zero(); val = val.shiftRight(1); } } protected void initialize(int offset, int step) { BDDFactory bdd = getFactory(); for (int n=0 ; n<bitvec.length ; n++) bitvec[n] = bdd.ithVar(offset+n*step); } protected void initialize(BDDDomain d) { initialize(d.vars()); } protected void initialize(int[] var) { BDDFactory bdd = getFactory(); for (int n=0 ; n<bitvec.length ; n++) bitvec[n] = bdd.ithVar(var[n]); } public abstract BDDFactory getFactory(); public BDDBitVector copy() { BDDFactory bdd = getFactory(); BDDBitVector dst = bdd.createBitVector(bitvec.length); for (int n = 0; n < bitvec.length; n++) dst.bitvec[n] = bitvec[n].id(); return dst; } public BDDBitVector coerce(int bitnum) { BDDFactory bdd = getFactory(); BDDBitVector dst = bdd.createBitVector(bitnum); int minnum = Math.min(bitnum, bitvec.length); int n; for (n = 0; n < minnum; n++) dst.bitvec[n] = bitvec[n].id(); for (; n < minnum; n++) dst.bitvec[n] = bdd.zero(); return dst; } public boolean isConst() { for (int n = 0; n < bitvec.length; n++) { BDD b = bitvec[n]; if (!b.isOne() && !b.isZero()) return false; } return true; } public int val() { int n, val = 0; for (n = bitvec.length - 1; n >= 0; n--) if (bitvec[n].isOne()) val = (val << 1) | 1; else if (bitvec[n].isZero()) val = val << 1; else return 0; return val; } public void free() { for (int n = 0; n < bitvec.length; n++) { bitvec[n].free(); } bitvec = null; } public BDDBitVector map2(BDDBitVector that, BDDFactory.BDDOp op) { if (bitvec.length != that.bitvec.length) throw new BDDException(); BDDFactory bdd = getFactory(); BDDBitVector res = bdd.createBitVector(bitvec.length); for (int n=0 ; n < bitvec.length ; n++) res.bitvec[n] = bitvec[n].apply(that.bitvec[n], op); return res; } public BDDBitVector add(BDDBitVector that) { if (bitvec.length != that.bitvec.length) throw new BDDException(); BDDFactory bdd = getFactory(); BDD c = bdd.zero(); BDDBitVector res = bdd.createBitVector(bitvec.length); for (int n = 0; n < res.bitvec.length; n++) { /* bitvec[n] = l[n] ^ r[n] ^ c; */ res.bitvec[n] = bitvec[n].xor(that.bitvec[n]); res.bitvec[n].xorWith(c.id()); /* c = (l[n] & r[n]) | (c & (l[n] | r[n])); */ BDD tmp1 = bitvec[n].or(that.bitvec[n]); tmp1.andWith(c); BDD tmp2 = bitvec[n].and(that.bitvec[n]); tmp2.orWith(tmp1); c = tmp2; } c.free(); return res; } public BDDBitVector sub(BDDBitVector that) { if (bitvec.length != that.bitvec.length) throw new BDDException(); BDDFactory bdd = getFactory(); BDD c = bdd.zero(); BDDBitVector res = bdd.createBitVector(bitvec.length); for (int n = 0; n < res.bitvec.length; n++) { /* bitvec[n] = l[n] ^ r[n] ^ c; */ res.bitvec[n] = bitvec[n].xor(that.bitvec[n]); res.bitvec[n].xorWith(c.id()); /* c = (l[n] & r[n] & c) | (!l[n] & (r[n] | c)); */ BDD tmp1 = that.bitvec[n].or(c); BDD tmp2 = this.bitvec[n].apply(tmp1, BDDFactory.less); tmp1.free(); tmp1 = this.bitvec[n].and(that.bitvec[n]); tmp1.andWith(c); tmp1.orWith(tmp2); c = tmp1; } c.free(); return res; } BDD lte(BDDBitVector r) { if (this.bitvec.length != r.bitvec.length) throw new BDDException(); BDDFactory bdd = getFactory(); BDD p = bdd.one(); for (int n=0 ; n<bitvec.length ; n++) { /* p = (!l[n] & r[n]) | * bdd_apply(l[n], r[n], bddop_biimp) & p; */ BDD tmp1 = bitvec[n].apply(r.bitvec[n], BDDFactory.less); BDD tmp2 = bitvec[n].apply(r.bitvec[n], BDDFactory.biimp); tmp2.andWith(p); tmp1.orWith(tmp2); p = tmp1; } return p; } static void div_rec(BDDBitVector divisor, BDDBitVector remainder, BDDBitVector result, int step) { BDD isSmaller = divisor.lte(remainder); BDDBitVector newResult = result.shl(1, isSmaller); BDDFactory bdd = divisor.getFactory(); BDDBitVector zero = bdd.buildVector(divisor.bitvec.length, false); BDDBitVector sub = bdd.buildVector(divisor.bitvec.length, false); for (int n = 0; n < divisor.bitvec.length; n++) sub.bitvec[n] = isSmaller.ite(divisor.bitvec[n], zero.bitvec[n]); BDDBitVector tmp = remainder.sub(sub); BDDBitVector newRemainder = tmp.shl(1, result.bitvec[divisor.bitvec.length - 1]); if (step > 1) div_rec(divisor, newRemainder, newResult, step - 1); tmp.free(); sub.free(); zero.free(); isSmaller.free(); result.replaceWith(newResult); remainder.replaceWith(newRemainder); } public void replaceWith(BDDBitVector that) { if (bitvec.length != that.bitvec.length) throw new BDDException(); free(); this.bitvec = that.bitvec; that.bitvec = null; } public BDDBitVector shl(int pos, BDD c) { int minnum = Math.min(bitvec.length, pos); if (minnum < 0) throw new BDDException(); BDDFactory bdd = getFactory(); BDDBitVector res = bdd.createBitVector(bitvec.length); int n; for (n = 0; n < minnum; n++) res.bitvec[n] = c.id(); for (n = minnum; n < bitvec.length; n++) res.bitvec[n] = bitvec[n - pos].id(); return res; } BDDBitVector shr(int pos, BDD c) { int maxnum = Math.max(0, bitvec.length - pos); if (maxnum < 0) throw new BDDException(); BDDFactory bdd = getFactory(); BDDBitVector res = bdd.createBitVector(bitvec.length); int n; for (n=maxnum ; n<bitvec.length ; n++) res.bitvec[n] = c.id(); for (n=0 ; n<maxnum ; n++) res.bitvec[n] = bitvec[n+pos].id(); return res; } public BDDBitVector divmod(long c, boolean which) { if (c <= 0L) throw new BDDException(); BDDFactory bdd = getFactory(); BDDBitVector divisor = bdd.constantVector(bitvec.length, c); BDDBitVector tmp = bdd.buildVector(bitvec.length, false); BDDBitVector tmpremainder = tmp.shl(1, bitvec[bitvec.length-1]); BDDBitVector result = this.shl(1, bdd.zero()); BDDBitVector remainder; div_rec(divisor, tmpremainder, result, divisor.bitvec.length); remainder = tmpremainder.shr(1, bdd.zero()); tmp.free(); tmpremainder.free(); divisor.free(); if (which) { remainder.free(); return result; } else { result.free(); return remainder; } } public int size() { return bitvec.length; } public BDD getBit(int n) { return bitvec[n]; } }