示例#1
0
        // Get a propositional formula and return its (raw) CNF form
        // addedVars: the names of the new variables introduced by the transformation
        private static ISet <ISet <string> > TseytinTransformation(FormulaNode formula, out ISet <string> addedVars)
        {
            ISet <ISet <string> > res      = new HashSet <ISet <string> >();
            ISet <TseytinBlock>   blockSet = new HashSet <TseytinBlock>();

            ticketMachine.Reset();
            TseytinBlock top = GetTseytinBlocks(formula, blockSet);

            if (top == null)
            {
                // The formula is simply a variable - no Tseitin blocks required
                res.Add(new HashSet <string> {
                    formula.GetName()
                });
            }
            else
            {
                // Create a conjunction of all Tseitin blocks
                foreach (TseytinBlock block in blockSet)
                {
                    res.UnionWith(TseytinBlockToCNF(block));
                }

                // Add the requirement that the topmost formula is true
                ISet <string> topClause = new HashSet <string>();
                topClause.Add(top.ticket.ToString());
                res.Add(topClause);
            }

            addedVars = new HashSet <string>();
            foreach (TseytinBlock block in blockSet)
            {
                addedVars.Add(block.ticket.ToString());
            }

            // Force the TRUE variable to true
            res.Add(new HashSet <string> {
                FormulaNode.TRUE_LITERAL
            });

            return(res);
        }
示例#2
0
        /* Replace the variables describing the state <from> with the ones that describe
         * state <to>
         */
        public static FormulaNode Substitute(FormulaNode formula, SymbolicState from, SymbolicState to)
        {
            if (formula.GetLogicOperator() == LogicOperator.VAR)
            {
                if (from.nameToElementary.Keys.Contains(formula.GetName()))
                {
                    // this variable represents an elementary formula
                    var elementary = from.nameToElementary[formula.GetName()];
                    return(new FormulaNode(to.elementaryNames[elementary]));
                }
                else
                {
                    return(new FormulaNode(formula.GetName()));
                }
            }

            if (formula.GetLogicOperator() == LogicOperator.ALL ||
                formula.GetLogicOperator() == LogicOperator.EXISTS)
            {
                FormulaNode result = new FormulaNode(formula.GetLogicOperator());
                if (from.nameToElementary.Keys.Contains(formula.GetName()))
                {
                    // this variable represents an elementary formula
                    var elementary = from.nameToElementary[formula.GetName()];
                    result.SetName(to.elementaryNames[elementary]);
                }
                else
                {
                    result.SetName(formula.GetName());
                }
                result.SetChildren(Substitute(formula[0], from, to), null);
                return(result);
            }

            FormulaNode res = new FormulaNode(formula.GetLogicOperator());

            FormulaNode left  = Substitute(formula[0], from, to);
            FormulaNode right = null;

            if (formula[1] != null)
            {
                right = Substitute(formula[1], from, to);
            }
            res.SetChildren(left, right);
            return(res);
        }
示例#3
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);
        }
示例#4
0
        /* Assumes the formula is in NNF form */
        public static ISet <FormulaNode> elementaryFormulas(FormulaNode formula)
        {
            HashSet <FormulaNode> result = new HashSet <FormulaNode>();

            switch (formula.GetLogicOperator())
            {
            case LogicOperator.AU:
            case LogicOperator.AR:
                // AX(f) is elementary
                FormulaNode ax_f = new FormulaNode(LogicOperator.AX);
                ax_f.SetChildren(formula, null);
                result.Add(ax_f);
                result.Add(nnfNegate(ax_f));
                result.UnionWith(elementaryFormulas(formula[0]));
                result.UnionWith(elementaryFormulas(formula[1]));
                break;

            case LogicOperator.EU:
            case LogicOperator.ER:
                // EX(f) is elementary
                FormulaNode ex_f = new FormulaNode(LogicOperator.EX);
                ex_f.SetChildren(formula, null);
                result.Add(ex_f);
                result.Add(nnfNegate(ex_f));
                result.UnionWith(elementaryFormulas(formula[0]));
                result.UnionWith(elementaryFormulas(formula[1]));
                break;

            case LogicOperator.EX:
            case LogicOperator.AX:
                // the formula itself is elementary
                result.Add(formula);
                result.Add(nnfNegate(formula));
                result.UnionWith(elementaryFormulas(formula[0]));
                break;

            case LogicOperator.OR:
            case LogicOperator.AND:
                result.UnionWith(elementaryFormulas(formula[0]));
                result.UnionWith(elementaryFormulas(formula[1]));
                break;

            case LogicOperator.NOT:
                Debug.Assert(formula[0].GetLogicOperator() == LogicOperator.VAR,
                             "Input to elementaryFormulas must be in NNF form");
                result.UnionWith(elementaryFormulas(formula[0]));
                break;

            case LogicOperator.VAR:
                if (formula.GetName() != FormulaNode.TRUE_LITERAL)
                {
                    result.Add(formula);
                    result.Add(nnfNegate(formula));
                }
                break;

            default:
                throw new Exception("Not implemented");
            }
            return(result);
        }
