1 /* Common part of the Prolog interfaces: variables and non-inline functions.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #include "ppl_prolog_common_defs.hh"
25 #include <exception>
26 #include <stdexcept>
27 #include <sstream>
28 #include <climits>
29 #include <typeinfo>
30
31 namespace Parma_Polyhedra_Library {
32
33 namespace Interfaces {
34
35 namespace Prolog {
36
37 #if PROLOG_TRACK_ALLOCATION || NOISY_PROLOG_TRACK_ALLOCATION
38
Allocation_Tracker()39 Allocation_Tracker::Allocation_Tracker() {
40 }
41
~Allocation_Tracker()42 Allocation_Tracker::~Allocation_Tracker() {
43 Set::size_type n = s.size();
44 if (n > 0)
45 std::cerr
46 << "Interfaces::Prolog::Allocation_Tracker: "
47 << n << " object(s) leaked!"
48 << std::endl;
49 }
50
51 Allocation_Tracker allocation_tracker;
52
53 #endif // PROLOG_TRACK_ALLOCATION || NOISY_PROLOG_TRACK_ALLOCATION
54
55
56
57 // For the out-of-memory exception.
58 Prolog_atom out_of_memory_exception_atom;
59
60 // For variables.
61 Prolog_atom a_dollar_VAR;
62
63 // For linear expressions.
64 Prolog_atom a_plus;
65 Prolog_atom a_minus;
66 Prolog_atom a_asterisk;
67
68 // To represent rational numbers as fractions.
69 Prolog_atom a_slash;
70
71 // For constraints.
72 Prolog_atom a_less_than;
73 Prolog_atom a_equal_less_than;
74 Prolog_atom a_equal;
75 Prolog_atom a_greater_than_equal;
76 Prolog_atom a_greater_than;
77
78 // For congruences.
79 Prolog_atom a_is_congruent_to;
80 Prolog_atom a_modulo;
81
82 // For generators.
83 Prolog_atom a_line;
84 Prolog_atom a_ray;
85 Prolog_atom a_point;
86 Prolog_atom a_closure_point;
87
88 // For grid_generators.
89 Prolog_atom a_grid_line;
90 Prolog_atom a_parameter;
91 Prolog_atom a_grid_point;
92
93 // For artificial_parameters.
94 Prolog_atom a_divided_by;
95
96 // For the relation between a polyhedron and a constraint.
97 Prolog_atom a_is_disjoint;
98 Prolog_atom a_strictly_intersects;
99 Prolog_atom a_is_included;
100 Prolog_atom a_saturates;
101
102 // For the relation between a polyhedron and a generator.
103 Prolog_atom a_subsumes;
104
105 // Denotes a closed interval boundary.
106 Prolog_atom a_c;
107
108 // Denotes the empty set such as the empty interval or polyhedron.
109 Prolog_atom a_empty;
110
111 // Denotes the universe polyhedron.
112 Prolog_atom a_universe;
113
114 // Denotes the maximization mode for optimization problems.
115 Prolog_atom a_max;
116
117 // Denotes the minimization mode for optimization problems.
118 Prolog_atom a_min;
119
120 // Denote possible widths of bounded integer types.
121 Prolog_atom a_bits_8;
122 Prolog_atom a_bits_16;
123 Prolog_atom a_bits_32;
124 Prolog_atom a_bits_64;
125 Prolog_atom a_bits_128;
126
127 // Denote possible representations of bounded integer types.
128 Prolog_atom a_unsigned;
129 Prolog_atom a_signed_2_complement;
130
131 // Denote possible overflow behavior of bounded integer types.
132 Prolog_atom a_overflow_wraps;
133 Prolog_atom a_overflow_undefined;
134 Prolog_atom a_overflow_impossible;
135
136 // Denote possible outcomes of MIP and PIP problems solution attempts.
137 Prolog_atom a_unfeasible;
138 Prolog_atom a_unbounded;
139 Prolog_atom a_optimized;
140
141 // Denotes an open interval boundary.
142 Prolog_atom a_o;
143
144 // Denotes the constructor that turns two boundaries into a proper interval.
145 Prolog_atom a_i;
146
147 // Denote the -infinity and +infinity interval boundaries.
148 Prolog_atom a_minf;
149 Prolog_atom a_pinf;
150
151 // Denote complexity classes.
152 Prolog_atom a_polynomial;
153 Prolog_atom a_simplex;
154 Prolog_atom a_any;
155
156 // Denote control_parameters.
157 Prolog_atom a_pricing;
158 Prolog_atom a_pricing_steepest_edge_float;
159 Prolog_atom a_pricing_steepest_edge_exact;
160 Prolog_atom a_pricing_textbook;
161
162 Prolog_atom a_cutting_strategy;
163 Prolog_atom a_cutting_strategy_first;
164 Prolog_atom a_cutting_strategy_deepest;
165 Prolog_atom a_cutting_strategy_all;
166
167 Prolog_atom a_pivot_row_strategy;
168 Prolog_atom a_pivot_row_strategy_first;
169 Prolog_atom a_pivot_row_strategy_max_column;
170
171 // Default timeout exception atom.
172 Prolog_atom a_time_out;
173
174 // "Out of memory" exception atom.
175 Prolog_atom a_out_of_memory;
176
177 // Boolean constants.
178 Prolog_atom a_true;
179 Prolog_atom a_false;
180
181 // To build exception terms.
182 Prolog_atom a_ppl_overflow_error;
183 Prolog_atom a_ppl_domain_error;
184 Prolog_atom a_ppl_length_error;
185 Prolog_atom a_ppl_invalid_argument;
186 Prolog_atom a_ppl_logic_error;
187 Prolog_atom a_ppl_representation_error;
188 Prolog_atom a_expected;
189 Prolog_atom a_found;
190 Prolog_atom a_where;
191
192 const Prolog_Interface_Atom prolog_interface_atoms[] = {
193 { &a_dollar_VAR, "$VAR" },
194
195 { &a_plus, "+" },
196 { &a_minus, "-" },
197 { &a_asterisk, "*" },
198
199 { &a_slash, "/" },
200
201 { &a_equal, "=" },
202 { &a_greater_than_equal, ">=" },
203 { &a_equal_less_than, "=<" },
204 { &a_greater_than, ">" },
205 { &a_less_than, "<" },
206
207 { &a_is_congruent_to, "=:=" },
208 { &a_modulo, "/" },
209
210 { &a_divided_by, "/" },
211
212 { &a_line, "line" },
213 { &a_ray, "ray" },
214 { &a_point, "point" },
215 { &a_closure_point, "closure_point" },
216
217 { &a_grid_line, "grid_line" },
218 { &a_parameter, "parameter" },
219 { &a_grid_point, "grid_point" },
220
221 { &a_is_disjoint, "is_disjoint" },
222 { &a_strictly_intersects, "strictly_intersects" },
223 { &a_is_included, "is_included" },
224 { &a_saturates, "saturates" },
225
226 { &a_subsumes, "subsumes" },
227
228 { &a_c, "c" },
229
230 { &a_empty, "empty" },
231 { &a_universe, "universe" },
232
233 { &a_max, "max" },
234 { &a_min, "min" },
235
236 { &a_bits_8, "bits_8" },
237 { &a_bits_16, "bits_16" },
238 { &a_bits_32, "bits_32" },
239 { &a_bits_64, "bits_64" },
240 { &a_bits_128, "bits_128" },
241
242 { &a_unsigned, "unsigned" },
243 { &a_signed_2_complement, "signed_2_complement" },
244
245 { &a_overflow_wraps, "overflow_wraps" },
246 { &a_overflow_undefined, "overflow_undefined" },
247 { &a_overflow_impossible, "overflow_impossible" },
248
249 { &a_unfeasible, "unfeasible" },
250 { &a_unbounded, "unbounded" },
251 { &a_optimized, "optimized" },
252
253 { &a_o, "o" },
254 { &a_i, "i" },
255
256 { &a_minf, "minf" },
257 { &a_pinf, "pinf" },
258
259 { &a_polynomial, "polynomial" },
260 { &a_simplex, "simplex" },
261 { &a_any, "any" },
262
263 { &a_pricing, "pricing" },
264 { &a_pricing_steepest_edge_float,
265 "pricing_steepest_edge_float" },
266 { &a_pricing_steepest_edge_exact,
267 "pricing_steepest_edge_exact" },
268 { &a_pricing_textbook, "pricing_textbook" },
269
270 { &a_cutting_strategy, "cutting_strategy" },
271 { &a_cutting_strategy_first, "cutting_strategy_first" },
272 { &a_cutting_strategy_deepest, "cutting_strategy_deepest" },
273 { &a_cutting_strategy_all, "cutting_strategy_all" },
274
275 { &a_pivot_row_strategy, "pivot_row_strategy" },
276 { &a_pivot_row_strategy_first, "pivot_row_strategy_first" },
277 { &a_pivot_row_strategy_max_column,
278 "pivot_row_strategy_max_column" },
279
280 { &a_time_out, "time_out" },
281 { &a_out_of_memory, "out_of_memory" },
282
283 { &a_true, "true" },
284 { &a_false, "false" },
285
286 { &a_ppl_invalid_argument, "ppl_invalid_argument" },
287 { &a_ppl_overflow_error, "ppl_overflow_error" },
288 { &a_ppl_domain_error, "ppl_domain_error" },
289 { &a_ppl_length_error, "ppl_length_error" },
290 { &a_ppl_invalid_argument, "ppl_invalid_argument" },
291 { &a_ppl_logic_error, "ppl_logic_error" },
292 { &a_ppl_representation_error, "ppl_representation_error" },
293 { &a_expected, "expected" },
294 { &a_found, "found" },
295 { &a_where, "where" },
296 { 0, 0 }
297 };
298
299 Prolog_term_ref
Prolog_atom_term_from_string(const char * s)300 Prolog_atom_term_from_string(const char* s) {
301 Prolog_term_ref t = Prolog_new_term_ref();
302 Prolog_put_atom(t, Prolog_atom_from_string(s));
303 return t;
304 }
305
306 void
handle_exception(const Prolog_unsigned_out_of_range & e)307 handle_exception(const Prolog_unsigned_out_of_range& e) {
308 Prolog_term_ref found = Prolog_new_term_ref();
309 Prolog_construct_compound(found, a_found, e.term());
310
311 Prolog_term_ref max = Prolog_new_term_ref();
312 Prolog_put_ulong(max, e.max());
313 Prolog_construct_compound(max,
314 Prolog_atom_from_string("unsigned_integer"
315 "_less_or_equal"),
316 max);
317 Prolog_term_ref expected = Prolog_new_term_ref();
318 Prolog_construct_compound(expected, a_expected, max);
319
320 Prolog_term_ref where = Prolog_new_term_ref();
321 Prolog_construct_compound(where, a_where,
322 Prolog_atom_term_from_string(e.where()));
323
324 Prolog_term_ref exception_term = Prolog_new_term_ref();
325 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
326 found, expected, where);
327 Prolog_raise_exception(exception_term);
328 }
329
330 void
handle_exception(const not_unsigned_integer & e)331 handle_exception(const not_unsigned_integer& e) {
332 Prolog_term_ref found = Prolog_new_term_ref();
333 Prolog_construct_compound(found, a_found, e.term());
334
335 Prolog_term_ref expected = Prolog_new_term_ref();
336 Prolog_construct_compound(expected, a_expected,
337 Prolog_atom_term_from_string("unsigned_integer"));
338
339 Prolog_term_ref where = Prolog_new_term_ref();
340 Prolog_construct_compound(where, a_where,
341 Prolog_atom_term_from_string(e.where()));
342
343 Prolog_term_ref exception_term = Prolog_new_term_ref();
344 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
345 found, expected, where);
346 Prolog_raise_exception(exception_term);
347 }
348
349 void
handle_exception(const non_linear & e)350 handle_exception(const non_linear& e) {
351 Prolog_term_ref found = Prolog_new_term_ref();
352 Prolog_construct_compound(found, a_found, e.term());
353
354 Prolog_term_ref expected = Prolog_new_term_ref();
355 Prolog_construct_compound(expected, a_expected,
356 Prolog_atom_term_from_string
357 ("linear_expression_or_constraint"));
358
359 Prolog_term_ref where = Prolog_new_term_ref();
360 Prolog_construct_compound(where, a_where,
361 Prolog_atom_term_from_string(e.where()));
362
363 Prolog_term_ref exception_term = Prolog_new_term_ref();
364 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
365 found, expected, where);
366 Prolog_raise_exception(exception_term);
367 }
368
369 void
handle_exception(const not_a_variable & e)370 handle_exception(const not_a_variable& e) {
371 Prolog_term_ref found = Prolog_new_term_ref();
372 Prolog_construct_compound(found, a_found,
373 e.term());
374
375 Prolog_term_ref expected = Prolog_new_term_ref();
376 Prolog_construct_compound(expected, a_expected,
377 Prolog_atom_term_from_string
378 ("$VAR(unsigned_integer)"));
379
380 Prolog_term_ref where = Prolog_new_term_ref();
381 Prolog_construct_compound(where, a_where,
382 Prolog_atom_term_from_string(e.where()));
383
384 Prolog_term_ref exception_term = Prolog_new_term_ref();
385 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
386 found, expected, where);
387 Prolog_raise_exception(exception_term);
388 }
389
390 void
handle_exception(const not_an_integer & e)391 handle_exception(const not_an_integer& e) {
392 Prolog_term_ref found = Prolog_new_term_ref();
393 Prolog_construct_compound(found, a_found, e.term());
394
395 Prolog_term_ref expected = Prolog_new_term_ref();
396 Prolog_construct_compound(expected, a_expected,
397 Prolog_atom_term_from_string("integer"));
398
399 Prolog_term_ref where = Prolog_new_term_ref();
400 Prolog_construct_compound(where, a_where,
401 Prolog_atom_term_from_string(e.where()));
402
403 Prolog_term_ref exception_term = Prolog_new_term_ref();
404 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
405 found, expected, where);
406 Prolog_raise_exception(exception_term);
407 }
408
409 void
handle_exception(const ppl_handle_mismatch & e)410 handle_exception(const ppl_handle_mismatch& e) {
411 Prolog_term_ref found = Prolog_new_term_ref();
412 Prolog_construct_compound(found, a_found, e.term());
413
414 Prolog_term_ref expected = Prolog_new_term_ref();
415 Prolog_construct_compound(expected, a_expected,
416 Prolog_atom_term_from_string("handle"));
417
418 Prolog_term_ref where = Prolog_new_term_ref();
419 Prolog_construct_compound(where, a_where,
420 Prolog_atom_term_from_string(e.where()));
421
422 Prolog_term_ref exception_term = Prolog_new_term_ref();
423 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
424 found, expected, where);
425 Prolog_raise_exception(exception_term);
426 }
427
428 void
handle_exception(const not_an_optimization_mode & e)429 handle_exception(const not_an_optimization_mode& e) {
430 Prolog_term_ref found = Prolog_new_term_ref();
431 Prolog_construct_compound(found, a_found, e.term());
432
433 Prolog_term_ref expected = Prolog_new_term_ref();
434 Prolog_put_nil(expected);
435 Prolog_construct_cons(expected,
436 Prolog_atom_term_from_string("max"), expected);
437 Prolog_construct_cons(expected,
438 Prolog_atom_term_from_string("min"), expected);
439 Prolog_construct_compound(expected, a_expected, expected);
440
441 Prolog_term_ref where = Prolog_new_term_ref();
442 Prolog_construct_compound(where, a_where,
443 Prolog_atom_term_from_string(e.where()));
444 Prolog_term_ref exception_term = Prolog_new_term_ref();
445 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
446 found, expected, where);
447 Prolog_raise_exception(exception_term);
448 }
449
450 void
handle_exception(const not_a_complexity_class & e)451 handle_exception(const not_a_complexity_class& e) {
452 Prolog_term_ref found = Prolog_new_term_ref();
453 Prolog_construct_compound(found, a_found, e.term());
454
455 Prolog_term_ref expected = Prolog_new_term_ref();
456 Prolog_put_nil(expected);
457 Prolog_construct_cons(expected,
458 Prolog_atom_term_from_string("polynomial"), expected);
459 Prolog_construct_cons(expected,
460 Prolog_atom_term_from_string("simplex"), expected);
461 Prolog_construct_cons(expected,
462 Prolog_atom_term_from_string("any"), expected);
463 Prolog_construct_compound(expected, a_expected, expected);
464
465 Prolog_term_ref where = Prolog_new_term_ref();
466 Prolog_construct_compound(where, a_where,
467 Prolog_atom_term_from_string(e.where()));
468 Prolog_term_ref exception_term = Prolog_new_term_ref();
469 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
470 found, expected, where);
471 Prolog_raise_exception(exception_term);
472 }
473
474 void
handle_exception(const not_a_control_parameter_name & e)475 handle_exception(const not_a_control_parameter_name& e) {
476 Prolog_term_ref found = Prolog_new_term_ref();
477 Prolog_construct_compound(found, a_found, e.term());
478
479 Prolog_term_ref expected = Prolog_new_term_ref();
480 Prolog_put_nil(expected);
481 Prolog_construct_cons(expected,
482 Prolog_atom_term_from_string("pricing"), expected);
483
484 Prolog_term_ref where = Prolog_new_term_ref();
485 Prolog_construct_compound(where, a_where,
486 Prolog_atom_term_from_string(e.where()));
487 Prolog_term_ref exception_term = Prolog_new_term_ref();
488 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
489 found, expected, where);
490 Prolog_raise_exception(exception_term);
491 }
492
493 void
handle_exception(const not_a_control_parameter_value & e)494 handle_exception(const not_a_control_parameter_value& e) {
495 Prolog_term_ref found = Prolog_new_term_ref();
496 Prolog_construct_compound(found, a_found, e.term());
497
498 Prolog_term_ref expected = Prolog_new_term_ref();
499 Prolog_put_nil(expected);
500 Prolog_construct_cons(expected,
501 Prolog_atom_term_from_string("pricing_steepest_edge_float"),
502 expected);
503 Prolog_construct_cons(expected,
504 Prolog_atom_term_from_string("pricing_steepest_edge_exact"),
505 expected);
506 Prolog_construct_cons(expected,
507 Prolog_atom_term_from_string("pricing_textbook"),
508 expected);
509
510 Prolog_term_ref where = Prolog_new_term_ref();
511 Prolog_construct_compound(where, a_where,
512 Prolog_atom_term_from_string(e.where()));
513 Prolog_term_ref exception_term = Prolog_new_term_ref();
514 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
515 found, expected, where);
516 Prolog_raise_exception(exception_term);
517 }
518
519 void
handle_exception(const not_a_pip_problem_control_parameter_name & e)520 handle_exception(const not_a_pip_problem_control_parameter_name& e) {
521 Prolog_term_ref found = Prolog_new_term_ref();
522 Prolog_construct_compound(found, a_found, e.term());
523
524 Prolog_term_ref expected = Prolog_new_term_ref();
525 Prolog_put_nil(expected);
526 Prolog_construct_cons(expected,
527 Prolog_atom_term_from_string("cutting_strategy"),
528 expected);
529 Prolog_construct_cons(expected,
530 Prolog_atom_term_from_string("pivot_row_strategy"),
531 expected);
532
533 Prolog_term_ref where = Prolog_new_term_ref();
534 Prolog_construct_compound(where, a_where,
535 Prolog_atom_term_from_string(e.where()));
536 Prolog_term_ref exception_term = Prolog_new_term_ref();
537 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
538 found, expected, where);
539 Prolog_raise_exception(exception_term);
540 }
541
542 void
handle_exception(const not_a_pip_problem_control_parameter_value & e)543 handle_exception(const not_a_pip_problem_control_parameter_value& e) {
544 Prolog_term_ref found = Prolog_new_term_ref();
545 Prolog_construct_compound(found, a_found, e.term());
546
547 Prolog_term_ref expected = Prolog_new_term_ref();
548 Prolog_put_nil(expected);
549 Prolog_construct_cons(expected,
550 Prolog_atom_term_from_string("cutting_strategy_first"),
551 expected);
552 Prolog_construct_cons(expected,
553 Prolog_atom_term_from_string("cutting_strategy_deepest"),
554 expected);
555 Prolog_construct_cons(expected,
556 Prolog_atom_term_from_string("cutting_strategy_all"),
557 expected);
558 Prolog_construct_cons(expected,
559 Prolog_atom_term_from_string("pivot_row_strategy_first"),
560 expected);
561 Prolog_construct_cons(expected,
562 Prolog_atom_term_from_string("pivot_row_strategy_max_column"),
563 expected);
564 Prolog_term_ref where = Prolog_new_term_ref();
565 Prolog_construct_compound(where, a_where,
566 Prolog_atom_term_from_string(e.where()));
567 Prolog_term_ref exception_term = Prolog_new_term_ref();
568 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
569 found, expected, where);
570 Prolog_raise_exception(exception_term);
571 }
572
573 void
handle_exception(const not_universe_or_empty & e)574 handle_exception(const not_universe_or_empty& e) {
575 Prolog_term_ref found = Prolog_new_term_ref();
576 Prolog_construct_compound(found, a_found, e.term());
577
578 Prolog_term_ref expected = Prolog_new_term_ref();
579 Prolog_put_nil(expected);
580 Prolog_construct_cons(expected,
581 Prolog_atom_term_from_string("universe"), expected);
582 Prolog_construct_cons(expected,
583 Prolog_atom_term_from_string("empty"), expected);
584 Prolog_construct_compound(expected, a_expected, expected);
585
586 Prolog_term_ref where = Prolog_new_term_ref();
587 Prolog_construct_compound(where, a_where,
588 Prolog_atom_term_from_string(e.where()));
589 Prolog_term_ref exception_term = Prolog_new_term_ref();
590 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
591 found, expected, where);
592 Prolog_raise_exception(exception_term);
593 }
594
595 void
handle_exception(const not_a_boolean & e)596 handle_exception(const not_a_boolean& e) {
597 Prolog_term_ref found = Prolog_new_term_ref();
598 Prolog_construct_compound(found, a_found, e.term());
599
600 Prolog_term_ref expected = Prolog_new_term_ref();
601 Prolog_put_nil(expected);
602 Prolog_construct_cons(expected,
603 Prolog_atom_term_from_string("true"), expected);
604 Prolog_construct_cons(expected,
605 Prolog_atom_term_from_string("false"), expected);
606 Prolog_construct_compound(expected, a_expected, expected);
607
608 Prolog_term_ref where = Prolog_new_term_ref();
609 Prolog_construct_compound(where, a_where,
610 Prolog_atom_term_from_string(e.where()));
611 Prolog_term_ref exception_term = Prolog_new_term_ref();
612 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
613 found, expected, where);
614 Prolog_raise_exception(exception_term);
615 }
616
617 void
handle_exception(const not_a_bounded_integer_type_width & e)618 handle_exception(const not_a_bounded_integer_type_width& e) {
619 Prolog_term_ref found = Prolog_new_term_ref();
620 Prolog_construct_compound(found, a_found, e.term());
621
622 Prolog_term_ref expected = Prolog_new_term_ref();
623 Prolog_put_nil(expected);
624 Prolog_construct_cons(expected,
625 Prolog_atom_term_from_string("bits_8"), expected);
626 Prolog_construct_cons(expected,
627 Prolog_atom_term_from_string("bits_16"), expected);
628 Prolog_construct_cons(expected,
629 Prolog_atom_term_from_string("bits_32"), expected);
630 Prolog_construct_cons(expected,
631 Prolog_atom_term_from_string("bits_64"), expected);
632 Prolog_construct_cons(expected,
633 Prolog_atom_term_from_string("bits_128"), expected);
634 Prolog_construct_compound(expected, a_expected, expected);
635
636 Prolog_term_ref where = Prolog_new_term_ref();
637 Prolog_construct_compound(where, a_where,
638 Prolog_atom_term_from_string(e.where()));
639 Prolog_term_ref exception_term = Prolog_new_term_ref();
640 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
641 found, expected, where);
642 Prolog_raise_exception(exception_term);
643 }
644
645 void
handle_exception(const not_a_bounded_integer_type_representation & e)646 handle_exception(const not_a_bounded_integer_type_representation& e) {
647 Prolog_term_ref found = Prolog_new_term_ref();
648 Prolog_construct_compound(found, a_found, e.term());
649
650 Prolog_term_ref expected = Prolog_new_term_ref();
651 Prolog_put_nil(expected);
652 Prolog_construct_cons(expected,
653 Prolog_atom_term_from_string("unsigned"), expected);
654 Prolog_construct_cons(expected,
655 Prolog_atom_term_from_string("signed_2_complement"),
656 expected);
657 Prolog_construct_compound(expected, a_expected, expected);
658
659 Prolog_term_ref where = Prolog_new_term_ref();
660 Prolog_construct_compound(where, a_where,
661 Prolog_atom_term_from_string(e.where()));
662 Prolog_term_ref exception_term = Prolog_new_term_ref();
663 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
664 found, expected, where);
665 Prolog_raise_exception(exception_term);
666 }
667
668 void
handle_exception(const not_a_bounded_integer_type_overflow & e)669 handle_exception(const not_a_bounded_integer_type_overflow& e) {
670 Prolog_term_ref found = Prolog_new_term_ref();
671 Prolog_construct_compound(found, a_found, e.term());
672
673 Prolog_term_ref expected = Prolog_new_term_ref();
674 Prolog_put_nil(expected);
675 Prolog_construct_cons(expected,
676 Prolog_atom_term_from_string("overflow_wraps"),
677 expected);
678 Prolog_construct_cons(expected,
679 Prolog_atom_term_from_string("overflow_undefined"),
680 expected);
681 Prolog_construct_cons(expected,
682 Prolog_atom_term_from_string("overflow_impossible"),
683 expected);
684 Prolog_construct_compound(expected, a_expected, expected);
685
686 Prolog_term_ref where = Prolog_new_term_ref();
687 Prolog_construct_compound(where, a_where,
688 Prolog_atom_term_from_string(e.where()));
689 Prolog_term_ref exception_term = Prolog_new_term_ref();
690 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
691 found, expected, where);
692 Prolog_raise_exception(exception_term);
693 }
694
695 void
handle_exception(const not_a_relation & e)696 handle_exception(const not_a_relation& e) {
697 Prolog_term_ref found = Prolog_new_term_ref();
698 Prolog_construct_compound(found, a_found, e.term());
699
700 Prolog_term_ref expected = Prolog_new_term_ref();
701 Prolog_put_nil(expected);
702 Prolog_construct_cons(expected,
703 Prolog_atom_term_from_string("="), expected);
704 Prolog_construct_cons(expected,
705 Prolog_atom_term_from_string(">="), expected);
706 Prolog_construct_cons(expected,
707 Prolog_atom_term_from_string("=<"), expected);
708 Prolog_construct_cons(expected,
709 Prolog_atom_term_from_string(">"), expected);
710 Prolog_construct_cons(expected,
711 Prolog_atom_term_from_string("<"), expected);
712 Prolog_construct_compound(expected, a_expected, expected);
713
714 Prolog_term_ref where = Prolog_new_term_ref();
715 Prolog_construct_compound(where, a_where,
716 Prolog_atom_term_from_string(e.where()));
717 Prolog_term_ref exception_term = Prolog_new_term_ref();
718 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
719 found, expected, where);
720 Prolog_raise_exception(exception_term);
721 }
722
723 void
handle_exception(const not_a_nil_terminated_list & e)724 handle_exception(const not_a_nil_terminated_list& e) {
725 Prolog_term_ref found = Prolog_new_term_ref();
726 Prolog_construct_compound(found, a_found, e.term());
727
728 Prolog_term_ref expected = Prolog_new_term_ref();
729 Prolog_put_nil(expected);
730 Prolog_construct_cons(expected,
731 Prolog_atom_term_from_string
732 ("Prolog_list"), expected);
733 Prolog_construct_compound(expected, a_expected, expected);
734
735 Prolog_term_ref where = Prolog_new_term_ref();
736 Prolog_construct_compound(where, a_where,
737 Prolog_atom_term_from_string(e.where()));
738 Prolog_term_ref exception_term = Prolog_new_term_ref();
739 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
740 found, expected, where);
741 Prolog_raise_exception(exception_term);
742 }
743
744 void
handle_exception(const PPL_integer_out_of_range & e)745 handle_exception(const PPL_integer_out_of_range& e) {
746 Prolog_term_ref where = Prolog_new_term_ref();
747 Prolog_construct_compound(where, a_where,
748 Prolog_atom_term_from_string("Coefficient_to_integer_term"));
749
750 Prolog_term_ref exception_term = Prolog_new_term_ref();
751 std::ostringstream s;
752 s << e.value();
753 std::string str = s.str();
754 Prolog_construct_compound(exception_term, a_ppl_representation_error,
755 Prolog_atom_term_from_string(str.c_str()),
756 where);
757 Prolog_raise_exception(exception_term);
758 }
759
760 void
handle_exception(const unknown_interface_error & e)761 handle_exception(const unknown_interface_error& e) {
762 Prolog_term_ref et = Prolog_new_term_ref();
763 Prolog_put_atom_chars(et, e.where());
764 Prolog_raise_exception(et);
765 }
766
767 void
handle_exception(const std::overflow_error & e)768 handle_exception(const std::overflow_error& e) {
769 Prolog_term_ref et = Prolog_new_term_ref();
770 Prolog_construct_compound(et, a_ppl_overflow_error,
771 Prolog_atom_term_from_string(e.what()));
772 Prolog_raise_exception(et);
773 }
774
775 void
handle_exception(const std::domain_error & e)776 handle_exception(const std::domain_error& e) {
777 Prolog_term_ref et = Prolog_new_term_ref();
778 Prolog_construct_compound(et, a_ppl_domain_error,
779 Prolog_atom_term_from_string(e.what()));
780 Prolog_raise_exception(et);
781 }
782
783 void
handle_exception(const std::length_error & e)784 handle_exception(const std::length_error& e) {
785 Prolog_term_ref et = Prolog_new_term_ref();
786 Prolog_construct_compound(et, a_ppl_length_error,
787 Prolog_atom_term_from_string(e.what()));
788 Prolog_raise_exception(et);
789 }
790
791 void
handle_exception(const std::invalid_argument & e)792 handle_exception(const std::invalid_argument& e) {
793 Prolog_term_ref et = Prolog_new_term_ref();
794 Prolog_construct_compound(et, a_ppl_invalid_argument,
795 Prolog_atom_term_from_string(e.what()));
796 Prolog_raise_exception(et);
797 }
798
799 void
handle_exception(const std::logic_error & e)800 handle_exception(const std::logic_error& e) {
801 Prolog_term_ref et = Prolog_new_term_ref();
802 Prolog_construct_compound(et, a_ppl_logic_error,
803 Prolog_atom_term_from_string(e.what()));
804 Prolog_raise_exception(et);
805 }
806
807 void
handle_exception(const std::bad_alloc &)808 handle_exception(const std::bad_alloc&) {
809 Prolog_term_ref et = Prolog_new_term_ref();
810 Prolog_put_atom(et, out_of_memory_exception_atom);
811 Prolog_raise_exception(et);
812 }
813
814 void
handle_exception(const std::exception & e)815 handle_exception(const std::exception& e) {
816 Prolog_term_ref et = Prolog_new_term_ref();
817 Prolog_put_atom_chars(et, e.what());
818 Prolog_raise_exception(et);
819 }
820
821 void
handle_exception()822 handle_exception() {
823 Prolog_term_ref et = Prolog_new_term_ref();
824 Prolog_put_atom_chars(et, "PPL bug: unknown exception raised");
825 Prolog_raise_exception(et);
826 }
827
828 Parma_Polyhedra_Library::Watchdog* p_timeout_object = 0;
829
830 typedef
831 Parma_Polyhedra_Library::Threshold_Watcher
832 <Parma_Polyhedra_Library::Weightwatch_Traits> Weightwatch;
833
834 Weightwatch* p_deterministic_timeout_object = 0;
835
836 void
reset_timeout()837 reset_timeout() {
838 if (p_timeout_object) {
839 delete p_timeout_object;
840 p_timeout_object = 0;
841 abandon_expensive_computations = 0;
842 }
843 }
844
845 void
reset_deterministic_timeout()846 reset_deterministic_timeout() {
847 if (p_deterministic_timeout_object) {
848 delete p_deterministic_timeout_object;
849 p_deterministic_timeout_object = 0;
850 abandon_expensive_computations = 0;
851 }
852 }
853
854 Prolog_atom timeout_exception_atom;
855
856 void
handle_exception(const timeout_exception &)857 handle_exception(const timeout_exception&) {
858 assert(p_timeout_object);
859 reset_timeout();
860 Prolog_term_ref et = Prolog_new_term_ref();
861 Prolog_put_atom(et, timeout_exception_atom);
862 Prolog_raise_exception(et);
863 }
864
865 void
handle_exception(const deterministic_timeout_exception &)866 handle_exception(const deterministic_timeout_exception&) {
867 assert(p_deterministic_timeout_object);
868 reset_deterministic_timeout();
869 Prolog_term_ref et = Prolog_new_term_ref();
870 Prolog_put_atom(et, timeout_exception_atom);
871 Prolog_raise_exception(et);
872 }
873
874 Prolog_term_ref
variable_term(dimension_type varid)875 variable_term(dimension_type varid) {
876 Prolog_term_ref v = Prolog_new_term_ref();
877 Prolog_put_ulong(v, varid);
878 Prolog_term_ref t = Prolog_new_term_ref();
879 Prolog_construct_compound(t, a_dollar_VAR, v);
880 return t;
881 }
882
883 Prolog_atom
term_to_boolean(Prolog_term_ref t,const char * where)884 term_to_boolean(Prolog_term_ref t, const char* where) {
885 if (Prolog_is_atom(t)) {
886 Prolog_atom name;
887 if (Prolog_get_atom_name(t, &name)
888 && (name == a_true || name == a_false))
889 return name;
890 }
891 throw not_a_boolean(t, where);
892 }
893
894 Prolog_atom
term_to_universe_or_empty(Prolog_term_ref t,const char * where)895 term_to_universe_or_empty(Prolog_term_ref t, const char* where) {
896 if (Prolog_is_atom(t)) {
897 Prolog_atom name;
898 if (Prolog_get_atom_name(t, &name)
899 && (name == a_universe || name == a_empty))
900 return name;
901 }
902 throw not_universe_or_empty(t, where);
903 }
904
905 Coefficient
integer_term_to_Coefficient(Prolog_term_ref t)906 integer_term_to_Coefficient(Prolog_term_ref t) {
907 PPL_DIRTY_TEMP_COEFFICIENT(n);
908 assert(Prolog_is_integer(t));
909 if (!Prolog_get_Coefficient(t, n))
910 abort();
911 return n;
912 }
913
914 Prolog_term_ref
Coefficient_to_integer_term(const Coefficient & n)915 Coefficient_to_integer_term(const Coefficient& n) {
916 Prolog_term_ref t = Prolog_new_term_ref();
917 if (!Prolog_put_Coefficient(t, n))
918 abort();
919 return t;
920 }
921
922 bool
unify_long(Prolog_term_ref t,long l)923 unify_long(Prolog_term_ref t, long l) {
924 Prolog_term_ref t_l = Prolog_new_term_ref();
925 return Prolog_put_long(t_l, l) && Prolog_unify(t, t_l);
926 }
927
928 bool
unify_ulong(Prolog_term_ref t,unsigned long l)929 unify_ulong(Prolog_term_ref t, unsigned long l) {
930 Prolog_term_ref t_l = Prolog_new_term_ref();
931 return Prolog_put_ulong(t_l, l) && Prolog_unify(t, t_l);
932 }
933
934 Linear_Expression
build_linear_expression(Prolog_term_ref t,const char * where)935 build_linear_expression(Prolog_term_ref t, const char* where) {
936 if (Prolog_is_integer(t))
937 return Linear_Expression(integer_term_to_Coefficient(t));
938 else if (Prolog_is_compound(t)) {
939 Prolog_atom functor;
940 int arity;
941 Prolog_get_compound_name_arity(t, &functor, &arity);
942 switch (arity) {
943 case 1:
944 {
945 Prolog_term_ref arg = Prolog_new_term_ref();
946 Prolog_get_arg(1, t, arg);
947 if (functor == a_minus)
948 // Unary minus.
949 return -build_linear_expression(arg, where);
950 else if (functor == a_dollar_VAR)
951 // Variable.
952 return Variable(term_to_unsigned<dimension_type>(arg, where));
953 }
954 break;
955 case 2:
956 {
957 Prolog_term_ref arg1 = Prolog_new_term_ref();
958 Prolog_term_ref arg2 = Prolog_new_term_ref();
959 Prolog_get_arg(1, t, arg1);
960 Prolog_get_arg(2, t, arg2);
961 if (functor == a_plus)
962 // Plus.
963 if (Prolog_is_integer(arg1))
964 return integer_term_to_Coefficient(arg1)
965 + build_linear_expression(arg2, where);
966 else if (Prolog_is_integer(arg2))
967 return build_linear_expression(arg1, where)
968 + integer_term_to_Coefficient(arg2);
969 else
970 return build_linear_expression(arg1, where)
971 + build_linear_expression(arg2, where);
972 else if (functor == a_minus)
973 // Minus.
974 if (Prolog_is_integer(arg1))
975 return integer_term_to_Coefficient(arg1)
976 - build_linear_expression(arg2, where);
977 else if (Prolog_is_integer(arg2))
978 return build_linear_expression(arg1, where)
979 - integer_term_to_Coefficient(arg2);
980 else
981 return build_linear_expression(arg1, where)
982 - build_linear_expression(arg2, where);
983 else if (functor == a_asterisk) {
984 // Times.
985 if (Prolog_is_integer(arg1))
986 return integer_term_to_Coefficient(arg1)
987 * build_linear_expression(arg2, where);
988 else if (Prolog_is_integer(arg2))
989 return build_linear_expression(arg1, where)
990 * integer_term_to_Coefficient(arg2);
991 }
992 }
993 }
994 }
995 // Invalid.
996 throw non_linear(t, where);
997 }
998
999 Constraint
build_constraint(Prolog_term_ref t,const char * where)1000 build_constraint(Prolog_term_ref t, const char* where) {
1001 if (Prolog_is_compound(t)) {
1002 Prolog_atom functor;
1003 int arity;
1004 Prolog_get_compound_name_arity(t, &functor, &arity);
1005 if (arity == 2) {
1006 Prolog_term_ref arg1 = Prolog_new_term_ref();
1007 Prolog_term_ref arg2 = Prolog_new_term_ref();
1008 Prolog_get_arg(1, t, arg1);
1009 Prolog_get_arg(2, t, arg2);
1010 if (functor == a_equal)
1011 // =
1012 if (Prolog_is_integer(arg1))
1013 return integer_term_to_Coefficient(arg1)
1014 == build_linear_expression(arg2, where);
1015 else if (Prolog_is_integer(arg2))
1016 return build_linear_expression(arg1, where)
1017 == integer_term_to_Coefficient(arg2);
1018 else
1019 return build_linear_expression(arg1, where)
1020 == build_linear_expression(arg2, where);
1021 else if (functor == a_equal_less_than)
1022 // =<
1023 if (Prolog_is_integer(arg1))
1024 return integer_term_to_Coefficient(arg1)
1025 <= build_linear_expression(arg2, where);
1026 else if (Prolog_is_integer(arg2))
1027 return build_linear_expression(arg1, where)
1028 <= integer_term_to_Coefficient(arg2);
1029 else
1030 return build_linear_expression(arg1, where)
1031 <= build_linear_expression(arg2, where);
1032 else if (functor == a_greater_than_equal)
1033 // >=
1034 if (Prolog_is_integer(arg1))
1035 return integer_term_to_Coefficient(arg1)
1036 >= build_linear_expression(arg2, where);
1037 else if (Prolog_is_integer(arg2))
1038 return build_linear_expression(arg1, where)
1039 >= integer_term_to_Coefficient(arg2);
1040 else
1041 return build_linear_expression(arg1, where)
1042 >= build_linear_expression(arg2, where);
1043 else if (functor == a_less_than)
1044 // <
1045 if (Prolog_is_integer(arg1))
1046 return integer_term_to_Coefficient(arg1)
1047 < build_linear_expression(arg2, where);
1048 else if (Prolog_is_integer(arg2))
1049 return build_linear_expression(arg1, where)
1050 < integer_term_to_Coefficient(arg2);
1051 else
1052 return build_linear_expression(arg1, where)
1053 < build_linear_expression(arg2, where);
1054 else if (functor == a_greater_than) {
1055 // >
1056 if (Prolog_is_integer(arg1))
1057 return integer_term_to_Coefficient(arg1)
1058 > build_linear_expression(arg2, where);
1059 else if (Prolog_is_integer(arg2))
1060 return build_linear_expression(arg1, where)
1061 > integer_term_to_Coefficient(arg2);
1062 else
1063 return build_linear_expression(arg1, where)
1064 > build_linear_expression(arg2, where);
1065 }
1066 }
1067 }
1068 // Invalid.
1069 throw non_linear(t, where);
1070 }
1071
1072 Congruence
build_congruence(Prolog_term_ref t,const char * where)1073 build_congruence(Prolog_term_ref t, const char* where) {
1074 if (Prolog_is_compound(t)) {
1075 Prolog_atom functor;
1076 int arity;
1077 Prolog_get_compound_name_arity(t, &functor, &arity);
1078 if (arity == 2) {
1079 Prolog_term_ref arg1 = Prolog_new_term_ref();
1080 Prolog_term_ref arg2 = Prolog_new_term_ref();
1081 Prolog_get_arg(1, t, arg1);
1082 Prolog_get_arg(2, t, arg2);
1083 if (functor == a_modulo) {
1084 // /
1085 if (Prolog_is_integer(arg2)) {
1086 Prolog_atom functor1;
1087 int arity1;
1088 Prolog_get_compound_name_arity(arg1, &functor1, &arity1);
1089 if (arity1 == 2) {
1090 if (functor1 == a_is_congruent_to) {
1091 // =:=
1092 Prolog_term_ref arg11 = Prolog_new_term_ref();
1093 Prolog_term_ref arg12 = Prolog_new_term_ref();
1094 Prolog_get_arg(1, arg1, arg11);
1095 Prolog_get_arg(2, arg1, arg12);
1096 if (Prolog_is_integer(arg12))
1097 return (build_linear_expression(arg11, where)
1098 %= integer_term_to_Coefficient(arg12))
1099 / integer_term_to_Coefficient(arg2);
1100 else
1101 return (build_linear_expression(arg11, where)
1102 %= build_linear_expression(arg12, where))
1103 / integer_term_to_Coefficient(arg2);
1104 }
1105 }
1106 }
1107 }
1108 else
1109 if (functor == a_is_congruent_to)
1110 // =:=
1111 if (Prolog_is_integer(arg2))
1112 return build_linear_expression(arg1, where)
1113 %= integer_term_to_Coefficient(arg2);
1114 else
1115 return build_linear_expression(arg1, where)
1116 %= build_linear_expression(arg2, where);
1117 else
1118 if (functor == a_equal) {
1119 // =
1120 if (Prolog_is_integer(arg1))
1121 return (build_linear_expression(arg2, where)
1122 %= integer_term_to_Coefficient(arg1)) / 0;
1123 else if (Prolog_is_integer(arg2))
1124 return (build_linear_expression(arg1, where)
1125 %= integer_term_to_Coefficient(arg2)) / 0;
1126 else
1127 return (build_linear_expression(arg1, where)
1128 %= build_linear_expression(arg2, where)) / 0;
1129 }
1130 }
1131 }
1132 // Invalid.
1133 throw non_linear(t, where);
1134 }
1135
1136 Generator
build_generator(Prolog_term_ref t,const char * where)1137 build_generator(Prolog_term_ref t, const char* where) {
1138 if (Prolog_is_compound(t)) {
1139 Prolog_atom functor;
1140 int arity;
1141 Prolog_get_compound_name_arity(t, &functor, &arity);
1142 if (arity == 1) {
1143 Prolog_term_ref arg = Prolog_new_term_ref();
1144 Prolog_get_arg(1, t, arg);
1145 if (functor == a_line)
1146 return Generator::line(build_linear_expression(arg, where));
1147 else if (functor == a_ray)
1148 return Generator::ray(build_linear_expression(arg, where));
1149 else if (functor == a_point)
1150 return Generator::point(build_linear_expression(arg, where));
1151 else if (functor == a_closure_point)
1152 return Generator::closure_point(build_linear_expression(arg, where));
1153 }
1154 else if (arity == 2) {
1155 Prolog_term_ref arg1 = Prolog_new_term_ref();
1156 Prolog_term_ref arg2 = Prolog_new_term_ref();
1157 Prolog_get_arg(1, t, arg1);
1158 Prolog_get_arg(2, t, arg2);
1159 if (Prolog_is_integer(arg2)) {
1160 if (functor == a_point)
1161 return Generator::point(build_linear_expression(arg1, where),
1162 integer_term_to_Coefficient(arg2));
1163 else if (functor == a_closure_point)
1164 return Generator::closure_point(build_linear_expression(arg1, where),
1165 integer_term_to_Coefficient(arg2));
1166 }
1167 }
1168 }
1169 // Invalid.
1170 throw non_linear(t, where);
1171 }
1172
1173 Grid_Generator
build_grid_generator(Prolog_term_ref t,const char * where)1174 build_grid_generator(Prolog_term_ref t, const char* where) {
1175 if (Prolog_is_compound(t)) {
1176 Prolog_atom functor;
1177 int arity;
1178 Prolog_get_compound_name_arity(t, &functor, &arity);
1179 if (arity == 1) {
1180 Prolog_term_ref arg = Prolog_new_term_ref();
1181 Prolog_get_arg(1, t, arg);
1182 if (functor == a_grid_line)
1183 return Grid_Generator::grid_line(build_linear_expression(arg, where));
1184 else if (functor == a_parameter)
1185 return Grid_Generator::parameter(build_linear_expression(arg, where));
1186 else if (functor == a_grid_point)
1187 return Grid_Generator::grid_point(build_linear_expression(arg, where));
1188 }
1189 else if (arity == 2) {
1190 Prolog_term_ref arg1 = Prolog_new_term_ref();
1191 Prolog_term_ref arg2 = Prolog_new_term_ref();
1192 Prolog_get_arg(1, t, arg1);
1193 Prolog_get_arg(2, t, arg2);
1194 if (Prolog_is_integer(arg2)) {
1195 if (functor == a_grid_point)
1196 return Grid_Generator::grid_point(build_linear_expression(arg1,
1197 where),
1198 integer_term_to_Coefficient(arg2));
1199 else if (functor == a_parameter)
1200 return Grid_Generator::parameter(build_linear_expression(arg1,
1201 where),
1202 integer_term_to_Coefficient(arg2));
1203 }
1204 }
1205 }
1206 // Invalid.
1207 throw non_linear(t, where);
1208 }
1209
1210 template <typename R>
1211 Prolog_term_ref
get_homogeneous_expression(const R & r)1212 get_homogeneous_expression(const R& r) {
1213 Prolog_term_ref so_far = Prolog_new_term_ref();
1214 PPL_DIRTY_TEMP_COEFFICIENT(coefficient);
1215 dimension_type varid = 0;
1216 dimension_type space_dimension = r.space_dimension();
1217 while (varid < space_dimension
1218 && (coefficient = r.coefficient(Variable(varid))) == 0)
1219 ++varid;
1220 if (varid >= space_dimension) {
1221 Prolog_put_long(so_far, 0);
1222 }
1223 else {
1224 Prolog_construct_compound(so_far, a_asterisk,
1225 Coefficient_to_integer_term(coefficient),
1226 variable_term(varid));
1227 while (true) {
1228 ++varid;
1229 while (varid < space_dimension
1230 && (coefficient = r.coefficient(Variable(varid))) == 0)
1231 ++varid;
1232 if (varid >= space_dimension)
1233 break;
1234 else {
1235 Prolog_term_ref addendum = Prolog_new_term_ref();
1236 Prolog_construct_compound(addendum, a_asterisk,
1237 Coefficient_to_integer_term(coefficient),
1238 variable_term(varid));
1239 Prolog_term_ref new_so_far = Prolog_new_term_ref();
1240 Prolog_construct_compound(new_so_far, a_plus,
1241 so_far, addendum);
1242 so_far = new_so_far;
1243 }
1244 }
1245 }
1246 return so_far;
1247 }
1248
1249 Prolog_term_ref
get_linear_expression(const Linear_Expression & le)1250 get_linear_expression(const Linear_Expression& le) {
1251 Prolog_term_ref t_homo = get_homogeneous_expression(le);
1252 if (le.inhomogeneous_term() == 0)
1253 return t_homo;
1254 else {
1255 Prolog_term_ref t_in
1256 = Coefficient_to_integer_term(le.inhomogeneous_term());
1257 if (unify_long(t_homo, 0))
1258 return t_in;
1259 else {
1260 Prolog_term_ref t_le = Prolog_new_term_ref();
1261 Prolog_construct_compound(t_le, a_plus, t_homo, t_in);
1262 return t_le;
1263 }
1264 }
1265 }
1266
1267 Prolog_term_ref
constraint_term(const Constraint & c)1268 constraint_term(const Constraint& c) {
1269 Prolog_atom relation = 0;
1270 switch (c.type()) {
1271 case Constraint::EQUALITY:
1272 relation = a_equal;
1273 break;
1274 case Constraint::NONSTRICT_INEQUALITY:
1275 relation = a_greater_than_equal;
1276 break;
1277 case Constraint::STRICT_INEQUALITY:
1278 relation = a_greater_than;
1279 break;
1280 default:
1281 throw unknown_interface_error("generator_term()");
1282 }
1283 Prolog_term_ref t = Prolog_new_term_ref();
1284 Prolog_construct_compound
1285 (t,
1286 relation,
1287 get_homogeneous_expression(c),
1288 Coefficient_to_integer_term(-c.inhomogeneous_term()));
1289 return t;
1290 }
1291
1292 Prolog_term_ref
congruence_term(const Congruence & cg)1293 congruence_term(const Congruence& cg) {
1294 Prolog_atom relation1 = a_is_congruent_to;
1295 Prolog_atom relation2 = a_modulo;
1296 Prolog_term_ref t_tmp = Prolog_new_term_ref();
1297 Prolog_term_ref t = Prolog_new_term_ref();
1298 Prolog_construct_compound
1299 (t_tmp,
1300 relation1,
1301 get_homogeneous_expression(cg),
1302 Coefficient_to_integer_term(-cg.inhomogeneous_term()));
1303 Prolog_construct_compound
1304 (t,
1305 relation2,
1306 t_tmp,
1307 Coefficient_to_integer_term(cg.modulus()));
1308 return t;
1309 }
1310
1311 Prolog_term_ref
generator_term(const Generator & g)1312 generator_term(const Generator& g) {
1313 Prolog_term_ref t = Prolog_new_term_ref();
1314 Prolog_atom constructor = 0;
1315 switch (g.type()) {
1316 case Generator::LINE:
1317 constructor = a_line;
1318 break;
1319 case Generator::RAY:
1320 constructor = a_ray;
1321 break;
1322 case Generator::POINT:
1323 {
1324 constructor = a_point;
1325 const Coefficient& divisor = g.divisor();
1326 if (divisor == 1)
1327 break;
1328 else {
1329 Prolog_construct_compound(t, constructor,
1330 get_homogeneous_expression(g),
1331 Coefficient_to_integer_term(divisor));
1332 return t;
1333 }
1334 }
1335 case Generator::CLOSURE_POINT:
1336 {
1337 constructor = a_closure_point;
1338 const Coefficient& divisor = g.divisor();
1339 if (divisor == 1)
1340 break;
1341 else {
1342 Prolog_construct_compound(t, constructor,
1343 get_homogeneous_expression(g),
1344 Coefficient_to_integer_term(divisor));
1345 return t;
1346 }
1347 }
1348 default:
1349 throw unknown_interface_error("generator_term()");
1350 }
1351 Prolog_construct_compound(t, constructor, get_homogeneous_expression(g));
1352 return t;
1353 }
1354
1355 Prolog_term_ref
grid_generator_term(const Grid_Generator & g)1356 grid_generator_term(const Grid_Generator& g) {
1357 Prolog_term_ref t = Prolog_new_term_ref();
1358 Prolog_atom constructor = 0;
1359 switch (g.type()) {
1360 case Grid_Generator::LINE:
1361 constructor = a_grid_line;
1362 break;
1363 case Grid_Generator::PARAMETER:
1364 {
1365 constructor = a_parameter;
1366 const Coefficient& divisor = g.divisor();
1367 if (divisor == 1)
1368 break;
1369 else {
1370 Prolog_construct_compound(t, constructor,
1371 get_homogeneous_expression(g),
1372 Coefficient_to_integer_term(divisor));
1373 return t;
1374 }
1375 }
1376 case Grid_Generator::POINT:
1377 {
1378 constructor = a_grid_point;
1379 const Coefficient& divisor = g.divisor();
1380 if (divisor == 1)
1381 break;
1382 else {
1383 Prolog_construct_compound(t, constructor,
1384 get_homogeneous_expression(g),
1385 Coefficient_to_integer_term(divisor));
1386 return t;
1387 }
1388 }
1389 default:
1390 throw unknown_interface_error("grid_generator_term()");
1391 }
1392 Prolog_construct_compound(t, constructor, get_homogeneous_expression(g));
1393 return t;
1394 }
1395
1396 Prolog_term_ref
artificial_parameter_term(const PIP_Tree_Node::Artificial_Parameter & art)1397 artificial_parameter_term(const PIP_Tree_Node::Artificial_Parameter& art) {
1398 Prolog_term_ref t = Prolog_new_term_ref();
1399 Prolog_construct_compound(t, a_divided_by,
1400 get_linear_expression(art),
1401 Coefficient_to_integer_term(art.denominator()));
1402 return t;
1403 }
1404
1405 Variable
term_to_Variable(Prolog_term_ref t,const char * where)1406 term_to_Variable(Prolog_term_ref t, const char* where) {
1407 if (Prolog_is_compound(t)) {
1408 Prolog_atom functor;
1409 int arity;
1410 Prolog_get_compound_name_arity(t, &functor, &arity);
1411 if (functor == a_dollar_VAR && arity == 1) {
1412 Prolog_term_ref arg = Prolog_new_term_ref();
1413 Prolog_get_arg(1, t, arg);
1414 return
1415 Variable(term_to_unsigned<dimension_type>(arg, "term_to_Variable"));
1416 }
1417 }
1418 throw not_a_variable(t, where);
1419 }
1420
1421 Coefficient
term_to_Coefficient(Prolog_term_ref t,const char * where)1422 term_to_Coefficient(Prolog_term_ref t, const char* where) {
1423 if (Prolog_is_integer(t))
1424 return integer_term_to_Coefficient(t);
1425 else
1426 throw not_an_integer(t, where);
1427 }
1428
1429 Prolog_atom
term_to_bounded_integer_type_width(Prolog_term_ref t,const char * where)1430 term_to_bounded_integer_type_width(Prolog_term_ref t, const char* where) {
1431 if (Prolog_is_atom(t)) {
1432 Prolog_atom name;
1433 if (Prolog_get_atom_name(t, &name)
1434 && (name == a_bits_8 || name == a_bits_16
1435 || name == a_bits_32 || name == a_bits_64
1436 || name == a_bits_128))
1437 return name;
1438 }
1439 throw not_a_bounded_integer_type_width(t, where);
1440 }
1441
1442 Prolog_atom
term_to_bounded_integer_type_representation(Prolog_term_ref t,const char * where)1443 term_to_bounded_integer_type_representation(Prolog_term_ref t,
1444 const char* where) {
1445 if (Prolog_is_atom(t)) {
1446 Prolog_atom name;
1447 if (Prolog_get_atom_name(t, &name)
1448 && (name == a_unsigned || name == a_signed_2_complement))
1449 return name;
1450 }
1451 throw not_a_bounded_integer_type_representation(t, where);
1452 }
1453
1454 Prolog_atom
term_to_bounded_integer_type_overflow(Prolog_term_ref t,const char * where)1455 term_to_bounded_integer_type_overflow(Prolog_term_ref t,
1456 const char* where) {
1457 if (Prolog_is_atom(t)) {
1458 Prolog_atom name;
1459 if (Prolog_get_atom_name(t, &name)
1460 && (name == a_overflow_wraps
1461 || name == a_overflow_undefined
1462 || name == a_overflow_impossible))
1463 return name;
1464 }
1465 throw not_a_bounded_integer_type_overflow(t, where);
1466 }
1467
1468 Prolog_atom
term_to_optimization_mode(Prolog_term_ref t,const char * where)1469 term_to_optimization_mode(Prolog_term_ref t, const char* where) {
1470 if (Prolog_is_atom(t)) {
1471 Prolog_atom name;
1472 if (Prolog_get_atom_name(t, &name)
1473 && (name == a_max || name == a_min))
1474 return name;
1475 }
1476 throw not_an_optimization_mode(t, where);
1477 }
1478
1479 Prolog_atom
term_to_control_parameter_name(Prolog_term_ref t,const char * where)1480 term_to_control_parameter_name(Prolog_term_ref t, const char* where) {
1481 if (Prolog_is_atom(t)) {
1482 Prolog_atom name;
1483 if (Prolog_get_atom_name(t, &name)
1484 && (name == a_pricing || name == a_cutting_strategy))
1485 return name;
1486 }
1487 throw not_a_control_parameter_name(t, where);
1488 }
1489
1490 Prolog_atom
term_to_pip_problem_control_parameter_name(Prolog_term_ref t,const char * where)1491 term_to_pip_problem_control_parameter_name(Prolog_term_ref t, const char* where) {
1492 if (Prolog_is_atom(t)) {
1493 Prolog_atom name;
1494 if (Prolog_get_atom_name(t, &name)
1495 && (name == a_cutting_strategy || name == a_pivot_row_strategy))
1496 return name;
1497 }
1498 throw not_a_pip_problem_control_parameter_name(t, where);
1499 }
1500
1501 Prolog_atom
term_to_control_parameter_value(Prolog_term_ref t,const char * where)1502 term_to_control_parameter_value(Prolog_term_ref t, const char* where) {
1503 if (Prolog_is_atom(t)) {
1504 Prolog_atom name;
1505 if (Prolog_get_atom_name(t, &name)
1506 && (name == a_pricing_steepest_edge_float
1507 || name == a_pricing_steepest_edge_exact
1508 || name == a_pricing_textbook
1509 || name == a_cutting_strategy_first
1510 || name == a_cutting_strategy_deepest))
1511 return name;
1512 }
1513 throw not_a_control_parameter_value(t, where);
1514 }
1515
1516 Prolog_atom
term_to_pip_problem_control_parameter_value(Prolog_term_ref t,const char * where)1517 term_to_pip_problem_control_parameter_value(Prolog_term_ref t,
1518 const char* where) {
1519 if (Prolog_is_atom(t)) {
1520 Prolog_atom name;
1521 if (Prolog_get_atom_name(t, &name)
1522 && (name == a_cutting_strategy_first
1523 || name == a_cutting_strategy_deepest
1524 || name == a_cutting_strategy_all
1525 || name == a_pivot_row_strategy_first
1526 || name == a_pivot_row_strategy_max_column))
1527 return name;
1528 }
1529 throw not_a_pip_problem_control_parameter_value(t, where);
1530 }
1531
1532 bool Prolog_interface_initialized = false;
1533
1534 void
check_nil_terminating(Prolog_term_ref t,const char * where)1535 check_nil_terminating(Prolog_term_ref t, const char* where) {
1536 if (Prolog_get_nil(t))
1537 return;
1538 throw not_a_nil_terminated_list(t, where);
1539 }
1540
1541 inline dimension_type
max_representable_dimension(dimension_type d)1542 max_representable_dimension(dimension_type d) {
1543 return
1544 Prolog_has_unbounded_integers
1545 ? d
1546 : std::min(d, static_cast<dimension_type>(Prolog_max_integer));
1547 }
1548
1549 bool
term_to_boundary(Prolog_term_ref t_b,Boundary_Kind kind,bool & finite,bool & closed,Coefficient & n,Coefficient & d)1550 term_to_boundary(Prolog_term_ref t_b, Boundary_Kind kind,
1551 bool& finite, bool& closed,
1552 Coefficient& n, Coefficient& d) {
1553 if (!Prolog_is_compound(t_b))
1554 return false;
1555
1556 Prolog_atom functor;
1557 int arity;
1558
1559 Prolog_get_compound_name_arity(t_b, &functor, &arity);
1560 // A boundary term is either of the form c(Limit) or o(Limit).
1561 if (arity != 1 || (functor != a_c && functor != a_o))
1562 return false;
1563
1564 Prolog_atom open_closed_atom = functor;
1565
1566 Prolog_term_ref t_limit = Prolog_new_term_ref();
1567 Prolog_get_arg(1, t_b, t_limit);
1568 if (Prolog_is_integer(t_limit)) {
1569 // A finite, integral limit.
1570 finite = true;
1571 closed = (open_closed_atom == a_c);
1572 n = integer_term_to_Coefficient(t_limit);
1573 d = 1;
1574 }
1575 else if (Prolog_is_atom(t_limit)) {
1576 Prolog_atom a;
1577 Prolog_get_atom_name(t_limit, &a);
1578 Prolog_atom allowed_infinity = (kind == LOWER_BOUNDARY ? a_minf : a_pinf);
1579 // Only open bounds may be unbounded.
1580 if (a != allowed_infinity || open_closed_atom != a_o)
1581 return false;
1582
1583 finite = false;
1584 }
1585 else if (Prolog_is_compound(t_limit)) {
1586 Prolog_get_compound_name_arity(t_limit, &functor, &arity);
1587 if (arity != 2 || functor != a_slash)
1588 return false;
1589
1590 Prolog_term_ref t_n = Prolog_new_term_ref();
1591 Prolog_term_ref t_d = Prolog_new_term_ref();
1592 Prolog_get_arg(1, t_limit, t_n);
1593 Prolog_get_arg(2, t_limit, t_d);
1594
1595 if (!Prolog_is_integer(t_n) || !Prolog_is_integer(t_d))
1596 return false;
1597 else {
1598 finite = true;
1599 closed = (open_closed_atom == a_c);
1600 n = integer_term_to_Coefficient(t_n);
1601 d = integer_term_to_Coefficient(t_d);
1602 // Catch negative denominators and divisions by zero here.
1603 if (d <= 0)
1604 return false;
1605 }
1606 }
1607 return true;
1608 }
1609
1610 Prolog_atom
term_to_relation(Prolog_term_ref t,const char * where)1611 term_to_relation(Prolog_term_ref t, const char* where) {
1612 if (Prolog_is_atom(t)) {
1613 Prolog_atom name;
1614 if (Prolog_get_atom_name(t, &name)
1615 && (name == a_equal
1616 || name == a_greater_than_equal
1617 || name == a_equal_less_than
1618 || name == a_greater_than
1619 || name == a_less_than))
1620 return name;
1621 }
1622 throw not_a_relation(t, where);
1623 }
1624
1625 Relation_Symbol
term_to_relation_symbol(Prolog_term_ref t_r,const char * where)1626 term_to_relation_symbol(Prolog_term_ref t_r, const char* where) {
1627 Prolog_atom ra = term_to_relation(t_r, where);
1628 Relation_Symbol r;
1629 if (ra == a_less_than)
1630 r = LESS_THAN;
1631 else if (ra == a_equal_less_than)
1632 r = LESS_OR_EQUAL;
1633 else if (ra == a_equal)
1634 r = EQUAL;
1635 else if (ra == a_greater_than_equal)
1636 r = GREATER_OR_EQUAL;
1637 else {
1638 assert(ra == a_greater_than);
1639 r = GREATER_THAN;
1640 }
1641 return r;
1642 }
1643
1644 Prolog_term_ref
rational_term(const Rational_Box::interval_type::boundary_type & q)1645 rational_term(const Rational_Box::interval_type::boundary_type& q) {
1646 Prolog_term_ref t = Prolog_new_term_ref();
1647 PPL_DIRTY_TEMP_COEFFICIENT(numerator);
1648 PPL_DIRTY_TEMP_COEFFICIENT(denominator);
1649 numerator = q.get_num();
1650 denominator = q.get_den();
1651 if (denominator == 1)
1652 Prolog_put_Coefficient(t, numerator);
1653 else
1654 Prolog_construct_compound(t, a_slash,
1655 Coefficient_to_integer_term(numerator),
1656 Coefficient_to_integer_term(denominator));
1657 return t;
1658 }
1659
1660 Prolog_term_ref
interval_term(const Rational_Box::interval_type & i)1661 interval_term(const Rational_Box::interval_type& i) {
1662 Prolog_term_ref t = Prolog_new_term_ref();
1663 if (i.is_empty())
1664 Prolog_put_atom(t, a_empty);
1665 else {
1666 // Lower bound.
1667 const Prolog_atom& l_oc = i.lower_is_open() ? a_o : a_c;
1668 Prolog_term_ref l_b = Prolog_new_term_ref();
1669 if (i.lower_is_boundary_infinity())
1670 Prolog_put_atom(l_b, a_minf);
1671 else
1672 Prolog_put_term(l_b, rational_term(i.lower()));
1673 Prolog_term_ref l_t = Prolog_new_term_ref();
1674 Prolog_construct_compound(l_t, l_oc, l_b);
1675
1676 // Upper bound.
1677 const Prolog_atom& u_oc = i.upper_is_open() ? a_o : a_c;
1678 Prolog_term_ref u_b = Prolog_new_term_ref();
1679 if (i.upper_is_boundary_infinity())
1680 Prolog_put_atom(u_b, a_pinf);
1681 else
1682 Prolog_put_term(u_b, rational_term(i.upper()));
1683 Prolog_term_ref u_t = Prolog_new_term_ref();
1684 Prolog_construct_compound(u_t, u_oc, u_b);
1685
1686 Prolog_construct_compound(t, a_i, l_t, u_t);
1687 }
1688 return t;
1689 }
1690
1691 Prolog_atom
term_to_complexity_class(Prolog_term_ref t,const char * where)1692 term_to_complexity_class(Prolog_term_ref t, const char* where) {
1693 if (Prolog_is_atom(t)) {
1694 Prolog_atom name;
1695 if (Prolog_get_atom_name(t, &name)
1696 && (name == a_polynomial || name == a_simplex || name == a_any))
1697 return name;
1698 }
1699 throw not_a_complexity_class(t, where);
1700 }
1701
1702 } // namespace Prolog
1703
1704 } // namespace Interfaces
1705
1706 } // namespace Parma_Polyhedra_Library
1707
1708 using namespace Parma_Polyhedra_Library::Interfaces::Prolog;
1709
1710 extern "C" Prolog_foreign_return_type
ppl_version_major(Prolog_term_ref t_v)1711 ppl_version_major(Prolog_term_ref t_v) {
1712 try {
1713 if (unify_ulong(t_v, version_major()))
1714 return PROLOG_SUCCESS;
1715 }
1716 CATCH_ALL;
1717 }
1718
1719 extern "C" Prolog_foreign_return_type
ppl_version_minor(Prolog_term_ref t_v)1720 ppl_version_minor(Prolog_term_ref t_v) {
1721 try {
1722 if (unify_ulong(t_v, version_minor()))
1723 return PROLOG_SUCCESS;
1724 }
1725 CATCH_ALL;
1726 }
1727
1728 extern "C" Prolog_foreign_return_type
ppl_version_revision(Prolog_term_ref t_v)1729 ppl_version_revision(Prolog_term_ref t_v) {
1730 try {
1731 if (unify_ulong(t_v, version_revision()))
1732 return PROLOG_SUCCESS;
1733 }
1734 CATCH_ALL;
1735 }
1736
1737 extern "C" Prolog_foreign_return_type
ppl_version_beta(Prolog_term_ref t_v)1738 ppl_version_beta(Prolog_term_ref t_v) {
1739 try {
1740 if (unify_ulong(t_v, version_beta()))
1741 return PROLOG_SUCCESS;
1742 }
1743 CATCH_ALL;
1744 }
1745
1746 extern "C" Prolog_foreign_return_type
ppl_version(Prolog_term_ref t_v)1747 ppl_version(Prolog_term_ref t_v) {
1748 try {
1749 Prolog_term_ref tmp = Prolog_new_term_ref();
1750 Prolog_put_atom_chars(tmp, version());
1751 if (Prolog_unify(t_v, tmp))
1752 return PROLOG_SUCCESS;
1753 }
1754 CATCH_ALL;
1755 }
1756
1757 extern "C" Prolog_foreign_return_type
ppl_banner(Prolog_term_ref t_b)1758 ppl_banner(Prolog_term_ref t_b) {
1759 try {
1760 Prolog_term_ref tmp = Prolog_new_term_ref();
1761 Prolog_put_atom_chars(tmp, banner());
1762 if (Prolog_unify(t_b, tmp))
1763 return PROLOG_SUCCESS;
1764 }
1765 CATCH_ALL;
1766 }
1767
1768 extern "C" Prolog_foreign_return_type
ppl_max_space_dimension(Prolog_term_ref t_msd)1769 ppl_max_space_dimension(Prolog_term_ref t_msd) {
1770 try {
1771 if (unify_ulong(t_msd, max_representable_dimension(max_space_dimension())))
1772 return PROLOG_SUCCESS;
1773 }
1774 CATCH_ALL;
1775 }
1776
1777 extern "C" Prolog_foreign_return_type
ppl_initialize()1778 ppl_initialize() {
1779 try {
1780 if (Prolog_interface_initialized)
1781 return PROLOG_SUCCESS;
1782 // Initialize the core library.
1783 initialize();
1784 for (size_t i = 0; prolog_interface_atoms[i].p_atom != 0; ++i) {
1785 Prolog_atom a = Prolog_atom_from_string(prolog_interface_atoms[i].name);
1786 *prolog_interface_atoms[i].p_atom = a;
1787 }
1788 timeout_exception_atom = a_time_out;
1789 out_of_memory_exception_atom = a_out_of_memory;
1790 ppl_Prolog_sysdep_init();
1791 Prolog_interface_initialized = true;
1792 return PROLOG_SUCCESS;
1793 }
1794 CATCH_ALL;
1795 }
1796
1797 extern "C" Prolog_foreign_return_type
ppl_finalize()1798 ppl_finalize() {
1799 try {
1800 if (!Prolog_interface_initialized)
1801 return PROLOG_SUCCESS;
1802
1803 Prolog_interface_initialized = false;
1804 // Finalize the core library.
1805 finalize();
1806 // Release the pending timeout object, if any.
1807 reset_timeout();
1808 ppl_Prolog_sysdep_deinit();
1809 return PROLOG_SUCCESS;
1810 }
1811 CATCH_ALL;
1812 }
1813
1814 extern "C" Prolog_foreign_return_type
ppl_set_rounding_for_PPL()1815 ppl_set_rounding_for_PPL() {
1816 try {
1817 set_rounding_for_PPL();
1818 return PROLOG_SUCCESS;
1819 }
1820 CATCH_ALL;
1821 }
1822
1823 extern "C" Prolog_foreign_return_type
ppl_restore_pre_PPL_rounding()1824 ppl_restore_pre_PPL_rounding() {
1825 try {
1826 restore_pre_PPL_rounding();
1827 return PROLOG_SUCCESS;
1828 }
1829 CATCH_ALL;
1830 }
1831
1832 extern "C" Prolog_foreign_return_type
ppl_irrational_precision(Prolog_term_ref t_p)1833 ppl_irrational_precision(Prolog_term_ref t_p) {
1834 try {
1835 if (unify_ulong(t_p, irrational_precision()))
1836 return PROLOG_SUCCESS;
1837 }
1838 CATCH_ALL;
1839 }
1840
1841 extern "C" Prolog_foreign_return_type
ppl_set_irrational_precision(Prolog_term_ref t_p)1842 ppl_set_irrational_precision(Prolog_term_ref t_p) {
1843 try {
1844 unsigned p
1845 = term_to_unsigned<unsigned>(t_p, "ppl_set_irrational_precision/1");
1846 set_irrational_precision(p);
1847 return PROLOG_SUCCESS;
1848 }
1849 CATCH_ALL;
1850 }
1851
1852 extern "C" Prolog_foreign_return_type
ppl_set_timeout_exception_atom(Prolog_term_ref t_tea)1853 ppl_set_timeout_exception_atom(Prolog_term_ref t_tea) {
1854 try {
1855 if (Prolog_is_atom(t_tea)) {
1856 Prolog_atom tea;
1857 if (Prolog_get_atom_name(t_tea, &tea)) {
1858 timeout_exception_atom = tea;
1859 return PROLOG_SUCCESS;
1860 }
1861 }
1862 Prolog_term_ref found = Prolog_new_term_ref();
1863 Prolog_construct_compound(found, a_found, t_tea);
1864
1865 Prolog_term_ref expected = Prolog_new_term_ref();
1866 Prolog_construct_compound(expected, a_expected,
1867 Prolog_atom_term_from_string("atom"));
1868
1869 Prolog_term_ref where = Prolog_new_term_ref();
1870 Prolog_construct_compound(where, a_where,
1871 Prolog_atom_term_from_string
1872 ("ppl_set_timeout_exception_atom"));
1873
1874 Prolog_term_ref exception_term = Prolog_new_term_ref();
1875 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
1876 found, expected, where);
1877 Prolog_raise_exception(exception_term);
1878 return PROLOG_FAILURE;
1879 }
1880 CATCH_ALL;
1881 }
1882
1883 extern "C" Prolog_foreign_return_type
ppl_timeout_exception_atom(Prolog_term_ref t)1884 ppl_timeout_exception_atom(Prolog_term_ref t) {
1885 try {
1886 Prolog_term_ref t_tea = Prolog_new_term_ref();
1887 Prolog_put_atom(t_tea, timeout_exception_atom);
1888 return Prolog_unify(t_tea, t) ? PROLOG_SUCCESS : PROLOG_FAILURE;
1889 }
1890 CATCH_ALL;
1891 }
1892
1893 extern "C" Prolog_foreign_return_type
ppl_set_timeout(Prolog_term_ref t_csecs)1894 ppl_set_timeout(Prolog_term_ref t_csecs) {
1895 try {
1896 // In case a timeout was already set.
1897 reset_timeout();
1898 static timeout_exception e;
1899 unsigned csecs = term_to_unsigned<unsigned>(t_csecs, "ppl_set_timeout/1");
1900 p_timeout_object =
1901 new Parma_Polyhedra_Library::Watchdog(csecs,
1902 abandon_expensive_computations,
1903 e);
1904 return PROLOG_SUCCESS;
1905 }
1906 CATCH_ALL;
1907 }
1908
1909 extern "C" Prolog_foreign_return_type
ppl_reset_timeout()1910 ppl_reset_timeout() {
1911 try {
1912 reset_timeout();
1913 return PROLOG_SUCCESS;
1914 }
1915 CATCH_ALL;
1916 }
1917
1918 extern "C" Prolog_foreign_return_type
ppl_set_deterministic_timeout(Prolog_term_ref t_unscaled_weight,Prolog_term_ref t_scale)1919 ppl_set_deterministic_timeout(Prolog_term_ref t_unscaled_weight,
1920 Prolog_term_ref t_scale) {
1921 try {
1922 // In case a deterministic timeout was already set.
1923 reset_deterministic_timeout();
1924 static deterministic_timeout_exception e;
1925 unsigned long unscaled_weight
1926 = term_to_unsigned<unsigned long>(t_unscaled_weight,
1927 "ppl_set_deterministic_timeout/2");
1928 unsigned scale
1929 = term_to_unsigned<unsigned>(t_scale, "ppl_set_deterministic_timeout/2");
1930 typedef Parma_Polyhedra_Library::Weightwatch_Traits Traits;
1931 p_deterministic_timeout_object
1932 = new Weightwatch(Traits::compute_delta(unscaled_weight, scale),
1933 abandon_expensive_computations, e);
1934 return PROLOG_SUCCESS;
1935 }
1936 CATCH_ALL;
1937 }
1938
1939 extern "C" Prolog_foreign_return_type
ppl_reset_deterministic_timeout()1940 ppl_reset_deterministic_timeout() {
1941 try {
1942 reset_deterministic_timeout();
1943 return PROLOG_SUCCESS;
1944 }
1945 CATCH_ALL;
1946 }
1947
1948 extern "C" Prolog_foreign_return_type
ppl_Coefficient_bits(Prolog_term_ref t_bits)1949 ppl_Coefficient_bits(Prolog_term_ref t_bits) {
1950 try {
1951 if (unify_ulong(t_bits, PPL_COEFFICIENT_BITS))
1952 return PROLOG_SUCCESS;
1953 }
1954 CATCH_ALL;
1955 }
1956
1957 extern "C" Prolog_foreign_return_type
ppl_Coefficient_is_bounded()1958 ppl_Coefficient_is_bounded() {
1959 try {
1960 if (std::numeric_limits<Coefficient>::is_bounded)
1961 return PROLOG_SUCCESS;
1962 }
1963 CATCH_ALL;
1964 }
1965
1966 extern "C" Prolog_foreign_return_type
ppl_Coefficient_min(Prolog_term_ref t_min)1967 ppl_Coefficient_min(Prolog_term_ref t_min) {
1968 try {
1969 if (std::numeric_limits<Coefficient>::is_bounded) {
1970 PPL_DIRTY_TEMP_COEFFICIENT(min);
1971 min = std::numeric_limits<Coefficient>::min();
1972 if (Prolog_has_unbounded_integers
1973 || (min >= Prolog_min_integer && min <= Prolog_min_integer))
1974 return Prolog_unify_Coefficient(t_min, min)
1975 ? PROLOG_SUCCESS : PROLOG_FAILURE;
1976 }
1977 }
1978 CATCH_ALL;
1979 }
1980
1981 extern "C" Prolog_foreign_return_type
ppl_Coefficient_max(Prolog_term_ref t_max)1982 ppl_Coefficient_max(Prolog_term_ref t_max) {
1983 try {
1984 if (std::numeric_limits<Coefficient>::is_bounded) {
1985 PPL_DIRTY_TEMP_COEFFICIENT(max);
1986 max = std::numeric_limits<Coefficient>::max();
1987 if (Prolog_has_unbounded_integers
1988 || (max >= Prolog_min_integer && max <= Prolog_min_integer))
1989 return Prolog_unify_Coefficient(t_max, max)
1990 ? PROLOG_SUCCESS : PROLOG_FAILURE;
1991 }
1992 }
1993 CATCH_ALL;
1994 }
1995
1996 extern "C" Prolog_foreign_return_type
ppl_new_MIP_Problem_from_space_dimension(Prolog_term_ref t_nd,Prolog_term_ref t_mip)1997 ppl_new_MIP_Problem_from_space_dimension
1998 (Prolog_term_ref t_nd, Prolog_term_ref t_mip) {
1999 static const char* where = "ppl_MIP_Problem_from_space_dimension/2";
2000 try {
2001 dimension_type d = term_to_unsigned<dimension_type>(t_nd, where);
2002 MIP_Problem* mip = new MIP_Problem(d);
2003 Prolog_term_ref tmp = Prolog_new_term_ref();
2004 Prolog_put_address(tmp, mip);
2005 if (Prolog_unify(t_mip, tmp)) {
2006 PPL_REGISTER(mip);
2007 return PROLOG_SUCCESS;
2008 }
2009 else
2010 delete mip;
2011 }
2012 CATCH_ALL;
2013 }
2014
2015 extern "C" Prolog_foreign_return_type
ppl_new_MIP_Problem(Prolog_term_ref t_nd,Prolog_term_ref t_clist,Prolog_term_ref t_le_expr,Prolog_term_ref t_opt,Prolog_term_ref t_mip)2016 ppl_new_MIP_Problem(Prolog_term_ref t_nd,
2017 Prolog_term_ref t_clist,
2018 Prolog_term_ref t_le_expr,
2019 Prolog_term_ref t_opt,
2020 Prolog_term_ref t_mip) {
2021 static const char* where = "ppl_new_MIP_Problem/5";
2022 try {
2023 Constraint_System cs;
2024 Prolog_term_ref c = Prolog_new_term_ref();
2025 while (Prolog_is_cons(t_clist)) {
2026 Prolog_get_cons(t_clist, c, t_clist);
2027 cs.insert(build_constraint(c, where));
2028 }
2029 // Check the list is properly terminated.
2030 check_nil_terminating(t_clist, where);
2031
2032 const Linear_Expression le = build_linear_expression(t_le_expr, where);
2033 Prolog_atom opt = term_to_optimization_mode(t_opt, where);
2034 Optimization_Mode mode = (opt == a_max) ? MAXIMIZATION : MINIMIZATION;
2035
2036 MIP_Problem* mip
2037 = new MIP_Problem(term_to_unsigned<dimension_type>(t_nd, where),
2038 cs, le, mode);
2039 Prolog_term_ref tmp = Prolog_new_term_ref();
2040 Prolog_put_address(tmp, mip);
2041 if (Prolog_unify(t_mip, tmp)) {
2042 PPL_REGISTER(mip);
2043 return PROLOG_SUCCESS;
2044 }
2045 else
2046 delete mip;
2047 }
2048 CATCH_ALL;
2049 }
2050
2051 extern "C" Prolog_foreign_return_type
ppl_new_MIP_Problem_from_MIP_Problem(Prolog_term_ref t_mip_source,Prolog_term_ref t_mip)2052 ppl_new_MIP_Problem_from_MIP_Problem(Prolog_term_ref t_mip_source,
2053 Prolog_term_ref t_mip) {
2054 static const char* where = "ppl_new_MIP_Problem_from_MIP_Problem/2";
2055 try {
2056 const MIP_Problem* mip_source
2057 = static_cast<const MIP_Problem*>
2058 (term_to_handle<MIP_Problem>(t_mip_source, where));
2059 PPL_CHECK(mip_source);
2060 MIP_Problem* mip = new MIP_Problem(*mip_source);
2061 Prolog_term_ref tmp = Prolog_new_term_ref();
2062 Prolog_put_address(tmp, mip);
2063 if (Prolog_unify(t_mip, tmp)) {
2064 PPL_REGISTER(mip);
2065 return PROLOG_SUCCESS;
2066 }
2067 else
2068 delete mip;
2069 }
2070 CATCH_ALL;
2071 }
2072
2073 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_swap(Prolog_term_ref t_lhs,Prolog_term_ref t_rhs)2074 ppl_MIP_Problem_swap(Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
2075 static const char* where = "ppl_MIP_Problem_swap/2";
2076 try {
2077 MIP_Problem* lhs = term_to_handle<MIP_Problem>(t_lhs, where);
2078 MIP_Problem* rhs = term_to_handle<MIP_Problem>(t_rhs, where);
2079 PPL_CHECK(lhs);
2080 PPL_CHECK(rhs);
2081 swap(*lhs, *rhs);
2082 return PROLOG_SUCCESS;
2083 }
2084 CATCH_ALL;
2085 }
2086
2087 extern "C" Prolog_foreign_return_type
ppl_delete_MIP_Problem(Prolog_term_ref t_mip)2088 ppl_delete_MIP_Problem(Prolog_term_ref t_mip) {
2089 static const char* where = "ppl_delete_MIP_Problem/1";
2090 try {
2091 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2092 PPL_UNREGISTER(mip);
2093 delete mip;
2094 return PROLOG_SUCCESS;
2095 }
2096 CATCH_ALL;
2097 }
2098
2099 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_space_dimension(Prolog_term_ref t_mip,Prolog_term_ref t_sd)2100 ppl_MIP_Problem_space_dimension(Prolog_term_ref t_mip, Prolog_term_ref t_sd) {
2101 static const char* where = "ppl_MIP_Problem_space_dimension/2";
2102 try {
2103 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2104 PPL_CHECK(mip);
2105 if (unify_ulong(t_sd, mip->space_dimension()))
2106 return PROLOG_SUCCESS;
2107 }
2108 CATCH_ALL;
2109 }
2110
2111 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_integer_space_dimensions(Prolog_term_ref t_mip,Prolog_term_ref t_vlist)2112 ppl_MIP_Problem_integer_space_dimensions(Prolog_term_ref t_mip,
2113 Prolog_term_ref t_vlist) {
2114 static const char* where = "ppl_MIP_Problem_integer_space_dimensions/2";
2115 try {
2116 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2117 PPL_CHECK(mip);
2118
2119 Prolog_term_ref tail = Prolog_new_term_ref();
2120 Prolog_put_nil(tail);
2121 const Variables_Set& i_vars = mip->integer_space_dimensions();
2122
2123 for (Variables_Set::const_iterator i = i_vars.begin(),
2124 i_end = i_vars.end(); i != i_end; ++i)
2125 Prolog_construct_cons(tail, variable_term(*i), tail);
2126
2127 if (Prolog_unify(t_vlist, tail))
2128 return PROLOG_SUCCESS;
2129 }
2130 CATCH_ALL;
2131 }
2132
2133 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_constraints(Prolog_term_ref t_mip,Prolog_term_ref t_clist)2134 ppl_MIP_Problem_constraints(Prolog_term_ref t_mip,
2135 Prolog_term_ref t_clist) {
2136 static const char* where = "ppl_MIP_Problem_constraints/2";
2137 try {
2138 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2139 PPL_CHECK(mip);
2140
2141 Prolog_term_ref tail = Prolog_new_term_ref();
2142 Prolog_put_nil(tail);
2143 for (MIP_Problem::const_iterator i = mip->constraints_begin(),
2144 i_end = mip->constraints_end(); i != i_end; ++i)
2145 Prolog_construct_cons(tail, constraint_term(*i), tail);
2146
2147 if (Prolog_unify(t_clist, tail))
2148 return PROLOG_SUCCESS;
2149 }
2150 CATCH_ALL;
2151 }
2152
2153 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_objective_function(Prolog_term_ref t_mip,Prolog_term_ref t_le_expr)2154 ppl_MIP_Problem_objective_function(Prolog_term_ref t_mip,
2155 Prolog_term_ref t_le_expr) {
2156 static const char* where = "ppl_MIP_Problem_objective_function/2";
2157 try {
2158 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2159 PPL_CHECK(mip);
2160
2161 const Linear_Expression& le = mip->objective_function();
2162 Prolog_term_ref t = get_linear_expression(le);
2163
2164 if (Prolog_unify(t_le_expr, t))
2165 return PROLOG_SUCCESS;
2166 }
2167 CATCH_ALL;
2168 }
2169
2170 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_optimization_mode(Prolog_term_ref t_mip,Prolog_term_ref t_opt)2171 ppl_MIP_Problem_optimization_mode(Prolog_term_ref t_mip,
2172 Prolog_term_ref t_opt) {
2173 static const char* where = "ppl_MIP_Problem_optimization_mode/2";
2174 try {
2175 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2176 PPL_CHECK(mip);
2177
2178 Optimization_Mode mode = mip->optimization_mode();
2179 Prolog_term_ref t = Prolog_new_term_ref();
2180 Prolog_atom a = (mode == MAXIMIZATION) ? a_max : a_min;
2181 Prolog_put_atom(t, a);
2182 if (Prolog_unify(t_opt, t))
2183 return PROLOG_SUCCESS;
2184 }
2185 CATCH_ALL;
2186 }
2187
2188 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_clear(Prolog_term_ref t_mip)2189 ppl_MIP_Problem_clear(Prolog_term_ref t_mip) {
2190 static const char* where = "ppl_MIP_Problem_clear/1";
2191 try {
2192 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2193 PPL_CHECK(mip);
2194 mip->clear();
2195 return PROLOG_SUCCESS;
2196 }
2197 CATCH_ALL;
2198 }
2199
2200 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_add_space_dimensions_and_embed(Prolog_term_ref t_mip,Prolog_term_ref t_nnd)2201 ppl_MIP_Problem_add_space_dimensions_and_embed
2202 (Prolog_term_ref t_mip, Prolog_term_ref t_nnd) {
2203 static const char* where
2204 = "ppl_MIP_Problem_add_space_dimensions_and_embed/2";
2205 try {
2206 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2207 PPL_CHECK(mip);
2208 dimension_type d = term_to_unsigned<dimension_type>(t_nnd, where);
2209 mip->add_space_dimensions_and_embed(d);
2210 return PROLOG_SUCCESS;
2211 }
2212 CATCH_ALL;
2213 }
2214
2215 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_add_to_integer_space_dimensions(Prolog_term_ref t_mip,Prolog_term_ref t_vlist)2216 ppl_MIP_Problem_add_to_integer_space_dimensions(Prolog_term_ref t_mip,
2217 Prolog_term_ref t_vlist) {
2218 static const char* where
2219 = "ppl_MIP_Problem_add_to_integer_space_dimensions/2";
2220 try {
2221 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2222 PPL_CHECK(mip);
2223 Variables_Set i_vars;
2224 Prolog_term_ref v = Prolog_new_term_ref();
2225
2226 while (Prolog_is_cons(t_vlist)) {
2227 Prolog_get_cons(t_vlist, v, t_vlist);
2228 i_vars.insert(term_to_Variable(v, where).id());
2229 }
2230
2231 // Check the list is properly terminated.
2232 check_nil_terminating(t_vlist, where);
2233
2234 mip->add_to_integer_space_dimensions(i_vars);
2235 return PROLOG_SUCCESS;
2236 }
2237 CATCH_ALL;
2238 }
2239
2240 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_add_constraint(Prolog_term_ref t_mip,Prolog_term_ref t_c)2241 ppl_MIP_Problem_add_constraint(Prolog_term_ref t_mip, Prolog_term_ref t_c) {
2242 static const char* where = "ppl_MIP_Problem_add_constraint/2";
2243 try {
2244 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2245 PPL_CHECK(mip);
2246 mip->add_constraint(build_constraint(t_c, where));
2247 return PROLOG_SUCCESS;
2248 }
2249 CATCH_ALL;
2250 }
2251
2252 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_add_constraints(Prolog_term_ref t_mip,Prolog_term_ref t_clist)2253 ppl_MIP_Problem_add_constraints(Prolog_term_ref t_mip,
2254 Prolog_term_ref t_clist) {
2255 static const char* where = "ppl_MIP_Problem_add_constraints/2";
2256 try {
2257 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2258 PPL_CHECK(mip);
2259 Constraint_System cs;
2260 Prolog_term_ref c = Prolog_new_term_ref();
2261
2262 while (Prolog_is_cons(t_clist)) {
2263 Prolog_get_cons(t_clist, c, t_clist);
2264 cs.insert(build_constraint(c, where));
2265 }
2266
2267 // Check the list is properly terminated.
2268 check_nil_terminating(t_clist, where);
2269
2270 mip->add_constraints(cs);
2271 return PROLOG_SUCCESS;
2272 }
2273 CATCH_ALL;
2274 }
2275
2276 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_set_objective_function(Prolog_term_ref t_mip,Prolog_term_ref t_le_expr)2277 ppl_MIP_Problem_set_objective_function(Prolog_term_ref t_mip,
2278 Prolog_term_ref t_le_expr) {
2279 static const char* where = "ppl_MIP_Problem_set_objective_function/2";
2280 try {
2281 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2282 PPL_CHECK(mip);
2283 mip->set_objective_function(build_linear_expression(t_le_expr, where));
2284 return PROLOG_SUCCESS;
2285 }
2286 CATCH_ALL;
2287 }
2288
2289 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_set_optimization_mode(Prolog_term_ref t_mip,Prolog_term_ref t_opt)2290 ppl_MIP_Problem_set_optimization_mode(Prolog_term_ref t_mip,
2291 Prolog_term_ref t_opt) {
2292 static const char* where = "ppl_MIP_Problem_set_optimization_mode/2";
2293 try {
2294 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2295 PPL_CHECK(mip);
2296
2297 Prolog_atom opt = term_to_optimization_mode(t_opt, where);
2298 Optimization_Mode mode = (opt == a_max) ? MAXIMIZATION : MINIMIZATION;
2299 mip->set_optimization_mode(mode);
2300 return PROLOG_SUCCESS;
2301 }
2302 CATCH_ALL;
2303 }
2304
2305 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_set_control_parameter(Prolog_term_ref t_mip,Prolog_term_ref t_cp_value)2306 ppl_MIP_Problem_set_control_parameter(Prolog_term_ref t_mip,
2307 Prolog_term_ref t_cp_value) {
2308 static const char* where = "ppl_MIP_Problem_set_control_parameter/2";
2309 try {
2310 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2311 PPL_CHECK(mip);
2312
2313 Prolog_atom cp_value = term_to_control_parameter_value(t_cp_value, where);
2314 if (cp_value == a_pricing_steepest_edge_float)
2315 mip->set_control_parameter(MIP_Problem::PRICING_STEEPEST_EDGE_FLOAT);
2316 else if (cp_value == a_pricing_steepest_edge_exact)
2317 mip->set_control_parameter(MIP_Problem::PRICING_STEEPEST_EDGE_EXACT);
2318 else if (cp_value == a_pricing_textbook)
2319 mip->set_control_parameter(MIP_Problem::PRICING_TEXTBOOK);
2320 else
2321 throw unknown_interface_error("ppl_MIP_Problem_get_control_parameter()");
2322 return PROLOG_SUCCESS;
2323 }
2324 CATCH_ALL;
2325 }
2326
2327 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_get_control_parameter(Prolog_term_ref t_mip,Prolog_term_ref t_cp_name,Prolog_term_ref t_cp_value)2328 ppl_MIP_Problem_get_control_parameter(Prolog_term_ref t_mip,
2329 Prolog_term_ref t_cp_name,
2330 Prolog_term_ref t_cp_value) {
2331 static const char* where = "ppl_MIP_Problem_get_control_parameter/3";
2332 try {
2333 MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2334 PPL_CHECK(mip);
2335 Prolog_atom cp_name = term_to_control_parameter_name(t_cp_name, where);
2336 MIP_Problem::Control_Parameter_Value ppl_cp_value;
2337 if (cp_name == a_pricing)
2338 ppl_cp_value = mip->get_control_parameter(MIP_Problem::PRICING);
2339 else
2340 throw unknown_interface_error("ppl_MIP_Problem_get_control_parameter()");
2341
2342 Prolog_term_ref t = Prolog_new_term_ref();
2343 Prolog_atom a;
2344 switch (ppl_cp_value) {
2345 case MIP_Problem::PRICING_STEEPEST_EDGE_FLOAT:
2346 a = a_pricing_steepest_edge_float;
2347 break;
2348 case MIP_Problem::PRICING_STEEPEST_EDGE_EXACT:
2349 a = a_pricing_steepest_edge_exact;
2350 break;
2351 case MIP_Problem::PRICING_TEXTBOOK:
2352 a = a_pricing_textbook;
2353 break;
2354 default:
2355 throw unknown_interface_error("ppl_MIP_Problem_get_control_parameter()");
2356 }
2357 Prolog_put_atom(t, a);
2358 if (Prolog_unify(t_cp_value, t))
2359 return PROLOG_SUCCESS;
2360 }
2361 CATCH_ALL;
2362 }
2363
2364 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_is_satisfiable(Prolog_term_ref t_mip)2365 ppl_MIP_Problem_is_satisfiable(Prolog_term_ref t_mip) {
2366 static const char* where = "ppl_MIP_Problem_is_satisfiable/1";
2367 try {
2368 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2369 PPL_CHECK(mip);
2370 if (mip->is_satisfiable())
2371 return PROLOG_SUCCESS;
2372 }
2373 CATCH_ALL;
2374 }
2375
2376 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_solve(Prolog_term_ref t_mip,Prolog_term_ref t_status)2377 ppl_MIP_Problem_solve(Prolog_term_ref t_mip, Prolog_term_ref t_status) {
2378 static const char* where = "ppl_MIP_Problem_solve/2";
2379 try {
2380 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2381 PPL_CHECK(mip);
2382
2383 Prolog_atom a;
2384 switch (mip->solve()) {
2385 case UNFEASIBLE_MIP_PROBLEM:
2386 a = a_unfeasible;
2387 break;
2388 case UNBOUNDED_MIP_PROBLEM:
2389 a = a_unbounded;
2390 break;
2391 case OPTIMIZED_MIP_PROBLEM:
2392 a = a_optimized;
2393 break;
2394 default:
2395 throw unknown_interface_error("ppl_MIP_Problem_solve()");
2396 }
2397 Prolog_term_ref t = Prolog_new_term_ref();
2398 Prolog_put_atom(t, a);
2399 if (Prolog_unify(t_status, t))
2400 return PROLOG_SUCCESS;
2401 }
2402 CATCH_ALL;
2403 }
2404
2405 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_feasible_point(Prolog_term_ref t_mip,Prolog_term_ref t_g)2406 ppl_MIP_Problem_feasible_point(Prolog_term_ref t_mip,
2407 Prolog_term_ref t_g) {
2408 static const char* where = "ppl_MIP_Problem_feasible_point/2";
2409 try {
2410 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2411 PPL_CHECK(mip);
2412 const Generator& g = mip->feasible_point();
2413 if (Prolog_unify(t_g, generator_term(g)))
2414 return PROLOG_SUCCESS;
2415 }
2416 CATCH_ALL;
2417 }
2418
2419 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_optimizing_point(Prolog_term_ref t_mip,Prolog_term_ref t_g)2420 ppl_MIP_Problem_optimizing_point(Prolog_term_ref t_mip,
2421 Prolog_term_ref t_g) {
2422 static const char* where = "ppl_MIP_Problem_optimizing_point/2";
2423 try {
2424 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2425 PPL_CHECK(mip);
2426 const Generator& g = mip->optimizing_point();
2427 if (Prolog_unify(t_g, generator_term(g)))
2428 return PROLOG_SUCCESS;
2429 }
2430 CATCH_ALL;
2431 }
2432
2433 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_optimal_value(Prolog_term_ref t_mip,Prolog_term_ref t_n,Prolog_term_ref t_d)2434 ppl_MIP_Problem_optimal_value(Prolog_term_ref t_mip,
2435 Prolog_term_ref t_n,
2436 Prolog_term_ref t_d) {
2437 static const char* where = "ppl_MIP_Problem_optimal_value/3";
2438 try {
2439 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2440 PPL_CHECK(mip);
2441 PPL_DIRTY_TEMP_COEFFICIENT(n);
2442 PPL_DIRTY_TEMP_COEFFICIENT(d);
2443 mip->optimal_value(n, d);
2444 if (Prolog_unify_Coefficient(t_n, n)
2445 && Prolog_unify_Coefficient(t_d, d))
2446 return PROLOG_SUCCESS;
2447 }
2448 CATCH_ALL;
2449 }
2450
2451 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_evaluate_objective_function(Prolog_term_ref t_mip,Prolog_term_ref t_g,Prolog_term_ref t_n,Prolog_term_ref t_d)2452 ppl_MIP_Problem_evaluate_objective_function(Prolog_term_ref t_mip,
2453 Prolog_term_ref t_g,
2454 Prolog_term_ref t_n,
2455 Prolog_term_ref t_d) {
2456 static const char* where = "ppl_MIP_Problem_evaluate_objective_function/4";
2457 try {
2458 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2459 PPL_CHECK(mip);
2460 PPL_DIRTY_TEMP_COEFFICIENT(n);
2461 PPL_DIRTY_TEMP_COEFFICIENT(d);
2462 mip->evaluate_objective_function(build_generator(t_g, where), n, d);
2463 if (Prolog_unify_Coefficient(t_n, n)
2464 && Prolog_unify_Coefficient(t_d, d))
2465 return PROLOG_SUCCESS;
2466 }
2467 CATCH_ALL;
2468 }
2469
2470 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_OK(Prolog_term_ref t_mip)2471 ppl_MIP_Problem_OK(Prolog_term_ref t_mip) {
2472 static const char* where = "ppl_MIP_Problem_OK/1";
2473 try {
2474 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2475 PPL_CHECK(mip);
2476 if (mip->OK())
2477 return PROLOG_SUCCESS;
2478 }
2479 CATCH_ALL;
2480 }
2481
2482 extern "C" Prolog_foreign_return_type
ppl_MIP_Problem_ascii_dump(Prolog_term_ref t_mip)2483 ppl_MIP_Problem_ascii_dump(Prolog_term_ref t_mip) {
2484 static const char* where = "ppl_MIP_Problem_ascii_dump/1";
2485 try {
2486 const MIP_Problem* mip = term_to_handle<MIP_Problem>(t_mip, where);
2487 PPL_CHECK(mip);
2488 mip->ascii_dump(std::cout);
2489 return PROLOG_SUCCESS;
2490 }
2491 CATCH_ALL;
2492 }
2493
2494 extern "C" Prolog_foreign_return_type
ppl_new_PIP_Problem_from_space_dimension(Prolog_term_ref t_nd,Prolog_term_ref t_pip)2495 ppl_new_PIP_Problem_from_space_dimension
2496 (Prolog_term_ref t_nd, Prolog_term_ref t_pip) {
2497 static const char* where = "ppl_PIP_Problem_from_space_dimension/2";
2498 try {
2499 dimension_type d = term_to_unsigned<dimension_type>(t_nd, where);
2500 PIP_Problem* pip = new PIP_Problem(d);
2501 Prolog_term_ref tmp = Prolog_new_term_ref();
2502 Prolog_put_address(tmp, pip);
2503 if (Prolog_unify(t_pip, tmp)) {
2504 PPL_REGISTER(pip);
2505 return PROLOG_SUCCESS;
2506 }
2507 else
2508 delete pip;
2509 }
2510 CATCH_ALL;
2511 }
2512
2513 extern "C" Prolog_foreign_return_type
ppl_new_PIP_Problem(Prolog_term_ref t_dim,Prolog_term_ref t_cs,Prolog_term_ref t_params,Prolog_term_ref t_pip)2514 ppl_new_PIP_Problem(Prolog_term_ref t_dim,
2515 Prolog_term_ref t_cs,
2516 Prolog_term_ref t_params,
2517 Prolog_term_ref t_pip) {
2518 static const char* where = "ppl_new_PIP_Problem/4";
2519 try {
2520 dimension_type dim = term_to_unsigned<dimension_type>(t_dim, where);
2521 Constraint_System cs;
2522 Prolog_term_ref t_c = Prolog_new_term_ref();
2523 while (Prolog_is_cons(t_cs)) {
2524 Prolog_get_cons(t_cs, t_c, t_cs);
2525 cs.insert(build_constraint(t_c, where));
2526 }
2527 // Check the list is properly terminated.
2528 check_nil_terminating(t_cs, where);
2529
2530 Variables_Set params;
2531 Prolog_term_ref t_par = Prolog_new_term_ref();
2532 while (Prolog_is_cons(t_params)) {
2533 Prolog_get_cons(t_params, t_par, t_params);
2534 params.insert(term_to_Variable(t_par, where).id());
2535 }
2536 // Check the list is properly terminated.
2537 check_nil_terminating(t_params, where);
2538
2539 PIP_Problem* pip = new PIP_Problem(dim, cs.begin(), cs.end(), params);
2540 Prolog_term_ref tmp = Prolog_new_term_ref();
2541 Prolog_put_address(tmp, pip);
2542 if (Prolog_unify(t_pip, tmp)) {
2543 PPL_REGISTER(pip);
2544 return PROLOG_SUCCESS;
2545 }
2546 else
2547 delete pip;
2548 }
2549 CATCH_ALL;
2550 }
2551
2552 extern "C" Prolog_foreign_return_type
ppl_new_PIP_Problem_from_PIP_Problem(Prolog_term_ref t_pip_source,Prolog_term_ref t_pip)2553 ppl_new_PIP_Problem_from_PIP_Problem(Prolog_term_ref t_pip_source,
2554 Prolog_term_ref t_pip) {
2555 static const char* where = "ppl_new_PIP_Problem_from_PIP_Problem/2";
2556 try {
2557 const PIP_Problem* pip_source
2558 = static_cast<const PIP_Problem*>
2559 (term_to_handle<PIP_Problem>(t_pip_source, where));
2560 PPL_CHECK(pip_source);
2561 PIP_Problem* pip = new PIP_Problem(*pip_source);
2562 Prolog_term_ref tmp = Prolog_new_term_ref();
2563 Prolog_put_address(tmp, pip);
2564 if (Prolog_unify(t_pip, tmp)) {
2565 PPL_REGISTER(pip);
2566 return PROLOG_SUCCESS;
2567 }
2568 else
2569 delete pip;
2570 }
2571 CATCH_ALL;
2572 }
2573
2574 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_swap(Prolog_term_ref t_lhs,Prolog_term_ref t_rhs)2575 ppl_PIP_Problem_swap(Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
2576 static const char* where = "ppl_PIP_Problem_swap/2";
2577 try {
2578 PIP_Problem* lhs = term_to_handle<PIP_Problem>(t_lhs, where);
2579 PIP_Problem* rhs = term_to_handle<PIP_Problem>(t_rhs, where);
2580 PPL_CHECK(lhs);
2581 PPL_CHECK(rhs);
2582 swap(*lhs, *rhs);
2583 return PROLOG_SUCCESS;
2584 }
2585 CATCH_ALL;
2586 }
2587
2588 extern "C" Prolog_foreign_return_type
ppl_delete_PIP_Problem(Prolog_term_ref t_pip)2589 ppl_delete_PIP_Problem(Prolog_term_ref t_pip) {
2590 static const char* where = "ppl_delete_PIP_Problem/1";
2591 try {
2592 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2593 PPL_UNREGISTER(pip);
2594 delete pip;
2595 return PROLOG_SUCCESS;
2596 }
2597 CATCH_ALL;
2598 }
2599
2600 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_space_dimension(Prolog_term_ref t_pip,Prolog_term_ref t_sd)2601 ppl_PIP_Problem_space_dimension(Prolog_term_ref t_pip, Prolog_term_ref t_sd) {
2602 static const char* where = "ppl_PIP_Problem_space_dimension/2";
2603 try {
2604 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2605 PPL_CHECK(pip);
2606 if (unify_ulong(t_sd, pip->space_dimension()))
2607 return PROLOG_SUCCESS;
2608 }
2609 CATCH_ALL;
2610 }
2611
2612 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_parameter_space_dimensions(Prolog_term_ref t_pip,Prolog_term_ref t_vlist)2613 ppl_PIP_Problem_parameter_space_dimensions(Prolog_term_ref t_pip,
2614 Prolog_term_ref t_vlist) {
2615 static const char* where = "ppl_PIP_Problem_parameter_space_dimensions/2";
2616 try {
2617 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2618 PPL_CHECK(pip);
2619
2620 Prolog_term_ref tail = Prolog_new_term_ref();
2621 Prolog_put_nil(tail);
2622 const Variables_Set& params = pip->parameter_space_dimensions();
2623
2624 for (Variables_Set::const_iterator i = params.begin(),
2625 i_end = params.end(); i != i_end; ++i)
2626 Prolog_construct_cons(tail, variable_term(*i), tail);
2627
2628 if (Prolog_unify(t_vlist, tail))
2629 return PROLOG_SUCCESS;
2630 }
2631 CATCH_ALL;
2632 }
2633
2634 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_constraints(Prolog_term_ref t_pip,Prolog_term_ref t_clist)2635 ppl_PIP_Problem_constraints(Prolog_term_ref t_pip,
2636 Prolog_term_ref t_clist) {
2637 static const char* where = "ppl_PIP_Problem_constraints/2";
2638 try {
2639 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2640 PPL_CHECK(pip);
2641
2642 Prolog_term_ref tail = Prolog_new_term_ref();
2643 Prolog_put_nil(tail);
2644 for (PIP_Problem::const_iterator i = pip->constraints_begin(),
2645 i_end = pip->constraints_end(); i != i_end; ++i)
2646 Prolog_construct_cons(tail, constraint_term(*i), tail);
2647
2648 if (Prolog_unify(t_clist, tail))
2649 return PROLOG_SUCCESS;
2650 }
2651 CATCH_ALL;
2652 }
2653
2654 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_clear(Prolog_term_ref t_pip)2655 ppl_PIP_Problem_clear(Prolog_term_ref t_pip) {
2656 static const char* where = "ppl_PIP_Problem_clear/1";
2657 try {
2658 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2659 PPL_CHECK(pip);
2660 pip->clear();
2661 return PROLOG_SUCCESS;
2662 }
2663 CATCH_ALL;
2664 }
2665
2666 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_add_space_dimensions_and_embed(Prolog_term_ref t_pip,Prolog_term_ref t_num_vars,Prolog_term_ref t_num_params)2667 ppl_PIP_Problem_add_space_dimensions_and_embed
2668 (Prolog_term_ref t_pip,
2669 Prolog_term_ref t_num_vars,
2670 Prolog_term_ref t_num_params) {
2671 static const char* where
2672 = "ppl_PIP_Problem_add_space_dimensions_and_embed/3";
2673 try {
2674 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2675 PPL_CHECK(pip);
2676 dimension_type nv = term_to_unsigned<dimension_type>(t_num_vars, where);
2677 dimension_type np = term_to_unsigned<dimension_type>(t_num_params, where);
2678 pip->add_space_dimensions_and_embed(nv, np);
2679 return PROLOG_SUCCESS;
2680 }
2681 CATCH_ALL;
2682 }
2683
2684 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_add_to_parameter_space_dimensions(Prolog_term_ref t_pip,Prolog_term_ref t_vlist)2685 ppl_PIP_Problem_add_to_parameter_space_dimensions(Prolog_term_ref t_pip,
2686 Prolog_term_ref t_vlist) {
2687 static const char* where
2688 = "ppl_PIP_Problem_add_to_parameter_space_dimensions/2";
2689 try {
2690 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2691 PPL_CHECK(pip);
2692 Variables_Set params;
2693 Prolog_term_ref v = Prolog_new_term_ref();
2694
2695 while (Prolog_is_cons(t_vlist)) {
2696 Prolog_get_cons(t_vlist, v, t_vlist);
2697 params.insert(term_to_Variable(v, where).id());
2698 }
2699
2700 // Check the list is properly terminated.
2701 check_nil_terminating(t_vlist, where);
2702
2703 pip->add_to_parameter_space_dimensions(params);
2704 return PROLOG_SUCCESS;
2705 }
2706 CATCH_ALL;
2707 }
2708
2709 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_add_constraint(Prolog_term_ref t_pip,Prolog_term_ref t_c)2710 ppl_PIP_Problem_add_constraint(Prolog_term_ref t_pip, Prolog_term_ref t_c) {
2711 static const char* where = "ppl_PIP_Problem_add_constraint/2";
2712 try {
2713 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2714 PPL_CHECK(pip);
2715 pip->add_constraint(build_constraint(t_c, where));
2716 return PROLOG_SUCCESS;
2717 }
2718 CATCH_ALL;
2719 }
2720
2721 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_add_constraints(Prolog_term_ref t_pip,Prolog_term_ref t_clist)2722 ppl_PIP_Problem_add_constraints(Prolog_term_ref t_pip,
2723 Prolog_term_ref t_clist) {
2724 static const char* where = "ppl_PIP_Problem_add_constraints/2";
2725 try {
2726 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2727 PPL_CHECK(pip);
2728 Constraint_System cs;
2729 Prolog_term_ref c = Prolog_new_term_ref();
2730
2731 while (Prolog_is_cons(t_clist)) {
2732 Prolog_get_cons(t_clist, c, t_clist);
2733 cs.insert(build_constraint(c, where));
2734 }
2735
2736 // Check the list is properly terminated.
2737 check_nil_terminating(t_clist, where);
2738
2739 pip->add_constraints(cs);
2740 return PROLOG_SUCCESS;
2741 }
2742 CATCH_ALL;
2743 }
2744
2745 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_get_control_parameter(Prolog_term_ref t_pip,Prolog_term_ref t_cp_name,Prolog_term_ref t_cp_value)2746 ppl_PIP_Problem_get_control_parameter(Prolog_term_ref t_pip,
2747 Prolog_term_ref t_cp_name,
2748 Prolog_term_ref t_cp_value) {
2749 static const char* where = "ppl_PIP_Problem_get_control_parameter/3";
2750 try {
2751 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2752 PPL_CHECK(pip);
2753 Prolog_atom cp_name = term_to_pip_problem_control_parameter_name(t_cp_name, where);
2754 PIP_Problem::Control_Parameter_Value ppl_cp_value;
2755 Prolog_atom a;
2756 if (cp_name == a_cutting_strategy) {
2757 ppl_cp_value
2758 = pip->get_control_parameter(PIP_Problem::CUTTING_STRATEGY);
2759 switch (ppl_cp_value) {
2760 case PIP_Problem::CUTTING_STRATEGY_FIRST:
2761 a = a_cutting_strategy_first;
2762 break;
2763 case PIP_Problem::CUTTING_STRATEGY_DEEPEST:
2764 a = a_cutting_strategy_deepest;
2765 break;
2766 case PIP_Problem::CUTTING_STRATEGY_ALL:
2767 a = a_cutting_strategy_all;
2768 break;
2769 default:
2770 throw unknown_interface_error(
2771 "ppl_PIP_Problem_get_control_parameter()");
2772 }
2773 }
2774 else if (cp_name == a_pivot_row_strategy) {
2775 ppl_cp_value
2776 = pip->get_control_parameter(PIP_Problem::PIVOT_ROW_STRATEGY);
2777 switch (ppl_cp_value) {
2778 case PIP_Problem::PIVOT_ROW_STRATEGY_FIRST:
2779 a = a_pivot_row_strategy_first;
2780 break;
2781 case PIP_Problem::PIVOT_ROW_STRATEGY_MAX_COLUMN:
2782 a = a_pivot_row_strategy_max_column;
2783 break;
2784 default:
2785 throw unknown_interface_error(
2786 "ppl_PIP_Problem_get_control_parameter()");
2787 }
2788 }
2789 else
2790 throw unknown_interface_error("ppl_PIP_Problem_get_control_parameter()");
2791
2792 Prolog_term_ref t = Prolog_new_term_ref();
2793 Prolog_put_atom(t, a);
2794 if (Prolog_unify(t_cp_value, t))
2795 return PROLOG_SUCCESS;
2796 }
2797 CATCH_ALL;
2798 }
2799
2800 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_set_control_parameter(Prolog_term_ref t_pip,Prolog_term_ref t_cp_value)2801 ppl_PIP_Problem_set_control_parameter(Prolog_term_ref t_pip,
2802 Prolog_term_ref t_cp_value) {
2803 static const char* where = "ppl_PIP_Problem_set_control_parameter/2";
2804 try {
2805 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2806 PPL_CHECK(pip);
2807
2808 Prolog_atom cp_value = term_to_pip_problem_control_parameter_value(t_cp_value, where);
2809 if (cp_value == a_cutting_strategy_first)
2810 pip->set_control_parameter(PIP_Problem::CUTTING_STRATEGY_FIRST);
2811 else if (cp_value == a_cutting_strategy_deepest)
2812 pip->set_control_parameter(PIP_Problem::CUTTING_STRATEGY_DEEPEST);
2813 else if (cp_value == a_cutting_strategy_all)
2814 pip->set_control_parameter(PIP_Problem::CUTTING_STRATEGY_ALL);
2815 else if (cp_value == a_pivot_row_strategy_first)
2816 pip->set_control_parameter(PIP_Problem::PIVOT_ROW_STRATEGY_FIRST);
2817 else if (cp_value == a_pivot_row_strategy_max_column)
2818 pip->set_control_parameter(PIP_Problem::PIVOT_ROW_STRATEGY_MAX_COLUMN);
2819 else
2820 throw unknown_interface_error("ppl_PIP_Problem_set_control_parameter()");
2821 return PROLOG_SUCCESS;
2822 }
2823 CATCH_ALL;
2824 }
2825
2826 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_has_big_parameter_dimension(Prolog_term_ref t_pip,Prolog_term_ref t_d)2827 ppl_PIP_Problem_has_big_parameter_dimension(Prolog_term_ref t_pip,
2828 Prolog_term_ref t_d) {
2829 static const char* where = "ppl_PIP_Problem_get_big_parameter_dimension/2";
2830 try {
2831 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2832 PPL_CHECK(pip);
2833 dimension_type dim = pip->get_big_parameter_dimension();
2834 if (dim == not_a_dimension())
2835 return PROLOG_FAILURE;
2836 if (unify_ulong(t_d, dim))
2837 return PROLOG_SUCCESS;
2838 }
2839 CATCH_ALL;
2840 }
2841
2842 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_set_big_parameter_dimension(Prolog_term_ref t_pip,Prolog_term_ref t_d)2843 ppl_PIP_Problem_set_big_parameter_dimension(Prolog_term_ref t_pip,
2844 Prolog_term_ref t_d) {
2845 static const char* where = "ppl_MIP_Problem_set_big_parameter_dimension/2";
2846 try {
2847 PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2848 PPL_CHECK(pip);
2849 dimension_type d = term_to_unsigned<dimension_type>(t_d, where);
2850 pip->set_big_parameter_dimension(d);
2851 return PROLOG_SUCCESS;
2852 }
2853 CATCH_ALL;
2854 }
2855
2856 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_is_satisfiable(Prolog_term_ref t_pip)2857 ppl_PIP_Problem_is_satisfiable(Prolog_term_ref t_pip) {
2858 static const char* where = "ppl_PIP_Problem_is_satisfiable/1";
2859 try {
2860 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2861 PPL_CHECK(pip);
2862 if (pip->is_satisfiable())
2863 return PROLOG_SUCCESS;
2864 }
2865 CATCH_ALL;
2866 }
2867
2868 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_solve(Prolog_term_ref t_pip,Prolog_term_ref t_status)2869 ppl_PIP_Problem_solve(Prolog_term_ref t_pip, Prolog_term_ref t_status) {
2870 static const char* where = "ppl_PIP_Problem_solve/2";
2871 try {
2872 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2873 PPL_CHECK(pip);
2874
2875 Prolog_atom a;
2876 switch (pip->solve()) {
2877 case UNFEASIBLE_PIP_PROBLEM:
2878 a = a_unfeasible;
2879 break;
2880 case OPTIMIZED_PIP_PROBLEM:
2881 a = a_optimized;
2882 break;
2883 default:
2884 throw unknown_interface_error("ppl_PIP_Problem_solve()");
2885 }
2886 Prolog_term_ref t = Prolog_new_term_ref();
2887 Prolog_put_atom(t, a);
2888 if (Prolog_unify(t_status, t))
2889 return PROLOG_SUCCESS;
2890 }
2891 CATCH_ALL;
2892 }
2893
2894 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_solution(Prolog_term_ref t_pip,Prolog_term_ref t_pip_tree)2895 ppl_PIP_Problem_solution(Prolog_term_ref t_pip,
2896 Prolog_term_ref t_pip_tree) {
2897 static const char* where = "ppl_PIP_Problem_solution/2";
2898 try {
2899 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2900 PPL_CHECK(pip);
2901 PIP_Tree_Node* sol = const_cast<PIP_Tree_Node*>(pip->solution());
2902 Prolog_term_ref t_sol = Prolog_new_term_ref();
2903 Prolog_put_address(t_sol, sol);
2904 if (Prolog_unify(t_pip_tree, t_sol)) {
2905 PPL_WEAK_REGISTER(sol);
2906 return PROLOG_SUCCESS;
2907 }
2908 }
2909 CATCH_ALL;
2910 }
2911
2912 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_optimizing_solution(Prolog_term_ref t_pip,Prolog_term_ref t_pip_tree)2913 ppl_PIP_Problem_optimizing_solution(Prolog_term_ref t_pip,
2914 Prolog_term_ref t_pip_tree) {
2915 static const char* where = "ppl_PIP_Problem_optimizing_solution/2";
2916 try {
2917 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2918 PPL_CHECK(pip);
2919 PIP_Tree_Node* sol = const_cast<PIP_Tree_Node*>(pip->optimizing_solution());
2920 Prolog_term_ref t_sol = Prolog_new_term_ref();
2921 Prolog_put_address(t_sol, sol);
2922 if (Prolog_unify(t_pip_tree, t_sol)) {
2923 PPL_WEAK_REGISTER(sol);
2924 return PROLOG_SUCCESS;
2925 }
2926 }
2927 CATCH_ALL;
2928 }
2929
2930 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_OK(Prolog_term_ref t_pip)2931 ppl_PIP_Problem_OK(Prolog_term_ref t_pip) {
2932 static const char* where = "ppl_PIP_Problem_OK/1";
2933 try {
2934 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2935 PPL_CHECK(pip);
2936 if (pip->OK())
2937 return PROLOG_SUCCESS;
2938 }
2939 CATCH_ALL;
2940 }
2941
2942 extern "C" Prolog_foreign_return_type
ppl_PIP_Problem_ascii_dump(Prolog_term_ref t_pip)2943 ppl_PIP_Problem_ascii_dump(Prolog_term_ref t_pip) {
2944 static const char* where = "ppl_PIP_Problem_ascii_dump/1";
2945 try {
2946 const PIP_Problem* pip = term_to_handle<PIP_Problem>(t_pip, where);
2947 PPL_CHECK(pip);
2948 pip->ascii_dump(std::cout);
2949 return PROLOG_SUCCESS;
2950 }
2951 CATCH_ALL;
2952 }
2953
2954 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_constraints(Prolog_term_ref t_pip,Prolog_term_ref t_cs)2955 ppl_PIP_Tree_Node_constraints(Prolog_term_ref t_pip,
2956 Prolog_term_ref t_cs) {
2957 static const char* where = "ppl_PIP_Tree_Node_constraints/2";
2958 try {
2959 const PIP_Tree_Node* pip = term_to_handle<PIP_Tree_Node>(t_pip, where);
2960 PPL_CHECK(pip);
2961
2962 Prolog_term_ref tail = Prolog_new_term_ref();
2963 Prolog_put_nil(tail);
2964 const Constraint_System& ppl_cs = pip->constraints();
2965 for (Constraint_System::const_iterator i = ppl_cs.begin(),
2966 ppl_cs_end = ppl_cs.end(); i != ppl_cs_end; ++i)
2967 Prolog_construct_cons(tail, constraint_term(*i), tail);
2968
2969 if (Prolog_unify(t_cs, tail)) {
2970 return PROLOG_SUCCESS;
2971 }
2972 }
2973 CATCH_ALL;
2974 }
2975
2976 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_is_solution(Prolog_term_ref t_pip)2977 ppl_PIP_Tree_Node_is_solution(Prolog_term_ref t_pip) {
2978 static const char* where = "ppl_PIP_Tree_Node_as_solution/2";
2979 try {
2980 const PIP_Tree_Node* pip = term_to_handle<PIP_Tree_Node>(t_pip, where);
2981 PPL_CHECK(pip);
2982
2983 if (pip != 0 && pip->as_solution() != 0)
2984 return PROLOG_SUCCESS;
2985 return PROLOG_FAILURE;
2986 }
2987 CATCH_ALL;
2988 }
2989
2990 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_is_decision(Prolog_term_ref t_pip)2991 ppl_PIP_Tree_Node_is_decision(Prolog_term_ref t_pip) {
2992 static const char* where = "ppl_PIP_Tree_Node_as_decision/2";
2993 try {
2994 const PIP_Tree_Node* pip = term_to_handle<PIP_Tree_Node>(t_pip, where);
2995 PPL_CHECK(pip);
2996
2997 if (pip != 0 && pip->as_decision() != 0)
2998 return PROLOG_SUCCESS;
2999 return PROLOG_FAILURE;
3000 }
3001 CATCH_ALL;
3002 }
3003
3004 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_is_bottom(Prolog_term_ref t_pip)3005 ppl_PIP_Tree_Node_is_bottom(Prolog_term_ref t_pip) {
3006 static const char* where = "ppl_PIP_Tree_Node_as_decision/2";
3007 try {
3008 const PIP_Tree_Node* pip = term_to_handle<PIP_Tree_Node>(t_pip, where);
3009 PPL_CHECK(pip);
3010
3011 if (pip == 0)
3012 return PROLOG_SUCCESS;
3013 return PROLOG_FAILURE;
3014 }
3015 CATCH_ALL;
3016 }
3017
3018 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_artificials(Prolog_term_ref t_tree_node,Prolog_term_ref t_artlist)3019 ppl_PIP_Tree_Node_artificials(Prolog_term_ref t_tree_node,
3020 Prolog_term_ref t_artlist) {
3021 static const char* where = "ppl_PIP_Tree_Node_artificials/2";
3022 try {
3023 const PIP_Tree_Node* node
3024 = term_to_handle<PIP_Tree_Node>(t_tree_node, where);
3025 PPL_CHECK(node);
3026
3027 Prolog_term_ref tail = Prolog_new_term_ref();
3028 Prolog_put_nil(tail);
3029 for (PIP_Tree_Node::Artificial_Parameter_Sequence::const_iterator
3030 i = node->art_parameter_begin(),
3031 arts_end = node->art_parameter_end(); i != arts_end; ++i)
3032 Prolog_construct_cons(tail, artificial_parameter_term(*i), tail);
3033
3034 if (Prolog_unify(t_artlist, tail))
3035 return PROLOG_SUCCESS;
3036 }
3037 CATCH_ALL;
3038 }
3039
3040 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_parametric_values(Prolog_term_ref t_pip,Prolog_term_ref t_var,Prolog_term_ref t_le)3041 ppl_PIP_Tree_Node_parametric_values(Prolog_term_ref t_pip,
3042 Prolog_term_ref t_var,
3043 Prolog_term_ref t_le) {
3044 static const char* where = "ppl_PIP_Solution_Node_get_parametric_values/3";
3045 try {
3046 const PIP_Solution_Node* pip
3047 = term_to_handle<PIP_Solution_Node>(t_pip, where);
3048 PPL_CHECK(pip);
3049 Variable var = term_to_Variable(t_var, where);
3050 if (Prolog_unify(t_le, get_linear_expression(pip->parametric_values(var))))
3051 return PROLOG_SUCCESS;
3052 }
3053 CATCH_ALL;
3054 }
3055
3056 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_true_child(Prolog_term_ref t_pip,Prolog_term_ref t_ptree)3057 ppl_PIP_Tree_Node_true_child(Prolog_term_ref t_pip,
3058 Prolog_term_ref t_ptree) {
3059 static const char* where = "ppl_PIP_Decision_Node_get_true_child/2";
3060 try {
3061 const PIP_Decision_Node* pip
3062 = term_to_handle<PIP_Decision_Node>(t_pip, where);
3063 PPL_CHECK(pip);
3064 bool b = true;
3065 PIP_Tree_Node* ppl_ptree = const_cast<PIP_Tree_Node*>(pip->child_node(b));
3066 Prolog_term_ref t_ppl_ptree = Prolog_new_term_ref();
3067 Prolog_put_address(t_ppl_ptree, ppl_ptree);
3068 if (Prolog_unify(t_ptree, t_ppl_ptree)) {
3069 PPL_WEAK_REGISTER(ppl_ptree);
3070 return PROLOG_SUCCESS;
3071 }
3072 }
3073 CATCH_ALL;
3074 }
3075
3076 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_false_child(Prolog_term_ref t_pip,Prolog_term_ref t_ptree)3077 ppl_PIP_Tree_Node_false_child(Prolog_term_ref t_pip,
3078 Prolog_term_ref t_ptree) {
3079 static const char* where = "ppl_PIP_Decision_Node_get_false_child/2";
3080 try {
3081 const PIP_Decision_Node* pip
3082 = term_to_handle<PIP_Decision_Node>(t_pip, where);
3083 PPL_CHECK(pip);
3084 bool b = false;
3085 PIP_Tree_Node* ppl_ptree = const_cast<PIP_Tree_Node*>(pip->child_node(b));
3086 Prolog_term_ref t_ppl_ptree = Prolog_new_term_ref();
3087 Prolog_put_address(t_ppl_ptree, ppl_ptree);
3088 if (Prolog_unify(t_ptree, t_ppl_ptree)) {
3089 PPL_WEAK_REGISTER(ppl_ptree);
3090 return PROLOG_SUCCESS;
3091 }
3092 }
3093 CATCH_ALL;
3094 }
3095
3096 extern "C" Prolog_foreign_return_type
ppl_PIP_Tree_Node_OK(Prolog_term_ref t_pip)3097 ppl_PIP_Tree_Node_OK(Prolog_term_ref t_pip) {
3098 static const char* where = "ppl_PIP_Tree_Node_OK/1";
3099 try {
3100 const PIP_Tree_Node* pip = term_to_handle<PIP_Tree_Node>(t_pip, where);
3101 PPL_CHECK(pip);
3102 if (pip->OK())
3103 return PROLOG_SUCCESS;
3104 }
3105 CATCH_ALL;
3106 }
3107