18#include "absl/container/flat_hash_map.h"
19#include "absl/container/flat_hash_set.h"
20#include "absl/log/check.h"
21#include "absl/strings/str_format.h"
22#include "absl/strings/str_join.h"
23#include "absl/strings/string_view.h"
54 if (bits_.
Value() == 0) {
65 bits_(new uint64_t[length_]),
66 stamps_(new uint64_t[length_]) {
68 memset(bits_, 0,
sizeof(*bits_) * length_);
69 memset(stamps_, 0,
sizeof(*stamps_) * length_);
77void RevBitSet::Save(
Solver*
const solver,
int offset) {
78 const uint64_t current_stamp = solver->
stamp();
79 if (current_stamp > stamps_[offset]) {
80 stamps_[offset] = current_stamp;
87 DCHECK_LT(
index, size_);
90 if (!(bits_[offset] &
OneBit64(pos))) {
98 DCHECK_LT(
index, size_);
101 if (bits_[offset] &
OneBit64(pos)) {
102 Save(solver, offset);
103 bits_[offset] &= ~OneBit64(pos);
109 DCHECK_LT(
index, size_);
115 for (
int i = 0; i < length_; ++i) {
122 for (
int i = 0; i < length_; ++i) {
131 bool found_one =
false;
132 for (
int i = 0; i < length_; ++i) {
133 const uint64_t partial = bits_[i];
135 if (!(partial & (partial - 1))) {
153 for (
int offset = 0; offset < length_; ++offset) {
155 Save(solver, offset);
156 bits_[offset] = uint64_t{0};
164 :
RevBitSet(rows * columns), rows_(rows), columns_(columns) {
166 DCHECK_GE(columns, 1);
173 DCHECK_LT(
row, rows_);
175 DCHECK_LT(
column, columns_);
182 DCHECK_LT(
row, rows_);
184 DCHECK_LT(
column, columns_);
190 DCHECK_LT(
row, rows_);
208 DCHECK_LT(
row, rows_);
209 DCHECK_LT(
start, columns_);
210 const int beginning =
row * columns_;
211 const int end = beginning + columns_ - 1;
214 if (position == -1) {
217 return position - beginning;
228 : bit_size_(bit_size),
230 bits_(word_size_, 0),
231 active_words_(word_size_) {}
234 const std::vector<uint64_t>& mask) {
235 CHECK_LE(mask.size(), word_size_);
236 for (
int i = 0; i < mask.size(); ++i) {
239 active_words_.
Insert(solver, i);
245 const std::vector<uint64_t>& mask) {
246 bool changed =
false;
248 for (
int index : active_words_) {
251 const uint64_t result = bits_[
index] & ~mask[
index];
254 to_remove_.push_back(
index);
259 CleanUpActives(solver);
263void UnsortedNullableRevBitset::CleanUpActives(
Solver*
const solver) {
266 for (
int i = to_remove_.size() - 1; i >= 0; --i) {
267 active_words_.
Remove(solver, to_remove_[i]);
272 const std::vector<uint64_t>& mask) {
273 bool changed =
false;
275 for (
int index : active_words_) {
276 if (
index < mask.size()) {
279 const uint64_t result = bits_[
index] & mask[
index];
282 to_remove_.push_back(
index);
289 to_remove_.push_back(
index);
292 CleanUpActives(solver);
297 int* support_index) {
298 DCHECK_GE(*support_index, 0);
299 DCHECK_LT(*support_index, word_size_);
300 if (mask[*support_index] & bits_[*support_index]) {
303 for (
int index : active_words_) {
305 *support_index =
index;
317 PrintModelVisitor() : indent_(0) {}
318 ~PrintModelVisitor()
override {}
321 void BeginVisitModel(
const std::string& solver_name)
override {
322 LOG(INFO) <<
"Model " << solver_name <<
" {";
326 void EndVisitModel(
const std::string& solver_name)
override {
329 CHECK_EQ(0, indent_);
332 void BeginVisitConstraint(
const std::string& type_name,
333 const Constraint*
const constraint)
override {
334 LOG(INFO) << Spaces() << type_name;
338 void EndVisitConstraint(
const std::string& type_name,
339 const Constraint*
const constraint)
override {
343 void BeginVisitIntegerExpression(
const std::string& type_name,
344 const IntExpr*
const expr)
override {
345 LOG(INFO) << Spaces() << type_name;
349 void EndVisitIntegerExpression(
const std::string& type_name,
350 const IntExpr*
const expr)
override {
354 void BeginVisitExtension(
const std::string& type_name)
override {
355 LOG(INFO) << Spaces() << type_name;
359 void EndVisitExtension(
const std::string& type_name)
override { Decrease(); }
361 void VisitIntegerVariable(
const IntVar*
const variable,
362 IntExpr*
const delegate)
override {
363 if (delegate !=
nullptr) {
364 delegate->Accept(
this);
366 if (variable->Bound() && variable->name().empty()) {
367 LOG(INFO) << Spaces() << variable->Min();
369 LOG(INFO) << Spaces() << variable->DebugString();
374 void VisitIntegerVariable(
const IntVar*
const variable,
375 const std::string& operation, int64_t
value,
376 IntVar*
const delegate)
override {
377 LOG(INFO) << Spaces() <<
"IntVar";
379 LOG(INFO) << Spaces() <<
value;
380 LOG(INFO) << Spaces() << operation;
381 delegate->Accept(
this);
385 void VisitIntervalVariable(
const IntervalVar*
const variable,
386 const std::string& operation, int64_t
value,
387 IntervalVar*
const delegate)
override {
388 if (delegate !=
nullptr) {
389 LOG(INFO) << Spaces() << operation <<
" <" <<
value <<
", ";
391 delegate->Accept(
this);
393 LOG(INFO) << Spaces() <<
">";
395 LOG(INFO) << Spaces() << variable->DebugString();
399 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
400 LOG(INFO) << Spaces() << sequence->DebugString();
404 void VisitIntegerArgument(
const std::string& arg_name,
405 int64_t
value)
override {
406 LOG(INFO) << Spaces() << arg_name <<
": " <<
value;
409 void VisitIntegerArrayArgument(
const std::string& arg_name,
410 const std::vector<int64_t>& values)
override {
411 LOG(INFO) << Spaces() << arg_name <<
": [" << absl::StrJoin(values,
", ")
415 void VisitIntegerMatrixArgument(
const std::string& arg_name,
416 const IntTupleSet& values)
override {
417 const int rows = values.NumTuples();
418 const int columns = values.Arity();
419 std::string array =
"[";
420 for (
int i = 0;
i < rows; ++
i) {
425 for (
int j = 0; j < columns; ++j) {
429 absl::StrAppendFormat(&array,
"%d", values.Value(i, j));
434 LOG(INFO) << Spaces() << arg_name <<
": " << array;
437 void VisitIntegerExpressionArgument(
const std::string& arg_name,
438 IntExpr*
const argument)
override {
439 set_prefix(absl::StrFormat(
"%s: ", arg_name));
441 argument->Accept(
this);
445 void VisitIntegerVariableArrayArgument(
446 const std::string& arg_name,
447 const std::vector<IntVar*>& arguments)
override {
448 LOG(INFO) << Spaces() << arg_name <<
": [";
450 for (
int i = 0;
i < arguments.size(); ++
i) {
451 arguments[
i]->Accept(
this);
454 LOG(INFO) << Spaces() <<
"]";
458 void VisitIntervalArgument(
const std::string& arg_name,
459 IntervalVar*
const argument)
override {
460 set_prefix(absl::StrFormat(
"%s: ", arg_name));
462 argument->Accept(
this);
466 virtual void VisitIntervalArgumentArray(
467 const std::string& arg_name,
const std::vector<IntervalVar*>& arguments) {
468 LOG(INFO) << Spaces() << arg_name <<
": [";
470 for (
int i = 0;
i < arguments.size(); ++
i) {
471 arguments[
i]->Accept(
this);
474 LOG(INFO) << Spaces() <<
"]";
478 void VisitSequenceArgument(
const std::string& arg_name,
479 SequenceVar*
const argument)
override {
480 set_prefix(absl::StrFormat(
"%s: ", arg_name));
482 argument->Accept(
this);
486 virtual void VisitSequenceArgumentArray(
487 const std::string& arg_name,
const std::vector<SequenceVar*>& arguments) {
488 LOG(INFO) << Spaces() << arg_name <<
": [";
490 for (
int i = 0;
i < arguments.size(); ++
i) {
491 arguments[
i]->Accept(
this);
494 LOG(INFO) << Spaces() <<
"]";
497 std::string DebugString()
const override {
return "PrintModelVisitor"; }
500 void Increase() { indent_ += 2; }
502 void Decrease() { indent_ -= 2; }
504 std::string Spaces() {
506 for (
int i = 0;
i < indent_ - 2 * (!prefix_.empty()); ++
i) {
509 if (!prefix_.empty()) {
510 result.append(prefix_);
516 void set_prefix(absl::string_view prefix) { prefix_ = prefix; }
524class ModelStatisticsVisitor :
public ModelVisitor {
526 ModelStatisticsVisitor()
527 : num_constraints_(0),
533 num_extensions_(0) {}
535 ~ModelStatisticsVisitor()
override {}
538 void BeginVisitModel(
const std::string& solver_name)
override {
540 num_constraints_ = 0;
542 num_expressions_ = 0;
547 already_visited_.clear();
548 constraint_types_.clear();
549 expression_types_.clear();
550 extension_types_.clear();
553 void EndVisitModel(
const std::string& solver_name)
override {
555 LOG(INFO) <<
"Model has:";
556 LOG(INFO) <<
" - " << num_constraints_ <<
" constraints.";
557 for (
const auto& it : constraint_types_) {
558 LOG(INFO) <<
" * " << it.second <<
" " << it.first;
560 LOG(INFO) <<
" - " << num_variables_ <<
" integer variables.";
561 LOG(INFO) <<
" - " << num_expressions_ <<
" integer expressions.";
562 for (
const auto& it : expression_types_) {
563 LOG(INFO) <<
" * " << it.second <<
" " << it.first;
565 LOG(INFO) <<
" - " << num_casts_ <<
" expressions casted into variables.";
566 LOG(INFO) <<
" - " << num_intervals_ <<
" interval variables.";
567 LOG(INFO) <<
" - " << num_sequences_ <<
" sequence variables.";
568 LOG(INFO) <<
" - " << num_extensions_ <<
" model extensions.";
569 for (
const auto& it : extension_types_) {
570 LOG(INFO) <<
" * " << it.second <<
" " << it.first;
574 void BeginVisitConstraint(
const std::string& type_name,
575 const Constraint*
const constraint)
override {
577 AddConstraintType(type_name);
580 void BeginVisitIntegerExpression(
const std::string& type_name,
581 const IntExpr*
const expr)
override {
582 AddExpressionType(type_name);
586 void BeginVisitExtension(
const std::string& type_name)
override {
587 AddExtensionType(type_name);
591 void VisitIntegerVariable(
const IntVar*
const variable,
592 IntExpr*
const delegate)
override {
597 VisitSubArgument(delegate);
601 void VisitIntegerVariable(
const IntVar*
const variable,
602 const std::string& operation, int64_t
value,
603 IntVar*
const delegate)
override {
607 VisitSubArgument(delegate);
610 void VisitIntervalVariable(
const IntervalVar*
const variable,
611 const std::string& operation, int64_t
value,
612 IntervalVar*
const delegate)
override {
615 VisitSubArgument(delegate);
619 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
621 for (
int i = 0;
i < sequence->size(); ++
i) {
622 VisitSubArgument(sequence->Interval(i));
627 void VisitIntegerExpressionArgument(
const std::string& arg_name,
628 IntExpr*
const argument)
override {
629 VisitSubArgument(argument);
632 void VisitIntegerVariableArrayArgument(
633 const std::string& arg_name,
634 const std::vector<IntVar*>& arguments)
override {
635 for (
int i = 0;
i < arguments.size(); ++
i) {
636 VisitSubArgument(arguments[i]);
641 void VisitIntervalArgument(
const std::string& arg_name,
642 IntervalVar*
const argument)
override {
643 VisitSubArgument(argument);
646 void VisitIntervalArrayArgument(
647 const std::string& arg_name,
648 const std::vector<IntervalVar*>& arguments)
override {
649 for (
int i = 0;
i < arguments.size(); ++
i) {
650 VisitSubArgument(arguments[i]);
655 void VisitSequenceArgument(
const std::string& arg_name,
656 SequenceVar*
const argument)
override {
657 VisitSubArgument(argument);
660 void VisitSequenceArrayArgument(
661 const std::string& arg_name,
662 const std::vector<SequenceVar*>& arguments)
override {
663 for (
int i = 0;
i < arguments.size(); ++
i) {
664 VisitSubArgument(arguments[i]);
668 std::string DebugString()
const override {
return "ModelStatisticsVisitor"; }
671 void Register(
const BaseObject*
const object) {
672 already_visited_.insert(
object);
675 bool AlreadyVisited(
const BaseObject*
const object) {
676 return already_visited_.contains(
object);
680 template <
typename T>
681 void VisitSubArgument(T*
object) {
682 if (!AlreadyVisited(
object)) {
684 object->Accept(
this);
688 void AddConstraintType(absl::string_view constraint_type) {
689 constraint_types_[constraint_type]++;
692 void AddExpressionType(absl::string_view expression_type) {
693 expression_types_[expression_type]++;
696 void AddExtensionType(absl::string_view extension_type) {
697 extension_types_[extension_type]++;
700 absl::flat_hash_map<std::string, int> constraint_types_;
701 absl::flat_hash_map<std::string, int> expression_types_;
702 absl::flat_hash_map<std::string, int> extension_types_;
703 int num_constraints_;
705 int num_expressions_;
710 absl::flat_hash_set<const BaseObject*> already_visited_;
715class VariableDegreeVisitor :
public ModelVisitor {
717 explicit VariableDegreeVisitor(
718 absl::flat_hash_map<const IntVar*, int>*
const map)
721 ~VariableDegreeVisitor()
override {}
724 void VisitIntegerVariable(
const IntVar*
const variable,
725 IntExpr*
const delegate)
override {
726 IntVar*
const var =
const_cast<IntVar*
>(variable);
727 if (map_->contains(
var)) {
731 VisitSubArgument(delegate);
735 void VisitIntegerVariable(
const IntVar*
const variable,
736 const std::string& operation, int64_t
value,
737 IntVar*
const delegate)
override {
738 IntVar*
const var =
const_cast<IntVar*
>(variable);
739 if (map_->contains(
var)) {
742 VisitSubArgument(delegate);
745 void VisitIntervalVariable(
const IntervalVar*
const variable,
746 const std::string& operation, int64_t
value,
747 IntervalVar*
const delegate)
override {
749 VisitSubArgument(delegate);
753 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
754 for (
int i = 0;
i < sequence->size(); ++
i) {
755 VisitSubArgument(sequence->Interval(i));
760 void VisitIntegerExpressionArgument(
const std::string& arg_name,
761 IntExpr*
const argument)
override {
762 VisitSubArgument(argument);
765 void VisitIntegerVariableArrayArgument(
766 const std::string& arg_name,
767 const std::vector<IntVar*>& arguments)
override {
768 for (
int i = 0;
i < arguments.size(); ++
i) {
769 VisitSubArgument(arguments[i]);
774 void VisitIntervalArgument(
const std::string& arg_name,
775 IntervalVar*
const argument)
override {
776 VisitSubArgument(argument);
779 void VisitIntervalArrayArgument(
780 const std::string& arg_name,
781 const std::vector<IntervalVar*>& arguments)
override {
782 for (
int i = 0;
i < arguments.size(); ++
i) {
783 VisitSubArgument(arguments[i]);
788 void VisitSequenceArgument(
const std::string& arg_name,
789 SequenceVar*
const argument)
override {
790 VisitSubArgument(argument);
793 void VisitSequenceArrayArgument(
794 const std::string& arg_name,
795 const std::vector<SequenceVar*>& arguments)
override {
796 for (
int i = 0;
i < arguments.size(); ++
i) {
797 VisitSubArgument(arguments[i]);
801 std::string DebugString()
const override {
return "VariableDegreeVisitor"; }
805 template <
typename T>
806 void VisitSubArgument(T*
object) {
807 object->Accept(
this);
810 absl::flat_hash_map<const IntVar*, int>*
const map_;
815 return RevAlloc(
new PrintModelVisitor);
819 return RevAlloc(
new ModelStatisticsVisitor);
823 absl::flat_hash_map<const IntVar*, int>*
const map) {
824 return RevAlloc(
new VariableDegreeVisitor(map));
830 std::vector<int64_t> result(
input.size());
831 for (
int i = 0; i <
input.size(); ++i) {
832 result[i] =
input[i];
void SetValue(Solver *const s, int index, const T &val)
void ClearAll(Solver *solver)
Cleans all bits.
int64_t GetFirstBit(int row, int start) const
void SetToZero(Solver *solver, int64_t row, int64_t column)
Erases the 'column' bit in the 'row' row.
void SetToOne(Solver *solver, int64_t row, int64_t column)
Sets the 'column' bit in the 'row' row.
int64_t Cardinality() const
Returns the number of bits set to one.
void ClearAll(Solver *solver)
Cleans all bits.
RevBitSet(int64_t size)
-------— RevBitSet -------—
void SetToZero(Solver *solver, int64_t index)
Erases the 'index' bit.
bool IsCardinalityOne() const
Does it contains only one bit set?
void SetToOne(Solver *solver, int64_t index)
Sets the 'index' bit.
friend class RevBitMatrix
bool IsSet(int64_t index) const
Returns whether the 'index' bit is set.
int64_t GetFirstBit(int start) const
bool IsCardinalityZero() const
Is bitset null?
void Remove(Solver *const solver, const T &value_index)
void Insert(Solver *const solver, const T &elt)
void SetValue(Solver *const s, const T &val)
void SetToZero(Solver *solver, int64_t pos)
Erases the 'pos' bit.
SmallRevBitSet(int64_t size)
-------— SmallRevBitSet -------—
void SetToOne(Solver *solver, int64_t pos)
Sets the 'pos' bit.
int64_t Cardinality() const
Returns the number of bits set to one.
int64_t GetFirstOne() const
For the time being, Solver is neither MT_SAFE nor MT_HOT.
ModelVisitor * MakeVariableDegreeVisitor(absl::flat_hash_map< const IntVar *, int > *map)
Compute the number of constraints a variable is attached to.
ModelVisitor * MakePrintModelVisitor()
Prints the model.
void SaveValue(T *o)
reversibility
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
bool Intersects(const std::vector< uint64_t > &mask, int *support_index)
bool RevSubtract(Solver *solver, const std::vector< uint64_t > &mask)
void Init(Solver *solver, const std::vector< uint64_t > &mask)
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
bool RevAnd(Solver *solver, const std::vector< uint64_t > &mask)
In SWIG mode, we don't want anything besides these top-level includes.
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
--— Vector manipulations --—
uint32_t BitPos64(uint64_t pos)
Bit operators used to manipulates bitsets.
uint64_t BitCountRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
Returns the number of bits set in bitset between positions start and end.
uint64_t BitCount64(uint64_t n)
Returns the number of bits set in n.
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
Returns true if the bit pos is set in bitset.
uint64_t OneBit64(int pos)
Returns a word with only bit pos set.
uint64_t BitOffset64(uint64_t pos)
Returns the word number corresponding to bit number pos.
bool IsEmptyRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
Returns true if no bits are set in bitset between start and end.
uint64_t BitLength64(uint64_t size)
Returns the number of words needed to store size bits.
int LeastSignificantBitPosition64(uint64_t n)
static int input(yyscan_t yyscanner)
std::optional< int64_t > end