Adiar  2.1.0
An External Memory Decision Diagram Library
Basic Usage

Creating BDDs

Constants

The Boolean constants true and false can be obtained directly with the adiar::bdd_true and adiar::bdd_false functions.

A reduced Binary Decision Diagram.
Definition: bdd.h:53
bdd bdd_true()
The BDD representing the constant true.

Alternatively, boolean constants can also be created directly from a value of type bool.

adiar::bdd bot = false;

Variables

For a single variable, e.g. xi, parse the label i to adiar::bdd_ithvar.

bdd bdd_ithvar(bdd::label_type var)
The BDD representing the i'th variable.

For the negation of a single variable, use adiar::bdd_nithvar

Combining BDDs

Negation

Use adiar::bdd_not or the ~ operator. For example, res below is equivalent to adiar::bdd_nithvar of 0.

bdd bdd_not(const bdd &f)
Negation of a BDD.
adiar::bdd res = ~x0;

Binary Operators

Use adiar::bdd_apply with an adiar::bool_op.

__bdd bdd_apply(const bdd &f, const bdd &g, const predicate< bool, bool > &op)
Apply a binary operator between two BDDs.
const predicate< bool, bool > xor_op
Logical 'xor' operator, i.e. the truth table: [0,1,1,0].
Definition: bool_op.h:34

Alternatively, there is a specializations of adiar::bdd_apply for each adiar::bool_op and for and, or, and xor one can also use the &, |, and ^ operators.

__bdd bdd_xor(const bdd &f, const bdd &g)
Logical 'xor' operator.
adiar::bdd f = x0 ^ x1;
adiar::bdd f = bot;
f ^= x0;
f ^= x1;

If-Then-Else Operator

Use adiar::bdd_ite.

adiar::bdd _ = adiar::bdd_ite(x0, x1, x2);
__bdd bdd_ite(const bdd &f, const bdd &g, const bdd &h)
If-Then-Else operator.

In other BDD packages, this function is good for manually constructing a BDD bottom-up. But, here you should use adiar::bdd_builder instead (see Manual Construction).

Restricting Variables

Use adiar::bdd_restrict. For example, res below is equivalent to ~x1.

__bdd bdd_restrict(const bdd &f, bdd::label_type var, bool val)
Restrict a single variable to a constant value.

Specifically to restrict the top variable, you can use adiar::bdd_low and adiar::bdd_high.

See also the Function Objects tutorial for better ways to use this operation.

Quantification

Use adiar::bdd_exists and adiar::bdd_forall. For example, res below is equivalent to adiar::bdd_true().

__bdd bdd_exists(const bdd &f, bdd::label_type var)
Existential quantification of a single variable.

See also the Function Objects tutorial for better ways to use these operations.

Satisfying Assignments

To get the number of satisfying assignments, use adiar::bdd_satcount. Its second (optional) argument is the total number of variables (including the possibly suppressed ones in the BDD).

size_t varcount = 3;
size_t _ = adiar::bdd_satcount(f, varcount); // 4
uint64_t bdd_satcount(const bdd &f, bdd::label_type varcount)
Count the number of assignments x that make f(x) true.

To get a cube of the lexicographical minimal or maximal assignment, use adiar::bdd_satmin and adiar::bdd_satmax respectively.

adiar::bdd f_min = adiar::bdd_satmin(f); // ~i & j
adiar::bdd f_max = adiar::bdd_satmax(f); // i & ~j
bdd bdd_satmin(const bdd &f)
The lexicographically smallest cube x such that f(x) is true.
bdd bdd_satmax(const bdd &f)
The lexicographically largest cube x such that f(x) is true.

Predicates

Boolean Constants

Use adiar::bdd_isconst to check whether a BDD is a constant Boolean value and adiar::bdd_istrue and adiar::bdd_isfalse to check for a specific boolean value.