示例#5
0
        /* Build a propositional formula representing the value of the given CTL
         * formula in this state
         */
        public FormulaNode ValueOf(FormulaNode formula)
        {
            FormulaNode result, er;

            switch (formula.GetLogicOperator())
            {
            case LogicOperator.VAR:
            case LogicOperator.EX:
                // literals and EX(...) formulas are considered positive elementary,
                // and so should correspond directly to a propositional variable
                if (formula.GetLogicOperator() == LogicOperator.VAR &&
                    formula.GetName() == FormulaNode.TRUE_LITERAL)
                {
                    return(new FormulaNode(FormulaNode.TRUE_LITERAL));
                }
                return(new FormulaNode(elementaryNames[formula]));

            case LogicOperator.AX:
                FormulaNode notBody = CTLUtils.nnfNegate(formula[0]);
                FormulaNode ex      = new FormulaNode(LogicOperator.EX, notBody, null);
                FormulaNode exValue = ValueOf(ex);
                return(new FormulaNode(LogicOperator.NOT, exValue, null));

            case LogicOperator.EU:
                result = ValueOf(new FormulaNode(LogicOperator.EX, formula, null));
                result = new FormulaNode(LogicOperator.AND, ValueOf(formula[0]), result);
                result = new FormulaNode(LogicOperator.OR, ValueOf(formula[1]), result);
                return(result);

            case LogicOperator.AU:
                er = new FormulaNode(LogicOperator.ER,
                                     CTLUtils.nnfNegate(formula[0]),
                                     CTLUtils.nnfNegate(formula[1]));
                result = ValueOf(new FormulaNode(LogicOperator.EX, er, null));
                result = new FormulaNode(LogicOperator.NOT, result, null);
                result = new FormulaNode(LogicOperator.AND, ValueOf(formula[0]), result);
                result = new FormulaNode(LogicOperator.OR, ValueOf(formula[1]), result);
                return(result);

            case LogicOperator.ER:
                result = ValueOf(new FormulaNode(LogicOperator.EX, formula, null));
                result = new FormulaNode(LogicOperator.OR, ValueOf(formula[0]), result);
                result = new FormulaNode(LogicOperator.AND, ValueOf(formula[1]), result);
                return(result);

            case LogicOperator.AR:
                er = new FormulaNode(LogicOperator.EU,
                                     CTLUtils.nnfNegate(formula[0]),
                                     CTLUtils.nnfNegate(formula[1]));
                result = ValueOf(new FormulaNode(LogicOperator.EX, er, null));
                result = new FormulaNode(LogicOperator.NOT, result, null);
                result = new FormulaNode(LogicOperator.OR, ValueOf(formula[0]), result);
                result = new FormulaNode(LogicOperator.AND, ValueOf(formula[1]), result);
                return(result);

            case LogicOperator.AND:
            case LogicOperator.OR:
                return(new FormulaNode(formula.GetLogicOperator(), ValueOf(formula[0]), ValueOf(formula[1])));

            case LogicOperator.NOT:
                FormulaNode bodyVar;
                if (formula[0].GetLogicOperator() == LogicOperator.VAR &&
                    formula[0].GetName() == FormulaNode.TRUE_LITERAL)
                {
                    bodyVar = new FormulaNode(FormulaNode.TRUE_LITERAL);
                }
                else if (!elementaryNames.ContainsKey(formula[0]))
                {
                    throw new Exception("Argument to SymbolicState.valueOf must be contained in the closure, and in NNF form.");
                }
                else
                {
                    bodyVar = new FormulaNode(elementaryNames[formula[0]]);
                }
                return(new FormulaNode(LogicOperator.NOT, bodyVar, null));

            default:
                throw new NotImplementedException();
            }
        }