Esempio n. 1
0
        /// <summary>
        /// Add a rule node into the appropriate chains within the graph.
        /// </summary>
        /// <remarks>
        /// The node is prepended to the watch chains for each of the two literals it
        /// watches.
        /// Assertions are skipped because they only require on a single package and
        /// have no alternative literal that could be true, so there is no need to
        /// watch changes in any literals.
        /// </remarks>
        /// <param name="node">The rule node to be inserted into the graph.</param>
        public void Add(RuleWatchNode node)
        {
            if (node.GetRule().IsAssertion)
            {
                return;
            }

            foreach (var literal in new[] { node.Watch1, node.Watch2 })
            {
                if (!watchChains.TryGetValue(literal, out LinkedList <RuleWatchNode> watchChainNode))
                {
                    watchChains[literal] = watchChainNode = new LinkedList <RuleWatchNode>();
                }

                watchChainNode.AddFirst(node);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Set propagate learn.
        /// </summary>
        /// <remarks>
        /// Add free decision (a positive literal) to decision queue
        /// increase level and propagate decision return if no conflict.
        /// in conflict case, analyze conflict rule, add resulting
        /// rule to learnt rule set, make decision from learnt
        /// rule (always unit) and re-propagate.
        /// </remarks>
        /// <returns>returns the new solver level or 0 if unsolvable.</returns>
        private int SetPropagateLearn(int level, int literal, Rule rule)
        {
            level++;

            decisions.Decide(literal, level, rule);

            while (true)
            {
                rule = Propagate(level);
                if (rule == null)
                {
                    // return if no conflict.
                    break;
                }

                if (level == 1)
                {
                    return(AnalyzeUnsolvable(rule));
                }

                // conflict
                var(learnLiteral, newLevel, newRule, why) = Analyze(level, rule);

                if (newLevel <= 0 || newLevel >= level)
                {
                    throw new SolverBugException(
                              $"Trying to revert to invalid level {newLevel} from level {level}.");
                }
                else if (newRule == null)
                {
                    throw new SolverBugException(
                              $"No rule was learned from analyzing {rule} at level {level}.");
                }

                level = newLevel;
                Revert(level);
                rules.Add(newRule, RuleType.Learned);
                learnedWhy[newRule.ObjectId] = why;
                var ruleNode = new RuleWatchNode(newRule);
                ruleNode.Watch2OnHighest(decisions);
                watchGraph.Add(ruleNode);
                decisions.Decide(learnLiteral, level, newRule);
            }

            return(level);
        }