14#ifndef ORTOOLS_SAT_PRESOLVE_UTIL_H_
15#define ORTOOLS_SAT_PRESOLVE_UTIL_H_
22#include "absl/container/flat_hash_map.h"
23#include "absl/container/flat_hash_set.h"
24#include "absl/random/bit_gen_ref.h"
25#include "absl/types/span.h"
70 absl::Span<const int> clause);
75 something_changed_.ClearAndResize(something_changed_.size());
83 Index IndexFromLiteral(
int ref)
const {
84 return Index(ref >= 0 ? 2 * ref : -2 * ref - 1);
87 std::vector<int> tmp_num_occurrences_;
91 absl::flat_hash_map<std::pair<Index, int>,
Domain> deductions_;
99 ConstraintProto* to_modify);
107 const ConstraintProto& definition, ConstraintProto* ct);
122 : index_to_position_(
i),
123 position_to_index_(pi),
124 position_to_value_(pv) {}
127 const int p = index_to_position_[index];
128 if (p < size_ && index == position_to_index_[p]) {
130 return position_to_value_[p];
134 index_to_position_[index] = size_;
135 position_to_index_[size_] = index;
136 position_to_value_[size_] = 0;
137 return position_to_value_[size_++];
142 int*
const index_to_position_;
143 int*
const position_to_index_;
144 T*
const position_to_value_;
149 index_to_position_.resize(size);
150 position_to_index_.resize(size);
151 position_to_value_.resize(size);
152 return View(index_to_position_.data(), position_to_index_.data(),
153 position_to_value_.data());
159 std::vector<int> index_to_position_;
162 std::vector<int> position_to_index_;
163 std::vector<T> position_to_value_;
206 absl::Span<
const std::pair<int, int64_t>> terms,
207 std::vector<std::array<int64_t, 2>>* conditional =
nullptr) {
208 return ComputeActivity(
false, terms, conditional);
211 absl::Span<
const std::pair<int, int64_t>> terms,
212 std::vector<std::array<int64_t, 2>>* conditional =
nullptr) {
213 return ComputeActivity(
true, terms, conditional);
225 absl::flat_hash_set<int>* literals_at_true);
233 absl::Span<
const std::pair<int, int64_t>> boolean_terms,
239 absl::Span<const int> literals);
242 bool IsAmo(absl::Span<const int> literals);
246 const Index
i = IndexFromLiteral(var);
247 const Index j = IndexFromLiteral(
NegatedRef(var));
248 return (
i < amo_indices_.size() ? amo_indices_[
i].size() : 0) +
249 (j < amo_indices_.size() ? amo_indices_[j].size() : 0);
254 Index IndexFromLiteral(
int ref)
const {
255 return Index(ref >= 0 ? 2 * ref : -2 * ref - 1);
258 bool AppearInTriggeredAmo(
int literal)
const;
260 int64_t ComputeActivity(
261 bool compute_min, absl::Span<
const std::pair<int, int64_t>> terms,
262 std::vector<std::array<int64_t, 2>>* conditional =
nullptr);
264 void PartitionIntoAmo(absl::Span<
const std::pair<int, int64_t>> terms);
268 int64_t ComputeMaxActivityInternal(
269 absl::Span<
const std::pair<int, int64_t>> terms,
270 std::vector<std::array<int64_t, 2>>* conditional =
nullptr);
274 int num_at_most_ones_ = 0;
277 std::vector<std::pair<int, int64_t>> tmp_terms_for_compute_activity_;
279 struct TermWithIndex {
284 std::vector<TermWithIndex> to_sort_;
287 VectorWithSparseUsage<int64_t> amo_sums_;
288 std::vector<int> partition_;
289 std::vector<int64_t> max_by_partition_;
290 std::vector<int64_t> second_max_by_partition_;
293 CompactVectorVector<int, int> part_to_literals_;
295 absl::flat_hash_set<int> triggered_amo_;
296 absl::flat_hash_set<int> tmp_set_;
297 std::vector<int> tmp_boolean_terms_in_some_amo_;
312 return clause_to_hash_[c] ^ literal_to_hash_[IndexFromLiteral(ref)];
320 Index IndexFromLiteral(
int ref)
const {
321 return Index(ref >= 0 ? 2 * ref : -2 * ref - 1);
324 absl::BitGenRef random_;
326 std::vector<uint64_t> clause_to_hash_;
339 absl::Span<const int> enforcement,
341 if (clause.size() != enforcement.size() + 1)
return false;
343 for (
int i = 0;
i < clause.size(); ++
i) {
344 if (clause[
i] == literal)
continue;
345 if (clause[
i] !=
NegatedRef(enforcement[j]))
return false;
353 const LinearConstraintProto& lin2,
int* var1,
354 int64_t* coeff1,
int* var2, int64_t* coeff2);
362 int64_t coeff1, coeff2;
void AddAllAtMostOnes(const CpModelProto &proto)
int64_t ComputeMaxActivity(absl::Span< const std::pair< int, int64_t > > terms, std::vector< std::array< int64_t, 2 > > *conditional=nullptr)
void AddAtMostOne(absl::Span< const int > amo)
int RemoveEnforcementThatMakesConstraintTrivial(absl::Span< const std::pair< int, int64_t > > boolean_terms, const Domain &other_terms, const Domain &rhs, ConstraintProto *ct)
int64_t ComputeMinActivity(absl::Span< const std::pair< int, int64_t > > terms, std::vector< std::array< int64_t, 2 > > *conditional=nullptr)
ActivityBoundHelper()=default
std::vector< absl::Span< const int > > PartitionLiteralsIntoAmo(absl::Span< const int > literals)
bool PresolveEnforcement(absl::Span< const int > refs, ConstraintProto *ct, absl::flat_hash_set< int > *literals_at_true)
bool IsAmo(absl::Span< const int > literals)
int NumAmoForVariable(int var) const
uint64_t HashWithout(int c, int ref) const
void RegisterClause(int c, absl::Span< const int > clause)
ClauseWithOneMissingHasher(absl::BitGenRef random)
uint64_t HashOfNegatedLiterals(absl::Span< const int > literals)
int NumDeductions() const
void MarkProcessingAsDoneForNow()
std::vector< std::pair< int, Domain > > ProcessClause(absl::Span< const int > clause)
void AddDeduction(int literal_ref, int var, Domain domain)
Domain ImpliedDomain(int literal_ref, int var) const
T & operator[](int index)
View(int *i, int *pi, T *pv)
View ClearedView(int size)
bool FindSingleLinearDifference(const LinearConstraintProto &lin1, const LinearConstraintProto &lin2, int *var1, int64_t *coeff1, int *var2, int64_t *coeff2)
bool ClauseIsEnforcementImpliesLiteral(absl::Span< const int > clause, absl::Span< const int > enforcement, int literal)
bool SubstituteVariable(int var, int64_t var_coeff_in_definition, const ConstraintProto &definition, ConstraintProto *ct)
bool AddLinearConstraintMultiple(int64_t factor, const ConstraintProto &to_add, ConstraintProto *to_modify)
bool LinearsDifferAtOneTerm(const LinearConstraintProto &lin1, const LinearConstraintProto &lin2)
#define DEFINE_STRONG_INDEX_TYPE(index_type_name)