Practical usage
After this short and possibly mindblowing introduction on decision diagrams in particular in the multivalued variation, below some practical information on using the common.multivaluetrees
library.
Variables
As you typically work with variables in several usekinds, like i
and i+
in the explanation above, this has to be defined first. The core functionality provided for that is in common.multivaluetrees.VarInfoBuilder
. The class is generic over the type of variables. As a convenience, the common.multivaluetrees.SimpleVarInfoBuilder
class has been created using common.multivaluetrees.SimpleVarVariable
variables (with a name, a lower bound, and a number of valid values).
After creating an instance providing the number of usekinds that you have, add the variables as you like. The order of adding is also the order of the variable nodes in the tree from the root towards the bottom ONE
or ZERO
terminator nodes. The elementary function is addVariable(<variable>, <usekind>)
which adds a node level for variable <variable>
and usage index <usekind>
(running from 0
to the number of usekinds excluding the upper bound).
As you usually want to have all usekinds for a variable, and often want them on consecutive node levels in the tree, addVariable(<variable>)
adds all usekinds in one call. For a list of variables, addVariablesGroupOnVariables(<listvariables>)
does the same for each variable in the list. First N
usekinds for the first variable, then N
usekinds for the second variable, and so on. If you want the same usekinds near each other instead, addVariablesGroupOnUseKind(<listvariables>)
exists.
Each call adds one or more VarInfo
instances to the builder. A VarInfo
instance is the equivalent of e.g. i
and i+
above. The VarInfoBuilder
instance also stores the relation between variables and their VarInfo
instances. With a variable you can ask it for all related VarInfo
instances (or just one instance), with a VarInfo
instance you can ask for the associated variable.
Trees and relations
The VarInfo
instances from the builder are used to construct multivalue nodes, and eventually trees of such nodes. This is done in the common.multivaluetrees.Tree
class, the work horse in multivalue diagram computations. Constructing it is a simple Tree t = new Tree();
which gives you an empty tree.
Constructed relations in t
are represented by common.multivaluetrees.Node
objects. These objects should be considered to be readonly. They can be stored anywhere in the application. Modifying a Node
object is not possible, but you can create a new (updated) object and store that.
You can read the information inside a Node
. The only somewhat useful operation that you can perform on Node n
is n.dumpGraphLines("adescriptionofn");
which dumps a humanreadable representation of the relation expressed in the node. You may however also want to check out t.dumpGraph(Node n)
which should provide better output.
The Tree t
object is where nodes are created and stored. It provides the following features:
Feature  Description 


Constant expressing the 

Constant expressing the 

Construct the elementary 

Construct a conjunction (‘and’ operator) of relations 

Construct a conjunction (‘and’ operator) of one or more relations. 

Construct a disjunction (‘or’ operator) of relations 

Construct a disjunction (‘or’ operator) of one or more relations. 

Construct an inverted relation (‘not’ operator) of relation 

Construct a new relation from relation 

Abstracts from the supplied variables. The variable is replaced by a disjunction of its children. 

Output a human readable description of relation 
The foolproof way to build a relation from the ground up is to use
Node t.buildEqualityValue(VarInfo varInfo, int value)
, combined withNode t.conjunct(Node a, Node b)
(‘and’ operator) andNode t.disjunct(Node a, Node b)
(‘or’ operator) calls.There is also
Node t.buildEqualityIndex(VarInfo varInfo, int index)
andNode t.buildEqualityIndex(VarInfo varInfo, int index, Node sub)
. These calls are more efficient, but ignore the lower bound (internally, the variable range is shifted to make the lower bound equal to0
), and the latter function assumes you build the relation bottom up (VarInfo
instances of last to first calls in theVarInfoBuilder
).The
Node t.replace(Node n, VarInfo oldVar, VarInfo newVar)
is simple and has few requirements, but it is not very efficient variable replacement. For massreplacement,Node t.adjacentReplacements(Node n, VariableReplacement[] replacements)
is better where the variable replacement instances are constructed withVariableReplacement(VarInfo oldVar, VarInfo newVar)
. TheoldVar
andnewVar
variables should be on adjacent levels in the tree, andreplacements
must be ordered topdown.A somewhat exotic method is
Node t.assign(Node n, VarInfo varInfo, int index)
. It selects the relation where thevarInfo
variable has theindex
value (with shifted lower bound), and eliminates that variable as well.