summaryrefslogtreecommitdiff
path: root/apt-pkg/solver3.cc
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2025-12-21 22:56:13 +0100
committerJulian Andres Klode <jak@debian.org>2026-01-05 21:20:24 +0000
commit982b94ba9d7615d2b5a6420411c3d41356fdf19a (patch)
treef1c4a6edba5104bbe1536a449100023f5cfa6923 /apt-pkg/solver3.cc
parent1700acb919ce9c495db4dce4003f73751cc9c1f2 (diff)
solver3: Implement value(Lit) and use it
Diffstat (limited to 'apt-pkg/solver3.cc')
-rw-r--r--apt-pkg/solver3.cc41
1 files changed, 23 insertions, 18 deletions
diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc
index 1b3852520..0779d2c7d 100644
--- a/apt-pkg/solver3.cc
+++ b/apt-pkg/solver3.cc
@@ -299,21 +299,26 @@ inline APT::Solver::Var APT::Solver::bestReason(APT::Solver::Clause const *claus
if (clause->reason == var)
for (auto choice : clause->solutions)
{
- if (clause->negative && (*this)[choice].decision == Decision::MUST)
+ if (clause->negative && value(choice) == Decision::MUST)
return choice;
- if (not clause->negative && (*this)[choice].decision == Decision::MUSTNOT)
+ if (not clause->negative && value(choice) == Decision::MUSTNOT)
return choice;
}
return clause->reason;
}
+inline APT::Solver::Decision APT::Solver::value(Lit lit) const
+{
+ return lit.sign() ? ~(*this)[lit.var()].decision : (*this)[lit.var()].decision;
+}
+
// Prints an implication graph part of the form A -> B -> C, possibly with "not"
std::string APT::Solver::WhyStr(Var reason) const
{
std::vector<std::string> out;
while (not reason.empty())
{
- if ((*this)[reason].decision == Decision::MUSTNOT)
+ if (value(reason) == Decision::MUSTNOT)
out.push_back(std::string("not ") + reason.toString(cache));
else
out.push_back(reason.toString(cache));
@@ -362,10 +367,10 @@ std::string APT::Solver::LongWhyStr(Var var, bool decision, const Clause *rclaus
if (choice == skip)
continue;
- if ((*this)[choice].decision == Decision::NONE)
+ if (value(choice) == Decision::NONE)
out << prefix << "- " << choice.toString(cache) << " is undecided\n";
else
- out << prefix << "- " << LongWhyStr(choice, (*this)[choice].decision == Decision::MUST, (*this)[choice].reason, prefix + " ", seen).substr(prefix.size() + 2);
+ out << prefix << "- " << LongWhyStr(choice, value(choice) == Decision::MUST, (*this)[choice].reason, prefix + " ", seen).substr(prefix.size() + 2);
}
};
@@ -386,7 +391,7 @@ std::string APT::Solver::LongWhyStr(Var var, bool decision, const Clause *rclaus
// We could be called with a decision we tried to make but failed due to a conflict;
// this checks if it is the real decision.
- if ((*this)[var].decision != Decision::NONE && decision == ((*this)[var].decision == Decision::MUST) && (*this)[var].reason == rclause)
+ if (value(var) != Decision::NONE && decision == (value(var) == Decision::MUST) && (*this)[var].reason == rclause)
{
// If we have seen the real decision before; we dont't need to print it again.
if (seen.find(var) != seen.end())
@@ -602,7 +607,7 @@ bool APT::Solver::Propagate()
{
Var var = propQ.front();
propQ.pop();
- if ((*this)[var].decision == Decision::MUST)
+ if (value(var) == Decision::MUST)
{
Discover(var);
for (auto &clause : (*this)[var].clauses)
@@ -618,19 +623,19 @@ bool APT::Solver::Propagate()
return false;
}
}
- else if ((*this)[var].decision == Decision::MUSTNOT)
+ else if (value(var) == Decision::MUSTNOT)
{
for (auto rclause : (*this)[var].rclauses)
{
if (rclause->negative || rclause->reason.empty())
continue;
- if ((*this)[rclause->reason].decision == Decision::MUSTNOT)
+ if (value(rclause->reason) == Decision::MUSTNOT)
continue;
auto count = std::count_if(rclause->solutions.begin(), rclause->solutions.end(), [this](auto var)
- { return (*this)[var].decision != Decision::MUSTNOT; });
+ { return value(var) != Decision::MUSTNOT; });
- if (count == 1 && (*this)[rclause->reason].decision == Decision::MUST)
+ if (count == 1 && value(rclause->reason) == Decision::MUST)
{
if (unlikely(debug >= 3))
std::cerr << "Propagate NOT " << var.toString(cache) << " to unit clause " << rclause->toString(cache);
@@ -644,7 +649,7 @@ bool APT::Solver::Propagate()
{
// Find the variable that must be chosen and enqueue it as a fact
for (auto sol : rclause->solutions)
- if ((*this)[sol].decision == Decision::NONE && not Enqueue(sol, rclause))
+ if (value(sol) == Decision::NONE && not Enqueue(sol, rclause))
return false;
}
continue;
@@ -815,7 +820,7 @@ void APT::Solver::Discover(Var var)
// Recursively discover everything else that is not already FALSE by fact (MUSTNOT at depth 0)
for (auto const &clause : state.clauses)
for (auto const &var : clause->solutions)
- if ((*this)[var].decision != Decision::MUSTNOT || (*this)[var].depth > 0)
+ if (value(var) != Decision::MUSTNOT || (*this)[var].depth > 0)
discoverQ.push(var);
}
}
@@ -1097,7 +1102,7 @@ bool APT::Solver::AddWork(Work &&w)
return Enqueue(w.clause->solutions[0], w.clause);
w.size = std::count_if(w.clause->solutions.begin(), w.clause->solutions.end(), [this](auto V)
- { return (*this)[V].decision != Decision::MUSTNOT; });
+ { return value(V) != Decision::MUSTNOT; });
work.push_back(std::move(w));
std::push_heap(work.begin(), work.end());
}
@@ -1134,7 +1139,7 @@ bool APT::Solver::Solve()
solved.push_back(Solved{Var(), item});
if (std::any_of(item.clause->solutions.begin(), item.clause->solutions.end(), [this](auto ver)
- { return (*this)[ver].decision == Decision::MUST; }))
+ { return value(ver) == Decision::MUST; }))
{
if (unlikely(debug >= 2))
std::cerr << "ELIDED " << item.toString(cache) << std::endl;
@@ -1147,7 +1152,7 @@ bool APT::Solver::Solve()
bool foundSolution = false;
for (auto &sol : item.clause->solutions)
{
- if ((*this)[sol].decision == Decision::MUSTNOT)
+ if (value(sol) == Decision::MUSTNOT)
{
if (unlikely(debug >= 3))
std::cerr << "(existing conflict: " << sol.toString(cache) << ")\n";
@@ -1322,11 +1327,11 @@ bool APT::Solver::ToDepCache(pkgDepCache &depcache) const
{
depcache[P].Marked = 0;
depcache[P].Garbage = 0;
- if ((*this)[P].decision == Decision::MUST)
+ if (value(Var(P)) == Decision::MUST)
{
pkgCache::VerIterator cand;
for (auto V = P.VersionList(); cand.end() && not V.end(); V++)
- if ((*this)[V].decision == Decision::MUST)
+ if (value(Var(V)) == Decision::MUST)
cand = V;
auto reasonClause = (*this)[cand].reason;