or-tools 0.3.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dba74899e2a57b086643657e5093f12e67fd4fcdda7e22c2b533911f9991e43a
4
- data.tar.gz: 963c0b75f55b4b772ead3a8402ec8bb4b90570c23de1c7dc3a437758e8949af2
3
+ metadata.gz: 405e26b51140e6605acd8904d7e90e0e7f48b7cfd83641fef6e2e737e7b8cda4
4
+ data.tar.gz: e6e0506979a829c260f8bae70e7769524d59d83b7a52e1cadfb6e553d8116587
5
5
  SHA512:
6
- metadata.gz: a5dc8662ec580c97a905817867346615e2fbb187d5b75d6b2b839a86e7385a20b2ed4f9f4c13ed536079c6141cdd0bf95bfad7ea6408d4eb81d8f0ed09e32a68
7
- data.tar.gz: 195967d1e662ba05751ff31fbec3c96ebac519cd58a343ca551f9ba6c12304542b7f4127a37f88e99cda6b214d42089df7ed9b5a3134c0ec1eb978ea72a95be4
6
+ metadata.gz: 237e13e7340682d974602743de724031c28c99add58c4cf49e670bb05f4fa0c691dcf00dd75797a9ab3efcc9b5505a96f3a2a3d542db8c8746652ec114b5a258
7
+ data.tar.gz: 5c782dd281122001095663da47fce8279f5a2c29b6eed65e2288df6727c55724ef424d4c3bfda3ed3b4ce53493964b88d64f67fc843e97dafd98f3e21a4c5183
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## 0.5.0 (2021-04-30)
2
+
3
+ - Updated OR-Tools to 9.0
4
+ - Added binary installation for CentOS 7
5
+ - Added `sufficient_assumptions_for_infeasibility` to `CpSolver`
6
+
7
+ ## 0.4.3 (2021-03-26)
8
+
9
+ - Added `add_assumption`, `add_assumptions`, and `clear_assumptions` to `CpModel`
10
+ - Added `add_hint` and `clear_hints` to `CpModel`
11
+ - Added `only_enforce_if` to `SatConstraint`
12
+ - Fixed installation for Debian
13
+
14
+ ## 0.4.2 (2021-03-03)
15
+
16
+ - Updated OR-Tools to 8.2
17
+
18
+ ## 0.4.1 (2021-02-23)
19
+
20
+ - Added solution printers
21
+ - Improved `inspect` and `to_s` for `CpModel`
22
+ - Improved constraint construction
23
+
24
+ ## 0.4.0 (2021-01-14)
25
+
26
+ - Updated OR-Tools to 8.1
27
+
1
28
  ## 0.3.4 (2021-01-14)
2
29
 
3
30
  - Added support for time limit for `CpSolver`
