|
|
@ -14,7 +14,7 @@ |
|
|
|
* limitations under the License. |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "sylvan_config.h" |
|
|
|
#include <sylvan_config.h> |
|
|
|
|
|
|
|
#include <assert.h> |
|
|
|
#include <inttypes.h> |
|
|
@ -25,11 +25,11 @@ |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
#include "refs.h" |
|
|
|
#include "sha2.h" |
|
|
|
#include "sylvan.h" |
|
|
|
#include "sylvan_common.h" |
|
|
|
#include "sylvan_mtbdd_int.h" |
|
|
|
#include <refs.h> |
|
|
|
#include <sha2.h> |
|
|
|
#include <sylvan.h> |
|
|
|
#include <sylvan_common.h> |
|
|
|
#include <sylvan_mtbdd_int.h> |
|
|
|
|
|
|
|
/* Primitives */ |
|
|
|
int |
|
|
@ -2326,6 +2326,111 @@ TASK_IMPL_2(double, mtbdd_satcount, MTBDD, dd, size_t, nvars) |
|
|
|
return hack.d; |
|
|
|
} |
|
|
|
|
|
|
|
static MTBDD |
|
|
|
mtbdd_enum_next_leaf(MTBDD dd, MTBDD variables, MTBDD prev) |
|
|
|
{ |
|
|
|
// dd is a leaf |
|
|
|
|
|
|
|
if (variables == mtbdd_true) { |
|
|
|
// if prev is not false, then it equals dd and we should return false (seen before) |
|
|
|
if (prev != mtbdd_false) return mtbdd_false; |
|
|
|
else return dd; |
|
|
|
} else { |
|
|
|
// get next variable from <variables> |
|
|
|
uint32_t v = mtbdd_getvar(variables); |
|
|
|
variables = mtbdd_gethigh(variables); |
|
|
|
|
|
|
|
// if prev is not false, get plow and phigh (one of these leads to "false") |
|
|
|
MTBDD plow, phigh; |
|
|
|
if (prev != mtbdd_false) { |
|
|
|
mtbddnode_t pn = GETNODE(prev); |
|
|
|
assert(!mtbdd_isleaf(prev) && mtbddnode_getvariable(pn) == v); |
|
|
|
plow = node_getlow(prev, pn); |
|
|
|
phigh = node_gethigh(prev, pn); |
|
|
|
assert(plow == mtbdd_false || phigh == mtbdd_false); |
|
|
|
} else { |
|
|
|
plow = phigh = mtbdd_false; |
|
|
|
} |
|
|
|
|
|
|
|
MTBDD sub; |
|
|
|
|
|
|
|
// first maybe follow low |
|
|
|
if (phigh == mtbdd_false) { |
|
|
|
sub = mtbdd_enum_next_leaf(dd, variables, plow); |
|
|
|
if (sub != mtbdd_false) return mtbdd_makenode(v, sub, mtbdd_false); |
|
|
|
} |
|
|
|
|
|
|
|
// if not low, try following high |
|
|
|
sub = mtbdd_enum_next_leaf(dd, variables, phigh); |
|
|
|
if (sub != mtbdd_false) return mtbdd_makenode(v, mtbdd_false, sub); |
|
|
|
|
|
|
|
// we've tried low and high, return false |
|
|
|
return mtbdd_false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
MTBDD |
|
|
|
mtbdd_enum_next(MTBDD dd, MTBDD variables, MTBDD prev, mtbdd_enum_filter_cb filter_cb) |
|
|
|
{ |
|
|
|
if (dd == mtbdd_false) { |
|
|
|
// the leaf dd is skipped |
|
|
|
return mtbdd_false; |
|
|
|
} else if (mtbdd_isleaf(dd)) { |
|
|
|
// a leaf for which the filter returns 0 is skipped |
|
|
|
if (filter_cb != NULL && filter_cb(dd) == 0) return mtbdd_false; |
|
|
|
// ok, we have a leaf that is not skipped, go for it! |
|
|
|
return mtbdd_enum_next_leaf(dd, variables, prev); |
|
|
|
} else { |
|
|
|
// if variables == true, then dd must be a leaf. But then this line is unreachable. |
|
|
|
assert(variables != mtbdd_true); |
|
|
|
|
|
|
|
// get next variable from <variables> |
|
|
|
uint32_t v = mtbdd_getvar(variables); |
|
|
|
variables = mtbdd_gethigh(variables); |
|
|
|
|
|
|
|
// if prev is not false, get plow and phigh (one of these leads to "false") |
|
|
|
MTBDD plow, phigh; |
|
|
|
if (prev != mtbdd_false) { |
|
|
|
mtbddnode_t pn = GETNODE(prev); |
|
|
|
assert(!mtbdd_isleaf(prev) && mtbddnode_getvariable(pn) == v); |
|
|
|
plow = node_getlow(prev, pn); |
|
|
|
phigh = node_gethigh(prev, pn); |
|
|
|
assert(plow == mtbdd_false || phigh == mtbdd_false); |
|
|
|
} else { |
|
|
|
plow = phigh = mtbdd_false; |
|
|
|
} |
|
|
|
|
|
|
|
// get cofactors ddlow and ddhigh |
|
|
|
MTBDD ddlow, ddhigh; |
|
|
|
if (!mtbdd_isleaf(dd)) { |
|
|
|
mtbddnode_t n = GETNODE(dd); |
|
|
|
if (mtbddnode_getvariable(n) == v) { |
|
|
|
ddlow = node_getlow(dd, n); |
|
|
|
ddhigh = node_gethigh(dd, n); |
|
|
|
} else { |
|
|
|
ddlow = ddhigh = dd; |
|
|
|
} |
|
|
|
} else { |
|
|
|
ddlow = ddhigh = dd; |
|
|
|
} |
|
|
|
|
|
|
|
MTBDD sub; |
|
|
|
|
|
|
|
// first maybe follow low |
|
|
|
if (phigh == mtbdd_false) { |
|
|
|
sub = mtbdd_enum_next(ddlow, variables, plow, filter_cb); |
|
|
|
if (sub != mtbdd_false) return mtbdd_makenode(v, sub, mtbdd_false); |
|
|
|
} |
|
|
|
|
|
|
|
// if not low, try following high |
|
|
|
sub = mtbdd_enum_next(ddhigh, variables, phigh, filter_cb); |
|
|
|
if (sub != mtbdd_false) return mtbdd_makenode(v, mtbdd_false, sub); |
|
|
|
|
|
|
|
// we've tried low and high, return false |
|
|
|
return mtbdd_false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Helper function for recursive unmarking |
|
|
|
*/ |
|
|
@ -2583,3 +2688,4 @@ mtbdd_map_removeall(MTBDDMAP map, MTBDD variables) |
|
|
|
} |
|
|
|
|
|
|
|
#include "sylvan_storm_custom.c" |
|
|
|
|