/// <summary>
        /// Xor brekdown
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool XOR(ref BoolExpr node)
        {
            if (node.Op == OperatorType.XOR)
            {
                var oldNode = node;

                var copyLeft     = BoolExprFactory.CreateCopy(node.Left);
                var copyRight    = BoolExprFactory.CreateCopy(node.Right);
                var negatedLeft  = new BoolExprNegation(copyLeft);
                var negatedRight = new BoolExprNegation(copyRight);
                copyLeft.Parent  = negatedLeft;
                copyRight.Parent = negatedRight;

                var left = new BoolExprConjunction(node.Left, negatedRight);
                node.Left.Parent    = left;
                negatedRight.Parent = left;

                var right = new BoolExprConjunction(negatedLeft, node.Right);
                negatedLeft.Parent = right;
                node.Right.Parent  = right;

                node = new BoolExprDisjunction(left, right);

                node.Parent  = oldNode.Parent;
                left.Parent  = node;
                right.Parent = node;

                UpdateParent(node, oldNode);
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// DeMorgan's Law
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool DeM(ref BoolExpr node)
        {
            if (node.Op == OperatorType.NOT)
            {
                if (node.Right.Op == OperatorType.AND)
                {
                    var oldNode = node;
                    var temp    = node.Right;
                    var left    = new BoolExprNegation(temp.Left);
                    var right   = new BoolExprNegation(temp.Right);
                    node         = new BoolExprDisjunction(left, right);
                    node.Parent  = oldNode.Parent;
                    left.Parent  = node;
                    right.Parent = node;

                    UpdateParent(node, oldNode);
                    return(true);
                }
                else if (node.Right.Op == OperatorType.OR)
                {
                    var oldNode = node;
                    var temp    = node.Right;
                    var left    = new BoolExprNegation(temp.Left);
                    var right   = new BoolExprNegation(temp.Right);
                    node         = new BoolExprConjunction(left, right);
                    node.Parent  = oldNode.Parent;
                    left.Parent  = node;
                    right.Parent = node;

                    UpdateParent(node, oldNode);
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Implication rule
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool Implication(ref BoolExpr node)
        {
            if (node.Op == OperatorType.CONDITIONAL)
            {
                var oldNode = node;
                var left    = new BoolExprNegation(node.Left);
                var right   = node.Right;
                node         = new BoolExprDisjunction(left, right);
                node.Parent  = oldNode.Parent;
                left.Parent  = node;
                right.Parent = node;

                UpdateParent(node, oldNode);
                return(true);
            }
            return(false);
        }