data/README.md CHANGED
@@ -267,7 +267,7 @@ Constraint Optimization
267
267
  - [Solving an Optimization Problem](#solving-an-optimization-problem)
268
268
  - [Cryptarithmetic](#cryptarithmetic)
269
269
  - [The N-queens Problem](#the-n-queens-problem)
270
- - [Setting Solver Limits](#setting-solver-limits) [master]
270
+ - [Setting Solver Limits](#setting-solver-limits)
271
271
 
272
272
  Assignment
273
273
 
@@ -0,0 +1,39 @@
1
+ #include <ortools/graph/assignment.h>
2
+
3
+ #include <rice/Array.hpp>
4
+ #include <rice/Constructor.hpp>
5
+ #include <rice/Module.hpp>
6
+
7
+ using operations_research::SimpleLinearSumAssignment;
8
+
9
+ using Rice::Array;
10
+ using Rice::Symbol;
11
+
12
+ void init_assignment(Rice::Module& m) {
13
+ Rice::define_class_under<SimpleLinearSumAssignment>(m, "LinearSumAssignment")
14
+ .define_constructor(Rice::Constructor<SimpleLinearSumAssignment>())
15
+ .define_method("add_arc_with_cost", &SimpleLinearSumAssignment::AddArcWithCost)
16
+ .define_method("num_nodes", &SimpleLinearSumAssignment::NumNodes)
17
+ .define_method("num_arcs", &SimpleLinearSumAssignment::NumArcs)
18
+ .define_method("left_node", &SimpleLinearSumAssignment::LeftNode)
19
+ .define_method("right_node", &SimpleLinearSumAssignment::RightNode)
20
+ .define_method("cost", &SimpleLinearSumAssignment::Cost)
21
+ .define_method("optimal_cost", &SimpleLinearSumAssignment::OptimalCost)
22
+ .define_method("right_mate", &SimpleLinearSumAssignment::RightMate)
23
+ .define_method("assignment_cost", &SimpleLinearSumAssignment::AssignmentCost)
24
+ .define_method(
25
+ "solve",
26
+ *[](SimpleLinearSumAssignment& self) {
27
+ auto status = self.Solve();
28
+
29
+ if (status == SimpleLinearSumAssignment::Status::OPTIMAL) {
30
+ return Symbol("optimal");
31
+ } else if (status == SimpleLinearSumAssignment::Status::INFEASIBLE) {
32
+ return Symbol("infeasible");
33
+ } else if (status == SimpleLinearSumAssignment::Status::POSSIBLE_OVERFLOW) {
34
+ return Symbol("possible_overflow");
35
+ } else {
36
+ throw std::runtime_error("Unknown status");
37
+ }
38
+ });
39
+ }
@@ -0,0 +1,55 @@
1
+ #include <ortools/algorithms/knapsack_solver.h>
2
+
3
+ #include <rice/Array.hpp>
4
+ #include <rice/Constructor.hpp>
5
+ #include <rice/Module.hpp>
6
+
7
+ using operations_research::KnapsackSolver;
8
+
9
+ using Rice::Array;
10
+ using Rice::Object;
11
+ using Rice::Symbol;
12
+
13
+ template<>
14
+ inline
15
+ KnapsackSolver::SolverType from_ruby<KnapsackSolver::SolverType>(Object x)
16
+ {
17
+ std::string s = Symbol(x).str();
18
+ if (s == "branch_and_bound") {
19
+ return KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER;
20
+ } else {
21
+ throw std::runtime_error("Unknown solver type: " + s);
22
+ }
23
+ }
24
+
25
+ void init_bin_packing(Rice::Module& m) {
26
+ Rice::define_class_under<KnapsackSolver>(m, "KnapsackSolver")
27
+ .define_constructor(Rice::Constructor<KnapsackSolver, KnapsackSolver::SolverType, std::string>())
28
+ .define_method("_solve", &KnapsackSolver::Solve)
29
+ .define_method("best_solution_contains?", &KnapsackSolver::BestSolutionContains)
30
+ .define_method(
31
+ "init",
32
+ *[](KnapsackSolver& self, Array rb_values, Array rb_weights, Array rb_capacities) {
33
+ std::vector<int64_t> values;
34
+ for (std::size_t i = 0; i < rb_values.size(); ++i) {
35
+ values.push_back(from_ruby<int64_t>(rb_values[i]));
36
+ }
37
+
38
+ std::vector<std::vector<int64_t>> weights;
39
+ for (std::size_t i = 0; i < rb_weights.size(); ++i) {
40
+ Array rb_w = Array(rb_weights[i]);
41
+ std::vector<int64_t> w;
42
+ for (std::size_t j = 0; j < rb_w.size(); ++j) {
43
+ w.push_back(from_ruby<int64_t>(rb_w[j]));
44
+ }
45
+ weights.push_back(w);
46
+ }
47
+
48
+ std::vector<int64_t> capacities;
49
+ for (std::size_t i = 0; i < rb_capacities.size(); ++i) {
50
+ capacities.push_back(from_ruby<int64_t>(rb_capacities[i]));
51
+ }
52
+
53
+ self.Init(values, weights, capacities);
54
+ });
55
+ }
@@ -0,0 +1,473 @@
1
+ #include <google/protobuf/text_format.h>
2
+ #include <ortools/sat/cp_model.h>
3
+
4
+ #include <rice/Array.hpp>
5
+ #include <rice/Constructor.hpp>
6
+ #include <rice/Module.hpp>
7
+
8
+ using operations_research::sat::BoolVar;
9
+ using operations_research::sat::Constraint;
10
+ using operations_research::sat::CpModelBuilder;
11
+ using operations_research::sat::CpSolverResponse;
12
+ using operations_research::sat::CpSolverStatus;
13
+ using operations_research::sat::LinearExpr;
14
+ using operations_research::sat::IntVar;
15
+ using operations_research::sat::IntervalVar;
16
+ using operations_research::sat::Model;
17
+ using operations_research::sat::NewFeasibleSolutionObserver;
18
+ using operations_research::sat::SatParameters;
19
+ using operations_research::sat::SolutionBooleanValue;
20
+ using operations_research::sat::SolutionIntegerValue;
21
+
22
+ using Rice::Array;
23
+ using Rice::Class;
24
+ using Rice::Object;
25
+ using Rice::String;
26
+ using Rice::Symbol;
27
+
28
+ Class rb_cBoolVar;
29
+ Class rb_cSatIntVar;
30
+
31
+ template<>
32
+ inline
33
+ LinearExpr from_ruby<LinearExpr>(Object x)
34
+ {
35
+ LinearExpr expr;
36
+
37
+ if (x.respond_to("to_i")) {
38
+ expr = from_ruby<int64_t>(x.call("to_i"));
39
+ } else if (x.respond_to("vars")) {
40
+ Array vars = x.call("vars");
41
+ for (auto const& var: vars) {
42
+ auto cvar = (Array) var;
43
+ Object o = cvar[0];
44
+ if (o.is_a(rb_cBoolVar)) {
45
+ expr.AddTerm(from_ruby<BoolVar>(cvar[0]), from_ruby<int64_t>(cvar[1]));
46
+ } else if (o.is_a(rb_cInteger)) {
47
+ expr.AddConstant(from_ruby<int64_t>(cvar[0]) * from_ruby<int64_t>(cvar[1]));
48
+ } else {
49
+ expr.AddTerm(from_ruby<IntVar>(cvar[0]), from_ruby<int64_t>(cvar[1]));
50
+ }
51
+ }
52
+ } else if (x.is_a(rb_cBoolVar)) {
53
+ expr = from_ruby<BoolVar>(x);
54
+ } else {
55
+ expr = from_ruby<IntVar>(x);
56
+ }
57
+
58
+ return expr;
59
+ }
60
+
61
+ // need a wrapper class since absl::Span doesn't own
62
+ class IntVarSpan {
63
+ std::vector<IntVar> vec;
64
+ public:
65
+ IntVarSpan(Object x) {
66
+ Array a = Array(x);
67
+ vec.reserve(a.size());
68
+ for (std::size_t i = 0; i < a.size(); ++i) {
69
+ vec.push_back(from_ruby<IntVar>(a[i]));
70
+ }
71
+ }
72
+ operator absl::Span<const IntVar>() {
73
+ return absl::Span<const IntVar>(vec);
74
+ }
75
+ };
76
+
77
+ template<>
78
+ inline
79
+ IntVarSpan from_ruby<IntVarSpan>(Object x)
80
+ {
81
+ return IntVarSpan(x);
82
+ }
83
+
84
+ // need a wrapper class since absl::Span doesn't own
85
+ class IntervalVarSpan {
86
+ std::vector<IntervalVar> vec;
87
+ public:
88
+ IntervalVarSpan(Object x) {
89
+ Array a = Array(x);
90
+ vec.reserve(a.size());
91
+ for (std::size_t i = 0; i < a.size(); ++i) {
92
+ vec.push_back(from_ruby<IntervalVar>(a[i]));
93
+ }
94
+ }
95
+ operator absl::Span<const IntervalVar>() {
96
+ return absl::Span<const IntervalVar>(vec);
97
+ }
98
+ };
99
+
100
+ template<>
101
+ inline
102
+ IntervalVarSpan from_ruby<IntervalVarSpan>(Object x)
103
+ {
104
+ return IntervalVarSpan(x);
105
+ }
106
+
107
+ // need a wrapper class since absl::Span doesn't own
108
+ class LinearExprSpan {
109
+ std::vector<LinearExpr> vec;
110
+ public:
111
+ LinearExprSpan(Object x) {
112
+ Array a = Array(x);
113
+ vec.reserve(a.size());
114
+ for (std::size_t i = 0; i < a.size(); ++i) {
115
+ vec.push_back(from_ruby<LinearExpr>(a[i]));
116
+ }
117
+ }
118
+ operator absl::Span<const LinearExpr>() {
119
+ return absl::Span<const LinearExpr>(vec);
120
+ }
121
+ };
122
+
123
+ template<>
124
+ inline
125
+ LinearExprSpan from_ruby<LinearExprSpan>(Object x)
126
+ {
127
+ return LinearExprSpan(x);
128
+ }
129
+
130
+ // need a wrapper class since absl::Span doesn't own
131
+ class BoolVarSpan {
132
+ std::vector<BoolVar> vec;
133
+ public:
134
+ BoolVarSpan(Object x) {
135
+ Array a = Array(x);
136
+ vec.reserve(a.size());
137
+ for (std::size_t i = 0; i < a.size(); ++i) {
138
+ if (((Object) a[i]).is_a(rb_cSatIntVar)) {
139
+ vec.push_back(from_ruby<IntVar>(a[i]).ToBoolVar());
140
+ } else {
141
+ vec.push_back(from_ruby<BoolVar>(a[i]));
142
+ }
143
+ }
144
+ }
145
+ operator absl::Span<const BoolVar>() {
146
+ return absl::Span<const BoolVar>(vec);
147
+ }
148
+ };
149
+
150
+ template<>
151
+ inline
152
+ BoolVarSpan from_ruby<BoolVarSpan>(Object x)
153
+ {
154
+ return BoolVarSpan(x);
155
+ }
156
+
157
+ void init_constraint(Rice::Module& m) {
158
+ rb_cSatIntVar = Rice::define_class_under<IntVar>(m, "SatIntVar")
159
+ .define_method("name", &IntVar::Name);
160
+
161
+ Rice::define_class_under<IntervalVar>(m, "SatIntervalVar")
162
+ .define_method("name", &IntervalVar::Name);
163
+
164
+ Rice::define_class_under<Constraint>(m, "SatConstraint")
165
+ .define_method(
166
+ "only_enforce_if",
167
+ *[](Constraint& self, Object literal) {
168
+ if (literal.is_a(rb_cSatIntVar)) {
169
+ return self.OnlyEnforceIf(from_ruby<IntVar>(literal).ToBoolVar());
170
+ } else if (literal.is_a(rb_cArray)) {
171
+ // TODO support IntVarSpan
172
+ return self.OnlyEnforceIf(from_ruby<BoolVarSpan>(literal));
173
+ } else {
174
+ return self.OnlyEnforceIf(from_ruby<BoolVar>(literal));
175
+ }
176
+ });
177
+
178
+ rb_cBoolVar = Rice::define_class_under<BoolVar>(m, "BoolVar")
179
+ .define_method("name", &BoolVar::Name)
180
+ .define_method("index", &BoolVar::index)
181
+ .define_method("not", &BoolVar::Not)
182
+ .define_method(
183
+ "inspect",
184
+ *[](BoolVar& self) {
185
+ String name(self.Name());
186
+ return "#<ORTools::BoolVar @name=" + name.inspect().str() + ">";
187
+ });
188
+
189
+ Rice::define_class_under<SatParameters>(m, "SatParameters")
190
+ .define_constructor(Rice::Constructor<SatParameters>())
191
+ .define_method("max_time_in_seconds=",
192
+ *[](SatParameters& self, double value) {
193
+ self.set_max_time_in_seconds(value);
194
+ });
195
+
196
+ Rice::define_class_under<CpModelBuilder>(m, "CpModel")
197
+ .define_constructor(Rice::Constructor<CpModelBuilder>())
198
+ .define_method(
199
+ "new_int_var",
200
+ *[](CpModelBuilder& self, int64_t start, int64_t end, const std::string& name) {
201
+ const operations_research::Domain domain(start, end);
202
+ return self.NewIntVar(domain).WithName(name);
203
+ })
204
+ .define_method(
205
+ "new_bool_var",
206
+ *[](CpModelBuilder& self, const std::string& name) {
207
+ return self.NewBoolVar().WithName(name);
208
+ })
209
+ .define_method(
210
+ "new_constant",
211
+ *[](CpModelBuilder& self, int64_t value) {
212
+ return self.NewConstant(value);
213
+ })
214
+ .define_method(
215
+ "true_var",
216
+ *[](CpModelBuilder& self) {
217
+ return self.TrueVar();
218
+ })
219
+ .define_method(
220
+ "false_var",
221
+ *[](CpModelBuilder& self) {
222
+ return self.FalseVar();
223
+ })
224
+ .define_method(
225
+ "new_interval_var",
226
+ *[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, const std::string& name) {
227
+ return self.NewIntervalVar(start, size, end).WithName(name);
228
+ })
229
+ .define_method(
230
+ "new_optional_interval_var",
231
+ *[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, BoolVar presence, const std::string& name) {
232
+ return self.NewOptionalIntervalVar(start, size, end, presence).WithName(name);
233
+ })
234
+ .define_method(
235
+ "add_bool_or",
236
+ *[](CpModelBuilder& self, BoolVarSpan literals) {
237
+ return self.AddBoolOr(literals);
238
+ })
239
+ .define_method(
240
+ "add_bool_and",
241
+ *[](CpModelBuilder& self, BoolVarSpan literals) {
242
+ return self.AddBoolAnd(literals);
243
+ })
244
+ .define_method(
245
+ "add_bool_xor",
246
+ *[](CpModelBuilder& self, BoolVarSpan literals) {
247
+ return self.AddBoolXor(literals);
248
+ })
249
+ .define_method(
250
+ "add_implication",
251
+ *[](CpModelBuilder& self, BoolVar a, BoolVar b) {
252
+ return self.AddImplication(a, b);
253
+ })
254
+ .define_method(
255
+ "add_equality",
256
+ *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
257
+ return self.AddEquality(x, y);
258
+ })
259
+ .define_method(
260
+ "add_greater_or_equal",
261
+ *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
262
+ return self.AddGreaterOrEqual(x, y);
263
+ })
264
+ .define_method(
265
+ "add_greater_than",
266
+ *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
267
+ return self.AddGreaterThan(x, y);
268
+ })
269
+ .define_method(
270
+ "add_less_or_equal",
271
+ *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
272
+ return self.AddLessOrEqual(x, y);
273
+ })
274
+ .define_method(
275
+ "add_less_than",
276
+ *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
277
+ return self.AddLessThan(x, y);
278
+ })
279
+ // TODO add domain
280
+ // .define_method(
281
+ // "add_linear_constraint",
282
+ // *[](CpModelBuilder& self, LinearExpr expr, Domain domain) {
283
+ // return self.AddLinearConstraint(expr, domain);
284
+ // })
285
+ .define_method(
286
+ "add_not_equal",
287
+ *[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
288
+ return self.AddNotEqual(x, y);
289
+ })
290
+ .define_method(
291
+ "add_all_different",
292
+ *[](CpModelBuilder& self, IntVarSpan vars) {
293
+ return self.AddAllDifferent(vars);
294
+ })
295
+ .define_method(
296
+ "add_inverse_constraint",
297
+ *[](CpModelBuilder& self, IntVarSpan variables, IntVarSpan inverse_variables) {
298
+ return self.AddInverseConstraint(variables, inverse_variables);
299
+ })
300
+ .define_method(
301
+ "add_min_equality",
302
+ *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
303
+ return self.AddMinEquality(target, vars);
304
+ })
305
+ .define_method(
306
+ "add_lin_min_equality",
307
+ *[](CpModelBuilder& self, LinearExpr target, LinearExprSpan exprs) {
308
+ return self.AddLinMinEquality(target, exprs);
309
+ })
310
+ .define_method(
311
+ "add_max_equality",
312
+ *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
313
+ return self.AddMaxEquality(target, vars);
314
+ })
315
+ .define_method(
316
+ "add_lin_max_equality",
317
+ *[](CpModelBuilder& self, LinearExpr target, LinearExprSpan exprs) {
318
+ return self.AddLinMaxEquality(target, exprs);
319
+ })
320
+ .define_method(
321
+ "add_division_equality",
322
+ *[](CpModelBuilder& self, IntVar target, IntVar numerator, IntVar denominator) {
323
+ return self.AddDivisionEquality(target, numerator, denominator);
324
+ })
325
+ .define_method(
326
+ "add_abs_equality",
327
+ *[](CpModelBuilder& self, IntVar target, IntVar var) {
328
+ return self.AddAbsEquality(target, var);
329
+ })
330
+ .define_method(
331
+ "add_modulo_equality",
332
+ *[](CpModelBuilder& self, IntVar target, IntVar var, IntVar mod) {
333
+ return self.AddModuloEquality(target, var, mod);
334
+ })
335
+ .define_method(
336
+ "add_product_equality",
337
+ *[](CpModelBuilder& self, IntVar target, IntVarSpan vars) {
338
+ return self.AddProductEquality(target, vars);
339
+ })
340
+ .define_method(
341
+ "add_no_overlap",
342
+ *[](CpModelBuilder& self, IntervalVarSpan vars) {
343
+ return self.AddNoOverlap(vars);
344
+ })
345
+ .define_method(
346
+ "maximize",
347
+ *[](CpModelBuilder& self, LinearExpr expr) {
348
+ self.Maximize(expr);
349
+ })
350
+ .define_method(
351
+ "minimize",
352
+ *[](CpModelBuilder& self, LinearExpr expr) {
353
+ self.Minimize(expr);
354
+ })
355
+ .define_method(
356
+ "scale_objective_by",
357
+ *[](CpModelBuilder& self, double scaling) {
358
+ self.ScaleObjectiveBy(scaling);
359
+ })
360
+ .define_method(
361
+ "add_hint",
362
+ *[](CpModelBuilder& self, IntVar var, int64_t value) {
363
+ self.AddHint(var, value);
364
+ })
365
+ .define_method(
366
+ "clear_hints",
367
+ *[](CpModelBuilder& self) {
368
+ self.ClearHints();
369
+ })
370
+ .define_method(
371
+ "add_assumption",
372
+ *[](CpModelBuilder& self, BoolVar lit) {
373
+ self.AddAssumption(lit);
374
+ })
375
+ .define_method(
376
+ "add_assumptions",
377
+ *[](CpModelBuilder& self, BoolVarSpan literals) {
378
+ self.AddAssumptions(literals);
379
+ })
380
+ .define_method(
381
+ "clear_assumptions",
382
+ *[](CpModelBuilder& self) {
383
+ self.ClearAssumptions();
384
+ })
385
+ .define_method(
386
+ "to_s",
387
+ *[](CpModelBuilder& self) {
388
+ std::string proto_string;
389
+ google::protobuf::TextFormat::PrintToString(self.Proto(), &proto_string);
390
+ return proto_string;
391
+ });
392
+
393
+ Rice::define_class_under(m, "CpSolver")
394
+ .define_method(
395
+ "_solve_with_observer",
396
+ *[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
397
+ Model m;
398
+
399
+ if (all_solutions) {
400
+ // set parameters for SearchForAllSolutions
401
+ parameters.set_enumerate_all_solutions(true);
402
+ }
403
+ m.Add(NewSatParameters(parameters));
404
+
405
+ m.Add(NewFeasibleSolutionObserver(
406
+ [callback](const CpSolverResponse& r) {
407
+ // TODO find a better way to do this
408
+ callback.call("response=", r);
409
+ callback.call("on_solution_callback");
410
+ })
411
+ );
412
+ return SolveCpModel(model.Build(), &m);
413
+ })
414
+ .define_method(
415
+ "_solve",
416
+ *[](Object self, CpModelBuilder& model, SatParameters& parameters) {
417
+ Model m;
418
+ m.Add(NewSatParameters(parameters));
419
+ return SolveCpModel(model.Build(), &m);
420
+ })
421
+ .define_method(
422
+ "_solution_integer_value",
423
+ *[](Object self, CpSolverResponse& response, IntVar& x) {
424
+ return SolutionIntegerValue(response, x);
425
+ })
426
+ .define_method(
427
+ "_solution_boolean_value",
428
+ *[](Object self, CpSolverResponse& response, BoolVar& x) {
429
+ return SolutionBooleanValue(response, x);
430
+ });
431
+
432
+ Rice::define_class_under<CpSolverResponse>(m, "CpSolverResponse")
433
+ .define_method("objective_value", &CpSolverResponse::objective_value)
434
+ .define_method("num_conflicts", &CpSolverResponse::num_conflicts)
435
+ .define_method("num_branches", &CpSolverResponse::num_branches)
436
+ .define_method("wall_time", &CpSolverResponse::wall_time)
437
+ .define_method(
438
+ "solution_integer_value",
439
+ *[](CpSolverResponse& self, IntVar& x) {
440
+ LinearExpr expr(x);
441
+ return SolutionIntegerValue(self, expr);
442
+ })
443
+ .define_method("solution_boolean_value", &SolutionBooleanValue)
444
+ .define_method(
445
+ "status",
446
+ *[](CpSolverResponse& self) {
447
+ auto status = self.status();
448
+
449
+ if (status == CpSolverStatus::OPTIMAL) {
450
+ return Symbol("optimal");
451
+ } else if (status == CpSolverStatus::FEASIBLE) {
452
+ return Symbol("feasible");
453
+ } else if (status == CpSolverStatus::INFEASIBLE) {
454
+ return Symbol("infeasible");
455
+ } else if (status == CpSolverStatus::MODEL_INVALID) {
456
+ return Symbol("model_invalid");
457
+ } else if (status == CpSolverStatus::UNKNOWN) {
458
+ return Symbol("unknown");
459
+ } else {
460
+ throw std::runtime_error("Unknown solver status");
461
+ }
462
+ })
463
+ .define_method(
464
+ "sufficient_assumptions_for_infeasibility",
465
+ *[](CpSolverResponse& self) {
466
+ auto a = Array();
467
+ auto assumptions = self.sufficient_assumptions_for_infeasibility();
468
+ for (auto const& v : assumptions) {
469
+ a.push(v);
470
+ }
471
+ return a;
472
+ });
473
+ }