28 const int size =
ct.bool_or().literals_size();
30 bool satisfied =
false;
31 for (
int i = 0; i < size; ++i) {
32 const int ref =
ct.bool_or().literals(i);
43 if (satisfied)
return;
46 const int first_ref =
ct.bool_or().literals(0);
53 const std::vector<bool>& prefer_lower_value,
54 std::vector<Domain>* domains) {
55 int64 fixed_activity = 0;
56 const int size =
ct.linear().vars().size();
57 std::vector<int> free_vars;
58 std::vector<int64> free_coeffs;
59 for (
int i = 0; i < size; ++i) {
60 const int var =
ct.linear().vars(i);
61 const int64 coeff =
ct.linear().coeffs(i);
63 if (coeff == 0)
continue;
65 fixed_activity += (*domains)[
var].FixedValue() * coeff;
67 free_vars.push_back(
var);
68 free_coeffs.push_back(coeff);
71 if (free_vars.empty())
return;
77 if (free_vars.size() == 1) {
78 const int var = free_vars[0];
94 std::vector<Domain> to_add;
95 to_add.push_back(
Domain(0));
96 for (
int i = 0; i + 1 < free_vars.size(); ++i) {
100 for (
int i = free_vars.size() - 1; i >= 0; --i) {
103 const int var = free_vars[i];
104 const int64 coeff = free_coeffs[i];
118 fixed_activity += coeff *
value;
127 for (
const int ref :
ct.int_max().vars()) {
139 const int target_ref =
ct.int_max().target();
142 (*domains)[target_var] = (*domains)[target_var].IntersectionWith(
Domain(m));
144 (*domains)[target_var] =
145 (*domains)[target_var].IntersectionWith(
Domain(-m));
147 CHECK(!(*domains)[target_var].IsEmpty());
152 const int index_ref =
ct.element().index();
154 const int target_ref =
ct.element().target();
160 if (!(*domains)[target_var].
IsFixed() && !(*domains)[index_var].
IsFixed()) {
161 const int64 index_value = (*domains)[index_var].Min();
162 (*domains)[index_var] =
Domain(index_value);
165 const int selected_ref =
ct.element().vars(
167 const int selected_var =
PositiveRef(selected_ref);
168 if (!(*domains)[selected_var].
IsFixed()) {
169 (*domains)[selected_var] =
Domain((*domains)[selected_var].Min());
174 if ((*domains)[index_var].
IsFixed()) {
175 const int64 index_value = (*domains)[index_var].FixedValue();
176 const int selected_ref =
ct.element().vars(
178 const int selected_var =
PositiveRef(selected_ref);
179 const int64 selected_value = (*domains)[selected_var].FixedValue();
180 (*domains)[target_var] = (*domains)[target_var].IntersectionWith(
184 DCHECK(!(*domains)[target_var].IsEmpty());
189 const int64 target_value = (*domains)[target_var].FixedValue();
190 int selected_index_value = -1;
191 for (
int i = 0; i <
ct.element().vars().size(); ++i) {
192 const int ref =
ct.element().vars(i);
196 if (
value == target_value) {
197 selected_index_value = i;
201 if (
value == -target_value) {
202 selected_index_value = i;
209 (*domains)[index_var] = (*domains)[index_var].IntersectionWith(
Domain(
210 RefIsPositive(index_var) ? selected_index_value : -selected_index_value));
211 DCHECK(!(*domains)[index_var].IsEmpty());
215 const CpModelProto& mapping_proto,
216 const std::vector<int>& postsolve_mapping,
220 *(
response->mutable_sufficient_assumptions_for_infeasibility())) {
230 if (
response->solution_size() != postsolve_mapping.size())
return;
234 std::vector<Domain> domains(mapping_proto.variables_size());
235 for (
int i = 0; i < postsolve_mapping.size(); ++i) {
236 CHECK_LE(postsolve_mapping[i], domains.size());
239 for (
int i = 0; i < domains.size(); ++i) {
240 if (domains[i].IsEmpty()) {
243 CHECK(!domains[i].IsEmpty());
250 CHECK(!mapping_proto.has_objective());
251 std::vector<bool> prefer_lower_value(domains.size(),
true);
252 if (mapping_proto.has_objective()) {
253 const int size = mapping_proto.objective().vars().size();
254 for (
int i = 0; i < size; ++i) {
255 int var = mapping_proto.objective().vars(i);
256 int64 coeff = mapping_proto.objective().coeffs(i);
261 prefer_lower_value[i] = (coeff >= 0);
266 const int num_constraints = mapping_proto.constraints_size();
267 for (
int i = num_constraints - 1; i >= 0; i--) {
268 const ConstraintProto&
ct = mapping_proto.constraints(i);
271 bool enforced =
true;
272 for (
const int ref :
ct.enforcement_literal()) {
279 if (!enforced)
continue;
281 switch (
ct.constraint_case()) {
282 case ConstraintProto::kBoolOr:
285 case ConstraintProto::kLinear:
288 case ConstraintProto::kIntMax:
291 case ConstraintProto::kElement:
297 LOG(
FATAL) <<
"Unsupported constraint: " <<
ct.ShortDebugString();
302 response->mutable_solution()->Clear();
303 CHECK_LE(num_variables_in_original_model, domains.size());
304 for (
int i = 0; i < num_variables_in_original_model; ++i) {
305 if (prefer_lower_value[i]) {
306 response->add_solution(domains[i].Min());
308 response->add_solution(domains[i].Max());