I\'m trying to convert a binary tree e.g.
OR (Implementation of Operator - a specialisation of TreeNode... see below)
|-A (Implementation of TreeNode... see
If AND and OR are the only operators you are using, it shouldn't be hard to tranform your tree to CNF. All you have to do is find structures in the form OR(AND(X,Y), Z) or OR(Z, AND(X,Y)) and use the distribution law.
private static TreeNode distribute(TreeNode n, TreeNode left, TreeNode right) {
if (n instanceof Or) {
if (left instanceof And) {
// distribute right over left AND
return new And(new Or(left.getLeft(), right),
new Or(left.getRight(), right));
} else if (right instanceof And) {
// distribute left over right AND
return new And(new Or(right.getLeft(), left),
new Or(right.getRight(), left));
}
}
// no change
return treeNode;
}
This algorithm must be applied to all nodes of your tree until the tree isn't changed anymore. The order in which you apply the algorithm to the nodes doesn't matter. Intuitively, repetitive application of the algorithm will pull up all AND nodes over OR nodes until the tree is in CNF.
TreeNode root = ....;
while (true) {
TreeNode transformedRoot = reconstruct(root);
if (root.equals(transformedRoot)) {
break;
}
root = transformedRoot;
}
// root is now in CNF
Note: Be aware that the CNF transformation may blow up your tree exponential in size. The shown implementation is quite primitive and doesn't use any enhancements to reduce computation time.