assertEquals("abc", ((LeafExpressionNode) node).getIdentifier());
// a&b|c&d -> (((a & b) | c) & )
node = parser.parse("a&b|c&d");
assertTrue(node instanceof NonLeafExpressionNode);
NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
// (a) -> (a)
node = parser.parse("(a)");
assertTrue(node instanceof LeafExpressionNode);
assertEquals("a", ((LeafExpressionNode) node).getIdentifier());
// (a&b) -> (a & b)
node = parser.parse(" ( a & b )");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
// ((((a&b)))) -> (a & b)
node = parser.parse("((((a&b))))");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
// (a|b)&(cc|def) -> ((a | b) & (cc | def))
node = parser.parse("( a | b ) & (cc|def)");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
NonLeafExpressionNode nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
NonLeafExpressionNode nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.OR, nlNodeLeft.getOperator());
assertEquals(2, nlNodeLeft.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
assertEquals("b", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(1)).getIdentifier());
assertEquals(Operator.OR, nlNodeRight.getOperator());
assertEquals(2, nlNodeRight.getChildExps().size());
assertEquals("cc", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
assertEquals("def", ((LeafExpressionNode) nlNodeRight.getChildExps().get(1)).getIdentifier());
// a&(cc|de) -> (a & (cc | de))
node = parser.parse("a&(cc|de)");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("cc", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("de", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
// (a&b)|c -> ((a & b) | c)
node = parser.parse("(a&b)|c");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
// (a&b&c)|d -> (((a & b) & c) | d)
node = parser.parse("(a&b&c)|d");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
// a&(b|(c|d)) -> (a & (b | (c | d)))
node = parser.parse("a&(b|(c|d))");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("c", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
// (!a) -> (!a)
node = parser.parse("(!a)");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.NOT, nlNode.getOperator());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
// a&(!b) -> (a & (!b))
node = parser.parse("a&(!b)");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.NOT, nlNode.getOperator());
assertEquals(1, nlNode.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
// !a&b -> ((!a) & b)
node = parser.parse("!a&b");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.NOT, nlNode.getOperator());
assertEquals(1, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
// !a&(!b) -> ((!a) & (!b))
node = parser.parse("!a&(!b)");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.NOT, nlNodeLeft.getOperator());
assertEquals(1, nlNodeLeft.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
assertEquals(Operator.NOT, nlNodeRight.getOperator());
assertEquals(1, nlNodeRight.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
// !a&!b -> ((!a) & (!b))
node = parser.parse("!a&!b");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.NOT, nlNodeLeft.getOperator());
assertEquals(1, nlNodeLeft.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
assertEquals(Operator.NOT, nlNodeRight.getOperator());
assertEquals(1, nlNodeRight.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
// !(a&b) -> (!(a & b))
node = parser.parse("!(a&b)");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.NOT, nlNode.getOperator());
assertEquals(1, nlNode.getChildExps().size());
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
// a&!b -> (a & (!b))
node = parser.parse("a&!b");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("a", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.NOT, nlNode.getOperator());
assertEquals(1, nlNode.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
// !((a|b)&!(c&!b)) -> (!((a | b) & (!(c & (!b)))))
node = parser.parse("!((a | b) & !(c & !b))");
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.NOT, nlNode.getOperator());
assertEquals(1, nlNode.getChildExps().size());
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
assertTrue(nlNode.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNodeLeft = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
nlNodeRight = (NonLeafExpressionNode) nlNode.getChildExps().get(1);
assertEquals(Operator.OR, nlNodeLeft.getOperator());
assertEquals("a", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(0)).getIdentifier());
assertEquals("b", ((LeafExpressionNode) nlNodeLeft.getChildExps().get(1)).getIdentifier());
assertEquals(Operator.NOT, nlNodeRight.getOperator());
assertEquals(1, nlNodeRight.getChildExps().size());
nlNodeRight = (NonLeafExpressionNode) nlNodeRight.getChildExps().get(0);
assertEquals(Operator.AND, nlNodeRight.getOperator());
assertEquals(2, nlNodeRight.getChildExps().size());
assertEquals("c", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
assertTrue(nlNodeRight.getChildExps().get(1) instanceof NonLeafExpressionNode);
nlNodeRight = (NonLeafExpressionNode) nlNodeRight.getChildExps().get(1);
assertEquals(Operator.NOT, nlNodeRight.getOperator());
assertEquals(1, nlNodeRight.getChildExps().size());
assertEquals("b", ((LeafExpressionNode) nlNodeRight.getChildExps().get(0)).getIdentifier());
}