summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2025-12-21 21:37:11 +0100
committerJulian Andres Klode <jak@debian.org>2026-01-05 21:20:24 +0000
commit6ae4194b68f04b7724e5f9d3bd19c0b52990ae4f (patch)
tree3d3e7bbd9e592ce87e89f0549583ad5f0f921883 /apt-pkg
parentbef1f303092a9b75c44bc6ac48a52e7b0c0ef9bc (diff)
solver3: Introduce a Lit type to hold literals
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/solver3.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/apt-pkg/solver3.h b/apt-pkg/solver3.h
index 45b55d962..97a833b5c 100644
--- a/apt-pkg/solver3.h
+++ b/apt-pkg/solver3.h
@@ -82,12 +82,14 @@ class Solver
enum class Decision : uint16_t;
enum class Hint : uint16_t;
struct Var;
+ struct Lit;
struct CompareProviders3;
struct State;
struct Clause;
struct Work;
struct Solved;
friend struct std::hash<APT::Solver::Var>;
+ friend struct std::hash<APT::Solver::Lit>;
// \brief Groups of works, these are ordered.
//
@@ -374,6 +376,9 @@ struct APT::Solver::Var
constexpr bool operator!=(Var const other) const { return value != other.value; }
constexpr bool operator==(Var const other) const { return value == other.value; }
+ /// \brief Negate
+ constexpr Lit operator~() const;
+
std::string toString(pkgCache &cache) const
{
if (auto P = Pkg(cache); not P.end())
@@ -385,6 +390,36 @@ struct APT::Solver::Var
};
/**
+ * \brief A literal is a variable with a sign.
+ *
+ * A literal 'A' means 'install A' whereas a literal '-A' means 'do not install A'.
+ */
+struct APT::Solver::Lit
+{
+ private:
+ friend struct std::hash<APT::Solver::Lit>;
+ // Private constructor from a number, to be used with operator~
+ explicit constexpr Lit(int32_t value) : value{value} {}
+ int32_t value;
+
+ public:
+ // SAFETY: value must be 31 bit, one bit is needed for the sign.
+ constexpr Lit(APT::Solver::Var var) : value{static_cast<int32_t>(var.value)} {}
+
+ // Accessors
+ constexpr APT::Solver::Var var() const { return APT::Solver::Var(std::abs(value)); }
+ constexpr bool sign() const { return value < 0; }
+ constexpr APT::Solver::Lit operator~() const { return Lit(-value); }
+
+ // Properties
+ constexpr bool empty() const { return value == 0; }
+ constexpr bool operator!=(Lit const other) const { return value != other.value; }
+ constexpr bool operator==(Lit const other) const { return value == other.value; }
+
+ std::string toString(pkgCache &cache) const { return (sign() ? "not " : "") + var().toString(cache); }
+};
+
+/**
* \brief A single clause
*
* A clause is a normalized, expanded dependency, translated into an implication
@@ -535,3 +570,16 @@ struct std::hash<APT::Solver::Var>
std::hash<decltype(APT::Solver::Var::value)> hash_value;
std::size_t operator()(const APT::Solver::Var &v) const noexcept { return hash_value(v.value); }
};
+
+// Custom specialization of std::hash can be injected in namespace std.
+template <>
+struct std::hash<APT::Solver::Lit>
+{
+ std::hash<decltype(APT::Solver::Lit::value)> hash_value;
+ std::size_t operator()(const APT::Solver::Lit &v) const noexcept { return hash_value(v.value); }
+};
+
+constexpr APT::Solver::Lit APT::Solver::Var::operator~() const
+{
+ return ~Lit(*this);
+}