bool _ = adiar::bdd_isconst(top); // true
bool _ = adiar::bdd_isconst(x0); // false
bool bdd_isconst(const bdd &f)
Whether a BDD is a constant.
bool _ = adiar::bdd_istrue(top); // true
bool _ = adiar::bdd_istrue(x0); // false
bool bdd_istrue(const bdd &f)
Whether a BDD is the constant true.
bool _ = adiar::bdd_isfalse(top); // false
bool _ = adiar::bdd_isfalse(bot); // true
bool bdd_isfalse(const bdd &f)
Whether a BDD is the constant false.

Single Variables

Use adiar::bdd_isvar, adiar::bdd_isithvar, and adiar::bdd_isnithvar to check whether a BDD represents a formula of exactly one variable.

bool _ = adiar::bdd_isvar(top); // false
bool _ = adiar::bdd_isvar(x0); // true
bool _ = adiar::bdd_isvar(~x0); // true
bool bdd_isvar(const bdd &f)
Whether a BDD is a function dependent on a single variable.
bool _ = adiar::bdd_isithvar(top); // false
bool _ = adiar::bdd_isithvar(x0); // true
bool _ = adiar::bdd_isithvar(~x0); // false
bool bdd_isithvar(const bdd &f)
Whether a BDD is the function of a single positive variable.
bool _ = adiar::bdd_isnithvar(top); // false
bool _ = adiar::bdd_isnithvar(x0); // false
bool _ = adiar::bdd_isnithvar(~x0); // true
bool bdd_isnithvar(const bdd &f)
Whether a BDD is the function of a single negative variable.

Cubes

To check whether a BDD represents a cube, i.e. where all the variables in its support have a fixed value, use adiar::bdd_iscube.

bool _ = adiar::bdd_iscube(f); // false
bool _ = adiar::bdd_iscube(f_min); // true
bool bdd_iscube(const bdd &f)
Whether a BDD represents a cube.

Equality

Use adiar::bdd_equal and adiar::bdd_unequal or the == and != operators.

adiar::bdd f2 = x1 ^ x0;
bool _ = adiar::bdd_equal(f,f2); // true
bool _ = f == f2; // true
bool bdd_equal(const bdd &f, const bdd &g)
Whether the two BDDs represent the same function.

BDD Information

Counting Operations

Use adiar::bdd_nodecount to get the number of BDD nodes.

size_t _ = adiar::bdd_nodecount(f); // 3
size_t bdd_nodecount(const bdd &f)
The number of (internal) nodes used to represent the function.

Use adiar::bdd_varcount to get the number of variables present in the BDD.

size_t _ = adiar::bdd_varcount(f); // 2
bdd::label_type bdd_varcount(const bdd &f)
The number of variables that influence the outcome of f, i.e. the number of levels in the BDD.

Use adiar::bdd_pathcount to get the number of paths to true.

size_t _ = adiar::bdd_pathcount(f); // 2
uint64_t bdd_pathcount(const bdd &f)
Count all unique (but not necessarily disjoint) paths to the true terminal.

Support

The top, minimal, and maximal variable label is can be obtained with adiar::bdd_topvar, adiar::bdd_minvar, and adiar::bdd_maxvar, respectively.

node_type::label_type label_type
Type of this node's variable label.
Definition: dd.h:282
bdd::label_type bdd_maxvar(const bdd &f)
Get the maximal occurring variable in the function's support.
bdd::label_type bdd_minvar(const bdd &f)
Get the minimal occurring variable in the function's support.
bdd::label_type bdd_topvar(const bdd &f)
Get the root's variable label.

Graphical Output

The BDD can be exported to the DOT format with adiar::bdd_printdot. The second argument can either be an output stream, e.g. std::cout, or a filename.

adiar::bdd_printdot(f, "./f.dot");
void bdd_printdot(const bdd &f, std::ostream &out=std::cout, bool include_id=false)
Output a DOT drawing of a BDD to the given output stream.