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"
41 bits_.SetValue(solver, bits_.Value() |
OneBit64(pos));
46 bits_.SetValue(solver, bits_.Value() & ~
OneBit64(pos));
54 if (bits_.Value() == 0) {
65 bits_(new uint64_t[length_]),
66 stamps_(new uint64_t[length_]) {
68 memset(bits_.get(), 0,
sizeof(bits_[0]) * length_);
69 memset(stamps_.get(), 0,
sizeof(stamps_[0]) * length_);
72void RevBitSet::Save(
Solver*
const solver,
int offset) {
73 const uint64_t current_stamp = solver->
stamp();
74 if (current_stamp > stamps_[offset]) {
75 stamps_[offset] = current_stamp;
82 DCHECK_LT(index, size_);
85 if (!(bits_[offset] &
OneBit64(pos))) {
93 DCHECK_LT(index, size_);
104 DCHECK_LT(index, size_);
110 for (
int i = 0; i < length_; ++i) {
117 for (
int i = 0; i < length_; ++i) {
126 bool found_one =
false;
127 for (
int i = 0; i < length_; ++i) {
128 const uint64_t partial = bits_[i];
130 if (!(partial & (partial - 1))) {
148 for (
int offset = 0; offset < length_; ++offset) {
150 Save(solver, offset);
151 bits_[offset] = uint64_t{0};
159 :
RevBitSet(rows * columns), rows_(rows), columns_(columns) {
161 DCHECK_GE(columns, 1);
168 DCHECK_LT(row, rows_);
169 DCHECK_GE(column, 0);
170 DCHECK_LT(column, columns_);
177 DCHECK_LT(row, rows_);
178 DCHECK_GE(column, 0);
179 DCHECK_LT(column, columns_);
185 DCHECK_LT(row, rows_);
186 const int start = row * columns_;
196 const int start = row * columns_;
203 DCHECK_LT(row, rows_);
204 DCHECK_LT(start, columns_);
205 const int beginning = row * columns_;
206 const int end = beginning + columns_ - 1;
209 if (position == -1) {
212 return position - beginning;
225 bits_(word_size_, 0),
226 active_words_(word_size_) {}
229 const std::vector<uint64_t>& mask) {
230 CHECK_LE(mask.size(), word_size_);
231 for (
int i = 0; i < mask.size(); ++i) {
233 bits_.SetValue(solver, i, mask[i]);
234 active_words_.Insert(solver, i);
240 const std::vector<uint64_t>& mask) {
241 bool changed =
false;
243 for (
int index : active_words_) {
244 if (index < mask.size() && (bits_[index] & mask[index]) != 0) {
246 const uint64_t result = bits_[index] & ~mask[index];
247 bits_.SetValue(solver, index, result);
249 to_remove_.push_back(index);
254 CleanUpActives(solver);
258void UnsortedNullableRevBitset::CleanUpActives(
Solver*
const solver) {
261 for (
int i = to_remove_.size() - 1; i >= 0; --i) {
262 active_words_.
Remove(solver, to_remove_[i]);
267 const std::vector<uint64_t>& mask) {
268 bool changed =
false;
270 for (
int index : active_words_) {
271 if (index < mask.size()) {
272 if ((bits_[index] & ~mask[index]) != 0) {
274 const uint64_t result = bits_[index] & mask[index];
275 bits_.SetValue(solver, index, result);
277 to_remove_.push_back(index);
283 bits_.SetValue(solver, index, 0);
284 to_remove_.push_back(index);
287 CleanUpActives(solver);
292 int* support_index) {
293 DCHECK_GE(*support_index, 0);
294 DCHECK_LT(*support_index, word_size_);
295 if (mask[*support_index] & bits_[*support_index]) {
298 for (
int index : active_words_) {
299 if (bits_[index] & mask[index]) {
300 *support_index = index;
312 PrintModelVisitor() : indent_(0) {}
313 ~PrintModelVisitor()
override {}
316 void BeginVisitModel(
const std::string& solver_name)
override {
317 LOG(INFO) <<
"Model " << solver_name <<
" {";
321 void EndVisitModel(
const std::string& solver_name)
override {
324 CHECK_EQ(0, indent_);
327 void BeginVisitConstraint(
const std::string& type_name,
328 const Constraint*
const constraint)
override {
329 LOG(INFO) << Spaces() << type_name;
333 void EndVisitConstraint(
const std::string& type_name,
334 const Constraint*
const constraint)
override {
338 void BeginVisitIntegerExpression(
const std::string& type_name,
339 const IntExpr*
const expr)
override {
340 LOG(INFO) << Spaces() << type_name;
344 void EndVisitIntegerExpression(
const std::string& type_name,
345 const IntExpr*
const expr)
override {
349 void BeginVisitExtension(
const std::string& type_name)
override {
350 LOG(INFO) << Spaces() << type_name;
354 void EndVisitExtension(
const std::string& type_name)
override { Decrease(); }
356 void VisitIntegerVariable(
const IntVar*
const variable,
357 IntExpr*
const delegate)
override {
358 if (delegate !=
nullptr) {
359 delegate->Accept(
this);
361 if (variable->Bound() && variable->name().empty()) {
362 LOG(INFO) << Spaces() << variable->Min();
364 LOG(INFO) << Spaces() << variable->DebugString();
369 void VisitIntegerVariable(
const IntVar*
const variable,
370 const std::string& operation, int64_t value,
371 IntVar*
const delegate)
override {
372 LOG(INFO) << Spaces() <<
"IntVar";
374 LOG(INFO) << Spaces() << value;
375 LOG(INFO) << Spaces() << operation;
376 delegate->Accept(
this);
380 void VisitIntervalVariable(
const IntervalVar*
const variable,
381 const std::string& operation, int64_t value,
382 IntervalVar*
const delegate)
override {
383 if (delegate !=
nullptr) {
384 LOG(INFO) << Spaces() << operation <<
" <" << value <<
", ";
386 delegate->Accept(
this);
388 LOG(INFO) << Spaces() <<
">";
390 LOG(INFO) << Spaces() << variable->DebugString();
394 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
395 LOG(INFO) << Spaces() << sequence->DebugString();
399 void VisitIntegerArgument(
const std::string& arg_name,
400 int64_t value)
override {
401 LOG(INFO) << Spaces() << arg_name <<
": " << value;
404 void VisitIntegerArrayArgument(
const std::string& arg_name,
405 const std::vector<int64_t>& values)
override {
406 LOG(INFO) << Spaces() << arg_name <<
": [" << absl::StrJoin(values,
", ")
410 void VisitIntegerMatrixArgument(
const std::string& arg_name,
411 const IntTupleSet& values)
override {
412 const int rows = values.NumTuples();
413 const int columns = values.Arity();
414 std::string array =
"[";
415 for (
int i = 0;
i < rows; ++
i) {
420 for (
int j = 0; j < columns; ++j) {
424 absl::StrAppendFormat(&array,
"%d", values.Value(i, j));
429 LOG(INFO) << Spaces() << arg_name <<
": " << array;
432 void VisitIntegerExpressionArgument(
const std::string& arg_name,
433 IntExpr*
const argument)
override {
434 set_prefix(absl::StrFormat(
"%s: ", arg_name));
436 argument->Accept(
this);
440 void VisitIntegerVariableArrayArgument(
441 const std::string& arg_name,
442 const std::vector<IntVar*>& arguments)
override {
443 LOG(INFO) << Spaces() << arg_name <<
": [";
445 for (
int i = 0;
i < arguments.size(); ++
i) {
446 arguments[
i]->Accept(
this);
449 LOG(INFO) << Spaces() <<
"]";
453 void VisitIntervalArgument(
const std::string& arg_name,
454 IntervalVar*
const argument)
override {
455 set_prefix(absl::StrFormat(
"%s: ", arg_name));
457 argument->Accept(
this);
461 virtual void VisitIntervalArgumentArray(
462 const std::string& arg_name,
const std::vector<IntervalVar*>& arguments) {
463 LOG(INFO) << Spaces() << arg_name <<
": [";
465 for (
int i = 0;
i < arguments.size(); ++
i) {
466 arguments[
i]->Accept(
this);
469 LOG(INFO) << Spaces() <<
"]";
473 void VisitSequenceArgument(
const std::string& arg_name,
474 SequenceVar*
const argument)
override {
475 set_prefix(absl::StrFormat(
"%s: ", arg_name));
477 argument->Accept(
this);
481 virtual void VisitSequenceArgumentArray(
482 const std::string& arg_name,
const std::vector<SequenceVar*>& arguments) {
483 LOG(INFO) << Spaces() << arg_name <<
": [";
485 for (
int i = 0;
i < arguments.size(); ++
i) {
486 arguments[
i]->Accept(
this);
489 LOG(INFO) << Spaces() <<
"]";
492 std::string DebugString()
const override {
return "PrintModelVisitor"; }
495 void Increase() { indent_ += 2; }
497 void Decrease() { indent_ -= 2; }
499 std::string Spaces() {
501 for (
int i = 0;
i < indent_ - 2 * (!prefix_.empty()); ++
i) {
504 if (!prefix_.empty()) {
505 result.append(prefix_);
511 void set_prefix(absl::string_view prefix) { prefix_ = prefix; }
521 ModelStatisticsVisitor()
522 : num_constraints_(0),
528 num_extensions_(0) {}
530 ~ModelStatisticsVisitor()
override {}
533 void BeginVisitModel(
const std::string& solver_name)
override {
535 num_constraints_ = 0;
537 num_expressions_ = 0;
542 already_visited_.clear();
543 constraint_types_.clear();
544 expression_types_.clear();
545 extension_types_.clear();
548 void EndVisitModel(
const std::string& solver_name)
override {
550 LOG(INFO) <<
"Model has:";
551 LOG(INFO) <<
" - " << num_constraints_ <<
" constraints.";
552 for (
const auto& it : constraint_types_) {
553 LOG(INFO) <<
" * " << it.second <<
" " << it.first;
555 LOG(INFO) <<
" - " << num_variables_ <<
" integer variables.";
556 LOG(INFO) <<
" - " << num_expressions_ <<
" integer expressions.";
557 for (
const auto& it : expression_types_) {
558 LOG(INFO) <<
" * " << it.second <<
" " << it.first;
560 LOG(INFO) <<
" - " << num_casts_ <<
" expressions casted into variables.";
561 LOG(INFO) <<
" - " << num_intervals_ <<
" interval variables.";
562 LOG(INFO) <<
" - " << num_sequences_ <<
" sequence variables.";
563 LOG(INFO) <<
" - " << num_extensions_ <<
" model extensions.";
564 for (
const auto& it : extension_types_) {
565 LOG(INFO) <<
" * " << it.second <<
" " << it.first;
569 void BeginVisitConstraint(
const std::string& type_name,
570 const Constraint*
const constraint)
override {
572 AddConstraintType(type_name);
575 void BeginVisitIntegerExpression(
const std::string& type_name,
576 const IntExpr*
const expr)
override {
577 AddExpressionType(type_name);
581 void BeginVisitExtension(
const std::string& type_name)
override {
582 AddExtensionType(type_name);
586 void VisitIntegerVariable(
const IntVar*
const variable,
587 IntExpr*
const delegate)
override {
592 VisitSubArgument(delegate);
596 void VisitIntegerVariable(
const IntVar*
const variable,
597 const std::string& operation, int64_t value,
598 IntVar*
const delegate)
override {
602 VisitSubArgument(delegate);
605 void VisitIntervalVariable(
const IntervalVar*
const variable,
606 const std::string& operation, int64_t value,
607 IntervalVar*
const delegate)
override {
610 VisitSubArgument(delegate);
614 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
616 for (
int i = 0;
i < sequence->size(); ++
i) {
617 VisitSubArgument(sequence->Interval(i));
622 void VisitIntegerExpressionArgument(
const std::string& arg_name,
623 IntExpr*
const argument)
override {
624 VisitSubArgument(argument);
627 void VisitIntegerVariableArrayArgument(
628 const std::string& arg_name,
629 const std::vector<IntVar*>& arguments)
override {
630 for (
int i = 0;
i < arguments.size(); ++
i) {
631 VisitSubArgument(arguments[i]);
636 void VisitIntervalArgument(
const std::string& arg_name,
637 IntervalVar*
const argument)
override {
638 VisitSubArgument(argument);
641 void VisitIntervalArrayArgument(
642 const std::string& arg_name,
643 const std::vector<IntervalVar*>& arguments)
override {
644 for (
int i = 0;
i < arguments.size(); ++
i) {
645 VisitSubArgument(arguments[i]);
650 void VisitSequenceArgument(
const std::string& arg_name,
651 SequenceVar*
const argument)
override {
652 VisitSubArgument(argument);
655 void VisitSequenceArrayArgument(
656 const std::string& arg_name,
657 const std::vector<SequenceVar*>& arguments)
override {
658 for (
int i = 0;
i < arguments.size(); ++
i) {
659 VisitSubArgument(arguments[i]);
663 std::string DebugString()
const override {
return "ModelStatisticsVisitor"; }
666 void Register(
const BaseObject*
const object) {
667 already_visited_.insert(
object);
670 bool AlreadyVisited(
const BaseObject*
const object) {
671 return already_visited_.contains(
object);
675 template <
typename T>
676 void VisitSubArgument(T*
object) {
677 if (!AlreadyVisited(
object)) {
679 object->Accept(
this);
683 void AddConstraintType(absl::string_view constraint_type) {
684 constraint_types_[constraint_type]++;
687 void AddExpressionType(absl::string_view expression_type) {
688 expression_types_[expression_type]++;
691 void AddExtensionType(absl::string_view extension_type) {
692 extension_types_[extension_type]++;
695 absl::flat_hash_map<std::string, int> constraint_types_;
696 absl::flat_hash_map<std::string, int> expression_types_;
697 absl::flat_hash_map<std::string, int> extension_types_;
698 int num_constraints_;
700 int num_expressions_;
705 absl::flat_hash_set<const BaseObject*> already_visited_;
712 explicit VariableDegreeVisitor(
713 absl::flat_hash_map<const IntVar*, int>*
const map)
716 ~VariableDegreeVisitor()
override {}
719 void VisitIntegerVariable(
const IntVar*
const variable,
720 IntExpr*
const delegate)
override {
721 IntVar*
const var =
const_cast<IntVar*
>(variable);
722 if (map_->contains(var)) {
726 VisitSubArgument(delegate);
730 void VisitIntegerVariable(
const IntVar*
const variable,
731 const std::string& operation, int64_t value,
732 IntVar*
const delegate)
override {
733 IntVar*
const var =
const_cast<IntVar*
>(variable);
734 if (map_->contains(var)) {
737 VisitSubArgument(delegate);
740 void VisitIntervalVariable(
const IntervalVar*
const variable,
741 const std::string& operation, int64_t value,
742 IntervalVar*
const delegate)
override {
744 VisitSubArgument(delegate);
748 void VisitSequenceVariable(
const SequenceVar*
const sequence)
override {
749 for (
int i = 0;
i < sequence->size(); ++
i) {
750 VisitSubArgument(sequence->Interval(i));
755 void VisitIntegerExpressionArgument(
const std::string& arg_name,
756 IntExpr*
const argument)
override {
757 VisitSubArgument(argument);
760 void VisitIntegerVariableArrayArgument(
761 const std::string& arg_name,
762 const std::vector<IntVar*>& arguments)
override {
763 for (
int i = 0;
i < arguments.size(); ++
i) {
764 VisitSubArgument(arguments[i]);
769 void VisitIntervalArgument(
const std::string& arg_name,
770 IntervalVar*
const argument)
override {
771 VisitSubArgument(argument);
774 void VisitIntervalArrayArgument(
775 const std::string& arg_name,
776 const std::vector<IntervalVar*>& arguments)
override {
777 for (
int i = 0;
i < arguments.size(); ++
i) {
778 VisitSubArgument(arguments[i]);
783 void VisitSequenceArgument(
const std::string& arg_name,
784 SequenceVar*
const argument)
override {
785 VisitSubArgument(argument);
788 void VisitSequenceArrayArgument(
789 const std::string& arg_name,
790 const std::vector<SequenceVar*>& arguments)
override {
791 for (
int i = 0;
i < arguments.size(); ++
i) {
792 VisitSubArgument(arguments[i]);
796 std::string DebugString()
const override {
return "VariableDegreeVisitor"; }
800 template <
typename T>
801 void VisitSubArgument(T*
object) {
802 object->Accept(
this);
805 absl::flat_hash_map<const IntVar*, int>*
const map_;
810 return RevAlloc(
new PrintModelVisitor);
814 return RevAlloc(
new ModelStatisticsVisitor);
818 absl::flat_hash_map<const IntVar*, int>*
const map) {
819 return RevAlloc(
new VariableDegreeVisitor(map));
825 std::vector<int64_t> result(
input.size());
826 for (
int i = 0; i <
input.size(); ++i) {
827 result[i] =
input[i];
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.
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 SetToZero(Solver *solver, int64_t pos)
Erases the 'pos' bit.
SmallRevBitSet(int64_t size)
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
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)
int64_t bit_size() const
Returns the number of bits given in the constructor of the bitset.
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)
ClosedInterval::Iterator end(ClosedInterval interval)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
uint32_t BitPos64(uint64_t pos)
uint64_t BitCountRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
uint64_t BitCount64(uint64_t n)
bool IsBitSet64(const uint64_t *const bitset, uint64_t pos)
uint64_t OneBit64(int pos)
uint64_t BitOffset64(uint64_t pos)
bool IsEmptyRange64(const uint64_t *bitset, uint64_t start, uint64_t end)
uint64_t BitLength64(uint64_t size)
int LeastSignificantBitPosition64(uint64_t n)
static int input(yyscan_t yyscanner)