Example #1
0
        /// <summary>
        /// Propagates a decision on a literal to all rules watching the literal.
        /// </summary>
        /// <remarks>
        /// If a decision, e.g. +A has been made, then all rules containing -A, e.g.
        /// (-A|+B|+C) now need to satisfy at least one of the other literals, so
        /// that the rule as a whole becomes true, since with +A applied the rule
        /// is now (false|+B|+C) so essentially (+B|+C).
        /// This means that all rules watching the literal -A need to be updated to
        /// watch 2 other literals which can still be satisfied instead. So literals
        /// that conflict with previously made decisions are not an option.
        /// Alternatively it can occur that a unit clause results: e.g. if in the
        /// above example the rule was (-A|+B), then A turning true means that
        /// B must now be decided true as well.
        /// </remarks>
        /// <param name="decidedLiteral">The literal which was decided.</param>
        /// <param name="level">The level at which the decision took place and at which all resulting decisions should be made.</param>
        /// <param name="decisions">Used to check previous decisions and to register decisions resulting from propagation.</param>
        /// <returns>If a conflict is found the conflicting rule is returned.</returns>
        public Rule PropagateLiteral(int decidedLiteral, int level, Decisions decisions)
        {
            // we invert the decided literal here, example:
            // A was decided => (-A|B) now requires B to be true, so we look for
            // rules which are fulfilled by -A, rather than A.
            // This means finding out the conflicts or requires.
            var literal = -decidedLiteral;

            if (!watchChains.TryGetValue(literal, out LinkedList <RuleWatchNode> chain))
            {
                return(null);
            }

            foreach (var node in chain.ToArray())
            {
                var otherWatch = node.GetOtherWatch(literal);
                if (!node.GetRule().Enable || decisions.IsSatisfy(otherWatch))
                {
                    continue;
                }

                var ruleLiterals        = node.GetRule().GetLiterals();
                var alternativeLiterals = Arr.Filter(ruleLiterals, (ruleLiteral) =>
                {
                    // Guaranteed selection decision is not at the same time
                    // as Watch1 and Watch2, guaranteeing no conflict.
                    return(literal != ruleLiteral && otherWatch != ruleLiteral && !decisions.IsConflict(ruleLiteral));
                });

                if (alternativeLiterals.Length > 0)
                {
                    var toLiteral = alternativeLiterals[0];

                    if (!watchChains.TryGetValue(toLiteral, out LinkedList <RuleWatchNode> toChain))
                    {
                        watchChains[toLiteral] = toChain = new LinkedList <RuleWatchNode>();
                    }

                    node.MoveWatch(literal, toLiteral);
                    chain.Remove(node);
                    toChain.AddFirst(node);
                    continue;
                }

                if (decisions.IsConflict(otherWatch))
                {
                    return(node.GetRule());
                }

                decisions.Decide(otherWatch, level, node.GetRule());
            }

            return(null);
        }
Example #2
0
        /// <summary>
        /// Resolve the requires of the requested.
        /// </summary>
        /// <param name="request">The request instance.</param>
        /// <param name="ignorePlantform">Whether is ignore plantform check.</param>
        /// <returns>An array of operation.</returns>
        public IOperation[] Solve(Request request, bool ignorePlantform = false)
        {
            jobs = request.GetJobs();

            SetupInstalledMap();
            rules = ruleSetGenerator.GetRulesFor(jobs, installedMap, ignorePlantform);
            CheckForRootRequiresProblems(ignorePlantform);

            decisions  = new Decisions(pool);
            watchGraph = new RuleWatchGraph();
            learnedWhy.Clear();
            learnedPool.Clear();
            branches.Clear();

            foreach (var rule in rules)
            {
                watchGraph.Add(rule);
            }

            SetupAssertionRuleDecisions();

            io.WriteError("Resolving requires through SAT", true, Verbosities.Debug);
            stopwatch.Restart();
            stopwatch.Start();

            RunSAT();

            io.WriteError(string.Empty, true, Verbosities.Debug);
            io.WriteError($"Dependency resolution completed in {stopwatch.Elapsed.TotalSeconds.ToString("0.00")} seconds", true, Verbosities.Debug);

            // If we don't make a decision about the packages we have
            // installed, then we think these packages will be uninstall.
            foreach (var item in installedMap)
            {
                var packageId = item.Key;
                if (decisions.IsUndecided(packageId))
                {
                    decisions.Decide(-packageId, 1, null);
                }
            }

            if (problems.Count > 0)
            {
                throw new SolverProblemsException(problems, installedMap);
            }

            var transaction = new Transaction(policy, pool, installedMap, decisions);

            return(transaction.GetOperations());
        }
 // can be used as interface to update all decision at once
 public void UpdateDecisions(uint frameCount = 3600)
 {
     // we assume 3600 is enough for all frame intervals
     decisions_.Decide(frameCount);
     decisions_.ExecuteDecision(frameCount);
 }
Example #4
0
 public void TestDecide()
 {
     Assert.AreEqual(0, decisions.Count);
     decisions.Decide(1, 1, defaultRule);
     Assert.AreEqual(1, decisions.Count);
     Assert.IsTrue(decisions.IsDecided(1));
 }