I am trying to convert a binary tree, for example.
OR (Implementation of Operator - a specialisation of TreeNode... see below) |-A (Implementation of TreeNode... see below) |-OR |-B |-AND (Implementation of Operator - a specialisation of TreeNode... see below) |-C |-OR |-D |-E
into this equivalent representation of the Conjunctive Normal Form (CND). I believe that since I use only the logical operators OR + AND, the only step I have to follow is to distribute AND over OR. This would create the following tree (still binary for my purposes) in CNF:
AND |-OR | |-A | |-OR | |-B | |-OR | |-E | |-D |-OR |-A |-OR |-B |-OR |-E |-C
I am having trouble creating an algorithm for this ... so far I have the following skeleton that will overwrite the bottom from bottom to top (note the recursive call to restore):
public TreeNode reconstruct(TreeNode treeNode) { if(treeNode instanceof Operator) { TreeNode left = reconstruct(((Operator)treeNode).getLeft()); TreeNode right = reconstruct(((Operator)treeNode).getRight()); return distribute(treeNode, left, right); } else return node; }
Using classes:
----------- | TreeNode | // Interface ----------- ^ | ----------- | Operator | // Interface ----------- | getLeft() | | getRight()| | setLeft() | | setRight()| -----------
Can anyone suggest a distribution implementation that will convert to CNF?
// EDIT 1 (after the response from nif)
private Node distribute(TreeNode node, TreeNode left, TreeNode right) { if (node instanceof Or) { if (left instanceof And) { // distribute right over left AND return new And( new Or(((Operator)left).getLeft(), right), new Or(((Operator)left).getRight(), right) ); } else if (right instanceof And) { // distribute left over right AND return new And( new Or(((Operator)right).getLeft(), left), new Or(((Operator)right).getRight(), left) ); } } if(node instanceof Operator) { ((Operator)node).setLeft(left); ((Operator)node).setRight(right); } // default return node; }