84 ignored_constraints_(
model_proto.constraints_size(), false) {
87 absl::flat_hash_set<BoolArgumentProto> exactly_ones_cache;
88 absl::flat_hash_set<LinearConstraintProto> encoding_cache;
89 std::vector<std::vector<EqualityDetectionHelper>> var_to_equalities(
90 model_proto_.variables_size());
91 absl::flat_hash_map<int, std::vector<VarValueCtIndex>>
92 literal_to_var_value_ct_indices;
95 for (
int c = 0; c < model_proto_.constraints_size(); ++c) {
102 if (!exactly_ones_cache.insert(bool_arg).second) {
103 ignored_constraints_[c] =
true;
104 ++num_ignored_constraints_;
119 const Domain domain_if_enforced =
132 var_to_equalities[var].push_back(
133 {c, enforcement_literal, inter.
FixedValue(),
true});
134 literal_to_var_value_ct_indices[enforcement_literal].push_back(
142 var_to_equalities[var].push_back(
143 {c, enforcement_literal, inter.
FixedValue(),
false});
149 absl::flat_hash_map<int64_t, LitVarEncodingInfo> value_encodings;
150 std::vector<std::pair<int64_t, int>> value_literal_pairs;
152 for (
int var = 0; var < var_to_equalities.size(); ++var) {
153 std::vector<EqualityDetectionHelper>& encoding = var_to_equalities[var];
154 if (encoding.empty())
continue;
156 std::sort(encoding.begin(), encoding.end());
158 value_encodings.clear();
160 for (
int j = 0; j + 1 < encoding.size(); j++) {
161 if ((encoding[j].value != encoding[j + 1].value) ||
162 (encoding[j].literal !=
NegatedRef(encoding[j + 1].literal)) ||
163 (encoding[j].is_equality !=
true) ||
164 (encoding[j + 1].is_equality !=
false)) {
169 value_encodings[encoding[j].value] = {encoding[j].literal,
170 encoding[j].constraint_index,
171 encoding[j + 1].constraint_index};
173 if (value_encodings.size() == domain.
Size()) {
174 value_literal_pairs.clear();
175 for (
const auto& [value, value_encoding] : value_encodings) {
176 ignored_constraints_[value_encoding.positive_ct_index] =
true;
177 ignored_constraints_[value_encoding.negative_ct_index] =
true;
178 num_ignored_constraints_ += 2;
179 value_literal_pairs.push_back({value, value_encoding.lit});
183 std::sort(value_literal_pairs.begin(), value_literal_pairs.end());
188 int64_t min_value = 0;
191 bool first_iteration =
true;
192 for (
const auto [value, lit] : value_literal_pairs) {
197 if (first_iteration) {
201 first_iteration =
false;
203 const int64_t delta = value - min_value;
217 if (encoding_cache.insert(var_encoding.
linear()).second) {
218 additional_constraints_.push_back(var_encoding);
219 num_full_encodings_++;
225 if (exactly_ones_cache.insert(exactly_one.
exactly_one()).second) {
226 additional_constraints_.push_back(exactly_one);
232 VLOG(1) <<
"Linear model created:";
233 VLOG(1) <<
" #model constraints: " << model_proto_.constraints_size();
234 VLOG(1) <<
" #full encodings detected: " << num_full_encodings_;
235 VLOG(1) <<
" #exactly_ones added: " << num_exactly_ones_;
236 VLOG(1) <<
" #constraints ignored: " << num_ignored_constraints_;
Domain IntersectionWith(const Domain &domain) const
Domain InverseMultiplicationBy(int64_t coeff) const