Esempio n. 1
0
        public static FormulaNode nnfNegate(FormulaNode formula)
        {
            FormulaNode result = new FormulaNode(LogicOperator.NOT);

            result.SetChildren(formula, null);
            return(result.NNF());
        }
        /*
         * <au> is an elementary formula of the form EX(ER(p,q))
         */
        private FormulaNode ComputeAUFragment(FormulaNode au, FormulaNode stateSet, SymbolicState state)
        {
#if DEBUG
            Console.WriteLine("Computing fragment for " + au);
#endif
            FormulaNode frag     = FormulaParser.Parse("~TRUE");
            FormulaNode notLeft  = new FormulaNode(LogicOperator.NOT, au[0][0], null);
            FormulaNode notRight = new FormulaNode(LogicOperator.NOT, au[0][1], null);
            while (true)
            {
                string        nextName   = "succ" + uniqueId.GetTicket().ToString();
                SymbolicState next       = new SymbolicState(elementary, nextName);
                FormulaNode   transition = GenTransition(state, next);
                FormulaNode   memberOf   = SymbolicState.Substitute(stateSet, state, next);
                FormulaNode   nextFrag   = SymbolicState.Substitute(frag, state, next);
                FormulaNode   newFrag    = new FormulaNode(LogicOperator.AND, transition, memberOf);
                newFrag = new FormulaNode(LogicOperator.AND, newFrag, nextFrag);
                newFrag = next.Quantify(LogicOperator.EXISTS, newFrag);

                newFrag = new FormulaNode(LogicOperator.AND, state.ValueOf(notLeft.NNF()), newFrag);

                // Add the big conjunction needed for fragAU
                List <FormulaNode> fragTerms = new List <FormulaNode>();

                foreach (FormulaNode el in elementary)
                {
                    if (el.GetLogicOperator() != LogicOperator.EX)
                    {
                        continue;
                    }

                    nextName   = "succ" + uniqueId.GetTicket().ToString();
                    next       = new SymbolicState(elementary, nextName);
                    transition = GenTransition(state, next);
                    memberOf   = SymbolicState.Substitute(stateSet, state, next);
                    nextFrag   = SymbolicState.Substitute(frag, state, next);


                    FormulaNode lhs = state.ValueOf(el);
                    FormulaNode rhs = new FormulaNode(LogicOperator.AND, transition, memberOf);
                    rhs = new FormulaNode(LogicOperator.AND, rhs, nextFrag);
                    rhs = new FormulaNode(LogicOperator.AND, rhs, next.ValueOf(SymbolicState.Substitute(el[0], state, next)));
                    rhs = next.Quantify(LogicOperator.EXISTS, rhs);

                    fragTerms.Add(new FormulaNode(LogicOperator.IMP, lhs, rhs));
                }

                newFrag = new FormulaNode(LogicOperator.AND, newFrag, JoinTerms(LogicOperator.AND, fragTerms));
                newFrag = new FormulaNode(LogicOperator.OR, state.ValueOf(notRight.NNF()), newFrag);

                if (IsFixpoint(newFrag, frag, state))
                {
                    return(frag);
                }

                frag = newFrag;
            }
        }
Esempio n. 3
0
        // We assume that the formula is in QBF
        // (But no other assumption)
        public static bool QBFSAT(FormulaNode formula)
        {
            // First convert the formula to PNF
            formula = formula.NNF().PNF();
            // Then convert it to QBCNF
            QBCNFormula qbcnf = ConvertToCNF(formula);

            return(QBFSolver.Solve(qbcnf));
        }
Esempio n. 4
0
        // Trnasfer the node to PNF (the formula is assumed to be in NNF)
        // We assume that the formula also has no temporal operators
        public FormulaNode PNF()
        {
            if (this.logicOp == LogicOperator.VAR)
            {
                return(new FormulaNode(this.name));
            }

            FormulaNode   res = null, left = null, right = null;
            ISet <string> leftSet, rightSet;
            string        varname;

            if (this.logicOp == LogicOperator.NOT)
            {
                res = new FormulaNode(LogicOperator.NOT);
                res.SetChildren(new FormulaNode(this.childNodes[0].name), null);
                return(res);
            }

            if (this.logicOp == LogicOperator.EXISTS ||
                this.logicOp == LogicOperator.ALL)
            {
                res = new FormulaNode(this.logicOp, this.name);
                res.SetChildren(this.childNodes[0].PNF(), null);
                return(res);
            }

            // Since we assume NNF, all NOT nodes are next to variables
            // Thus all of the remaining operators are binary
            left  = this.childNodes[0].PNF();
            right = this.childNodes[1].PNF();

            leftSet  = left.GetVariables();
            rightSet = right.GetVariables();

            if (this.logicOp == LogicOperator.AND ||
                this.logicOp == LogicOperator.OR)
            {
                FormulaNode temp;
                if (left.logicOp == LogicOperator.EXISTS ||
                    left.logicOp == LogicOperator.ALL)
                {
                    if (rightSet.Contains(left.name))
                    {
                        varname = UniquePNFVariable();
                        left    = left.Substitute(left.name, varname);
                    }

                    res  = new FormulaNode(left.logicOp, left.name);
                    temp = new FormulaNode(this.logicOp);
                    temp.SetChildren(left.childNodes[0], right);
                    res.SetChildren(temp.PNF(), null);
                }
                else if (right.logicOp == LogicOperator.EXISTS ||
                         right.logicOp == LogicOperator.ALL)
                {
                    if (leftSet.Contains(right.name))
                    {
                        varname = UniquePNFVariable();
                        right   = right.Substitute(right.name, varname);
                    }

                    res  = new FormulaNode(right.logicOp, right.name);
                    temp = new FormulaNode(this.logicOp);
                    temp.SetChildren(left, right.childNodes[0]);
                    res.SetChildren(temp.PNF(), null);
                }
                else
                {
                    res = new FormulaNode(this.logicOp);
                    res.SetChildren(left, right);
                }
            }

            // For convenience, we get rid of "->" operators
            if (this.logicOp == LogicOperator.IMP)
            {
                res = new FormulaNode(LogicOperator.OR);
                res.SetChildren(new FormulaNode(LogicOperator.NOT), right);
                res.childNodes[0].SetChildren(left, null);
                res = res.NNF().PNF();
            }

            return(res);
        }
