Exemple #1
0
        /// <summary>
        /// Gets all pure literals from Cnf
        /// </summary>
        /// <param name="cnf"></param>
        /// <returns>Returns a list containing all pure literals of Cnf</returns>
        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);
        }
Exemple #2
0
        /// <summary>
        /// Determines whether a given literal is pure
        /// </summary>
        /// <param name="cnf"></param>
        /// <param name="literal"></param>
        /// <returns>True is literal is pure; false otherwise</returns>
        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);
        }
Exemple #3
0
        /// <summary>
        /// Splits the Cnf on a given literal
        /// </summary>
        /// <param name="cnf"></param>
        /// <param name="literal"></param>
        /// <returns>A tuple of Cnfs one for the left branch another for the right branch</returns>
        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));
        }
Exemple #4
0
        /// <summary>
        /// Applies the one literal rule i.e. finds all literals that are the single member of their clause.
        /// </summary>
        /// <param name="cnf"></param>
        /// <returns>Returns a tuple with the resulting Cnf after having removed clauses containing one literals or their negations and an integer which can be 0 (no clauses), 1 (continue dpll), -1 (empty clause)</returns>
        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;

                // Finding clauses where the unit literal is, these clauses will be deleted
                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();

                // Leave clausules 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));
        }