14#ifndef OR_TOOLS_SAT_INTEGER_BASE_H_
15#define OR_TOOLS_SAT_INTEGER_BASE_H_
28#include "absl/container/flat_hash_map.h"
29#include "absl/log/check.h"
30#include "absl/strings/str_cat.h"
31#include "absl/types/span.h"
65 std::numeric_limits<IntegerValue::ValueType>::max() - 1);
69 const double kInfinity = std::numeric_limits<double>::infinity();
72 return static_cast<double>(value.value());
75template <
class IntType>
77 return IntType(std::abs(t.value()));
81 IntegerValue positive_divisor) {
82 DCHECK_GT(positive_divisor, 0);
83 const IntegerValue result = dividend / positive_divisor;
84 const IntegerValue adjust =
85 static_cast<IntegerValue
>(result * positive_divisor < dividend);
86 return result + adjust;
90 IntegerValue positive_divisor) {
91 DCHECK_GT(positive_divisor, 0);
92 const IntegerValue result = dividend / positive_divisor;
93 const IntegerValue adjust =
94 static_cast<IntegerValue
>(result * positive_divisor > dividend);
95 return result - adjust;
100inline IntegerValue
CapProdI(IntegerValue a, IntegerValue
b) {
101 return IntegerValue(
CapProd(a.value(),
b.value()));
104inline IntegerValue
CapSubI(IntegerValue a, IntegerValue
b) {
105 return IntegerValue(
CapSub(a.value(),
b.value()));
108inline IntegerValue
CapAddI(IntegerValue a, IntegerValue
b) {
109 return IntegerValue(
CapAdd(a.value(),
b.value()));
127 IntegerValue positive_divisor) {
128 DCHECK_GT(positive_divisor, 0);
129 const IntegerValue m = dividend % positive_divisor;
130 return m < 0 ? m + positive_divisor : m;
133inline bool AddTo(IntegerValue a, IntegerValue* result) {
135 const IntegerValue add =
CapAddI(a, *result);
142inline bool AddProductTo(IntegerValue a, IntegerValue
b, IntegerValue* result) {
143 const IntegerValue prod =
CapProdI(a,
b);
145 const IntegerValue add =
CapAddI(prod, *result);
164 return IntegerVariable(
i.value() ^ 1);
168 return (
i.value() & 1) == 0;
172 return IntegerVariable(
i.value() & (~1));
178 return PositiveOnlyIndex(var.value() / 2);
182 IntegerValue coeff) {
184 return absl::StrCat(coeff.value(),
"*X", var.value() / 2);
188std::vector<IntegerVariable>
NegationOf(absl::Span<const IntegerVariable> vars);
233 ? absl::StrCat(
"I",
var.value() / 2,
">=",
bound.value())
234 : absl::StrCat(
"I",
var.value() / 2,
"<=", -
bound.value());
239 IntegerValue
bound = IntegerValue(0);
248 absl::Span<const IntegerLiteral> literals) {
257 os << literal.DebugString();
303 IntegerValue
ValueAt(IntegerValue var_value)
const {
319 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
")");
321 return absl::StrCat(
"(",
coeff.value(),
" * X",
var.value(),
" + ",
331 IntegerValue
coeff = IntegerValue(0);
338 h = H::combine(std::move(h), e.
var);
339 h = H::combine(std::move(h), e.
coeff);
341 h = H::combine(std::move(h), e.
constant);
380 bool allow_negation =
false);
393 const int first =
coeffs[0] == 0 ? 1 : 0;
394 const int last =
coeffs[1] == 0 ? 0 : 1;
395 return absl::MakeSpan(&
vars[first], last - first + 1);
399 const int first =
coeffs[0] == 0 ? 1 : 0;
400 const int last =
coeffs[1] == 0 ? 0 : 1;
401 return absl::MakeSpan(&
coeffs[first], last - first + 1);
420 os << absl::StrCat(expr.
coeffs[0],
" X", expr.
vars[0],
" + ", expr.
coeffs[1],
427 h = H::combine(std::move(h), e.
vars[0]);
428 h = H::combine(std::move(h), e.
vars[1]);
429 h = H::combine(std::move(h), e.
coeffs[0]);
430 h = H::combine(std::move(h), e.
coeffs[1]);
446 IntegerValue ub)
const;
455 absl::flat_hash_map<LinearExpression2, std::pair<IntegerValue, IntegerValue>>
495 return (a.
value <
b.value) ||
506 IntegerValue
value = IntegerValue(0);
520 IntegerValue bound) {
526 IntegerValue bound) {
549 IntegerValue bound)
const {
IntegerValue GetUpperBound(LinearExpression2 expr) const
bool Add(LinearExpression2 expr, IntegerValue lb, IntegerValue ub)
RelationStatus GetStatus(LinearExpression2 expr, IntegerValue lb, IntegerValue ub) const
Returns the known status of expr <= bound.
bool AddSquareTo(IntegerValue a, IntegerValue *result)
Computes result += a * a, and return false iff there is an overflow.
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool AddProductTo(IntegerValue a, IntegerValue b, IntegerValue *result)
Computes result += a * b, and return false iff there is an overflow.
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
bool AddTo(IntegerValue a, IntegerValue *result)
IntType IntTypeAbs(IntType t)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
bool ProdOverflow(IntegerValue t, IntegerValue value)
const LiteralIndex kNoLiteralIndex(-1)
std::string IntegerTermDebugString(IntegerVariable var, IntegerValue coeff)
std::vector< IntegerVariable > NegationOf(absl::Span< const IntegerVariable > vars)
Returns the vector of the negated variables.
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
const IntervalVariable kNoIntervalVariable(-1)
IntegerVariable PositiveVariable(IntegerVariable i)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
IntegerValue PositiveRemainder(IntegerValue dividend, IntegerValue positive_divisor)
IntegerValue CapAddI(IntegerValue a, IntegerValue b)
H AbslHashValue(H h, const IntVar &i)
– ABSL HASHING SUPPORT --------------------------------------------------—
constexpr Fractional kInfinity
Infinity for type Fractional.
PositiveOnlyIndex GetPositiveOnlyIndex(IntegerVariable var)
bool VariableIsPositive(IntegerVariable i)
IntegerValue CapSubI(IntegerValue a, IntegerValue b)
bool AtMinOrMaxInt64I(IntegerValue t)
IntegerValue CapProdI(IntegerValue a, IntegerValue b)
Overflows and saturated arithmetic.
double ToDouble(IntegerValue value)
In SWIG mode, we don't want anything besides these top-level includes.
bool AtMinOrMaxInt64(int64_t x)
Checks if x is equal to the min or the max value of an int64_t.
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapSub(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
#define DEFINE_STRONG_INT64_TYPE(integer_type_name)
#define DEFINE_STRONG_INDEX_TYPE(index_type_name)
IntegerLiteral GreaterOrEqual(IntegerValue bound) const
var * coeff + constant >= bound.
bool operator==(AffineExpression o) const
AffineExpression MultipliedBy(IntegerValue multiplier) const
AffineExpression Negated() const
AffineExpression(IntegerVariable v, IntegerValue c, IntegerValue cst)
AffineExpression()=default
Helper to construct an AffineExpression.
IntegerValue ValueAt(IntegerValue var_value) const
Returns the value of this affine expression given its variable value.
AffineExpression(IntegerVariable v, IntegerValue c)
double LpValue(const util_intops::StrongVector< IntegerVariable, double > &lp_values) const
Returns the affine expression value under a given LP solution.
AffineExpression(IntegerValue cst)
AffineExpression(IntegerVariable v)
std::string DebugString() const
IntegerLiteral LowerOrEqual(IntegerValue bound) const
var * coeff + constant <= bound.
std::vector< int64_t > proto_values
util_intops::StrongVector< IntegerVariable, bool > ivar_has_value
util_intops::StrongVector< IntegerVariable, IntegerValue > ivar_values
bool operator==(IntegerLiteral o) const
bool IsAlwaysFalse() const
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
static IntegerLiteral TrueLiteral()
IntegerLiteral Negated() const
The negation of x >= bound is x <= bound - 1.
std::string DebugString() const
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
bool IsAlwaysTrue() const
static IntegerLiteral FalseLiteral()
IntegerLiteral(IntegerVariable v, IntegerValue b)
bool operator!=(IntegerLiteral o) const
IntegerLiteral()
Clients should prefer the static construction methods above.
std::vector< std::function< bool()> > callbacks
bool operator==(const LinearExpression2 &o) const
bool operator<(const LinearExpression2 &o) const
LinearExpression2(IntegerVariable v1, IntegerVariable v2, IntegerValue c1, IntegerValue c2)
absl::Span< const IntegerValue > non_zero_coeffs() const
bool NegateForCanonicalization()
absl::Span< const IntegerVariable > non_zero_vars() const
LinearExpression2()=default
void CanonicalizeAndUpdateBounds(IntegerValue &lb, IntegerValue &ub, bool allow_negation=false)
static LinearExpression2 Difference(IntegerVariable v1, IntegerVariable v2)
Build (v1 - v2)
IntegerValue DivideByGcd()
void Negate()
Take the negation of this expression.
void SimpleCanonicalization()
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
bool operator()(const ValueLiteralPair &a, const ValueLiteralPair &b) const
std::string DebugString() const
bool operator==(const ValueLiteralPair &o) const