Пример #1
0
        private void UnitPropagation(TrailNode node, out Conflict conflict)
        {
            conflict = null;

            foreach (var clause in ClauseReferences[node.Literal.index])
            {
                if (TryPropagate(node, clause, out bool error) is Literal empty)
                {
                    AssignLiteral(empty);
                    var newNode = new TrailNode(level, empty, clause);
                    trail.Add(newNode);
                    UnitPropagation(newNode, out conflict);
                    if (conflict != null)
                    {
                        return;
                    }
                }

                if (error)
                {
                    var learnedClause = trail.GetUIP(clause, out int targetLevel);
                    conflict = new Conflict(targetLevel, learnedClause);
                    return;
                }
            }
        }
Пример #2
0
        private TrailNode Backtrack()
        {
            var conflict = latestConflict;

            latestConflict = null;
            AddClause(conflict.Clause);
            RevertToLevel(conflict.Level);
            ApplyVSIDS(conflict.Clause);

            var empty = FindEmpty(conflict.Clause);

            if (debug)
            {
                Console.WriteLine($"Revert to level {level} | Learned: {conflict.Clause} | Empty: {string.Join(" ", empty)}");
                StateDebug();
            }

            if (empty.Count == 1)
            {
                AssignLiteral(empty[0]);
                var node = new TrailNode(level, empty[0], conflict.Clause);
                trail.Add(node);
                return(node);
            }
            else
            {
                return(Decision());
            }
        }
Пример #3
0
        private TrailNode Decision(Literal?force = null)
        {
            level++;
            Literal literal = force ?? SelectLiteral();

            AssignLiteral(literal);
            var node = new TrailNode(level, literal);

            trail.Add(node);
            return(node);
        }
Пример #4
0
        private Literal?TryPropagate(TrailNode node, Clause clause, out bool conflict)
        {
            int     assignedValues = 0;
            int     falseValues    = 0;
            Literal empty          = default;

            conflict = false;

            foreach (var lit in clause)
            {
                if (literals[lit.index].HasValue)
                {
                    if (literals[lit.index].Value.value != lit.value)
                    {
                        falseValues++;
                    }
                    assignedValues++;
                }
                else
                {
                    empty = lit;
                }
            }

            if (assignedValues != falseValues)
            {
                return(null);
            }

            if (assignedValues == clause.Count - 1)
            {
                return(empty);
            }

            if (falseValues == clause.Count)
            {
                conflict = true;
                return(null);
            }

            return(null);
        }
Пример #5
0
        private void InitialUnitPropagation(out Conflict conflict)
        {
            conflict = null;
            foreach (var clause in Clauses)
            {
                if (clause.Count == 1)
                {
                    Literal literal = clause[0];

                    if (!literals[literal.index].HasValue)
                    {
                        AssignLiteral(literal);
                        var node = new TrailNode(level, literal, clause);
                        trail.Add(node);
                        UnitPropagation(node, out conflict);
                        if (conflict != null)
                        {
                            return;
                        }
                    }
                }
            }
        }
Пример #6
0
        public override SolverResult Run()
        {
            if (Running)
            {
                throw new InvalidOperationException("Solver is already running");
            }
            Running    = true;
            totalwatch = Stopwatch.StartNew();

            InitialUnitPropagation(out Conflict conflict);

            if (conflict != null)
            {
                Running = false;
                return(SolverResult.Fail(0));
            }

            if (AllAssigned)
            {
                Running = false;
                return(SolverResult.Success(0, literals));
            }

            if (debug)
            {
                Console.WriteLine();
            }
            while (true)
            {
                if (debug && latestConflict != null)
                {
                    Console.WriteLine("- Conflict");
                    Console.WriteLine(trail.DebugMessage);
                }

                iterations++;
                TrailNode node = Travel();
                UnitPropagation(node, out conflict);

                if (debug)
                {
                    StateDebug();
                }

                if (conflict == null && AllAssigned)
                {
                    Running = false;
                    return(SolverResult.Success(iterations, literals));
                }

                if (conflict != null && level == 0)
                {
                    Running = false;
                    return(SolverResult.Fail(iterations));
                }

                if (conflict != null)
                {
                    latestConflict = conflict;
                }

                if (timeout != 0 && totalwatch.ElapsedMilliseconds > timeout)
                {
                    Running = false;
                    return(SolverResult.Timeout(iterations, (int)totalwatch.ElapsedMilliseconds));
                }
            }
        }