23#include "absl/log/check.h"
36 for (
int i = 0;
i < 2; ++
i) {
50 for (
int i = 0;
i < 2; ++
i) {
65 const uint64_t gcd = std::gcd(
coeffs[0].value(),
coeffs[1].value());
69 return IntegerValue(gcd);
71 return IntegerValue(1);
103 const uint64_t gcd = std::gcd(
coeffs[0].value(),
coeffs[1].value());
118 for (
int i : {0, 1}) {
136 int var_index, IntegerValue expr_lb, IntegerValue other_var_lb)
const {
137 DCHECK_GE(var_index, 0);
138 DCHECK_LT(var_index, 2);
139 const IntegerValue coeff =
coeffs[var_index];
140 const IntegerVariable var =
vars[var_index];
142 const IntegerVariable other_var =
vars[1 - var_index];
143 const IntegerValue other_coeff =
coeffs[1 - var_index];
147 DCHECK_GT(other_coeff, 0);
153 DCHECK_EQ(std::gcd(other_coeff.value(), coeff.value()), 1);
168 const IntegerValue ceil_coeff_ratio =
CeilRatio(other_coeff, coeff);
169 const IntegerValue residual = coeff * ceil_coeff_ratio - other_coeff;
171 CeilRatio(expr_lb + residual * other_var_lb, coeff));
176 for (
int i = 0;
i < 2; ++
i) {
195 auto [it, inserted] = best_bounds_.insert({expr, {lb, ub}});
197 std::pair<AddResult, AddResult> result = {
200 if (negated) std::swap(result.first, result.second);
204 const auto [known_lb, known_ub] = it->second;
206 std::pair<AddResult, AddResult> result = {
212 it->second.first = lb;
218 it->second.second = ub;
220 if (negated) std::swap(result.first, result.second);
226 IntegerValue ub)
const {
232 const auto it = best_bounds_.find(expr);
233 if (it != best_bounds_.end()) {
234 const auto [known_lb, known_ub] = it->second;
241std::vector<std::pair<LinearExpression2, IntegerValue>>
243 std::vector<std::pair<LinearExpression2, IntegerValue>> root_relations_sorted;
244 root_relations_sorted.reserve(2 * best_bounds_.size());
245 for (
const auto& [expr, bounds] : best_bounds_) {
249 root_relations_sorted.push_back({negated_expr, -bounds.first});
252 root_relations_sorted.push_back({expr, bounds.second});
255 std::sort(root_relations_sorted.begin(), root_relations_sorted.end());
256 return root_relations_sorted;
259std::vector<std::tuple<LinearExpression2, IntegerValue, IntegerValue>>
261 std::vector<std::tuple<LinearExpression2, IntegerValue, IntegerValue>>
262 root_relations_sorted;
263 root_relations_sorted.reserve(best_bounds_.size());
264 for (
const auto& [expr, bounds] : best_bounds_) {
265 root_relations_sorted.push_back({expr, bounds.first, bounds.second});
267 std::sort(root_relations_sorted.begin(), root_relations_sorted.end());
268 return root_relations_sorted;
std::pair< AddResult, AddResult > Add(LinearExpression2 expr, IntegerValue lb, IntegerValue ub)
std::vector< std::tuple< LinearExpression2, IntegerValue, IntegerValue > > GetSortedNonTrivialBounds() const
std::vector< std::pair< LinearExpression2, IntegerValue > > GetSortedNonTrivialUpperBounds() const
RelationStatus GetStatus(LinearExpression2 expr, IntegerValue lb, IntegerValue ub) const
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
std::vector< IntegerVariable > NegationOf(absl::Span< const IntegerVariable > vars)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
IntegerVariable PositiveVariable(IntegerVariable i)
bool VariableIsPositive(IntegerVariable i)
bool NegateForCanonicalization()
void MakeVariablesPositive()
IntegerValue DivideByGcd()
AffineExpression GetAffineLowerBound(int var_index, IntegerValue expr_lb, IntegerValue other_var_lb) const
bool IsCanonicalized() const
bool CanonicalizeAndUpdateBounds(IntegerValue &lb, IntegerValue &ub)
void SimpleCanonicalization()