// 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)); }
// Write the given QCNF formula into a file in QDIMACS format public static void CreateQDIMACS(QBCNFormula qbcnf, string filename) { using (StreamWriter sw = File.CreateText(filename)) { // Write preamble sw.WriteLine("p cnf " + qbcnf.quantifiers.Count + " " + qbcnf.propositional.Count); // Write prefix if (qbcnf.quantifiers.Count > 0) { char lastQuant = qbcnf.quantifiers[0][0]; sw.Write(lastQuant + " " + qbcnf.quantifiers[0].Substring(1)); for (int i = 1; i < qbcnf.quantifiers.Count; i++) { if (qbcnf.quantifiers[i][0] != lastQuant) { sw.Write(" 0"); sw.WriteLine(); sw.Write(qbcnf.quantifiers[i][0] + " "); lastQuant = qbcnf.quantifiers[i][0]; } sw.Write(" " + qbcnf.quantifiers[i].Substring(1)); } sw.Write(" 0"); sw.WriteLine(); } // Write clauses foreach (ISet <string> clause in qbcnf.propositional) { foreach (string literal in clause) { sw.Write(literal + " "); } sw.Write("0"); sw.WriteLine(); } } }
// 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); }