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);
        }
Ejemplo n.º 3
0
        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));
        }