Esempio n. 1
0
        // Get a PNF formula and return its QBCNF
        public static QBCNFormula ConvertToCNF(FormulaNode formula)
        {
            QBCNFormula   res  = new QBCNFormula();
            FormulaNode   node = formula;
            ISet <string> addedVars;

            res.quantifiers = new List <string>();
            while (node.GetLogicOperator() == LogicOperator.EXISTS ||
                   node.GetLogicOperator() == LogicOperator.ALL)
            {
                if (node.GetLogicOperator() == LogicOperator.EXISTS)
                {
                    res.quantifiers.Add("e" + node.GetName());
                }
                else
                {
                    res.quantifiers.Add("a" + node.GetName());
                }
                node = node[0];
            }

            if (res.quantifiers.Count != formula.GetVariables().Count)
            {
                throw new Exception("Non-quantified variables in formula!");
            }

            res.propositional = TseytinTransformation(node, out addedVars);

            //Replace strings with numbers
            ISet <string> literals = res.GetLiterals();
            Dictionary <string, string> changes = new Dictionary <string, string>();

            foreach (string literal in literals)
            {
                int  n;
                bool isNum = int.TryParse(literal, out n);
                if (!changes.ContainsKey(literal) & !isNum)
                {
                    int ticket = ticketMachine.GetTicket();
                    if (literal[0] != '-')
                    {
                        changes.Add(literal, ticket.ToString());
                        changes.Add("-" + literal, (-ticket).ToString());
                    }
                    else
                    {
                        changes.Add(literal, (-ticket).ToString());
                        changes.Add(literal.Substring(1), ticket.ToString());
                    }
                }
            }

            res.ReplaceLiterals(changes);

            // Quantify the Tseytin variables with EXISTS
            foreach (string var in addedVars)
            {
                res.quantifiers.Add("e" + var);
            }

            return(res);
        }
Esempio n. 2
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);
        }