[Javabdd-checkins] SF.net SVN: javabdd: [476] trunk/JavaBDD
Brought to you by:
joewhaley
|
From: <joe...@us...> - 2007-03-06 06:08:41
|
Revision: 476
http://svn.sourceforge.net/javabdd/?rev=476&view=rev
Author: joewhaley
Date: 2007-03-05 22:08:40 -0800 (Mon, 05 Mar 2007)
Log Message:
-----------
Added new UberMicroFactory.
Fixed setCacheRatio().
Added Intel compiler flag to optimize for Core 2 Duo processors.
Other small cleanups.
Modified Paths:
--------------
trunk/JavaBDD/Makefile
trunk/JavaBDD/net/sf/javabdd/BDDFactory.java
trunk/JavaBDD/net/sf/javabdd/BDDFactoryIntImpl.java
trunk/JavaBDD/net/sf/javabdd/BDDVarSet.java
trunk/JavaBDD/net/sf/javabdd/BuDDyFactory.java
trunk/JavaBDD/net/sf/javabdd/JFactory.java
Added Paths:
-----------
trunk/JavaBDD/net/sf/javabdd/BitString.java
trunk/JavaBDD/net/sf/javabdd/UberMicroFactory.java
Modified: trunk/JavaBDD/Makefile
===================================================================
--- trunk/JavaBDD/Makefile 2006-12-05 10:59:01 UTC (rev 475)
+++ trunk/JavaBDD/Makefile 2007-03-06 06:08:40 UTC (rev 476)
@@ -35,7 +35,7 @@
CUDD_DLL_NAME = cudd.dll
CAL_DLL_NAME = cal.dll
ifeq (${CC},icl) # Intel Windows compiler
- CFLAGS = -DSPECIALIZE_RELPROD -DSPECIALIZE_OR -DSPECIALIZE_AND -DSMALL_NODES /O2 /Ob2 $(EXTRA_CFLAGS)
+ CFLAGS = -DSPECIALIZE_RELPROD -DSPECIALIZE_OR -DSPECIALIZE_AND -DSMALL_NODES /O2 /Ob2 /QxT $(EXTRA_CFLAGS)
CUDD_CFLAGS = $(CFLAGS) -DHAVE_SYS_RESOURCE_H=0
CAL_CFLAGS = $(CFLAGS) -DCLOCK_RESOLUTION=60 -DRLIMIT_DATA_DEFAULT=16777216 -DNDEBUG=1 -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_UNISTD_H=0 -DHAVE_ERRNO_H=1 -DHAVE_ASSERT_H=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_PWD_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_SYS_TIME_H=0 -DHAVE_SYS_RESOURCE_H=0 -DHAVE_STDARG_H=1 -DSIZEOF_VOID_P=4 -DSIZEOF_INT=4 -DHAVE_IEEE_754=1 -DPAGE_SIZE=4096 -DLG_PAGE_SIZE=12 -DRETSIGTYPE=void -DHAVE_STRCOLL=1 -DHAVE_SYSCONF=1 -DHAVE_GETHOSTNAME=1 -DHAVE_STRCSPN=1 -DHAVE_STRERROR=1 -DHAVE_STRSPN=1 -DHAVE_STRSTR=1 -DHAVE_GETENV=1 -DHAVE_STRCHR=1 -DHAVE_GETRLIMIT=1 -DHAVE_GETRUSAGE=1 -DHAVE_VALLOC=0
OBJECT_OUTPUT_OPTION = -Fo
Modified: trunk/JavaBDD/net/sf/javabdd/BDDFactory.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/BDDFactory.java 2006-12-05 10:59:01 UTC (rev 475)
+++ trunk/JavaBDD/net/sf/javabdd/BDDFactory.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -76,7 +76,9 @@
return CALFactory.init(nodenum, cachesize);
if (bddpackage.equals("j") || bddpackage.equals("java"))
return JFactory.init(nodenum, cachesize);
- if (bddpackage.equals("u") || bddpackage.equals("micro"))
+ if (bddpackage.equals("u"))
+ return UberMicroFactory.init(nodenum, cachesize);
+ if (bddpackage.equals("micro"))
return MicroFactory.init(nodenum, cachesize);
if (bddpackage.equals("jdd"))
return JDDFactory.init(nodenum, cachesize);
@@ -1278,6 +1280,12 @@
sb.append("Unique Chain: ");
sb.append(uniqueChain);
sb.append(newLine);
+ sb.append("=> Ave. chain = ");
+ if (uniqueAccess > 0)
+ sb.append(((float) uniqueChain) / ((float) uniqueAccess));
+ else
+ sb.append((float)0);
+ sb.append(newLine);
sb.append("Unique Hit: ");
sb.append(uniqueHit);
sb.append(newLine);
@@ -1830,7 +1838,11 @@
}
protected static void bdd_default_gbchandler(boolean pre, GCStats s) {
- if (!pre) {
+ if (pre) {
+ if (s.freenodes != 0)
+ System.err.println("Starting GC cycle #"+(s.num+1)+
+ ": "+s.nodes+" nodes / "+s.freenodes+" free");
+ } else {
System.err.println(s.toString());
}
}
Modified: trunk/JavaBDD/net/sf/javabdd/BDDFactoryIntImpl.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/BDDFactoryIntImpl.java 2006-12-05 10:59:01 UTC (rev 475)
+++ trunk/JavaBDD/net/sf/javabdd/BDDFactoryIntImpl.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -209,12 +209,10 @@
protected void finalize() throws Throwable {
super.finalize();
- if (USE_FINALIZER) {
- if (false && v != invalid_bdd_impl()) {
- System.out.println("BDD not freed! "+System.identityHashCode(this));
- }
- deferredFree(v);
+ if (false && v != invalid_bdd_impl()) {
+ System.out.println("BDD not freed! "+System.identityHashCode(this));
}
+ deferredFree(v);
}
}
@@ -347,12 +345,10 @@
protected void finalize() throws Throwable {
super.finalize();
- if (USE_FINALIZER) {
- if (false && v != invalid_bdd_impl()) {
- System.out.println("BDD not freed! "+System.identityHashCode(this));
- }
- deferredFree(v);
+ if (false && v != invalid_bdd_impl()) {
+ System.out.println("BDD not freed! "+System.identityHashCode(this));
}
+ deferredFree(v);
}
}
@@ -524,6 +520,8 @@
protected /*bdd*/int[] to_free = new /*bdd*/int[8];
protected /*bdd*/int to_free_length = 0;
public void deferredFree(int v) {
+ if (v == invalid_bdd_impl())
+ return;
synchronized(to_free) {
if (to_free_length == to_free.length) {
/*bdd*/int[] t = new /*bdd*/int[to_free.length * 2];
Modified: trunk/JavaBDD/net/sf/javabdd/BDDVarSet.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/BDDVarSet.java 2006-12-05 10:59:01 UTC (rev 475)
+++ trunk/JavaBDD/net/sf/javabdd/BDDVarSet.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -34,7 +34,16 @@
public abstract int[] toLevelArray();
public String toString() {
- return Arrays.toString(toArray());
+ //return Arrays.toString(toArray());
+ int[] a = toArray();
+ StringBuffer sb = new StringBuffer(a.length * 4 + 2);
+ sb.append('[');
+ for (int i = 0; i < a.length; ++i) {
+ if (i != 0) sb.append(',');
+ sb.append(a[i]);
+ }
+ sb.append(']');
+ return sb.toString();
}
/**
Added: trunk/JavaBDD/net/sf/javabdd/BitString.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/BitString.java (rev 0)
+++ trunk/JavaBDD/net/sf/javabdd/BitString.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -0,0 +1,805 @@
+// BitString.java, created Wed May 16 17:26:33 2001 by joewhaley
+// Copyright (C) 2001-3 John Whaley <jw...@al...>
+// Licensed under the terms of the GNU LGPL; see COPYING for details.
+package net.sf.javabdd;
+
+import java.util.Iterator;
+
+/**
+ * <code>BitString</code> implements a vector of bits much like <code>java.util.BitSet</code>,
+ * except that this implementation actually works. Also, <code>BitString</code>
+ * has some groovy features which <code>BitSet</code> doesn't; mostly related to
+ * efficient iteration over <code>true</code> and <code>false</code> components.
+ * <p>
+ * Each component of the <code>BitString</code> has a boolean value.
+ * The bits of a <code>BitString</code> are indexed by non-negative
+ * integers (that means they are zero-based, of course). Individual
+ * indexed bits can be examined, set, or cleared. One
+ * <code>BitString</code> may be used to modify the contents of another
+ * <code>BitString</code> through logical AND, logical inclusive OR,
+ * and logical exclusive OR operations.
+ * <p>
+ * By default, all bits in the set initially have the value
+ * <code>false</code>.
+ * <p>
+ * Every bit set has a current size, which is the number of bits of
+ * space currently in use by the bit set. Note that the size is related
+ * to the implementation of a bit set, so it may change with implementation.
+ * The length of a bit set related to the logical length of a bit set
+ * and is defined independently of implementation.
+ *
+ * @author John Whaley <jw...@al...>
+ * @version $Id: BitString.java 2279 2005-05-28 10:24:54Z joewhaley $
+ */
+public final class BitString implements Cloneable, java.io.Serializable {
+
+ /**
+ * Version ID for serialization.
+ */
+ private static final long serialVersionUID = 3257570590025265971L;
+
+ /* There are 2^BITS_PER_UNIT bits in each unit (int) */
+ private static final int BITS_PER_UNIT = 5;
+ private static final int MASK = (1 << BITS_PER_UNIT) - 1;
+ private int[] bits;
+
+ /**
+ * Convert bitIndex to a subscript into the bits[] array.
+ */
+ private static int subscript(int bitIndex) {
+ return bitIndex >> BITS_PER_UNIT;
+ }
+
+ /**
+ * Creates an empty string with the specified size.
+ * @param nbits the size of the string
+ */
+ public BitString(int nbits) {
+ /* subscript(nbits + MASK) is the length of the array needed to hold
+ * nbits. Can also be written 1+subscript(nbits-1). */
+ bits = new int[subscript(nbits + MASK)];
+ }
+
+ /**
+ * Returns the first index in the bit string which is set, or
+ * -1 if there is no such index.
+ */
+ public int firstSet() {
+ return firstSet(-1);
+ }
+
+ /**
+ * Returns the first index greater than <code>where</code> in the
+ * bit string which is set, or -1 if there is no such index.
+ * @param where the starting point for the search. May be negative.
+ */
+ public int firstSet(int where) {
+ // convert exclusive starting point to inclusive starting point
+ where = (where < -1) ? 0 : (where + 1);
+ // search in first unit is masked.
+ int mask = (~0) << (where & MASK);
+ // search through units
+ for (int i = subscript(where); i < bits.length; i++, mask = ~0) {
+ int unit = bits[i] & mask;
+ if (unit != 0) return (i << BITS_PER_UNIT) + (bsf(unit) - 1);
+ }
+ return -1;
+ }
+
+ /**
+ * Utility function to return the number of 1 bits in the given integer
+ * value.
+ *
+ * @param b value to check
+ * @return byte number of one bits
+ */
+ public static final byte popcount(int b) {
+ int t, x;
+ x = b;
+ x = x - ((x >> 1) & 0x55555555);
+ t = ((x >> 2) & 0x33333333);
+ x = (x & 0x33333333) + t;
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x = x + (x >> 8);
+ x = x + (x >> 16);
+ return (byte) x;
+ }
+
+ /**
+ * Utility function to return the number of 1 bits in the given long value.
+ *
+ * @param b value to check
+ * @return byte number of one bits
+ */
+ public static final byte popcount(long b) {
+ long t, x;
+ x = b;
+ x = x - ((x >> 1) & 0x5555555555555555L);
+ t = ((x >> 2) & 0x3333333333333333L);
+ x = (x & 0x3333333333333333L) + t;
+ x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0FL;
+ x = x + (x >> 8);
+ x = x + (x >> 16);
+ x = x + (x >> 32);
+ return (byte) x;
+ }
+
+ /**
+ * Utility function to return the index of the first (lowest-order) one bit
+ * in the given integer. Returns zero if the given number is zero.
+ *
+ * @param b value to check
+ * @return byte index of first one bit, or zero if the number is zero
+ */
+ public static final int bsf(int b) {
+ int t = ~(b | -b);
+ return popcount(t);
+ }
+
+ /**
+ * Utility function to return the index of the last one bit in the given
+ * integer. Returns zero if the given number is zero.
+ *
+ * @param v value to check
+ * @return byte index of first one bit, or zero if the number is zero
+ */
+ public static final int bsr(int v) {
+ if ((v & 0xFFFF0000) != 0) {
+ if ((v & 0xFF000000) != 0)
+ return 24 + bytemsb[(v >> 24) & 0xFF];
+ else
+ return 16 + bytemsb[v >> 16];
+ }
+ if ((v & 0x0000FF00) != 0)
+ return 8 + bytemsb[v >> 8];
+ else
+ return bytemsb[v];
+ }
+
+ /** Highest bit set in a byte. */
+ private static final byte bytemsb[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 /* 256 */};
+
+ /**
+ * Returns the last index less than <code>where</code> in the
+ * bit string which is set, or -1 if there is no such index.
+ * @param where the starting point for the search.
+ */
+ public int lastSet(int where) {
+ // convert exclusive starting point to inclusive starting point
+ if (--where < 0) return -1;
+ int start = (bits.length - 1), mask = ~0;
+ if (subscript(where) < bits.length) {
+ // search in first unit is masked.
+ start = subscript(where);
+ mask = (~0) >>> (MASK - (where & mask));
+ }
+ // search through units
+ for (int i = start; i >= 0; i--, mask = ~0) {
+ int unit = bits[i] & mask;
+ if (unit != 0) return (i << BITS_PER_UNIT) + (bsr(unit) - 1);
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the last index in the bit string which is set, or
+ * -1 if there is no such index.
+ */
+ public int lastSet() {
+ return lastSet(size());
+ }
+
+ /**
+ * Sets all bits.
+ */
+ public void setAll() {
+ int i = bits.length;
+ while (i-- > 0) {
+ bits[i] = ~0;
+ }
+ }
+
+ /**
+ * Sets all bits up to and including the given bit.
+ * @param bit the bit to be set up to (zero-based)
+ */
+ public void setUpTo(int bit) {
+ int where = subscript(bit);
+ /* preaddition of 1 to bit is a clever hack to avoid long arithmetic */
+ bits[where] |= ((1 << ((bit + 1) & MASK)) - 1);
+ while (where-- > 0) {
+ bits[where] = ~0;
+ }
+ }
+
+ public void setRange(int lo, int hi) {
+ int where1 = subscript(lo);
+ int where2 = subscript(hi);
+ if (where1 == where2) {
+ for ( ; lo <= hi; ++lo)
+ bits[where1] |= (1 << (lo & MASK));
+ } else {
+ /* preaddition of 1 to bit is a clever hack to avoid long arithmetic */
+ bits[where2] |= ((1 << ((hi + 1) & MASK)) - 1);
+ while (--where2 > where1) {
+ bits[where2] = ~0;
+ }
+ bits[where1] |= -(1 << (lo & MASK));
+ }
+ }
+
+ /**
+ * Sets a bit.
+ * @param bit the bit to be set (zero-based)
+ */
+ public void set(int bit) {
+ bits[subscript(bit)] |= (1 << (bit & MASK));
+ }
+
+ /**
+ * Clears all bits.
+ */
+ public void clearAll() {
+ int i = bits.length;
+ while (i-- > 0) {
+ bits[i] = 0;
+ }
+ }
+
+ /**
+ * Clears all bits up to and including the given bit.
+ * @param bit the bit to be set up to (zero-based)
+ */
+ public void clearUpTo(int bit) {
+ int where = subscript(bit);
+ /* preaddition of 1 to bit is a clever hack to avoid long arithmetic */
+ bits[where] &= ~((1 << ((bit + 1) & MASK)) - 1);
+ while (where-- > 0) {
+ bits[where] = 0;
+ }
+ }
+
+ /**
+ * Clears a bit.
+ * @param bit the bit to be cleared (zero-based)
+ */
+ public void clear(int bit) {
+ bits[subscript(bit)] &= ~(1 << (bit & MASK));
+ }
+
+ /**
+ * Gets a bit.
+ * @param bit the bit to be gotten (zero-based)
+ */
+ public boolean get(int bit) {
+ int n = subscript(bit);
+ return ((bits[n] & (1 << (bit & MASK))) != 0);
+ }
+
+ /**
+ * Logically ANDs this bit set with the specified set of bits.
+ * Returns <code>true</code> if <code>this</code> was modified in
+ * response to the operation.
+ * @param set the bit set to be ANDed with
+ */
+ public boolean and(BitString set) {
+ if (this == set) { // should help alias analysis
+ return false;
+ }
+ int n = bits.length;
+ boolean changed = false;
+ for (int i = n; i-- > 0;) {
+ int old = bits[i];
+ bits[i] &= set.bits[i];
+ changed |= (old != bits[i]);
+ }
+ return changed;
+ }
+
+ /**
+ * Logically ORs this bit set with the specified set of bits.
+ * Returns <code>true</code> if <code>this</code> was modified in
+ * response to the operation.
+ * @param set the bit set to be ORed with
+ */
+ public boolean or(BitString set) {
+ if (this == set) { // should help alias analysis
+ return false;
+ }
+ int setLength = set.bits.length;
+ boolean changed = false;
+ for (int i = setLength; i-- > 0;) {
+ int old = bits[i];
+ bits[i] |= set.bits[i];
+ changed |= (old != bits[i]);
+ }
+ return changed;
+ }
+
+ /**
+ * Logically ORs this bit set with the specified set of bits.
+ * Returns <code>true</code> if <code>this</code> was modified in
+ * response to the operation.
+ * @param set the bit set to be ORed with
+ */
+ public boolean or_upTo(BitString set, int bit) {
+ if (this == set) { // should help alias analysis
+ return false;
+ }
+ boolean result;
+ int where = subscript(bit);
+ int old = bits[where];
+ bits[where] |= (set.bits[where] & ((1 << ((bit + 1) & MASK)) - 1));
+ result = (bits[where] != old);
+ while (where-- > 0) {
+ old = bits[where];
+ bits[where] |= set.bits[where];
+ result |= (bits[where] != old);
+ }
+ return result;
+ }
+
+ /**
+ * Logically XORs this bit set with the specified set of bits.
+ * Returns <code>true</code> if <code>this</code> was modified in
+ * response to the operation.
+ * @param set the bit set to be XORed with
+ */
+ public boolean xor(BitString set) {
+ int setLength = set.bits.length;
+ boolean changed = false;
+ for (int i = setLength; i-- > 0;) {
+ int old = bits[i];
+ bits[i] ^= set.bits[i];
+ changed |= (old != bits[i]);
+ }
+ return changed;
+ }
+
+ /**
+ * Logically subtracts this bit set with the specified set of bits.
+ * Returns <code>true</code> if <code>this</code> was modified in
+ * response to the operation.
+ * @param set the bit set to subtract
+ */
+ public boolean minus(BitString set) {
+ int n = bits.length;
+ boolean changed = false;
+ for (int i = n; i-- > 0;) {
+ int old = bits[i];
+ bits[i] &= ~set.bits[i];
+ changed |= (old != bits[i]);
+ }
+ return changed;
+ }
+
+ /**
+ * Check if the intersection of the two sets is empty
+ * @param other the set to check intersection with
+ */
+ public boolean intersectionEmpty(BitString other) {
+ int n = bits.length;
+ for (int i = n; i-- > 0;) {
+ if ((bits[i] & other.bits[i]) != 0) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if this set contains all bits of the given set.
+ * @param other the set to check containment with
+ */
+ public boolean contains(BitString other) {
+ int n = bits.length;
+ for (int i = n; i-- > 0;) {
+ if ((bits[i] & other.bits[i]) != other.bits[i]) return false;
+ }
+ return true;
+ }
+
+ private static void shld(int[] bits, int i1, int i2, int amt) {
+ //Assert._assert(amt >= 0 && amt < BITS_PER_UNIT);
+ bits[i1] = (bits[i1] << amt) | ((bits[i2] << (BITS_PER_UNIT - amt)) >> (BITS_PER_UNIT - amt));
+ }
+
+ /**
+ * Performs a left-shift operation.
+ * @param amt number of bits to shift, can be negative
+ */
+ public void shl(int amt) {
+ final int div = amt >> BITS_PER_UNIT;
+ final int mod = amt & MASK;
+ final int size = bits.length;
+ if (amt < 0) {
+ shr(-amt); return;
+ }
+ // big moves
+ if (div > 0) {
+ System.arraycopy(bits, 0, bits, div, size - div);
+ for (int i = 0; i < div; ++i)
+ bits[i] = 0;
+ /*
+ int i;
+ for (i = size - 1; i >= div; --i) {
+ bits[i] = bits[i - div];
+ }
+ for (; i >= 0; --i) {
+ bits[i] = 0;
+ }
+ */
+ }
+ // small moves
+ if (mod > 0) {
+ int i;
+ for (i = size - 1; i > div; --i) {
+ shld(bits, i, i - 1, mod);
+ }
+ bits[i] <<= mod;
+ }
+ }
+
+ private static void shrd(int[] bits, int i1, int i2, int amt) {
+ //Assert._assert(amt >= 0 && amt < BITS_PER_UNIT);
+ bits[i1] = (bits[i1] >>> amt) | ((bits[i2] >>> (BITS_PER_UNIT - amt)) << (BITS_PER_UNIT - amt));
+ }
+
+ /**
+ * Performs a right-shift operation.
+ * @param amt number of bits to shift
+ */
+ public void shr(int amt) {
+ final int div = amt >> BITS_PER_UNIT;
+ final int mod = amt & MASK;
+ final int size = bits.length;
+ // big moves
+ if (div > 0) {
+ System.arraycopy(bits, div, bits, 0, size - div);
+ for (int i = size-div; i < size; ++i)
+ bits[i] = 0;
+ /*
+ int i;
+ for (i = 0; i < size - div; ++i) {
+ bits[i] = bits[i + div];
+ }
+ for (; i < size; ++i) {
+ bits[i] = 0;
+ }
+ */
+ }
+ // small moves
+ if (mod > 0) {
+ int i;
+ for (i = 0; i < size - div - 1; ++i) {
+ shrd(bits, i, i + 1, mod);
+ }
+ bits[i] >>>= mod;
+ }
+ }
+
+ /**
+ * Copies the values of the bits in the specified set into this set.
+ * @param set the bit set to copy the bits from
+ */
+ public void copyBits(BitString set) {
+ System.arraycopy(set.bits, 0, bits, 0, Math.min(bits.length, set.bits.length));
+ }
+
+ /**
+ * Returns a hash code value for this bit string whose value depends
+ * only on which bits have been set within this <code>BitString</code>.
+ */
+ public int hashCode() {
+ int h = 1234;
+ for (int i = bits.length; --i >= 0;) {
+ h ^= bits[i] * (i + 1);
+ }
+ return h;
+ }
+
+ /**
+ * Returns the "logical size" of this <code>BitString</code>: the
+ * index of the highest set bit in the <code>BitString</code> plus
+ * one. Returns zero if the <code>BitString</code> contains no
+ * set bits.
+ */
+ public int length() {
+ return lastSet() + 1;
+ }
+
+ /**
+ * Returns the number of bits of space actually in use by this
+ * <code>BitString</code> to represent bit values.
+ * The maximum element in the set is the size - 1st element.
+ * The minimum element in the set is the zero'th element.
+ */
+ public int size() {
+ return bits.length << BITS_PER_UNIT;
+ }
+
+ /**
+ * Compares this object against the specified object.
+ * @param obj the object to compare with
+ * @return true if the contents of the bitsets are the same; false otherwise.
+ */
+ public boolean equals(Object obj) {
+ BitString set;
+ if (obj == null) return false;
+ if (this == obj) return true; //should help alias analysis
+ try {
+ set = (BitString) obj;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ if (length() != set.length()) return false;
+ int n = bits.length - 1;
+ while (n >= 0 && bits[n] == 0) n--;
+ // now n has the first non-zero entry
+ for (int i = n; i >= 0; i--) {
+ if (bits[i] != set.bits[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns whether this <code>BitString</code> is all zeroes.
+ * @return true if it is all zeroes.
+ */
+ public boolean isZero() {
+ int setLength = bits.length;
+ for (int i = setLength; i-- > 0;) {
+ if (bits[i] != 0) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns the number of ones in this <code>BitString</code>.
+ * @return number of bits set.
+ */
+ public int numberOfOnes() {
+ int setLength = bits.length;
+ int number = 0;
+ for (int i = setLength; i-- > 0;) {
+ number += popcount(bits[i]);
+ }
+ return number;
+ }
+
+ /**
+ * Returns the number of ones in this <code>BitString</code> up to a given index.
+ * @return number of bits set.
+ */
+ public int numberOfOnes(int where) {
+ int setLength = subscript(where);
+ int number = 0;
+ for (int i = setLength; i-- > 0;) {
+ number += popcount(bits[i]);
+ }
+ number += popcount(bits[setLength] & ((1 << ((where + 1) & MASK)) - 1));
+ return number;
+ }
+
+ /**
+ * Clones the BitString.
+ */
+ public Object clone() {
+ BitString result = null;
+ try {
+ result = (BitString) super.clone();
+ } catch (CloneNotSupportedException e) {
+ // this shouldn't happen, since we are Cloneable
+ throw new InternalError();
+ }
+ result.bits = new int[bits.length];
+ System.arraycopy(bits, 0, result.bits, 0, result.bits.length);
+ return result;
+ }
+
+ /**
+ * Converts the BitString to a String.
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ boolean needSeparator = false;
+ buffer.append('{');
+ for (ForwardBitStringIterator i=iterator(); i.hasNext(); ) {
+ int x = i.nextIndex();
+ if (needSeparator) {
+ buffer.append(", ");
+ } else {
+ needSeparator = true;
+ }
+ buffer.append(x);
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * Returns an iterator that iterates through the bits in forward order.
+ */
+ public ForwardBitStringIterator iterator() {
+ return new ForwardBitStringIterator();
+ }
+
+ public ForwardBitStringZeroIterator zeroIterator() {
+ return new ForwardBitStringZeroIterator();
+ }
+
+ /**
+ * Returns an iterator that iterates through the bits in backward order.
+ */
+ public BackwardBitStringIterator backwardsIterator() {
+ return new BackwardBitStringIterator();
+ }
+
+ /**
+ * Returns an iterator that iterates through the bits in backward order,
+ * starting at the given index.
+ */
+ public BackwardBitStringIterator backwardsIterator(int i) {
+ return new BackwardBitStringIterator(i);
+ }
+
+ /**
+ * Abstract bit string iterator class.
+ */
+ public abstract static class BitStringIterator implements Iterator {
+
+ /**
+ * Returns the index of the next bit set.
+ */
+ public abstract int nextIndex();
+
+ /**
+ * @see java.util.Iterator#next()
+ */
+ public final Object next() {
+ return new Integer(nextIndex());
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Unmodifiable Iterator");
+ }
+
+ }
+
+ /**
+ * Iterator for iterating through a bit string in forward order.
+ */
+ public class ForwardBitStringIterator extends BitStringIterator {
+ private int j, k, t;
+
+ ForwardBitStringIterator() {
+ j = 0;
+ k = 0;
+ t = bits[0];
+ }
+
+ /**
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ while (t == 0) {
+ if (j == bits.length - 1) return false;
+ t = bits[++j];
+ k += 1 << BITS_PER_UNIT;
+ }
+ return true;
+ }
+
+ /**
+ * @see jwutil.math.BitString.BitStringIterator#nextIndex()
+ */
+ public int nextIndex() {
+ while (t == 0) {
+ if (j == bits.length - 1) throw new java.util.NoSuchElementException();
+ t = bits[++j];
+ k += 1 << BITS_PER_UNIT;
+ }
+ int t2 = (t ^ (-t));
+ int index = 31 - popcount(t2);
+ t &= t2;
+ return k + index;
+ /*
+ int t2 = ~(t | (-t));
+ int index = popcount(t2);
+ t &= ~(t2 + 1);
+ return k + index;
+ */
+ }
+
+ }
+
+ /**
+ * Iterator for iterating through a bit string in forward order.
+ */
+ public class ForwardBitStringZeroIterator extends BitStringIterator {
+ private int j, k, t;
+
+ ForwardBitStringZeroIterator() {
+ j = 0;
+ k = 0;
+ t = ~bits[0];
+ }
+
+ /**
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ while (t == 0) {
+ if (j == bits.length - 1) return false;
+ t = ~bits[++j];
+ k += 1 << BITS_PER_UNIT;
+ }
+ return true;
+ }
+
+ /**
+ * @see jwutil.math.BitString.BitStringIterator#nextIndex()
+ */
+ public int nextIndex() {
+ while (t == 0) {
+ if (j == bits.length - 1) throw new java.util.NoSuchElementException();
+ t = ~bits[++j];
+ k += 1 << BITS_PER_UNIT;
+ }
+ int t2 = (t ^ (-t));
+ int index = 31 - popcount(t2);
+ t &= t2;
+ return k + index;
+ }
+
+ }
+
+ /**
+ * Iterator for iterating through a bit string in backward order.
+ */
+ public class BackwardBitStringIterator extends BitStringIterator {
+ private int j, k, t;
+
+ BackwardBitStringIterator(int i) {
+ j = subscript(i);
+ t = bits[j];
+ t &= (1 << ((i + 1) & MASK)) - 1;
+ k = j << BITS_PER_UNIT;
+ }
+
+ BackwardBitStringIterator() {
+ j = bits.length - 1;
+ t = bits[j];
+ k = j << BITS_PER_UNIT;
+ }
+
+ /**
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ while (t == 0) {
+ if (j == 0) {
+ return false;
+ }
+ t = bits[--j];
+ k -= 1 << BITS_PER_UNIT;
+ }
+ return true;
+ }
+
+ /**
+ * @see jwutil.math.BitString.BitStringIterator#nextIndex()
+ */
+ public int nextIndex() {
+ while (t == 0) {
+ if (j == 0) throw new java.util.NoSuchElementException();
+ t = bits[--j];
+ k -= 1 << BITS_PER_UNIT;
+ }
+ int index = bsr(t) - 1;
+ t &= ~(1 << index);
+ return k + index;
+ }
+
+ }
+}
Modified: trunk/JavaBDD/net/sf/javabdd/BuDDyFactory.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/BuDDyFactory.java 2006-12-05 10:59:01 UTC (rev 475)
+++ trunk/JavaBDD/net/sf/javabdd/BuDDyFactory.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -295,7 +295,7 @@
* @see net.sf.javabdd.BDDFactory#setCacheRatio(int)
*/
public double setCacheRatio(double x) {
- return setCacheRatio0((int)(x * 100.)) / 100.;
+ return setCacheRatio0((int)x);
}
private static native int setCacheRatio0(int x);
Modified: trunk/JavaBDD/net/sf/javabdd/JFactory.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/JFactory.java 2006-12-05 10:59:01 UTC (rev 475)
+++ trunk/JavaBDD/net/sf/javabdd/JFactory.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -214,7 +214,7 @@
public int getCacheSize() { return cachesize; }
public int reorderGain() { return bdd_reorder_gain(); }
public void printStat() { bdd_fprintstat(System.out); }
- public double setCacheRatio(double x) { return bdd_setcacheratio((int)(x * 100)) / 100.; }
+ public double setCacheRatio(double x) { return bdd_setcacheratio((int)x); }
public int varNum() { return bdd_varnum(); }
public int setVarNum(int num) { return bdd_setvarnum(num); }
public void printAll() { bdd_fprintall(System.out); }
@@ -1431,7 +1431,7 @@
}
checkresize();
- if (true) bdd_validate(res);
+ if (false) bdd_validate(res);
return res;
}
@@ -2574,7 +2574,7 @@
}
checkresize();
- if (true) bdd_validate(res);
+ if (false) bdd_validate(res);
return res;
}
@@ -5331,21 +5331,28 @@
resizedInMakenode = false;
if (imatrixDepends(iactmtx, var, bddlevel2var[level + 1])) {
+ // This var depends on the next one.
+ // (ie there is some BDD with both this var and the next one)
+
+ // Rehash this level and return a list of nodes that depend on the
+ // next level.
int toBeProcessed = reorder_downSimple(var);
levelData l = levels[var];
if (l.nodenum < (l.size) / 3
|| l.nodenum >= (l.size * 3) / 2
&& l.size < l.maxsize) {
+ // Hash table for this level is too big or too small, resize it.
reorder_swapResize(toBeProcessed, var);
reorder_localGbcResize(toBeProcessed, var);
} else {
+ // Swap the variable and do a GC pass on this level.
reorder_swap(toBeProcessed, var);
reorder_localGbc(var);
}
}
- /* Swap the var<->level tables */
+ // Swap the var<->level tables
n = bddlevel2var[level];
bddlevel2var[level] = bddlevel2var[level + 1];
bddlevel2var[level + 1] = n;
@@ -5439,13 +5446,17 @@
int reorder_downSimple(int var0) {
int toBeProcessed = 0;
+
+ // Next variable to swap with.
int var1 = bddlevel2var[bddvar2level[var0] + 1];
+
+ // Hash table range for source variable.
int vl0 = levels[var0].start;
int size0 = levels[var0].size;
int n;
+ // Rehash this level and recalculate the number of nodes.
levels[var0].nodenum = 0;
-
for (n = 0; n < size0; n++) {
int r;
@@ -5455,26 +5466,17 @@
while (r != 0) {
int next = NEXT(r);
-/***
- if (LOW(r) == -1) {
- System.out.println(r+": LOW="+LOW(r));
- }
- if (HIGH(r) == -1) {
- System.out.println(r+": HIGH="+HIGH(r));
- }
-***/
if (VARr(LOW(r)) != var1 && VARr(HIGH(r)) != var1) {
- /* Node does not depend on next var, let it stay in the chain */
+ // Node does not depend on next var, put it in the chain
SETNEXT(r, HASH(n + vl0));
SETHASH(n + vl0, r);
levels[var0].nodenum++;
} else {
- /* Node depends on next var - save it for later procesing */
+ // Node depends on next var - save it for later processing
SETNEXT(r, toBeProcessed);
toBeProcessed = r;
if (SWAPCOUNT)
cachestats.swapCount++;
-
}
r = next;
@@ -5493,7 +5495,7 @@
int f1 = HIGH(toBeProcessed);
int f00, f01, f10, f11;
- /* Find the cofactors for the new nodes */
+ // Find the cofactors for the new nodes
if (VARr(f0) == var1) {
f00 = LOW(f0);
f01 = HIGH(f0);
@@ -5520,14 +5522,14 @@
DECREF(LOW(toBeProcessed));
DECREF(HIGH(toBeProcessed));
- /* Update in-place */
+ // Update in-place
SETVARr(toBeProcessed, var1);
SETLOW(toBeProcessed, f0);
SETHIGH(toBeProcessed, f1);
levels[var1].nodenum++;
- /* Do not rehash yet since we are going to resize the hash table */
+ // Do not rehash yet since we are going to resize the hash table
toBeProcessed = next;
}
@@ -5595,13 +5597,15 @@
void reorder_swap(int toBeProcessed, int var0) {
int var1 = bddlevel2var[bddvar2level[var0] + 1];
+ // toBeProcessed is a linked list of nodes that depend on the next level.
+
while (toBeProcessed != 0) {
int next = NEXT(toBeProcessed);
int f0 = LOW(toBeProcessed);
int f1 = HIGH(toBeProcessed);
int f00, f01, f10, f11, hash;
- /* Find the cofactors for the new nodes */
+ // Find the cofactors for the new nodes
if (VARr(f0) == var1) {
f00 = LOW(f0);
f01 = HIGH(f0);
@@ -5620,22 +5624,25 @@
//node = bddnodes[toBeProcessed]; /* Might change in makenode */
/* We know that the refcou of the grandchilds of this node
- * is greater than one (these are f00...f11), so there is
- * no need to do a recursive refcou decrease. It is also
- * possible for the node.low/high nodes to come alive again,
- * so deref. of the childs is delayed until the local GBC. */
+ * is greater than one (these are f00...f11), so there is
+ * no need to do a recursive refcou decrease. It is also
+ * possible for the node.low/high nodes to come alive again,
+ * so deref. of the childs is delayed until the local GBC. */
DECREF(LOW(toBeProcessed));
DECREF(HIGH(toBeProcessed));
- /* Update in-place */
+ // Update in-place
+ // NOTE: This node may be a duplicate. However, we add this to the start
+ // of the list so we will always encounter this one first. The refcount
+ // of the node we duplicated will go to zero.
SETVARr(toBeProcessed, var1);
SETLOW(toBeProcessed, f0);
SETHIGH(toBeProcessed, f1);
levels[var1].nodenum++;
- /* Rehash the node since it got new childs */
+ // Rehash the node since it has new children
hash = NODEHASH2(VARr(toBeProcessed), LOW(toBeProcessed), HIGH(toBeProcessed));
SETNEXT(toBeProcessed, HASH(hash));
SETHASH(hash, toBeProcessed);
@@ -5658,7 +5665,7 @@
cachestats.uniqueAccess++;
/* Note: We know that low,high has a refcou greater than zero, so
- there is no need to add reference *recursively* */
+ there is no need to add reference *recursively* */
if (ZDD) {
/* check whether high child is zero */
@@ -5701,9 +5708,9 @@
return 0;
/* Try to allocate more nodes - call noderesize without
- * enabling rehashing.
+ * enabling rehashing.
* Note: if ever rehashing is allowed here, then remember to
- * update local variable "hash" */
+ * update local variable "hash" */
bdd_noderesize(false);
resizedInMakenode = true;
@@ -5740,12 +5747,18 @@
}
int reorder_init() {
+ // This method does the following:
+ // - Calculate interaction matrix "iactmtx"
+ // - Calculates the number of nodes with each variable.
+ // - Mutates each node to store the var instead of the level.
+ // - Sets refcounts for all links, including internal ones.
+
int n;
reorder_handler(true, reorderstats);
+ // Split the hash table into a separate region for each variable.
levels = new levelData[bddvarnum];
-
for (n = 0; n < bddvarnum; n++) {
levels[n] = new levelData();
levels[n].start = -1;
@@ -5753,15 +5766,15 @@
levels[n].nodenum = 0;
}
- /* First mark and recursive refcou. all roots and childs. Also do some
- * setup here for both setLevellookup and reorder_gbc */
+ // First mark and recursive refcou. all roots and childs. Also do some
+ // setup here for both setLevellookup and reorder_gbc
if (mark_roots() < 0)
return -1;
- /* Initialize the hash tables */
+ // Initialize the hash tables
reorder_setLevellookup();
- /* Garbage collect and rehash to new scheme */
+ // Garbage collect and rehash to new scheme
reorder_gbc();
return 0;
@@ -5786,14 +5799,19 @@
iactmtx = imatrixNew(bddvarnum);
+ // Loop to compute dependences and node refcounts.
for (n = 2, extrootsize = 0; n < bddnodesize; n++) {
if (MARKED(n)) {
+ // Node has an external reference.
UNMARK(n);
extroots[extrootsize++] = n;
+ // Calculate the set of variables in this BDD.
+ // Also sets refcounts on internal nodes.
for (int i = 0; i < bddvarnum; ++i)
dep[i] = false;
+
dep[VARr(n)] = true;
levels[VARr(n)].nodenum++;
@@ -5835,12 +5853,15 @@
return;
if (!HASREF(r) || MARKED(r)) {
+ // We haven't processed the node yet.
+ // Processed nodes have a refcount and are unmarked.
+
bddfreenum--;
- /* Detect variable dependencies for the interaction matrix */
+ // Detect variable dependencies for the interaction matrix
dep[VARr(r) & ~MARK_MASK] = true;
- /* Make sure the nodenum field is updated. Used in the initial GBC */
+ // Make sure the nodenum field is updated. Used in the initial GBC
levels[VARr(r) & ~MARK_MASK].nodenum++;
addref_rec(LOW(r), dep);
@@ -5848,8 +5869,8 @@
} else {
int n;
- /* Update (from previously found) variable dependencies
- * for the interaction matrix */
+ // Update (from previously found) variable dependencies
+ // for the interaction matrix
for (n = 0; n < bddvarnum; n++)
dep[n]
|= imatrixDepends(iactmtx, VARr(r) & ~MARK_MASK, n);
@@ -5913,7 +5934,7 @@
CLEARREF(n);
/* This is where we go from .var to .level again!
- * - Do NOT use the LEVEL macro here. */
+ * - Do NOT use the LEVEL macro here. */
SETLEVELANDMARK(n, bddvar2level[LEVELANDMARK(n)]);
}
Added: trunk/JavaBDD/net/sf/javabdd/UberMicroFactory.java
===================================================================
--- trunk/JavaBDD/net/sf/javabdd/UberMicroFactory.java (rev 0)
+++ trunk/JavaBDD/net/sf/javabdd/UberMicroFactory.java 2007-03-06 06:08:40 UTC (rev 476)
@@ -0,0 +1,6763 @@
+// UberMicroFactory.java, created Jan 29, 2005 8:24:17 PM by joewhaley
+// Copyright (C) 2005 John Whaley <jw...@al...>
+// Licensed under the terms of the GNU LGPL; see COPYING for details.
+package net.sf.javabdd;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Random;
+import java.util.Set;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+
+/**
+ * <p>BDD factory where each node only takes 16 bytes.
+ * This is accomplished by tightly packing the bits, eliminating
+ * the refcount, splitting out the unique table and limiting the
+ * maximum number of BDD variables to 2^11 = 2048.</p>
+ *
+ * <p>This BDD factory is not only more memory efficient than
+ * JFactory, it also seems to perform better, probably due to
+ * better memory locality. It performs cache-aware BDD node
+ * placement.</p>
+ *
+ * @author jwhaley
+ * @version $Id: UberMicroFactory.java 465 2006-07-26 16:42:44Z joewhaley $
+ */
+public class UberMicroFactory extends BDDFactoryIntImpl {
+
+ public static boolean FLUSH_CACHE_ON_GC = true;
+
+ static final boolean VERIFY_ASSERTIONS = true;
+ static final boolean ORDER_CACHE = false;
+ static final int CACHESTATS = 0;
+ static final boolean SWAPCOUNT = false;
+
+ public static final String REVISION = "$Revision: 465 $";
+
+ public String getVersion() {
+ return "UberMicroFactory "+REVISION.substring(11, REVISION.length()-2);
+ }
+
+ private UberMicroFactory() { }
+
+ /* (non-Javadoc)
+ * @see net.sf.javabdd.BDDFactory#init(int, int)
+ */
+ public static BDDFactory init(int nodenum, int cachesize) {
+ BDDFactory f = new UberMicroFactory();
+ f.initialize(nodenum, cachesize);
+ if (CACHESTATS > 0) addShutdownHook(f);
+ return f;
+ }
+
+ static void addShutdownHook(final BDDFactory f) {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ System.out.println(f.getCacheStats().toString());
+ }
+ });
+ }
+
+ protected IntBDD makeBDD(/*bdd*/int v) {
+ return new Micro5BDD(v);
+ }
+
+ static final boolean USE_WEAK_REFS = false;
+
+ Collection externalRefBDDs, externalRefVarSets;
+
+ class Micro5BDD extends BDDFactoryIntImpl.IntBDD {
+ Micro5BDD(int v) {
+ super(v);
+ if (VERIFY_ASSERTIONS) {
+ if (v == INVALID_BDD)
+ bdd_error(BDD_BREAK); /* distinctive */
+ if (v >= bddnodesize)
+ bdd_error(BDD_ILLBDD);
+ if (bddnodes[v] == 0)
+ bdd_error(BDD_ILLBDD);
+ }
+ if (USE_WEAK_REFS)
+ externalRefBDDs.add(new java.lang.ref.WeakReference(this));
+ else
+ externalRefBDDs.add(this);
+ }
+ }
+
+ protected IntBDDVarSet makeBDDVarSet(/*bdd*/int v) {
+ return new Micro5VarSet(v);
+ }
+
+ public class Micro5VarSet extends IntBDDVarSet {
+ Micro5VarSet(int v) {
+ super(v);
+ if (VERIFY_ASSERTIONS) {
+ if (v == INVALID_BDD)
+ bdd_error(BDD_BREAK); /* distinctive */
+ if (v >= bddnodesize)
+ bdd_error(BDD_ILLBDD);
+ if (bddnodes[v] == 0)
+ bdd_error(BDD_ILLBDD);
+ }
+ if (USE_WEAK_REFS)
+ externalRefVarSets.add(new java.lang.ref.WeakReference(this));
+ else
+ externalRefVarSets.add(this);
+ }
+ }
+
+ public void handleDeferredFree() {
+ to_free_length = 0;
+ }
+
+ /**
+ * Implementation of BDDPairing used by JFactory.
+ */
+ class bddPair extends BDDPairing {
+ int[] result;
+ int last;
+ int id;
+ bddPair next;
+
+ /* (non-Javadoc)
+ * @see net.sf.javabdd.BDDPairing#set(int, int)
+ */
+ public void set(int oldvar, int newvar) {
+ bdd_setpair(this, oldvar, newvar);
+ }
+ /* (non-Javadoc)
+ * @see net.sf.javabdd.BDDPairing#set(int, net.sf.javabdd.BDD)
+ */
+ public void set(int oldvar, BDD newvar) {
+ bdd_setbddpair(this, oldvar, unwrap(newvar));
+ }
+ /* (non-Javadoc)
+ * @see net.sf.javabdd.BDDPairing#reset()
+ */
+ public void reset() {
+ bdd_resetpair(this);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('{');
+ boolean any = false;
+ for (int i = 0; i < result.length; ++i) {
+ if (result[i] != bdd_ithvar(bddlevel2var[i])) {
+ if (any) sb.append(", ");
+ any = true;
+ sb.append(bddlevel2var[i]);
+ sb.append('=');
+ BDD b = makeBDD(result[i]);
+ sb.append(b);
+ b.free();
+ }
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.javabdd.BDDFactory#makePair()
+ */
+ public BDDPairing makePair() {
+ bddPair p = new bddPair();
+ p.result = new int[bddvarnum];
+ int n;
+ for (n = 0; n < bddvarnum; n++)
+ p.result[n] = bdd_ithvar(bddlevel2var[n]);
+
+ p.id = update_pairsid();
+ p.last = -1;
+
+ bdd_register_pair(p);
+ return p;
+ }
+
+ // Redirection functions.
+
+ protected void addref_impl(int v) { }
+ protected void delref_impl(int v) { }
+ protected int zero_impl() { return BDDZERO; }
+ protected int one_impl() { return BDDONE; }
+ protected int invalid_bdd_impl() { return INVALID_BDD; }
+ protected int var_impl(int v) { return bdd_var(v); }
+ protected int level_impl(int v) { return LEVEL(v); }
+ protected int low_impl(int v) { return bdd_low(v); }
+ protected int high_impl(int v) { return bdd_high(v); }
+ protected int ithVar_impl(int var) { return bdd_ithvar(var); }
+ protected int nithVar_impl(int var) { return bdd_nithvar(var); }
+
+ protected int makenode_impl(int lev, int lo, int hi) { return bdd_makenode(lev, lo, hi); }
+ protected int ite_impl(int v1, int v2, int v3) { return bdd_ite(v1, v2, v3); }
+ protected int apply_impl(int v1, int v2, BDDOp opr) { return bdd_apply(v1, v2, opr.id); }
+ protected int not_impl(int v1) { return bdd_not(v1); }
+ protected int applyAll_impl(int v1, int v2, BDDOp opr, int v3) { return bdd_appall(v1, v2, opr.id, v3); }
+ protected int applyEx_impl(int v1, int v2, BDDOp opr, int v3) { return bdd_appex(v1, v2, opr.id, v3); }
+ protected int applyUni_impl(int v1, int v2, BDDOp opr, int v3) { return bdd_appuni(v1, v2, opr.id, v3); }
+ protected int compose_impl(int v1, int v2, int var) { return bdd_compose(v1, v2, var); }
+ protected int constrain_impl(int v1, int v2) { return bdd_constrain(v1, v2); }
+ protected int restrict_impl(int v1, int v2) { return bdd_restrict(v1, v2); }
+ protected int simplify_impl(int v1, int v2) { return bdd_simplify(v1, v2); }
+ protected int support_impl(int v) { return bdd_support(v); }
+ protected int exist_impl(int v1, int v2) { return bdd_exist(v1, v2); }
+ protected int forAll_impl(int v1, int v2) { return bdd_forall(v1, v2); }
+ protected int unique_impl(int v1, int v2) { return bdd_unique(v1, v2); }
+ protected int fullSatOne_impl(int v) { return bdd_fullsatone(v); }
+
+ protected int replace_impl(int v, BDDPairing p) { return bdd_replace(v, (bddPair)p); }
+ protected int veccompose_impl(int v, BDDPairing p) { return bdd_veccompose(v, (bddPair)p); }
+
+ protected int nodeCount_impl(int v) { return bdd_nodecount(v); }
+ protected double pathCount_impl(int v) { return bdd_pathcount(v); }
+ protected double satCount_impl(int v) { return bdd_satcount(v); }
+ protected int satOne_impl(int v) { return bdd_satone(v); }
+ protected int satOne_impl2(int v1, int v2, boolean pol) { return bdd_satoneset(v1, v2, pol); }
+ protected int nodeCount_impl2(int[] v) { return bdd_anodecount(v); }
+ protected int[] varProfile_impl(int v) { return bdd_varprofile(v); }
+ protected void printTable_impl(int v) { bdd_fprinttable(System.out, v); }
+
+ // More redirection functions.
+
+ protected void initialize(int initnodesize, int cs) { bdd_init(initnodesize, cs); }
+ public void addVarBlock(int first, int last, boolean fixed) { bdd_intaddvarblock(first, last, fixed); }
+ public void varBlockAll() { bdd_varblockall(); }
+ public void clearVarBlocks() { bdd_clrvarblocks(); }
+ public void printOrder() { bdd_fprintorder(System.out); }
+ public int getNodeTableSize() { return bdd_getallocnum(); }
+ public int setNodeTableSize(int size) { return bdd_setallocnum(size); }
+ public int setCacheSize(int v) { return bdd_setcachesize(v); }
+ public boolean isInitialized() { return bddrunning; }
+ public void done() { super.done(); bdd_done(); }
+ public void setError(int code) { bdderrorcond = code; }
+ public void clearError() { bdderrorcond = 0; }
+ public int setMaxNodeNum(int size) { return bdd_setmaxnodenum(size); }
+ public double setMinFreeNodes(double x) { return bdd_setminfreenodes((int)(x * 100.)) / 100.; }
+ public int setMaxIncrease(int x) { return bdd_setmaxincrease(x); }
+ public double setIncreaseFactor(double x) { return bdd_setincreasefactor(x); }
+ public int getNodeNum() { return bdd_getnodenum(); }
+ public int getCacheSize() { return cachesize; }
+ public int reorderGain() { return bdd_reorder_gain(); }
+ public void printStat() { bdd_fprintstat(System.out); }
+ public double setCacheRatio(double x) { return bdd_setcacheratio((int)x); }
+ public int varNum() { return bdd_varnum(); }
+ public int setVarNum(int num) { return bdd_setvarnum(num); }
+ public void printAll() { bdd_fprintall(System.out); }
+ public BDD load(BufferedReader in, int[] translate) throws IOException { return makeBDD(bdd_load(in, translate)); }
+ public void save(BufferedWriter out, BDD b) throws IOException { bdd_save(out, unwrap(b)); }
+ public void setVarOrder(int[] neworder) { bdd_setvarorder(neworder); }
+ public int level2Var(int level) { return bddlevel2var[level]; }
+ public int var2Level(int var) { return bddvar2level[var]; }
+ public int getReorderTimes() { return bddreordertimes; }
+ public void disableReorder() { bdd_disable_reorder(); }
+ public void enableReorder() { bdd_enable_reorder(); }
+ public int reorderVerbose(int v) { return bdd_reorder_verbose(v); }
+ public void reorder(ReorderMethod m) { bdd_reorder(m.id); }
+ public void autoReorder(ReorderMethod method) { bdd_autoreorder(method.id); }
+ public void autoReorder(ReorderMethod method, int max) { bdd_autoreorder_times(method.id, max); }
+ public void swapVar(int v1, int v2) { bdd_swapvar(v1, v2); }
+
+ public ReorderMethod getReorderMethod() {
+ switch (bddreordermethod) {
+ case BDD_REORDER_NONE :
+ return REORDER_NONE;
+ case BDD_REORDER_WIN2 :
+ return REORDER_WIN2;
+ case BDD_REORDER_WIN2ITE :
+ return REORDER_WIN2ITE;
+ case BDD_REORDER_WIN3 :
+ return REORDER_WIN3;
+ case BDD_REORDER_WIN3ITE :
+ return REORDER_WIN3ITE;
+ case BDD_REORDER_SIFT :
+ return REORDER_SIFT;
+ case BDD_REORDER_SIFTITE :
+ return REORDER_SIFTITE;
+ case BDD_REORDER_RANDOM :
+ return REORDER_RANDOM;
+ default :
+ throw new BDDException();
+ }
+ }
+
+ // Experimental functions.
+
+ public void validateAll() { bdd_validate_all(); }
+ public void validateLive() { bdd_validate_live(); }
+ public void validateBDD(BDD b) { bdd_validate(unwrap(b)); }
+
+
+ /***** IMPLEMENTATION BELOW *****/
+
+ long[] bddnodes;
+
+ static final int LEV_BITS = 11;
+ static final int NODE_BITS = 26;
+ static final int LOW_SHIFT = 12;
+ static final int HIGH_SHIFT = 38;
+ static final int LEV_SHIFT = 1;
+ static final int MARK_MASK = 0x001;
+ static final int LEV_MASK = 0xffe;
+ static final long LO_MASK = 0x0000003ffffff000L;
+ static final long HI_MASK = 0xffffffc000000000L;
+ static final long LOHILEV_MASK = LO_MASK | HI_MASK | LEV_MASK;
+
+ static final int INVALID_BDD = -1;
+ static final int MAXVAR = (1 << LEV_BITS) - 1;
+ static final int MAX_PAIRSID = MAXVAR;
+ static final int NODE_MASK = (1 << NODE_BITS) - 1;
+
+ private final int LEVEL(int node) {
+ return ((int)bddnodes[node] & LEV_MASK) >> LEV_SHIFT;
+ }
+
+ private final void SETLEVEL(int node, int val) {
+ if (VERIFY_ASSERTIONS)
+ _assert(val >= 0 && val <= MAXVAR);
+ long a = bddnodes[node] & ~LEV_MASK;
+ a |= val << LEV_SHIFT;
+ bddnodes[node] = a;
+ }
+
+ private final void SETMARK(int n) {
+ bddnodes[n] |= MARK_MASK;
+ }
+
+ private final void UNMARK(int n) {
+ if (VERIFY_ASSERTIONS) _assert(n > 1);
+ bddnodes[n] &= ~MARK_MASK;
+ }
+
+ private final boolean MARKED(int n) {
+ return ((int)bddnodes[n] & MARK_MASK) != 0;
+ }
+
+ private final int LOW(int r) {
+ return (int)(bddnodes[r] >> LOW_SHIFT) & NODE_MASK;
+ }
+
+ private final void SETLOW(int r, int v) {
+ if (VERIFY_ASSERTIONS) _assert(v >= 0 && v <= NODE_MASK);
+ long a = bddnodes[r] & ~LO_MASK;
+ a |= (long)v << LOW_SHIFT;
+ bddnodes[r] = a;
+ }
+
+ private final int HIGH(int r) {
+ return (int)(bddnodes[r] >> HIGH_SHIFT) & NODE_MASK;
+ }
+
+ private final void SETHIGH(int r, int v) {
+ if (VERIFY_ASSERTIONS) _assert(v >= 0 && v <= NODE_MASK);
+ long a = bddnodes[r] & ~HI_MASK;
+ a |= (long)v << HIGH_SHIFT;
+ bddnodes[r] = a;
+ }
+
+ private static final long MAKE_NODE(int lev, int lo, int hi) {
+ long a = lev << LEV_SHIFT;
+ a |= (long)lo << LOW_SHIFT;
+ a |= (long)hi << HIGH_SHIFT;
+ return a;
+ }
+
+ private final int VARr(int node) {
+ return ((int)bddnodes[node] & LEV_MASK) >> LEV_SHIFT;
+ }
+
+ private final void SETVARr(int node, int val) {
+ if (VERIFY_ASSERTIONS)
+ _assert(val >= 0 && val <= MAXVAR);
+ long a = bddnodes[node] & ~LEV_MASK;
+ a |= val << LEV_SHIFT;
+ bddnodes[node] = a;
+ }
+
+ static final int BUCKET_SIZE = 8;
+
+ class freelist {
+ BitString fullbuckets;
+
+ void reset() {
+ if (VERIFY_ASSERTIONS) _assert((bddnodesize & -BUCKET_SIZE) == bddnodesize);
+ int b = bddnodesize / BUCKET_SIZE;
+ if (fullbuckets == null || b != fullbuckets.size())
+ fullbuckets = new BitString(b);
+ last_bucket = 0;
+ }
+
+ void resize() {
+ if (fullbuckets == null) {
+ reset();
+ } else {
+ if (VERIFY_ASSERTIONS) _assert((bddnodesize & -BUCKET_SIZE) == bddnodesize);
+ int b = bddnodesize / BUCKET_SIZE;
+ if (b !...
[truncated message content] |