Esempio n. 5
0
        // Transfer the node to NNF
        public FormulaNode NNF()
        {
            if (this.logicOp == LogicOperator.VAR)
            {
                return(new FormulaNode(this.name));
            }

            FormulaNode res = null, left = null, right = null;

            if (this.logicOp != LogicOperator.NOT)
            {
                res = new FormulaNode(this.logicOp, this.name);
                if (this.childNodes[0] != null)
                {
                    left = this.childNodes[0].NNF();
                }
                if (this.childNodes[1] != null)
                {
                    right = this.childNodes[1].NNF();
                }
                res.SetChildren(left, right);
                return(res);
            }

            // If we reached here, our node is "~" and hence we should
            // rearrange the formula tree
            // We note that a "~" should be unary and hence it only
            // has a left child

            switch (this.childNodes[0].logicOp)
            {
            case LogicOperator.EXISTS:
                res = new FormulaNode(LogicOperator.ALL, this.childNodes[0].name);
                break;

            case LogicOperator.ALL:
                res = new FormulaNode(LogicOperator.EXISTS, this.childNodes[0].name);
                break;

            case LogicOperator.AND:
                res = new FormulaNode(LogicOperator.OR);
                break;

            case LogicOperator.OR:
                res = new FormulaNode(LogicOperator.AND);
                break;

            case LogicOperator.NOT:
                return(this.childNodes[0].childNodes[0].NNF());

            case LogicOperator.IMP:
                // ~(a->b) == a & ~b
                res   = new FormulaNode(LogicOperator.AND);
                left  = this.childNodes[0].childNodes[0].NNF();
                right = new FormulaNode(LogicOperator.NOT);
                right.SetChildren(this.childNodes[0].childNodes[1].NNF(), null);
                res.SetChildren(left, right.NNF());
                return(res);

            case LogicOperator.EF:
                res = new FormulaNode(LogicOperator.AG);
                break;

            case LogicOperator.AF:
                res = new FormulaNode(LogicOperator.EG);
                break;

            case LogicOperator.EG:
                res = new FormulaNode(LogicOperator.AF);
                break;

            case LogicOperator.AG:
                res = new FormulaNode(LogicOperator.EF);
                break;

            case LogicOperator.AX:
                res = new FormulaNode(LogicOperator.EX);
                break;

            case LogicOperator.EX:
                res = new FormulaNode(LogicOperator.AX);
                break;

            case LogicOperator.EU:
                res = new FormulaNode(LogicOperator.AR);
                break;

            case LogicOperator.AU:
                res = new FormulaNode(LogicOperator.ER);
                break;

            case LogicOperator.ER:
                res = new FormulaNode(LogicOperator.AU);
                break;

            case LogicOperator.AR:
                res = new FormulaNode(LogicOperator.EU);
                break;

            case LogicOperator.VAR:
                res = new FormulaNode(LogicOperator.NOT);
                res.SetChildren(new FormulaNode(this.childNodes[0].name), null);
                return(res);

            default:
                res = null;
                break;
            }

            if (this.childNodes[0].childNodes[0] != null)
            {
                left = new FormulaNode(LogicOperator.NOT);
                left.SetChildren(this.childNodes[0].childNodes[0].NNF(), null);
                left = left.NNF();
            }
            if (this.childNodes[0].childNodes[1] != null)
            {
                right = new FormulaNode(LogicOperator.NOT);
                right.SetChildren(this.childNodes[0].childNodes[1].NNF(), null);
                right = right.NNF();
            }
            res.SetChildren(left, right);

            return(res);
        }