private bool PureLiteral(Cnf cnf, Formula literal) { var negation = NegateLiteral(literal); foreach (var clause in cnf.Clauses) { foreach (var l in clause.Literals) { if (clause.LiteralEquals(l, negation)) { return(false); } } } return(true); }
private IEnumerable <Formula> PureLiterals(Cnf cnf) { var result = new List <Formula>(); foreach (var clause in cnf.Clauses) { foreach (var literal in clause.Literals) { if (PureLiteral(cnf, literal)) { result.Add(literal); } } } return(result); }
public static void Display() { Console.WriteLine(string.Empty); Console.WriteLine(" Listing 2-12: Creating Formula (p ∨ q ∨ r) ∧ (p ∨ q ∨ ¬r) ∧ (p ∨ ¬q ∨ r) ∧ (p ∨ ¬q ∨ ¬r) ∧ (¬p ∨ q ∨ r) ∧ (¬p ∨ q ∨ ¬r) ∧ (¬p ∨ ¬q ∨ r) and Finding Out If It's Satisfiable Using the DPLL Algorithm"); Console.WriteLine(string.Empty); var p = new Variable(true) { Name = "p" }; var q = new Variable(true) { Name = "q" }; var r = new Variable(true) { Name = "r" }; var f1 = new Or(p, new Or(q, r)); var f2 = new Or(p, new Or(q, new Not(r))); var f3 = new Or(p, new Or(new Not(q), r)); var f4 = new Or(p, new Or(new Not(q), new Not(r))); var f5 = new Or(new Not(p), new Or(q, r)); var f6 = new Or(new Not(p), new Or(q, new Not(r))); var f7 = new Or(new Not(p), new Or(new Not(q), r)); var formula = new And(f1, new And(f2, new And(f3, new And(f4, new And(f5, new And(f6, f7)))))); var nnf = formula.ToNnf(); Console.WriteLine("NNF: " + nnf); nnf = nnf.ToCnf(); var cnf = new Cnf(nnf as And); cnf.SimplifyCnf(); Console.WriteLine("CNF: " + cnf); Console.WriteLine("SAT: " + cnf.Dpll()); }
private Tuple <Cnf, Cnf> SplittingOnLiteral(Cnf cnf, Formula literal) { // List of clauses containing literal var @in = new List <Clause>(); // List of clauses containing Not(literal) var inNegated = new List <Clause>(); // List of clauses not containing literal nor Not(literal) var @out = new List <Clause>(); var negated = NegateLiteral(literal); foreach (var clause in cnf.Clauses) { if (clause.Contains(literal)) { @in.Add(clause); } else if (clause.Contains(negated)) { inNegated.Add(clause); } else { @out.Add(clause); } } var inCnf = new Cnf { Clauses = @in }; var outCnf = new Cnf { Clauses = @inNegated }; inCnf.Join(@out); outCnf.Join(@out); return(new Tuple <Cnf, Cnf>(inCnf, outCnf)); }
private Tuple <Cnf, int> OneLiteral(Cnf cnf) { var unitLiteral = UnitClause(cnf); if (unitLiteral == null) { return(new Tuple <Cnf, int>(cnf, 1)); } var newCnf = new Cnf(); while (unitLiteral != null) { var clausesToRemove = new List <int>(); var i = 0; // 1st Loop - Finding clauses where the // unit literal is, these clauses will not be // considered in the new Cnf foreach (var clause in cnf.Clauses) { if (clause.Literals.Any(literal => clause. LiteralEquals(literal, unitLiteral))) { clausesToRemove.Add(i); } i++; } // New Cnf after removing every clause where // unit literal is newCnf = new Cnf(); // 2nd Loop - Leave clause that do not include // the unit literal for (var j = 0; j < cnf.Clauses.Count; j++) { if (!clausesToRemove.Contains(j)) { newCnf.Clauses.Add(cnf.Clauses[j]); } } // No clauses, which implies SAT if (newCnf.Clauses.Count == 0) { return(new Tuple <Cnf, int>(newCnf, 0)); } // Remove negation of unit literal from // remaining clauses var unitNegated = NegateLiteral(unitLiteral); var clausesNoLitNeg = new List <Clause>(); foreach (var clause in newCnf.Clauses) { var newClause = new Clause(); // Leaving every literal except the unit // literal negated foreach (var literal in clause.Literals) { if (!clause.LiteralEquals(literal, unitNegated)) { newClause.Literals.Add(literal); } } clausesNoLitNeg.Add(newClause); } newCnf.Clauses = new List <Clause>(clausesNoLitNeg); // Resetting variables for next stage cnf = newCnf; unitLiteral = UnitClause(cnf); // Empty clause found if (cnf.Clauses.Any(c => c.Literals.Count == 0)) { return(new Tuple <Cnf, int>(newCnf, -1)); } } return(new Tuple <Cnf, int>(newCnf, 1)); }