// This program is an example of the use of binary decision diagrams (BDD's).
// Since BDD's implement the BooleanAlgebra interface, all the boolean algebra
// operators ("&", "|", "^", "~", and "mux") can be used on BDD's.
import jazz.circuit.*;
import jazz.circuit.bdd.*;
// Function defined over any boolean algebra.
fun fbool(u, v, w) = (~u | v) & (v ^ w);
// Create three BDD variables "x", "y", and "z" such that "x < y < z".
var vars = Bdd.newVars(3)(["x", "y", "z"]);
var x = vars[0];
var y = vars[1];
var z = vars[2];
// Build the BDD that computes "fbool" by giving the three BDD variables as
// argument to "fbool" (this is legal since "fbool" is defined for any boolean
// algebra and BDD's implement the BooleanAlgebra interface).
var bdd = fbool(x, y, z);
// Display the BDD as a canonical set of Jazz equations (the "%a" format calls
// the "toString()" method of the BDD).
@ print("bdd(%a, %a, %a) = %a\n\n", x, y, z, bdd);
// Build a function "bdd2fun" that can be used to build a function that
// computes the BDD for x, y, and z over any particular boolean algebra given
// the "zero" and "one" constants of the algebra.
fun bdd2fun(zero, one)(x, y, z) =
Bdd.toFunction(3)(vars)(1)([bdd])(zero, one)([x, y, z])[0];
// Build the function that computes the bdd for booleans (since zero=false,
// and one=true for this boolean algebra)
var fbool' = bdd2fun(false, true);
// Check that "fbool" and "fbool'" compute the same function over booleans
{
var bools = [false, true];
for (i < 2) {
for (j < 2) {
for (k < 2) {
var u = bools[i];
var v = bools[j];
var w = bools[k];
var fb = fbool(u, v, w);
var fb' = fbool'(u, v, w);
assert(fb == fb');
@ print("fbool'(%a, %a, %a) = %a\n", u, v, w, fb);
}
}
}
}
// Check that "fper" computes the same thing as "fbool" for a few sets of
// three periodic numbers chosen at random.
{
// Build the function that computes the BDD for periodics (since zero=#(0),
// and one=#(1) for this boolean algebra).
var fper = bdd2fun(#(0), #(1));
// Returns a random periodic number.
fun random() = (per) (Integer.random(25) / (1 + 2 * Integer.random(35)));
@ print("\n");
for (i < 5) {
var u = random();
var v = random();
var w = random();
var fb = fbool(u, v, w);
var fp = fper(u, v, w);
assert(fb == fp);
@ print("fper(%a, %a, %a) = %a\n", u, v, w, fb);
}
}
// Create a new bdd from "fbool'", which is essentially the restriction of
// "fbool" to booleans (since "fbool" was defined over any boolean algebra),
// and thus implements the truth table of "fbool".
var bdd' = Bdd.fromFunction(3)(vars)(f)
{
fun f(v) = fbool'(v[0], v[1], v[2]);
}
// Formally check that the two BDD's are indeed equal (that is to say, that
// they compute the same function).
assert(bdd == bdd');
@ print("\n(bdd == bdd')\n\n");
// Create a device computing the BDD over nets.
device Test {
input in1: Net;
input in2: Net;
input in3: Net;
output out: Net;
var zero = Net.constant(#(0));
var one = Net.constant(#(1));
out = bdd2fun(zero, one)(in1, in2, in3);
}
export Test();