package splar.plugins.reasoners.bdd.javabdd;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import net.sf.javabdd.BDD;
public class BDDTraversal {
protected Set<String> path;
protected byte[] bddPath;
public static final byte DONTCARE = 2;
public static final byte TRUE = 1;
public static final byte FALSE = 0;
public BDDTraversal() {
path = new LinkedHashSet<String>();
bddPath = null;
}
public void dfs(BDD bdd) {
path.clear();
bddPath = new byte[bdd.getFactory().varNum()];
Arrays.fill(bddPath, (byte)DONTCARE);
dfsTraversal(bdd);
onTraversalDone();
}
protected byte[] getSolution() {
return bddPath;
}
protected Set<String> getPath() {
return path;
}
public boolean searchStopped() {
return false;
}
private void dfsTraversal(BDD bdd) {
if ( !searchStopped() ) {
if ( bdd.isOne() ) {
onOneTerminalFound(path, bddPath);
}
else if ( bdd.isZero() ) {
onZeroTerminalFound(path, bddPath);
}
else {
onVisitingNode(bdd, path, bddPath);
BDD firstNode = bdd.low(), secondNode = bdd.high();
boolean polarity = false;
if (!visitLowNodeFirst(bdd) ) {
firstNode = bdd.high();
secondNode = bdd.low();
polarity = true;
}
// visit child one
if ( !searchStopped() ) {
if ( canVisitNode(bdd, polarity) ) {
String pathEntry = bdd.var() + ":" + polarity;
path.add(pathEntry);
bddPath[bdd.var()] = (byte)((polarity)?TRUE:FALSE);
dfsTraversal(firstNode);
bddPath[bdd.var()] = DONTCARE;
path.remove(pathEntry);
}
else {
onSkippedNode(bdd, polarity, path, bddPath);
}
}
// visit child two
if ( !searchStopped() ) {
if ( canVisitNode(bdd, !polarity) ) {
String pathEntry = bdd.var() + ":" + !polarity;
path.add(pathEntry);
bddPath[bdd.var()] = (byte)((!polarity)?TRUE:FALSE);
dfsTraversal(secondNode);
bddPath[bdd.var()] = DONTCARE;
path.remove(pathEntry);
}
else {
onSkippedNode(bdd, !polarity, path, bddPath);
}
}
onVisitedNode(bdd, path, bddPath);
bdd.free();
}
}
}
public void onVisitingNode(BDD bddNode, Set<String> path, byte solution[]) {
}
public void onVisitedNode(BDD bddNode, Set<String> path, byte solution[]) {
}
public void onZeroTerminalFound(Set<String> path, byte solution[]) {
}
public void onOneTerminalFound(Set<String> path, byte solution[]) {
}
public boolean canVisitNode(BDD bddNode, boolean polarity) {
return true;
}
public void onSkippedNode(BDD bdNode, boolean polarity, Set<String> path, byte solution[]) {
}
public boolean visitLowNodeFirst(BDD bddNode) {
return true;
}
public void onTraversalDone() {
}
}