00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ppl.hh"
00024 #include "pwl.hh"
00025 #include "track_allocation.hh"
00026 #include <set>
00027 #include <vector>
00028 #include <exception>
00029 #include <stdexcept>
00030 #include <sstream>
00031 #include <climits>
00032
00033 using namespace Parma_Polyhedra_Library;
00034
00035 namespace {
00036
00037 Prolog_atom out_of_memory_exception_atom;
00038
00039
00040 Prolog_atom a_nil;
00041
00042
00043 Prolog_atom a_dollar_VAR;
00044
00045
00046 Prolog_atom a_plus;
00047 Prolog_atom a_minus;
00048 Prolog_atom a_asterisk;
00049
00050
00051 Prolog_atom a_slash;
00052
00053
00054 Prolog_atom a_less_than;
00055 Prolog_atom a_equal_less_than;
00056 Prolog_atom a_equal;
00057 Prolog_atom a_greater_than_equal;
00058 Prolog_atom a_greater_than;
00059
00060
00061 Prolog_atom a_line;
00062 Prolog_atom a_ray;
00063 Prolog_atom a_point;
00064 Prolog_atom a_closure_point;
00065
00066
00067 Prolog_atom a_is_disjoint;
00068 Prolog_atom a_strictly_intersects;
00069 Prolog_atom a_is_included;
00070 Prolog_atom a_saturates;
00071
00072
00073 Prolog_atom a_subsumes;
00074
00075
00076 Prolog_atom a_c;
00077
00078
00079 Prolog_atom a_empty;
00080
00081
00082 Prolog_atom a_universe;
00083
00084
00085 Prolog_atom a_max;
00086
00087
00088 Prolog_atom a_min;
00089
00090
00091 Prolog_atom a_unfeasible;
00092 Prolog_atom a_unbounded;
00093 Prolog_atom a_optimized;
00094
00095
00096 Prolog_atom a_o;
00097
00098
00099 Prolog_atom a_i;
00100
00101
00102 Prolog_atom a_minf;
00103 Prolog_atom a_pinf;
00104
00105
00106 Prolog_atom a_polynomial;
00107 Prolog_atom a_simplex;
00108 Prolog_atom a_any;
00109
00110
00111 Prolog_atom a_time_out;
00112
00113
00114 Prolog_atom a_out_of_memory;
00115
00116
00117 Prolog_atom a_true;
00118 Prolog_atom a_false;
00119
00120
00121 Prolog_atom a_ppl_invalid_argument;
00122 Prolog_atom a_ppl_overflow_error;
00123 Prolog_atom a_ppl_domain_error;
00124 Prolog_atom a_ppl_length_error;
00125 Prolog_atom a_ppl_representation_error;
00126 Prolog_atom a_expected;
00127 Prolog_atom a_found;
00128 Prolog_atom a_where;
00129
00130 struct {
00131 Prolog_atom* p_atom;
00132 const char* name;
00133 } const prolog_atoms[] = {
00134 { &a_nil, "[]" },
00135
00136 { &a_dollar_VAR, "$VAR" },
00137
00138 { &a_plus, "+" },
00139 { &a_minus, "-" },
00140 { &a_asterisk, "*" },
00141
00142 { &a_slash, "/" },
00143
00144 { &a_equal, "=" },
00145 { &a_greater_than_equal, ">=" },
00146 { &a_equal_less_than, "=<" },
00147 { &a_greater_than, ">" },
00148 { &a_less_than, "<" },
00149
00150 { &a_line, "line" },
00151 { &a_ray, "ray" },
00152 { &a_point, "point" },
00153 { &a_closure_point, "closure_point" },
00154
00155 { &a_is_disjoint, "is_disjoint" },
00156 { &a_strictly_intersects, "strictly_intersects" },
00157 { &a_is_included, "is_included" },
00158 { &a_saturates, "saturates" },
00159
00160 { &a_subsumes, "subsumes" },
00161
00162 { &a_c, "c" },
00163
00164 { &a_empty, "empty" },
00165 { &a_universe, "universe" },
00166
00167 { &a_max, "max" },
00168 { &a_min, "min" },
00169
00170 { &a_unfeasible, "unfeasible" },
00171 { &a_unbounded, "unbounded" },
00172 { &a_optimized, "optimized" },
00173
00174 { &a_o, "o" },
00175 { &a_i, "i" },
00176
00177 { &a_minf, "minf" },
00178 { &a_pinf, "pinf" },
00179
00180 { &a_polynomial, "polynomial" },
00181 { &a_simplex, "simplex" },
00182 { &a_any, "any" },
00183
00184 { &a_time_out, "time_out" },
00185 { &a_out_of_memory, "out_of_memory" },
00186
00187 { &a_true, "true" },
00188 { &a_false, "false" },
00189
00190 { &a_ppl_invalid_argument, "ppl_invalid_argument" },
00191 { &a_ppl_overflow_error, "ppl_overflow_error" },
00192 { &a_ppl_domain_error, "ppl_domain_error" },
00193 { &a_ppl_length_error, "ppl_length_error" },
00194 { &a_ppl_representation_error, "ppl_representation_error" },
00195 { &a_expected, "expected" },
00196 { &a_found, "found" },
00197 { &a_where, "where" }
00198 };
00199
00200 Prolog_term_ref
00201 Prolog_atom_term_from_string(const char* s) {
00202 Prolog_term_ref t = Prolog_new_term_ref();
00203 Prolog_put_atom(t, Prolog_atom_from_string(s));
00204 return t;
00205 }
00206
00207 void
00208 handle_exception(const Prolog_unsigned_out_of_range& e) {
00209 Prolog_term_ref found = Prolog_new_term_ref();
00210 Prolog_construct_compound(found, a_found, e.term());
00211
00212 Prolog_term_ref max = Prolog_new_term_ref();
00213 Prolog_put_ulong(max, e.max());
00214 Prolog_construct_compound(max,
00215 Prolog_atom_from_string("unsigned_integer"
00216 "_less_than_or_equal_to"),
00217 max);
00218 Prolog_term_ref expected = Prolog_new_term_ref();
00219 Prolog_construct_compound(expected, a_expected, max);
00220
00221 Prolog_term_ref where = Prolog_new_term_ref();
00222 Prolog_construct_compound(where, a_where,
00223 Prolog_atom_term_from_string("term_to_unsigned"));
00224
00225 Prolog_term_ref exception_term = Prolog_new_term_ref();
00226 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00227 found, expected, where);
00228 Prolog_raise_exception(exception_term);
00229 }
00230
00231 void
00232 handle_exception(const not_unsigned_integer& e) {
00233 Prolog_term_ref found = Prolog_new_term_ref();
00234 Prolog_construct_compound(found, a_found, e.term());
00235
00236 Prolog_term_ref expected = Prolog_new_term_ref();
00237 Prolog_construct_compound(expected, a_expected,
00238 Prolog_atom_term_from_string("unsigned_integer"));
00239
00240 Prolog_term_ref where = Prolog_new_term_ref();
00241 Prolog_construct_compound(where, a_where,
00242 Prolog_atom_term_from_string("term_to_unsigned"));
00243
00244 Prolog_term_ref exception_term = Prolog_new_term_ref();
00245 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00246 found, expected, where);
00247 Prolog_raise_exception(exception_term);
00248 }
00249
00250 void
00251 handle_exception(const non_linear& e) {
00252 Prolog_term_ref found = Prolog_new_term_ref();
00253 Prolog_construct_compound(found, a_found, e.term());
00254
00255 Prolog_term_ref expected = Prolog_new_term_ref();
00256 Prolog_construct_compound(expected, a_expected,
00257 Prolog_atom_term_from_string
00258 ("linear_expression_or_constraint"));
00259
00260 Prolog_term_ref where = Prolog_new_term_ref();
00261 Prolog_construct_compound(where, a_where,
00262 Prolog_atom_term_from_string(e.where()));
00263
00264 Prolog_term_ref exception_term = Prolog_new_term_ref();
00265 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00266 found, expected, where);
00267 Prolog_raise_exception(exception_term);
00268 }
00269
00270 void
00271 handle_exception(const not_a_variable& e) {
00272 Prolog_term_ref found = Prolog_new_term_ref();
00273 Prolog_construct_compound(found, a_found,
00274 e.term());
00275
00276 Prolog_term_ref expected = Prolog_new_term_ref();
00277 Prolog_construct_compound(expected, a_expected,
00278 Prolog_atom_term_from_string
00279 ("$VAR(unsigned_integer)"));
00280
00281 Prolog_term_ref where = Prolog_new_term_ref();
00282 Prolog_construct_compound(where, a_where,
00283 Prolog_atom_term_from_string("term_to_Variable"));
00284
00285 Prolog_term_ref exception_term = Prolog_new_term_ref();
00286 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00287 found, expected, where);
00288 Prolog_raise_exception(exception_term);
00289 }
00290
00291 void
00292 handle_exception(const not_an_integer& e) {
00293 Prolog_term_ref found = Prolog_new_term_ref();
00294 Prolog_construct_compound(found, a_found, e.term());
00295
00296 Prolog_term_ref expected = Prolog_new_term_ref();
00297 Prolog_construct_compound(expected, a_expected,
00298 Prolog_atom_term_from_string("integer"));
00299
00300 Prolog_term_ref where = Prolog_new_term_ref();
00301 Prolog_construct_compound(where, a_where,
00302 Prolog_atom_term_from_string
00303 ("term_to_Coefficient"));
00304
00305 Prolog_term_ref exception_term = Prolog_new_term_ref();
00306 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00307 found, expected, where);
00308 Prolog_raise_exception(exception_term);
00309 }
00310
00311 void
00312 handle_exception(const not_a_polyhedron_handle& e) {
00313 Prolog_term_ref found = Prolog_new_term_ref();
00314 Prolog_construct_compound(found, a_found, e.term());
00315
00316 Prolog_term_ref expected = Prolog_new_term_ref();
00317 Prolog_construct_compound(expected, a_expected,
00318 Prolog_atom_term_from_string("polyhedron_handle"));
00319
00320 Prolog_term_ref where = Prolog_new_term_ref();
00321 Prolog_construct_compound(where, a_where,
00322 Prolog_atom_term_from_string
00323 ("term_to_polyhedron_handle"));
00324
00325 Prolog_term_ref exception_term = Prolog_new_term_ref();
00326 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00327 found, expected, where);
00328 Prolog_raise_exception(exception_term);
00329 }
00330
00331 void
00332 handle_exception(const not_an_optimization_mode& e) {
00333 Prolog_term_ref found = Prolog_new_term_ref();
00334 Prolog_construct_compound(found, a_found, e.term());
00335
00336 Prolog_term_ref expected = Prolog_new_term_ref();
00337 Prolog_put_atom(expected, a_nil);
00338 Prolog_construct_cons(expected,
00339 Prolog_atom_term_from_string("max"), expected);
00340 Prolog_construct_cons(expected,
00341 Prolog_atom_term_from_string("min"), expected);
00342 Prolog_construct_compound(expected, a_expected, expected);
00343
00344 Prolog_term_ref where = Prolog_new_term_ref();
00345 Prolog_construct_compound(where, a_where,
00346 Prolog_atom_term_from_string
00347 ("term_to_optimization_mode"));
00348 Prolog_term_ref exception_term = Prolog_new_term_ref();
00349 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00350 found, expected, where);
00351 Prolog_raise_exception(exception_term);
00352 }
00353
00354 void
00355 handle_exception(const not_an_lp_problem_handle& e) {
00356 Prolog_term_ref found = Prolog_new_term_ref();
00357 Prolog_construct_compound(found, a_found, e.term());
00358
00359 Prolog_term_ref expected = Prolog_new_term_ref();
00360 Prolog_construct_compound(expected, a_expected,
00361 Prolog_atom_term_from_string("lp_problem_handle"));
00362
00363 Prolog_term_ref where = Prolog_new_term_ref();
00364 Prolog_construct_compound(where, a_where,
00365 Prolog_atom_term_from_string
00366 ("term_to_lp_problem_handle"));
00367
00368 Prolog_term_ref exception_term = Prolog_new_term_ref();
00369 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00370 found, expected, where);
00371 Prolog_raise_exception(exception_term);
00372 }
00373
00374 void
00375 handle_exception(const not_a_complexity_class& e) {
00376 Prolog_term_ref found = Prolog_new_term_ref();
00377 Prolog_construct_compound(found, a_found, e.term());
00378
00379 Prolog_term_ref expected = Prolog_new_term_ref();
00380 Prolog_put_atom(expected, a_nil);
00381 Prolog_construct_cons(expected,
00382 Prolog_atom_term_from_string("polynomial"), expected);
00383 Prolog_construct_cons(expected,
00384 Prolog_atom_term_from_string("simplex"), expected);
00385 Prolog_construct_cons(expected,
00386 Prolog_atom_term_from_string("any"), expected);
00387 Prolog_construct_compound(expected, a_expected, expected);
00388
00389 Prolog_term_ref where = Prolog_new_term_ref();
00390 Prolog_construct_compound(where, a_where,
00391 Prolog_atom_term_from_string
00392 ("term_to_complexity_class"));
00393 Prolog_term_ref exception_term = Prolog_new_term_ref();
00394 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00395 found, expected, where);
00396 Prolog_raise_exception(exception_term);
00397 }
00398
00399 void
00400 handle_exception(const not_universe_or_empty& e) {
00401 Prolog_term_ref found = Prolog_new_term_ref();
00402 Prolog_construct_compound(found, a_found, e.term());
00403
00404 Prolog_term_ref expected = Prolog_new_term_ref();
00405 Prolog_put_atom(expected, a_nil);
00406 Prolog_construct_cons(expected,
00407 Prolog_atom_term_from_string("universe"), expected);
00408 Prolog_construct_cons(expected,
00409 Prolog_atom_term_from_string("empty"), expected);
00410 Prolog_construct_compound(expected, a_expected, expected);
00411
00412 Prolog_term_ref where = Prolog_new_term_ref();
00413 Prolog_construct_compound(where, a_where,
00414 Prolog_atom_term_from_string
00415 ("term_to_universe_or_empty"));
00416 Prolog_term_ref exception_term = Prolog_new_term_ref();
00417 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00418 found, expected, where);
00419 Prolog_raise_exception(exception_term);
00420 }
00421
00422 void
00423 handle_exception(const not_a_relation& e) {
00424 Prolog_term_ref found = Prolog_new_term_ref();
00425 Prolog_construct_compound(found, a_found, e.term());
00426
00427 Prolog_term_ref expected = Prolog_new_term_ref();
00428 Prolog_put_atom(expected, a_nil);
00429 Prolog_construct_cons(expected,
00430 Prolog_atom_term_from_string("="), expected);
00431 Prolog_construct_cons(expected,
00432 Prolog_atom_term_from_string(">="), expected);
00433 Prolog_construct_cons(expected,
00434 Prolog_atom_term_from_string("=<"), expected);
00435 Prolog_construct_cons(expected,
00436 Prolog_atom_term_from_string(">"), expected);
00437 Prolog_construct_cons(expected,
00438 Prolog_atom_term_from_string("<"), expected);
00439 Prolog_construct_compound(expected, a_expected, expected);
00440
00441 Prolog_term_ref where = Prolog_new_term_ref();
00442 Prolog_construct_compound(where, a_where,
00443 Prolog_atom_term_from_string
00444 ("term_to_relation"));
00445 Prolog_term_ref exception_term = Prolog_new_term_ref();
00446 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00447 found, expected, where);
00448 Prolog_raise_exception(exception_term);
00449 }
00450
00451 void
00452 handle_exception(const not_a_nil_terminated_list& e) {
00453 Prolog_term_ref found = Prolog_new_term_ref();
00454 Prolog_construct_compound(found, a_found, e.term());
00455
00456 Prolog_term_ref expected = Prolog_new_term_ref();
00457 Prolog_put_atom(expected, a_nil);
00458 Prolog_construct_cons(expected,
00459 Prolog_atom_term_from_string
00460 ("Prolog_list"), expected);
00461 Prolog_construct_compound(expected, a_expected, expected);
00462
00463 Prolog_term_ref where = Prolog_new_term_ref();
00464 Prolog_construct_compound(where, a_where,
00465 Prolog_atom_term_from_string
00466 ("check_nil_terminating"));
00467 Prolog_term_ref exception_term = Prolog_new_term_ref();
00468 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
00469 found, expected, where);
00470 Prolog_raise_exception(exception_term);
00471 }
00472
00473 void
00474 handle_exception(const PPL_integer_out_of_range& e) {
00475 Prolog_term_ref where = Prolog_new_term_ref();
00476 Prolog_construct_compound(where, a_where,
00477 Prolog_atom_term_from_string
00478 ("Coefficient_to_integer_term"));
00479
00480 Prolog_term_ref exception_term = Prolog_new_term_ref();
00481 std::ostringstream s;
00482 s << e.i();
00483 Prolog_construct_compound(exception_term, a_ppl_representation_error,
00484 Prolog_atom_term_from_string(s.str().c_str()),
00485 where);
00486 Prolog_raise_exception(exception_term);
00487 }
00488
00489 void
00490 handle_exception(const unknown_interface_error& e) {
00491 Prolog_term_ref et = Prolog_new_term_ref();
00492 Prolog_put_atom_chars(et, e.where());
00493 Prolog_raise_exception(et);
00494 }
00495
00496 void
00497 handle_exception(const std::overflow_error& e) {
00498 Prolog_term_ref et = Prolog_new_term_ref();
00499 Prolog_construct_compound(et, a_ppl_overflow_error,
00500 Prolog_atom_term_from_string(e.what()));
00501 Prolog_raise_exception(et);
00502 }
00503
00504 void
00505 handle_exception(const std::length_error& e) {
00506 Prolog_term_ref et = Prolog_new_term_ref();
00507 Prolog_construct_compound(et, a_ppl_length_error,
00508 Prolog_atom_term_from_string(e.what()));
00509 Prolog_raise_exception(et);
00510 }
00511
00512 void
00513 handle_exception(const std::bad_alloc&) {
00514 Prolog_term_ref et = Prolog_new_term_ref();
00515 Prolog_put_atom(et, out_of_memory_exception_atom);
00516 Prolog_raise_exception(et);
00517 }
00518
00519 void
00520 handle_exception(const std::exception& e) {
00521 Prolog_term_ref et = Prolog_new_term_ref();
00522 Prolog_put_atom_chars(et, e.what());
00523 Prolog_raise_exception(et);
00524 }
00525
00526 void
00527 handle_exception() {
00528 Prolog_term_ref et = Prolog_new_term_ref();
00529 Prolog_put_atom_chars(et, "PPL bug: unknown exception raised");
00530 Prolog_raise_exception(et);
00531 }
00532
00533 class timeout_exception : public Throwable {
00534 public:
00535 void throw_me() const {
00536 throw *this;
00537 }
00538 int priority() const {
00539 return 0;
00540 }
00541 timeout_exception() {
00542 }
00543 };
00544
00545 Prolog_atom timeout_exception_atom;
00546
00547 Parma_Watchdog_Library::Watchdog* p_timeout_object = 0;
00548
00549 void
00550 reset_timeout() {
00551 if (p_timeout_object) {
00552 delete p_timeout_object;
00553 p_timeout_object = 0;
00554 abandon_expensive_computations = 0;
00555 }
00556 }
00557
00558 void
00559 handle_exception(const timeout_exception&) {
00560 assert(p_timeout_object);
00561 reset_timeout();
00562 Prolog_term_ref et = Prolog_new_term_ref();
00563 Prolog_put_atom(et, timeout_exception_atom);
00564 Prolog_raise_exception(et);
00565 }
00566
00567 #define CATCH_ALL \
00568 catch (const Prolog_unsigned_out_of_range& e) { \
00569 handle_exception(e); \
00570 } \
00571 catch (const not_unsigned_integer& e) { \
00572 handle_exception(e); \
00573 } \
00574 catch (const non_linear& e) { \
00575 handle_exception(e); \
00576 } \
00577 catch (const not_a_variable& e) { \
00578 handle_exception(e); \
00579 } \
00580 catch (const not_an_integer& e) { \
00581 handle_exception(e); \
00582 } \
00583 catch (const not_a_polyhedron_handle& e) { \
00584 handle_exception(e); \
00585 } \
00586 catch (const not_an_optimization_mode& e) { \
00587 handle_exception(e); \
00588 } \
00589 catch (const not_an_lp_problem_handle& e) { \
00590 handle_exception(e); \
00591 } \
00592 catch (const not_a_complexity_class& e) { \
00593 handle_exception(e); \
00594 } \
00595 catch (const not_universe_or_empty& e) { \
00596 handle_exception(e); \
00597 } \
00598 catch (const not_a_relation& e) { \
00599 handle_exception(e); \
00600 } \
00601 catch (const not_a_nil_terminated_list& e) { \
00602 handle_exception(e); \
00603 } \
00604 catch (const PPL_integer_out_of_range& e) { \
00605 handle_exception(e); \
00606 } \
00607 catch (const unknown_interface_error& e) { \
00608 handle_exception(e); \
00609 } \
00610 catch (const timeout_exception& e) { \
00611 handle_exception(e); \
00612 } \
00613 catch(const std::overflow_error& e) { \
00614 handle_exception(e); \
00615 } \
00616 catch(const std::length_error& e) { \
00617 handle_exception(e); \
00618 } \
00619 catch (const std::bad_alloc& e) { \
00620 handle_exception(e); \
00621 } \
00622 catch (const std::exception& e) { \
00623 handle_exception(e); \
00624 } \
00625 catch (...) { \
00626 handle_exception(); \
00627 } \
00628 return PROLOG_FAILURE
00629
00630 Prolog_term_ref
00631 variable_term(dimension_type varid) {
00632 Prolog_term_ref v = Prolog_new_term_ref();
00633 Prolog_put_ulong(v, varid);
00634 Prolog_term_ref t = Prolog_new_term_ref();
00635 Prolog_construct_compound(t, a_dollar_VAR, v);
00636 return t;
00637 }
00638
00639 #if 0
00640 unsigned int
00641 get_unsigned_int(long n) {
00642 if (n >= 0 && static_cast<unsigned long>(n) <= UINT_MAX)
00643 return n;
00644 else {
00645 Prolog_term_ref n_term = Prolog_new_term_ref();
00646 Prolog_put_long(n_term, n);
00647 throw not_unsigned_integer(n_term);
00648 }
00649 }
00650 #endif
00651
00652 template <typename U>
00653 U
00654 term_to_unsigned(Prolog_term_ref t) {
00655 if (!Prolog_is_integer(t))
00656 throw not_unsigned_integer(t);
00657
00658 U d = 0;
00659 long l;
00660 if (Prolog_get_long(t, &l))
00661 if (l < 0)
00662 throw not_unsigned_integer(t);
00663 else if (static_cast<unsigned long>(l) > std::numeric_limits<U>::max())
00664 throw Prolog_unsigned_out_of_range(t, std::numeric_limits<U>::max());
00665 else
00666 d = l;
00667 else {
00668 Coefficient v = integer_term_to_Coefficient(t);
00669 if (v < 0)
00670 throw not_unsigned_integer(t);
00671 if (assign_r(d, raw_value(v), ROUND_NOT_NEEDED) != V_EQ)
00672 throw Prolog_unsigned_out_of_range(t, std::numeric_limits<U>::max());
00673 }
00674 return d;
00675 }
00676
00677 Prolog_atom
00678 term_to_universe_or_empty(Prolog_term_ref t) {
00679 if (Prolog_is_atom(t)) {
00680 Prolog_atom name;
00681 if (Prolog_get_atom_name(t, &name)
00682 && (name == a_universe || name == a_empty))
00683 return name;
00684 }
00685 throw not_universe_or_empty(t);
00686 }
00687
00688 Linear_Expression
00689 build_linear_expression(Prolog_term_ref t) {
00690 if (Prolog_is_integer(t))
00691 return Linear_Expression(integer_term_to_Coefficient(t));
00692 else if (Prolog_is_compound(t)) {
00693 Prolog_atom functor;
00694 int arity;
00695 Prolog_get_compound_name_arity(t, &functor, &arity);
00696 switch (arity) {
00697 case 1:
00698 {
00699 Prolog_term_ref arg = Prolog_new_term_ref();
00700 Prolog_get_arg(1, t, arg);
00701 if (functor == a_minus)
00702
00703 return -build_linear_expression(arg);
00704 else if (functor == a_dollar_VAR)
00705
00706 return Variable(term_to_unsigned<dimension_type>(arg));
00707 }
00708 break;
00709 case 2:
00710 {
00711 Prolog_term_ref arg1 = Prolog_new_term_ref();
00712 Prolog_term_ref arg2 = Prolog_new_term_ref();
00713 Prolog_get_arg(1, t, arg1);
00714 Prolog_get_arg(2, t, arg2);
00715 if (functor == a_plus)
00716
00717 if (Prolog_is_integer(arg1))
00718 return integer_term_to_Coefficient(arg1)
00719 + build_linear_expression(arg2);
00720 else if (Prolog_is_integer(arg2))
00721 return build_linear_expression(arg1)
00722 + integer_term_to_Coefficient(arg2);
00723 else
00724 return build_linear_expression(arg1)
00725 + build_linear_expression(arg2);
00726 else if (functor == a_minus)
00727
00728 if (Prolog_is_integer(arg1))
00729 return integer_term_to_Coefficient(arg1)
00730 - build_linear_expression(arg2);
00731 else if (Prolog_is_integer(arg2))
00732 return build_linear_expression(arg1)
00733 - integer_term_to_Coefficient(arg2);
00734 else
00735 return build_linear_expression(arg1)
00736 - build_linear_expression(arg2);
00737 else if (functor == a_asterisk)
00738
00739 if (Prolog_is_integer(arg1))
00740 return integer_term_to_Coefficient(arg1)
00741 * build_linear_expression(arg2);
00742 else if (Prolog_is_integer(arg2))
00743 return build_linear_expression(arg1)
00744 * integer_term_to_Coefficient(arg2);
00745 }
00746 }
00747 }
00748
00749 throw non_linear("build_linear_expression", t);
00750 }
00751
00752
00753 Constraint
00754 build_constraint(Prolog_term_ref t) {
00755 if (Prolog_is_compound(t)) {
00756 Prolog_atom functor;
00757 int arity;
00758 Prolog_get_compound_name_arity(t, &functor, &arity);
00759 if (arity == 2) {
00760 Prolog_term_ref arg1 = Prolog_new_term_ref();
00761 Prolog_term_ref arg2 = Prolog_new_term_ref();
00762 Prolog_get_arg(1, t, arg1);
00763 Prolog_get_arg(2, t, arg2);
00764 if (functor == a_equal)
00765
00766 if (Prolog_is_integer(arg1))
00767 return integer_term_to_Coefficient(arg1)
00768 == build_linear_expression(arg2);
00769 else if (Prolog_is_integer(arg2))
00770 return build_linear_expression(arg1)
00771 == integer_term_to_Coefficient(arg2);
00772 else
00773 return build_linear_expression(arg1)
00774 == build_linear_expression(arg2);
00775 else if (functor == a_equal_less_than)
00776
00777 if (Prolog_is_integer(arg1))
00778 return integer_term_to_Coefficient(arg1)
00779 <= build_linear_expression(arg2);
00780 else if (Prolog_is_integer(arg2))
00781 return build_linear_expression(arg1)
00782 <= integer_term_to_Coefficient(arg2);
00783 else
00784 return build_linear_expression(arg1)
00785 <= build_linear_expression(arg2);
00786 else if (functor == a_greater_than_equal)
00787
00788 if (Prolog_is_integer(arg1))
00789 return integer_term_to_Coefficient(arg1)
00790 >= build_linear_expression(arg2);
00791 else if (Prolog_is_integer(arg2))
00792 return build_linear_expression(arg1)
00793 >= integer_term_to_Coefficient(arg2);
00794 else
00795 return build_linear_expression(arg1)
00796 >= build_linear_expression(arg2);
00797 else if (functor == a_less_than)
00798
00799 if (Prolog_is_integer(arg1))
00800 return integer_term_to_Coefficient(arg1)
00801 < build_linear_expression(arg2);
00802 else if (Prolog_is_integer(arg2))
00803 return build_linear_expression(arg1)
00804 < integer_term_to_Coefficient(arg2);
00805 else
00806 return build_linear_expression(arg1)
00807 < build_linear_expression(arg2);
00808 else if (functor == a_greater_than)
00809
00810 if (Prolog_is_integer(arg1))
00811 return integer_term_to_Coefficient(arg1)
00812 > build_linear_expression(arg2);
00813 else if (Prolog_is_integer(arg2))
00814 return build_linear_expression(arg1)
00815 > integer_term_to_Coefficient(arg2);
00816 else
00817 return build_linear_expression(arg1)
00818 > build_linear_expression(arg2);
00819 }
00820 }
00821
00822 throw non_linear("build_constraint", t);
00823 }
00824
00825 Generator
00826 build_generator(Prolog_term_ref t) {
00827 if (Prolog_is_compound(t)) {
00828 Prolog_atom functor;
00829 int arity;
00830 Prolog_get_compound_name_arity(t, &functor, &arity);
00831 if (arity == 1) {
00832 Prolog_term_ref arg = Prolog_new_term_ref();
00833 Prolog_get_arg(1, t, arg);
00834 if (functor == a_line)
00835 return Generator::line(build_linear_expression(arg));
00836 else if (functor == a_ray)
00837 return Generator::ray(build_linear_expression(arg));
00838 else if (functor == a_point)
00839 return Generator::point(build_linear_expression(arg));
00840 else if (functor == a_closure_point)
00841 return Generator::closure_point(build_linear_expression(arg));
00842 }
00843 else if (arity == 2) {
00844 Prolog_term_ref arg1 = Prolog_new_term_ref();
00845 Prolog_term_ref arg2 = Prolog_new_term_ref();
00846 Prolog_get_arg(1, t, arg1);
00847 Prolog_get_arg(2, t, arg2);
00848 if (Prolog_is_integer(arg2)) {
00849 if (functor == a_point)
00850 return Generator::point(build_linear_expression(arg1),
00851 integer_term_to_Coefficient(arg2));
00852 else if (functor == a_closure_point)
00853 return Generator::closure_point(build_linear_expression(arg1),
00854 integer_term_to_Coefficient(arg2));
00855 }
00856 }
00857 }
00858
00859 throw non_linear("build_generator", t);
00860 }
00861
00862 template <typename R>
00863 Prolog_term_ref
00864 get_linear_expression(const R& r) {
00865 Prolog_term_ref so_far = Prolog_new_term_ref();
00866 Coefficient coefficient;
00867 dimension_type varid = 0;
00868 dimension_type space_dimension = r.space_dimension();
00869 while (varid < space_dimension
00870 && (coefficient = r.coefficient(Variable(varid))) == 0)
00871 ++varid;
00872 if (varid >= space_dimension) {
00873 Prolog_put_long(so_far, 0);
00874 }
00875 else {
00876 Prolog_construct_compound(so_far, a_asterisk,
00877 Coefficient_to_integer_term(coefficient),
00878 variable_term(varid));
00879 while (true) {
00880 ++varid;
00881 while (varid < space_dimension
00882 && (coefficient = r.coefficient(Variable(varid))) == 0)
00883 ++varid;
00884 if (varid >= space_dimension)
00885 break;
00886 else {
00887 Prolog_term_ref addendum = Prolog_new_term_ref();
00888 Prolog_construct_compound(addendum, a_asterisk,
00889 Coefficient_to_integer_term(coefficient),
00890 variable_term(varid));
00891 Prolog_term_ref new_so_far = Prolog_new_term_ref();
00892 Prolog_construct_compound(new_so_far, a_plus,
00893 so_far, addendum);
00894 so_far = new_so_far;
00895 }
00896 }
00897 }
00898 return so_far;
00899 }
00900
00901 Prolog_term_ref
00902 constraint_term(const Constraint& c) {
00903 Prolog_atom relation = 0;
00904 switch (c.type()) {
00905 case Constraint::EQUALITY:
00906 relation = a_equal;
00907 break;
00908 case Constraint::NONSTRICT_INEQUALITY:
00909 relation = a_greater_than_equal;
00910 break;
00911 case Constraint::STRICT_INEQUALITY:
00912 relation = a_greater_than;
00913 break;
00914 default:
00915 throw unknown_interface_error("generator_term()");
00916 }
00917 Prolog_term_ref t = Prolog_new_term_ref();
00918 Prolog_construct_compound
00919 (t,
00920 relation,
00921 get_linear_expression(c),
00922 Coefficient_to_integer_term(-c.inhomogeneous_term()));
00923 return t;
00924 }
00925
00926 Prolog_term_ref
00927 generator_term(const Generator& g) {
00928 Prolog_term_ref t = Prolog_new_term_ref();
00929 Prolog_atom constructor = 0;
00930 switch (g.type()) {
00931 case Generator::LINE:
00932 constructor = a_line;
00933 break;
00934 case Generator::RAY:
00935 constructor = a_ray;
00936 break;
00937 case Generator::POINT:
00938 {
00939 constructor = a_point;
00940 const Coefficient& divisor = g.divisor();
00941 if (divisor == 1)
00942 break;
00943 else {
00944 Prolog_construct_compound(t, constructor,
00945 get_linear_expression(g),
00946 Coefficient_to_integer_term(divisor));
00947 return t;
00948 }
00949 }
00950 case Generator::CLOSURE_POINT:
00951 {
00952 constructor = a_closure_point;
00953 const Coefficient& divisor = g.divisor();
00954 if (divisor == 1)
00955 break;
00956 else {
00957 Prolog_construct_compound(t, constructor,
00958 get_linear_expression(g),
00959 Coefficient_to_integer_term(divisor));
00960 return t;
00961 }
00962 }
00963 default:
00964 throw unknown_interface_error("generator_term()");
00965 }
00966 Prolog_construct_compound(t, constructor, get_linear_expression(g));
00967 return t;
00968 }
00969
00970 Variable
00971 term_to_Variable(Prolog_term_ref t) {
00972 if (Prolog_is_compound(t)) {
00973 Prolog_atom functor;
00974 int arity;
00975 Prolog_get_compound_name_arity(t, &functor, &arity);
00976 if (functor == a_dollar_VAR && arity == 1) {
00977 Prolog_term_ref arg = Prolog_new_term_ref();
00978 Prolog_get_arg(1, t, arg);
00979 return Variable(term_to_unsigned<dimension_type>(arg));
00980 }
00981 }
00982 throw not_a_variable(t);
00983 }
00984
00985 Coefficient
00986 term_to_Coefficient(Prolog_term_ref t) {
00987 if (Prolog_is_integer(t))
00988 return integer_term_to_Coefficient(t);
00989 else
00990 throw not_an_integer(t);
00991 }
00992
00993 Polyhedron*
00994 term_to_polyhedron_handle(Prolog_term_ref t_ph) {
00995 if (Prolog_is_address(t_ph)) {
00996 void* p;
00997 if (Prolog_get_address(t_ph, &p))
00998 return static_cast<Polyhedron*>(p);
00999 }
01000 throw not_a_polyhedron_handle(t_ph);
01001 }
01002
01003 LP_Problem*
01004 term_to_lp_problem_handle(Prolog_term_ref t_lp) {
01005 if (Prolog_is_address(t_lp)) {
01006 void* p;
01007 if (Prolog_get_address(t_lp, &p))
01008 return static_cast<LP_Problem*>(p);
01009 }
01010 throw not_an_lp_problem_handle(t_lp);
01011 }
01012
01013 Prolog_atom
01014 term_to_optimization_mode(Prolog_term_ref t) {
01015 if (Prolog_is_atom(t)) {
01016 Prolog_atom name;
01017 if (Prolog_get_atom_name(t, &name)
01018 && (name == a_max || name == a_min))
01019 return name;
01020 }
01021 throw not_an_optimization_mode(t);
01022 }
01023
01024 bool Prolog_interface_initialized = false;
01025
01026 bool
01027 unify_long(Prolog_term_ref t, long l) {
01028 Prolog_term_ref t_l = Prolog_new_term_ref();
01029 return Prolog_put_long(t_l, l) && Prolog_unify(t, t_l);
01030 }
01031
01032 bool
01033 unify_ulong(Prolog_term_ref t, unsigned long l) {
01034 Prolog_term_ref t_l = Prolog_new_term_ref();
01035 return Prolog_put_ulong(t_l, l) && Prolog_unify(t, t_l);
01036 }
01037
01038 void
01039 check_nil_terminating(Prolog_term_ref t) {
01040 if (Prolog_is_atom(t)) {
01041 Prolog_atom a;
01042 Prolog_get_atom_name(t, &a);
01043 if (a == a_nil)
01044 return;
01045 }
01046 throw not_a_nil_terminated_list(t);
01047 }
01048
01049 }
01050
01051 extern "C" Prolog_foreign_return_type
01052 ppl_version_major(Prolog_term_ref t_v) {
01053 try {
01054 if (unify_ulong(t_v, version_major()))
01055 return PROLOG_SUCCESS;
01056 }
01057 CATCH_ALL;
01058 }
01059
01060 extern "C" Prolog_foreign_return_type
01061 ppl_version_minor(Prolog_term_ref t_v) {
01062 try {
01063 if (unify_ulong(t_v, version_minor()))
01064 return PROLOG_SUCCESS;
01065 }
01066 CATCH_ALL;
01067 }
01068
01069 extern "C" Prolog_foreign_return_type
01070 ppl_version_revision(Prolog_term_ref t_v) {
01071 try {
01072 if (unify_ulong(t_v, version_revision()))
01073 return PROLOG_SUCCESS;
01074 }
01075 CATCH_ALL;
01076 }
01077
01078 extern "C" Prolog_foreign_return_type
01079 ppl_version_beta(Prolog_term_ref t_v) {
01080 try {
01081 if (unify_ulong(t_v, version_beta()))
01082 return PROLOG_SUCCESS;
01083 }
01084 CATCH_ALL;
01085 }
01086
01087 extern "C" Prolog_foreign_return_type
01088 ppl_version(Prolog_term_ref t_v) {
01089 try {
01090 Prolog_term_ref tmp = Prolog_new_term_ref();
01091 Prolog_put_atom_chars(tmp, version());
01092 if (Prolog_unify(t_v, tmp))
01093 return PROLOG_SUCCESS;
01094 }
01095 CATCH_ALL;
01096 }
01097
01098 extern "C" Prolog_foreign_return_type
01099 ppl_banner(Prolog_term_ref t_b) {
01100 try {
01101 Prolog_term_ref tmp = Prolog_new_term_ref();
01102 Prolog_put_atom_chars(tmp, banner());
01103 if (Prolog_unify(t_b, tmp))
01104 return PROLOG_SUCCESS;
01105 }
01106 CATCH_ALL;
01107 }
01108
01109 namespace {
01110
01111 inline dimension_type
01112 max_representable_dimension(dimension_type d) {
01113 return
01114 Prolog_has_unbounded_integers
01115 ? d
01116 : std::min(d, static_cast<dimension_type>(Prolog_max_integer));
01117 }
01118
01119 }
01120
01121 extern "C" Prolog_foreign_return_type
01122 ppl_max_space_dimension(Prolog_term_ref t_msd) {
01123 try {
01124 if (unify_ulong(t_msd, max_representable_dimension(max_space_dimension())))
01125 return PROLOG_SUCCESS;
01126 }
01127 CATCH_ALL;
01128 }
01129
01130 extern "C" Prolog_foreign_return_type
01131 ppl_initialize() {
01132 try {
01133 if (Prolog_interface_initialized)
01134 return PROLOG_SUCCESS;
01135 for (size_t
01136 i = sizeof(prolog_atoms)/sizeof(prolog_atoms[0]); i-- > 0; ) {
01137 Prolog_atom a = Prolog_atom_from_string(prolog_atoms[i].name);
01138 *prolog_atoms[i].p_atom = a;
01139 }
01140 timeout_exception_atom = a_time_out;
01141 out_of_memory_exception_atom = a_out_of_memory;
01142 ppl_Prolog_sysdep_init();
01143 Prolog_interface_initialized = true;
01144 return PROLOG_SUCCESS;
01145 }
01146 CATCH_ALL;
01147 }
01148
01149 extern "C" Prolog_foreign_return_type
01150 ppl_finalize() {
01151 try {
01152 if (!Prolog_interface_initialized)
01153 return PROLOG_SUCCESS;
01154
01155 Prolog_interface_initialized = false;
01156
01157 reset_timeout();
01158 ppl_Prolog_sysdep_deinit();
01159 return PROLOG_SUCCESS;
01160 }
01161 CATCH_ALL;
01162 }
01163
01164 extern "C" Prolog_foreign_return_type
01165 ppl_set_timeout_exception_atom(Prolog_term_ref t_tea) {
01166 try {
01167 if (Prolog_is_atom(t_tea)) {
01168 Prolog_atom tea;
01169 if (Prolog_get_atom_name(t_tea, &tea)) {
01170 timeout_exception_atom = tea;
01171 return PROLOG_SUCCESS;
01172 }
01173 }
01174 Prolog_term_ref found = Prolog_new_term_ref();
01175 Prolog_construct_compound(found, a_found, t_tea);
01176
01177 Prolog_term_ref expected = Prolog_new_term_ref();
01178 Prolog_construct_compound(expected, a_expected,
01179 Prolog_atom_term_from_string("atom"));
01180
01181 Prolog_term_ref where = Prolog_new_term_ref();
01182 Prolog_construct_compound(where, a_where,
01183 Prolog_atom_term_from_string
01184 ("ppl_set_timeout_exception_atom"));
01185
01186 Prolog_term_ref exception_term = Prolog_new_term_ref();
01187 Prolog_construct_compound(exception_term, a_ppl_invalid_argument,
01188 found, expected, where);
01189 Prolog_raise_exception(exception_term);
01190 return PROLOG_FAILURE;
01191 }
01192 CATCH_ALL;
01193 }
01194
01195 extern "C" Prolog_foreign_return_type
01196 ppl_timeout_exception_atom(Prolog_term_ref t) {
01197 try {
01198 Prolog_term_ref t_tea = Prolog_new_term_ref();
01199 Prolog_put_atom(t_tea, timeout_exception_atom);
01200 return Prolog_unify(t_tea, t) ? PROLOG_SUCCESS : PROLOG_FAILURE;
01201 }
01202 CATCH_ALL;
01203 }
01204
01205 extern "C" Prolog_foreign_return_type
01206 ppl_set_timeout(Prolog_term_ref t_time) {
01207 try {
01208
01209 reset_timeout();
01210 static timeout_exception e;
01211 unsigned hundredth_secs = term_to_unsigned<unsigned>(t_time);
01212 p_timeout_object =
01213 new Parma_Watchdog_Library::Watchdog(hundredth_secs,
01214 abandon_expensive_computations,
01215 e);
01216 return PROLOG_SUCCESS;
01217 }
01218 CATCH_ALL;
01219 }
01220
01221 extern "C" Prolog_foreign_return_type
01222 ppl_reset_timeout() {
01223 try {
01224 reset_timeout();
01225 return PROLOG_SUCCESS;
01226 }
01227 CATCH_ALL;
01228 }
01229
01230 extern "C" Prolog_foreign_return_type
01231 ppl_Coefficient_is_bounded() {
01232 try {
01233 if (std::numeric_limits<Coefficient>::is_bounded)
01234 return PROLOG_SUCCESS;
01235 }
01236 CATCH_ALL;
01237 }
01238
01239 extern "C" Prolog_foreign_return_type
01240 ppl_Coefficient_min(Prolog_term_ref t_min) {
01241 try {
01242 if (std::numeric_limits<Coefficient>::is_bounded) {
01243 Coefficient min = std::numeric_limits<Coefficient>::min();
01244 if (Prolog_has_unbounded_integers
01245 || (min >= Prolog_min_integer && min <= Prolog_min_integer))
01246 return Prolog_unify(t_min, Coefficient_to_integer_term(min));
01247 }
01248 }
01249 CATCH_ALL;
01250 }
01251
01252 extern "C" Prolog_foreign_return_type
01253 ppl_Coefficient_max(Prolog_term_ref t_max) {
01254 try {
01255 if (std::numeric_limits<Coefficient>::is_bounded) {
01256 Coefficient max = std::numeric_limits<Coefficient>::max();
01257 if (Prolog_has_unbounded_integers
01258 || (max >= Prolog_min_integer && max <= Prolog_min_integer))
01259 return Prolog_unify(t_max, Coefficient_to_integer_term(max));
01260 }
01261 }
01262 CATCH_ALL;
01263 }
01264
01265 extern "C" Prolog_foreign_return_type
01266 ppl_new_C_Polyhedron_from_space_dimension(Prolog_term_ref t_nd,
01267 Prolog_term_ref t_uoe,
01268 Prolog_term_ref t_ph) {
01269 try {
01270 Polyhedron* ph;
01271 Prolog_atom uoe = term_to_universe_or_empty(t_uoe);
01272
01273 if (uoe == a_empty)
01274 ph = new C_Polyhedron(term_to_unsigned<dimension_type>(t_nd),
01275 EMPTY);
01276 else
01277 ph = new C_Polyhedron(term_to_unsigned<dimension_type>(t_nd));
01278
01279
01280 Prolog_term_ref tmp = Prolog_new_term_ref();
01281 Prolog_put_address(tmp, ph);
01282 if (Prolog_unify(t_ph, tmp)) {
01283 REGISTER(ph);
01284 return PROLOG_SUCCESS;
01285 }
01286 else
01287 delete ph;
01288 }
01289 CATCH_ALL;
01290 }
01291
01292 extern "C" Prolog_foreign_return_type
01293 ppl_new_NNC_Polyhedron_from_space_dimension(Prolog_term_ref t_nd,
01294 Prolog_term_ref t_uoe,
01295 Prolog_term_ref t_ph) {
01296 try {
01297 Polyhedron* ph;
01298 Prolog_atom uoe = term_to_universe_or_empty(t_uoe);
01299
01300 if (uoe == a_empty)
01301 ph = new NNC_Polyhedron(term_to_unsigned<dimension_type>(t_nd),
01302 EMPTY);
01303 else
01304 ph = new NNC_Polyhedron(term_to_unsigned<dimension_type>(t_nd));
01305
01306
01307 Prolog_term_ref tmp = Prolog_new_term_ref();
01308 Prolog_put_address(tmp, ph);
01309 if (Prolog_unify(t_ph, tmp)) {
01310 REGISTER(ph);
01311 return PROLOG_SUCCESS;
01312 }
01313 else
01314 delete ph;
01315 }
01316 CATCH_ALL;
01317 }
01318
01319 extern "C" Prolog_foreign_return_type
01320 ppl_new_C_Polyhedron_from_C_Polyhedron(Prolog_term_ref t_ph_source,
01321 Prolog_term_ref t_ph) {
01322 try {
01323 Polyhedron* ph;
01324 const C_Polyhedron* ph_source
01325 = static_cast<const C_Polyhedron*>
01326 (term_to_polyhedron_handle(t_ph_source));
01327 CHECK(ph_source);
01328 ph = new C_Polyhedron(*ph_source);
01329 Prolog_term_ref tmp = Prolog_new_term_ref();
01330 Prolog_put_address(tmp, ph);
01331 if (Prolog_unify(t_ph, tmp)) {
01332 REGISTER(ph);
01333 return PROLOG_SUCCESS;
01334 }
01335 else
01336 delete ph;
01337 }
01338 CATCH_ALL;
01339 }
01340
01341 extern "C" Prolog_foreign_return_type
01342 ppl_new_NNC_Polyhedron_from_C_Polyhedron(Prolog_term_ref t_ph_source,
01343 Prolog_term_ref t_ph) {
01344 try {
01345 Polyhedron* ph;
01346 const C_Polyhedron* ph_source
01347 = static_cast<const C_Polyhedron*>
01348 (term_to_polyhedron_handle(t_ph_source));
01349 CHECK(ph_source);
01350 ph = new NNC_Polyhedron(*ph_source);
01351 Prolog_term_ref tmp = Prolog_new_term_ref();
01352 Prolog_put_address(tmp, ph);
01353 if (Prolog_unify(t_ph, tmp)) {
01354 REGISTER(ph);
01355 return PROLOG_SUCCESS;
01356 }
01357 else
01358 delete ph;
01359 }
01360 CATCH_ALL;
01361 }
01362
01363 extern "C" Prolog_foreign_return_type
01364 ppl_new_C_Polyhedron_from_NNC_Polyhedron(Prolog_term_ref t_ph_source,
01365 Prolog_term_ref t_ph) {
01366 try {
01367 Polyhedron* ph;
01368 const NNC_Polyhedron* ph_source
01369 = static_cast<const NNC_Polyhedron*>
01370 (term_to_polyhedron_handle(t_ph_source));
01371 CHECK(ph_source);
01372 ph = new C_Polyhedron(*ph_source);
01373 Prolog_term_ref tmp = Prolog_new_term_ref();
01374 Prolog_put_address(tmp, ph);
01375 if (Prolog_unify(t_ph, tmp)) {
01376 REGISTER(ph);
01377 return PROLOG_SUCCESS;
01378 }
01379 else
01380 delete ph;
01381 }
01382 CATCH_ALL;
01383 }
01384
01385 extern "C" Prolog_foreign_return_type
01386 ppl_new_NNC_Polyhedron_from_NNC_Polyhedron(Prolog_term_ref t_ph_source,
01387 Prolog_term_ref t_ph) {
01388 try {
01389 Polyhedron* ph;
01390 const NNC_Polyhedron* ph_source
01391 = static_cast<const NNC_Polyhedron*>
01392 (term_to_polyhedron_handle(t_ph_source));
01393 CHECK(ph_source);
01394 ph = new NNC_Polyhedron(*ph_source);
01395 Prolog_term_ref tmp = Prolog_new_term_ref();
01396 Prolog_put_address(tmp, ph);
01397 if (Prolog_unify(t_ph, tmp)) {
01398 REGISTER(ph);
01399 return PROLOG_SUCCESS;
01400 }
01401 else
01402 delete ph;
01403 }
01404 CATCH_ALL;
01405 }
01406
01407 extern "C" Prolog_foreign_return_type
01408 ppl_new_C_Polyhedron_from_constraints(Prolog_term_ref t_clist,
01409 Prolog_term_ref t_ph) {
01410 try {
01411 Constraint_System cs;
01412 Prolog_term_ref c = Prolog_new_term_ref();
01413
01414 while (Prolog_is_cons(t_clist)) {
01415 Prolog_get_cons(t_clist, c, t_clist);
01416 cs.insert(build_constraint(c));
01417 }
01418
01419
01420 check_nil_terminating(t_clist);
01421
01422 Polyhedron* ph;
01423 ph = new C_Polyhedron(cs);
01424 Prolog_term_ref tmp = Prolog_new_term_ref();
01425 Prolog_put_address(tmp, ph);
01426 if (Prolog_unify(t_ph, tmp)) {
01427 REGISTER(ph);
01428 return PROLOG_SUCCESS;
01429 }
01430 else
01431 delete ph;
01432 }
01433 CATCH_ALL;
01434 }
01435
01436 extern "C" Prolog_foreign_return_type
01437 ppl_new_NNC_Polyhedron_from_constraints(Prolog_term_ref t_clist,
01438 Prolog_term_ref t_ph) {
01439 try {
01440 Constraint_System cs;
01441 Prolog_term_ref c = Prolog_new_term_ref();
01442
01443 while (Prolog_is_cons(t_clist)) {
01444 Prolog_get_cons(t_clist, c, t_clist);
01445 cs.insert(build_constraint(c));
01446 }
01447
01448
01449 check_nil_terminating(t_clist);
01450
01451 Polyhedron* ph;
01452 ph = new NNC_Polyhedron(cs);
01453 Prolog_term_ref tmp = Prolog_new_term_ref();
01454 Prolog_put_address(tmp, ph);
01455 if (Prolog_unify(t_ph, tmp)) {
01456 REGISTER(ph);
01457 return PROLOG_SUCCESS;
01458 }
01459 else
01460 delete ph;
01461 }
01462 CATCH_ALL;
01463 }
01464
01465 extern "C" Prolog_foreign_return_type
01466 ppl_new_C_Polyhedron_from_generators(Prolog_term_ref t_glist,
01467 Prolog_term_ref t_ph) {
01468 try {
01469 Generator_System gs;
01470 Prolog_term_ref g = Prolog_new_term_ref();
01471
01472 while (Prolog_is_cons(t_glist)) {
01473 Prolog_get_cons(t_glist, g, t_glist);
01474 gs.insert(build_generator(g));
01475 }
01476
01477
01478 check_nil_terminating(t_glist);
01479
01480 Polyhedron* ph;
01481 ph = new C_Polyhedron(gs);
01482 Prolog_term_ref tmp = Prolog_new_term_ref();
01483 Prolog_put_address(tmp, ph);
01484 if (Prolog_unify(t_ph, tmp)) {
01485 REGISTER(ph);
01486 return PROLOG_SUCCESS;
01487 }
01488 else
01489 delete ph;
01490 }
01491 CATCH_ALL;
01492 }
01493
01494 extern "C" Prolog_foreign_return_type
01495 ppl_new_NNC_Polyhedron_from_generators(Prolog_term_ref t_glist,
01496 Prolog_term_ref t_ph) {
01497 try {
01498 Generator_System gs;
01499 Prolog_term_ref g = Prolog_new_term_ref();
01500
01501 while (Prolog_is_cons(t_glist)) {
01502 Prolog_get_cons(t_glist, g, t_glist);
01503 gs.insert(build_generator(g));
01504 }
01505
01506
01507 check_nil_terminating(t_glist);
01508
01509 Polyhedron* ph;
01510 ph = new NNC_Polyhedron(gs);
01511 Prolog_term_ref tmp = Prolog_new_term_ref();
01512 Prolog_put_address(tmp, ph);
01513 if (Prolog_unify(t_ph, tmp)) {
01514 REGISTER(ph);
01515 return PROLOG_SUCCESS;
01516 }
01517 else
01518 delete ph;
01519 }
01520 CATCH_ALL;
01521 }
01522
01523 namespace {
01524
01525 enum Boundary_Kind {
01526 LOWER,
01527 UPPER
01528 };
01529
01530 bool
01531 term_to_boundary(Prolog_term_ref t_b, Boundary_Kind kind,
01532 bool& finite, bool& closed,
01533 Coefficient& n, Coefficient& d) {
01534 if (!Prolog_is_compound(t_b))
01535 return false;
01536
01537 Prolog_atom functor;
01538 int arity;
01539
01540 Prolog_get_compound_name_arity(t_b, &functor, &arity);
01541
01542 if (arity != 1 || (functor != a_c && functor != a_o))
01543 return false;
01544
01545 Prolog_atom open_closed_atom = functor;
01546
01547 Prolog_term_ref t_limit = Prolog_new_term_ref();
01548 Prolog_get_arg(1, t_b, t_limit);
01549 if (Prolog_is_integer(t_limit)) {
01550
01551 finite = true;
01552 closed = (open_closed_atom == a_c);
01553 n = integer_term_to_Coefficient(t_limit);
01554 d = 1;
01555 }
01556 else if (Prolog_is_atom(t_limit)) {
01557 Prolog_atom a;
01558 Prolog_get_atom_name(t_limit, &a);
01559 Prolog_atom allowed_infinity = (kind == LOWER ? a_minf : a_pinf);
01560
01561 if (a != allowed_infinity || open_closed_atom != a_o)
01562 return false;
01563
01564 finite = false;
01565 }
01566 else if (Prolog_is_compound(t_limit)) {
01567 Prolog_get_compound_name_arity(t_limit, &functor, &arity);
01568 if (arity != 2 || functor != a_slash)
01569 return false;
01570
01571 Prolog_term_ref t_n = Prolog_new_term_ref();
01572 Prolog_term_ref t_d = Prolog_new_term_ref();
01573 Prolog_get_arg(1, t_limit, t_n);
01574 Prolog_get_arg(2, t_limit, t_d);
01575
01576 if (!Prolog_is_integer(t_n) || !Prolog_is_integer(t_d))
01577 return false;
01578 else {
01579 finite = true;
01580 closed = (open_closed_atom == a_c);
01581 n = integer_term_to_Coefficient(t_n);
01582 d = integer_term_to_Coefficient(t_d);
01583
01584 if (d <= 0)
01585 return false;
01586 }
01587 }
01588 return true;
01589 }
01590
01591 }
01592
01593 extern "C" Prolog_foreign_return_type
01594 ppl_new_C_Polyhedron_from_bounding_box(Prolog_term_ref t_bb,
01595 Prolog_term_ref t_ph) {
01596 try {
01597
01598 Prolog_term_ref t_l = Prolog_new_term_ref();
01599 Prolog_term_ref t_interval = Prolog_new_term_ref();
01600 Prolog_put_term(t_l, t_bb);
01601 dimension_type dimension;
01602 for (dimension = 0; Prolog_is_cons(t_l); ++dimension)
01603 Prolog_get_cons(t_l, t_interval, t_l);
01604
01605
01606 check_nil_terminating(t_l);
01607
01608 Bounding_Box bbox(dimension);
01609
01610 for (dimension_type i = 0; i < dimension; ++i) {
01611 Prolog_get_cons(t_bb, t_interval, t_bb);
01612
01613
01614 if (Prolog_is_atom(t_interval)) {
01615 Prolog_atom name;
01616 if (Prolog_get_atom_name(t_interval, &name) && name == a_empty) {
01617 bbox.set_empty();
01618 continue;
01619 }
01620 else
01621 return PROLOG_FAILURE;
01622 }
01623
01624 if (!Prolog_is_compound(t_interval))
01625 return PROLOG_FAILURE;
01626
01627 Prolog_atom functor;
01628 int arity;
01629 Prolog_get_compound_name_arity(t_interval, &functor, &arity);
01630 if (arity != 2 || functor != a_i)
01631 return PROLOG_FAILURE;
01632
01633 bool finite;
01634 bool closed;
01635 Coefficient n;
01636 Coefficient d;
01637 Prolog_term_ref t_bound = Prolog_new_term_ref();
01638
01639
01640 Prolog_get_arg(1, t_interval, t_bound);
01641 if (!term_to_boundary(t_bound, LOWER, finite, closed, n, d))
01642 return PROLOG_FAILURE;
01643 if (finite)
01644 bbox.raise_lower_bound(i, closed, n, d);
01645
01646
01647 Prolog_get_arg(2, t_interval, t_bound);
01648 if (!term_to_boundary(t_bound, UPPER, finite, closed, n, d))
01649 return PROLOG_FAILURE;
01650 if (finite)
01651 bbox.lower_upper_bound(i, closed, n, d);
01652 }
01653
01654 Polyhedron* ph;
01655 ph = new C_Polyhedron(bbox, From_Bounding_Box());
01656 Prolog_term_ref tmp = Prolog_new_term_ref();
01657 Prolog_put_address(tmp, ph);
01658 if (Prolog_unify(t_ph, tmp)) {
01659 REGISTER(ph);
01660 return PROLOG_SUCCESS;
01661 }
01662 else
01663 delete ph;
01664 }
01665 CATCH_ALL;
01666 }
01667
01668 extern "C" Prolog_foreign_return_type
01669 ppl_new_NNC_Polyhedron_from_bounding_box(Prolog_term_ref t_bb,
01670 Prolog_term_ref t_ph) {
01671 try {
01672
01673 Prolog_term_ref t_l = Prolog_new_term_ref();
01674 Prolog_term_ref t_interval = Prolog_new_term_ref();
01675 Prolog_put_term(t_l, t_bb);
01676 dimension_type dimension;
01677 for (dimension = 0; Prolog_is_cons(t_l); ++dimension)
01678 Prolog_get_cons(t_l, t_interval, t_l);
01679
01680
01681 check_nil_terminating(t_l);
01682
01683 Bounding_Box bbox(dimension);
01684
01685 for (dimension_type i = 0; i < dimension; ++i) {
01686 Prolog_get_cons(t_bb, t_interval, t_bb);
01687
01688
01689 if (Prolog_is_atom(t_interval)) {
01690 Prolog_atom name;
01691 if (Prolog_get_atom_name(t_interval, &name) && name == a_empty) {
01692 bbox.set_empty();
01693 continue;
01694 }
01695 else
01696 return PROLOG_FAILURE;
01697 }
01698
01699 if (!Prolog_is_compound(t_interval))
01700 return PROLOG_FAILURE;
01701
01702 Prolog_atom functor;
01703 int arity;
01704 Prolog_get_compound_name_arity(t_interval, &functor, &arity);
01705 if (arity != 2 || functor != a_i)
01706 return PROLOG_FAILURE;
01707
01708 bool finite;
01709 bool closed;
01710 Coefficient n;
01711 Coefficient d;
01712 Prolog_term_ref t_bound = Prolog_new_term_ref();
01713
01714
01715 Prolog_get_arg(1, t_interval, t_bound);
01716 if (!term_to_boundary(t_bound, LOWER, finite, closed, n, d))
01717 return PROLOG_FAILURE;
01718 if (finite)
01719 bbox.raise_lower_bound(i, closed, n, d);
01720
01721
01722 Prolog_get_arg(2, t_interval, t_bound);
01723 if (!term_to_boundary(t_bound, UPPER, finite, closed, n, d))
01724 return PROLOG_FAILURE;
01725 if (finite)
01726 bbox.lower_upper_bound(i, closed, n, d);
01727 }
01728
01729 Polyhedron* ph;
01730 ph = new NNC_Polyhedron(bbox, From_Bounding_Box());
01731 Prolog_term_ref tmp = Prolog_new_term_ref();
01732 Prolog_put_address(tmp, ph);
01733 if (Prolog_unify(t_ph, tmp)) {
01734 REGISTER(ph);
01735 return PROLOG_SUCCESS;
01736 }
01737 else
01738 delete ph;
01739 }
01740 CATCH_ALL;
01741 }
01742
01743 extern "C" Prolog_foreign_return_type
01744 ppl_Polyhedron_swap(Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
01745 try {
01746 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
01747 Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
01748 CHECK(lhs);
01749 CHECK(rhs);
01750 lhs->swap(*rhs);
01751 return PROLOG_SUCCESS;
01752 }
01753 CATCH_ALL;
01754 }
01755
01756 extern "C" Prolog_foreign_return_type
01757 ppl_delete_Polyhedron(Prolog_term_ref t_ph) {
01758 try {
01759 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01760 UNREGISTER(ph);
01761 delete ph;
01762 return PROLOG_SUCCESS;
01763 }
01764 CATCH_ALL;
01765 }
01766
01767 extern "C" Prolog_foreign_return_type
01768 ppl_Polyhedron_space_dimension(Prolog_term_ref t_ph, Prolog_term_ref t_sd) {
01769 try {
01770 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01771 CHECK(ph);
01772 if (unify_ulong(t_sd, ph->space_dimension()))
01773 return PROLOG_SUCCESS;
01774 }
01775 CATCH_ALL;
01776 }
01777
01778 extern "C" Prolog_foreign_return_type
01779 ppl_Polyhedron_affine_dimension(Prolog_term_ref t_ph, Prolog_term_ref t_sd) {
01780 try {
01781 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01782 CHECK(ph);
01783 if (unify_ulong(t_sd, ph->affine_dimension()))
01784 return PROLOG_SUCCESS;
01785 }
01786 CATCH_ALL;
01787 }
01788
01789 extern "C" Prolog_foreign_return_type
01790 ppl_Polyhedron_get_constraints(Prolog_term_ref t_ph,
01791 Prolog_term_ref t_clist) {
01792 try {
01793 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01794 CHECK(ph);
01795
01796 Prolog_term_ref tail = Prolog_new_term_ref();
01797 Prolog_put_atom(tail, a_nil);
01798 const Constraint_System& cs = ph->constraints();
01799 for (Constraint_System::const_iterator i = cs.begin(),
01800 cs_end = cs.end(); i != cs_end; ++i)
01801 Prolog_construct_cons(tail, constraint_term(*i), tail);
01802
01803 if (Prolog_unify(t_clist, tail))
01804 return PROLOG_SUCCESS;
01805 }
01806 CATCH_ALL;
01807 }
01808
01809 extern "C" Prolog_foreign_return_type
01810 ppl_Polyhedron_get_minimized_constraints(Prolog_term_ref t_ph,
01811 Prolog_term_ref t_clist) {
01812 try {
01813 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01814 CHECK(ph);
01815
01816 Prolog_term_ref tail = Prolog_new_term_ref();
01817 Prolog_put_atom(tail, a_nil);
01818 const Constraint_System& cs = ph->minimized_constraints();
01819 for (Constraint_System::const_iterator i = cs.begin(),
01820 cs_end = cs.end(); i != cs_end; ++i)
01821 Prolog_construct_cons(tail, constraint_term(*i), tail);
01822
01823 if (Prolog_unify(t_clist, tail))
01824 return PROLOG_SUCCESS;
01825 }
01826 CATCH_ALL;
01827 }
01828
01829 extern "C" Prolog_foreign_return_type
01830 ppl_Polyhedron_get_generators(Prolog_term_ref t_ph,
01831 Prolog_term_ref t_glist) {
01832 try {
01833 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01834 CHECK(ph);
01835
01836 Prolog_term_ref tail = Prolog_new_term_ref();
01837 Prolog_put_atom(tail, a_nil);
01838 const Generator_System& gs = ph->generators();
01839 for (Generator_System::const_iterator i = gs.begin(),
01840 gs_end = gs.end(); i != gs_end; ++i)
01841 Prolog_construct_cons(tail, generator_term(*i), tail);
01842
01843 if (Prolog_unify(t_glist, tail))
01844 return PROLOG_SUCCESS;
01845 }
01846 CATCH_ALL;
01847 }
01848
01849 extern "C" Prolog_foreign_return_type
01850 ppl_Polyhedron_get_minimized_generators(Prolog_term_ref t_ph,
01851 Prolog_term_ref t_glist) {
01852 try {
01853 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01854 CHECK(ph);
01855
01856 Prolog_term_ref tail = Prolog_new_term_ref();
01857 Prolog_put_atom(tail, a_nil);
01858 const Generator_System& gs = ph->minimized_generators();
01859 for (Generator_System::const_iterator i = gs.begin(),
01860 gs_end = gs.end(); i != gs_end; ++i)
01861 Prolog_construct_cons(tail, generator_term(*i), tail);
01862
01863 if (Prolog_unify(t_glist, tail))
01864 return PROLOG_SUCCESS;
01865 }
01866 CATCH_ALL;
01867 }
01868
01869 extern "C" Prolog_foreign_return_type
01870 ppl_Polyhedron_relation_with_constraint(Prolog_term_ref t_ph,
01871 Prolog_term_ref t_c,
01872 Prolog_term_ref t_r) {
01873 try {
01874 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01875 CHECK(ph);
01876 Poly_Con_Relation r = ph->relation_with(build_constraint(t_c));
01877
01878 Prolog_term_ref tail = Prolog_new_term_ref();
01879 Prolog_put_atom(tail, a_nil);
01880 while (r != Poly_Con_Relation::nothing()) {
01881 if (r.implies(Poly_Con_Relation::is_disjoint())) {
01882 Prolog_term_ref t_dis = Prolog_new_term_ref();
01883 Prolog_put_atom(t_dis, a_is_disjoint);
01884 Prolog_construct_cons(tail, t_dis, tail);
01885 r = r - Poly_Con_Relation::is_disjoint();
01886 }
01887 else if (r.implies(Poly_Con_Relation::strictly_intersects())) {
01888 Prolog_term_ref t_sin = Prolog_new_term_ref();
01889 Prolog_put_atom(t_sin, a_strictly_intersects);
01890 Prolog_construct_cons(tail, t_sin, tail);
01891 r = r - Poly_Con_Relation::strictly_intersects();
01892 }
01893 else if (r.implies(Poly_Con_Relation::is_included())) {
01894 Prolog_term_ref t_inc = Prolog_new_term_ref();
01895 Prolog_put_atom(t_inc, a_is_included);
01896 Prolog_construct_cons(tail, t_inc, tail);
01897 r = r - Poly_Con_Relation::is_included();
01898 }
01899 else if (r.implies(Poly_Con_Relation::saturates())) {
01900 Prolog_term_ref t_sat = Prolog_new_term_ref();
01901 Prolog_put_atom(t_sat, a_saturates);
01902 Prolog_construct_cons(tail, t_sat, tail);
01903 r = r - Poly_Con_Relation::saturates();
01904 }
01905 }
01906 if (Prolog_unify(t_r, tail))
01907 return PROLOG_SUCCESS;
01908 }
01909 CATCH_ALL;
01910 }
01911
01912 extern "C" Prolog_foreign_return_type
01913 ppl_Polyhedron_relation_with_generator(Prolog_term_ref t_ph,
01914 Prolog_term_ref t_g,
01915 Prolog_term_ref t_r) {
01916 try {
01917 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
01918 CHECK(ph);
01919 Poly_Gen_Relation r = ph->relation_with(build_generator(t_g));
01920
01921 Prolog_term_ref tail = Prolog_new_term_ref();
01922 Prolog_put_atom(tail, a_nil);
01923 while (r != Poly_Gen_Relation::nothing()) {
01924 if (r.implies(Poly_Gen_Relation::subsumes())) {
01925 Prolog_term_ref t_sub = Prolog_new_term_ref();
01926 Prolog_put_atom(t_sub, a_subsumes);
01927 Prolog_construct_cons(tail, t_sub, tail);
01928 r = r - Poly_Gen_Relation::subsumes();
01929 }
01930 }
01931 if (Prolog_unify(t_r, tail))
01932 return PROLOG_SUCCESS;
01933 }
01934 CATCH_ALL;
01935 }
01936
01937 namespace {
01938
01939 Prolog_term_ref
01940 extended_rational_term(const ERational& e) {
01941 Prolog_term_ref t = Prolog_new_term_ref();
01942 if (is_plus_infinity(e))
01943 Prolog_put_atom(t, a_pinf);
01944 else if (is_minus_infinity(e))
01945 Prolog_put_atom(t, a_minf);
01946 else {
01947 Coefficient numerator = raw_value(e).get_num();
01948 Coefficient denominator = raw_value(e).get_den();
01949 if (denominator == 1)
01950 Prolog_put_term(t, Coefficient_to_integer_term(numerator));
01951 else
01952 Prolog_construct_compound(t, a_slash,
01953 Coefficient_to_integer_term(numerator),
01954 Coefficient_to_integer_term(denominator));
01955 }
01956 return t;
01957 }
01958
01959 Prolog_term_ref
01960 interval_term(const Interval& i) {
01961 Prolog_term_ref t = Prolog_new_term_ref();
01962 if (i.is_empty())
01963 Prolog_put_atom(t, a_empty);
01964 else {
01965
01966 const LBoundary& l = i.lower_bound();
01967 Prolog_term_ref lt = Prolog_new_term_ref();
01968 if (l.is_closed())
01969 Prolog_construct_compound(lt, a_c, extended_rational_term(l.bound()));
01970 else
01971 Prolog_construct_compound(lt, a_o, extended_rational_term(l.bound()));
01972
01973
01974 const UBoundary& u = i.upper_bound();
01975 Prolog_term_ref ut = Prolog_new_term_ref();
01976 if (u.is_closed())
01977 Prolog_construct_compound(ut, a_c, extended_rational_term(u.bound()));
01978 else
01979 Prolog_construct_compound(ut, a_o, extended_rational_term(u.bound()));
01980
01981 Prolog_construct_compound(t, a_i, lt, ut);
01982 }
01983 return t;
01984 }
01985
01986 Prolog_atom
01987 term_to_complexity_class(Prolog_term_ref t) {
01988 if (Prolog_is_atom(t)) {
01989 Prolog_atom name;
01990 if (Prolog_get_atom_name(t, &name)
01991 && (name == a_polynomial || name == a_simplex || name == a_any))
01992 return name;
01993 }
01994 throw not_a_complexity_class(t);
01995 }
01996
01997 }
01998
01999 extern "C" Prolog_foreign_return_type
02000 ppl_Polyhedron_get_bounding_box(Prolog_term_ref t_ph,
02001 Prolog_term_ref t_cc,
02002 Prolog_term_ref t_bb) {
02003 try {
02004 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02005 CHECK(ph);
02006
02007 Prolog_atom p_cc = term_to_complexity_class(t_cc);
02008 Complexity_Class cc;
02009 if (p_cc == a_polynomial)
02010 cc = POLYNOMIAL_COMPLEXITY;
02011 else if (p_cc == a_simplex)
02012 cc = SIMPLEX_COMPLEXITY;
02013 else
02014 cc = ANY_COMPLEXITY;
02015
02016 dimension_type dimension = ph->space_dimension();
02017 Bounding_Box bbox(dimension);
02018 ph->shrink_bounding_box(bbox, cc);
02019 Prolog_term_ref tail = Prolog_new_term_ref();
02020 Prolog_put_atom(tail, a_nil);
02021 for (dimension_type i = dimension; i-- > 0; )
02022 Prolog_construct_cons(tail, interval_term(bbox[i]), tail);
02023 if (Prolog_unify(t_bb, tail))
02024 return PROLOG_SUCCESS;
02025 }
02026 CATCH_ALL;
02027 }
02028
02029 extern "C" Prolog_foreign_return_type
02030 ppl_Polyhedron_is_empty(Prolog_term_ref t_ph) {
02031 try {
02032 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02033 CHECK(ph);
02034 if (ph->is_empty())
02035 return PROLOG_SUCCESS;
02036 }
02037 CATCH_ALL;
02038 }
02039
02040 extern "C" Prolog_foreign_return_type
02041 ppl_Polyhedron_is_universe(Prolog_term_ref t_ph) {
02042 try {
02043 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02044 CHECK(ph);
02045 if (ph->is_universe())
02046 return PROLOG_SUCCESS;
02047 }
02048 CATCH_ALL;
02049 }
02050
02051 extern "C" Prolog_foreign_return_type
02052 ppl_Polyhedron_is_bounded(Prolog_term_ref t_ph) {
02053 try {
02054 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02055 CHECK(ph);
02056 if (ph->is_bounded())
02057 return PROLOG_SUCCESS;
02058 }
02059 CATCH_ALL;
02060 }
02061
02062 extern "C" Prolog_foreign_return_type
02063 ppl_Polyhedron_bounds_from_above(Prolog_term_ref t_ph,
02064 Prolog_term_ref t_expr) {
02065 try {
02066 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02067 CHECK(ph);
02068 Linear_Expression l = build_linear_expression(t_expr);
02069 if (ph->bounds_from_above(l))
02070 return PROLOG_SUCCESS;
02071 }
02072 CATCH_ALL;
02073 }
02074
02075 extern "C" Prolog_foreign_return_type
02076 ppl_Polyhedron_bounds_from_below(Prolog_term_ref t_ph,
02077 Prolog_term_ref t_expr) {
02078 try {
02079 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02080 CHECK(ph);
02081 Linear_Expression l = build_linear_expression(t_expr);
02082 if (ph->bounds_from_below(l))
02083 return PROLOG_SUCCESS;
02084 }
02085 CATCH_ALL;
02086 }
02087
02088 extern "C" Prolog_foreign_return_type
02089 ppl_Polyhedron_maximize(Prolog_term_ref t_ph,
02090 Prolog_term_ref t_le_expr,
02091 Prolog_term_ref t_n,
02092 Prolog_term_ref t_d,
02093 Prolog_term_ref t_max) {
02094 try {
02095 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02096 CHECK(ph);
02097 const Linear_Expression le = build_linear_expression(t_le_expr);
02098 Coefficient n;
02099 Coefficient d;
02100 bool max;
02101 if (ph->maximize(le, n, d, max)) {
02102 Prolog_term_ref t = Prolog_new_term_ref();
02103 Prolog_atom a = (max ? a_true : a_false);
02104 Prolog_put_atom(t, a);
02105 if (Prolog_unify(t_n, Coefficient_to_integer_term(n))
02106 && Prolog_unify(t_d, Coefficient_to_integer_term(d))
02107 && Prolog_unify(t_max, t))
02108 return PROLOG_SUCCESS;
02109 }
02110 }
02111 CATCH_ALL;
02112 }
02113
02114 extern "C" Prolog_foreign_return_type
02115 ppl_Polyhedron_maximize_with_point(Prolog_term_ref t_ph,
02116 Prolog_term_ref t_le_expr,
02117 Prolog_term_ref t_n,
02118 Prolog_term_ref t_d,
02119 Prolog_term_ref t_max,
02120 Prolog_term_ref t_g) {
02121 try {
02122 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02123 CHECK(ph);
02124 const Linear_Expression le = build_linear_expression(t_le_expr);
02125 Coefficient n;
02126 Coefficient d;
02127 bool max;
02128 Generator g(point());
02129 if (ph->maximize(le, n, d, max, g)) {
02130 Prolog_term_ref t = Prolog_new_term_ref();
02131 Prolog_atom a = (max ? a_true : a_false);
02132 Prolog_put_atom(t, a);
02133 if (Prolog_unify(t_n, Coefficient_to_integer_term(n))
02134 && Prolog_unify(t_d, Coefficient_to_integer_term(d))
02135 && Prolog_unify(t_max, t)
02136 && Prolog_unify(t_g, generator_term(g)))
02137 return PROLOG_SUCCESS;
02138 }
02139 }
02140 CATCH_ALL;
02141 }
02142
02143 extern "C" Prolog_foreign_return_type
02144 ppl_Polyhedron_minimize(Prolog_term_ref t_ph,
02145 Prolog_term_ref t_le_expr,
02146 Prolog_term_ref t_n,
02147 Prolog_term_ref t_d,
02148 Prolog_term_ref t_min) {
02149 try {
02150 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02151 CHECK(ph);
02152 const Linear_Expression le = build_linear_expression(t_le_expr);
02153 Coefficient n;
02154 Coefficient d;
02155 bool min;
02156 if (ph->minimize(le, n, d, min)) {
02157 Prolog_term_ref t = Prolog_new_term_ref();
02158 Prolog_atom a = (min ? a_true : a_false);
02159 Prolog_put_atom(t, a);
02160 if (Prolog_unify(t_n, Coefficient_to_integer_term(n))
02161 && Prolog_unify(t_d, Coefficient_to_integer_term(d))
02162 && Prolog_unify(t_min, t))
02163 return PROLOG_SUCCESS;
02164 }
02165 }
02166 CATCH_ALL;
02167 }
02168
02169 extern "C" Prolog_foreign_return_type
02170 ppl_Polyhedron_minimize_with_point(Prolog_term_ref t_ph,
02171 Prolog_term_ref t_le_expr,
02172 Prolog_term_ref t_n,
02173 Prolog_term_ref t_d,
02174 Prolog_term_ref t_min,
02175 Prolog_term_ref t_g) {
02176 try {
02177 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02178 CHECK(ph);
02179 const Linear_Expression le = build_linear_expression(t_le_expr);
02180 Coefficient n;
02181 Coefficient d;
02182 bool min;
02183 Generator g(point());
02184 if (ph->minimize(le, n, d, min, g)) {
02185 Prolog_term_ref t = Prolog_new_term_ref();
02186 Prolog_atom a = (min ? a_true : a_false);
02187 Prolog_put_atom(t, a);
02188 if (Prolog_unify(t_n, Coefficient_to_integer_term(n))
02189 && Prolog_unify(t_d, Coefficient_to_integer_term(d))
02190 && Prolog_unify(t_min, t)
02191 && Prolog_unify(t_g, generator_term(g)))
02192 return PROLOG_SUCCESS;
02193 }
02194 }
02195 CATCH_ALL;
02196 }
02197
02198 extern "C" Prolog_foreign_return_type
02199 ppl_Polyhedron_is_topologically_closed(Prolog_term_ref t_ph) {
02200 try {
02201 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02202 CHECK(ph);
02203 if (ph->is_topologically_closed())
02204 return PROLOG_SUCCESS;
02205 }
02206 CATCH_ALL;
02207 }
02208
02209 extern "C" Prolog_foreign_return_type
02210 ppl_Polyhedron_topological_closure_assign(Prolog_term_ref t_ph) {
02211 try {
02212 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02213 CHECK(ph);
02214 ph->topological_closure_assign();
02215 return PROLOG_SUCCESS;
02216 }
02217 CATCH_ALL;
02218 }
02219
02220 extern "C" Prolog_foreign_return_type
02221 ppl_Polyhedron_contains_Polyhedron(Prolog_term_ref t_lhs,
02222 Prolog_term_ref t_rhs) {
02223 try {
02224 const Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02225 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02226 CHECK(lhs);
02227 CHECK(rhs);
02228 if (lhs->contains(*rhs))
02229 return PROLOG_SUCCESS;
02230 }
02231 CATCH_ALL;
02232 }
02233
02234 extern "C" Prolog_foreign_return_type
02235 ppl_Polyhedron_strictly_contains_Polyhedron(Prolog_term_ref t_lhs,
02236 Prolog_term_ref t_rhs) {
02237 try {
02238 const Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02239 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02240 CHECK(lhs);
02241 CHECK(rhs);
02242 if (lhs->strictly_contains(*rhs))
02243 return PROLOG_SUCCESS;
02244 }
02245 CATCH_ALL;
02246 }
02247
02248 extern "C" Prolog_foreign_return_type
02249 ppl_Polyhedron_is_disjoint_from_Polyhedron(Prolog_term_ref t_lhs,
02250 Prolog_term_ref t_rhs) {
02251 try {
02252 const Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02253 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02254 CHECK(lhs);
02255 CHECK(rhs);
02256 if (lhs->is_disjoint_from(*rhs))
02257 return PROLOG_SUCCESS;
02258 }
02259 CATCH_ALL;
02260 }
02261
02262 extern "C" Prolog_foreign_return_type
02263 ppl_Polyhedron_equals_Polyhedron(Prolog_term_ref t_lhs,
02264 Prolog_term_ref t_rhs) {
02265 try {
02266 const Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02267 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02268 CHECK(lhs);
02269 CHECK(rhs);
02270 if (*lhs == *rhs)
02271 return PROLOG_SUCCESS;
02272 }
02273 CATCH_ALL;
02274 }
02275
02276 extern "C" Prolog_foreign_return_type
02277 ppl_Polyhedron_OK(Prolog_term_ref t_ph) {
02278 try {
02279 const Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02280 CHECK(ph);
02281 if (ph->OK())
02282 return PROLOG_SUCCESS;
02283 }
02284 CATCH_ALL;
02285 }
02286
02287 extern "C" Prolog_foreign_return_type
02288 ppl_Polyhedron_add_constraint(Prolog_term_ref t_ph, Prolog_term_ref t_c) {
02289 try {
02290 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02291 CHECK(ph);
02292 ph->add_constraint(build_constraint(t_c));
02293 return PROLOG_SUCCESS;
02294 }
02295 CATCH_ALL;
02296 }
02297
02298 extern "C" Prolog_foreign_return_type
02299 ppl_Polyhedron_add_constraint_and_minimize(Prolog_term_ref t_ph,
02300 Prolog_term_ref t_c) {
02301 try {
02302 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02303 CHECK(ph);
02304 if (ph->add_constraint_and_minimize(build_constraint(t_c)))
02305 return PROLOG_SUCCESS;
02306 }
02307 CATCH_ALL;
02308 }
02309
02310 extern "C" Prolog_foreign_return_type
02311 ppl_Polyhedron_add_generator(Prolog_term_ref t_ph, Prolog_term_ref t_g) {
02312 try {
02313 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02314 CHECK(ph);
02315 ph->add_generator(build_generator(t_g));
02316 return PROLOG_SUCCESS;
02317 }
02318 CATCH_ALL;
02319 }
02320
02321 extern "C" Prolog_foreign_return_type
02322 ppl_Polyhedron_add_generator_and_minimize(Prolog_term_ref t_ph,
02323 Prolog_term_ref t_g) {
02324 try {
02325 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02326 CHECK(ph);
02327 if (ph->add_generator_and_minimize(build_generator(t_g)))
02328 return PROLOG_SUCCESS;
02329 }
02330 CATCH_ALL;
02331 }
02332
02333 extern "C" Prolog_foreign_return_type
02334 ppl_Polyhedron_add_constraints(Prolog_term_ref t_ph,
02335 Prolog_term_ref t_clist) {
02336 try {
02337 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02338 CHECK(ph);
02339 Constraint_System cs;
02340 Prolog_term_ref c = Prolog_new_term_ref();
02341
02342 while (Prolog_is_cons(t_clist)) {
02343 Prolog_get_cons(t_clist, c, t_clist);
02344 cs.insert(build_constraint(c));
02345 }
02346
02347
02348 check_nil_terminating(t_clist);
02349
02350 ph->add_constraints(cs);
02351 return PROLOG_SUCCESS;
02352 }
02353 CATCH_ALL;
02354 }
02355
02356 extern "C" Prolog_foreign_return_type
02357 ppl_Polyhedron_add_constraints_and_minimize(Prolog_term_ref t_ph,
02358 Prolog_term_ref t_clist) {
02359 try {
02360 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02361 CHECK(ph);
02362 Constraint_System cs;
02363 Prolog_term_ref c = Prolog_new_term_ref();
02364
02365 while (Prolog_is_cons(t_clist)) {
02366 Prolog_get_cons(t_clist, c, t_clist);
02367 cs.insert(build_constraint(c));
02368 }
02369
02370
02371 check_nil_terminating(t_clist);
02372
02373 if (ph->add_constraints_and_minimize(cs))
02374 return PROLOG_SUCCESS;
02375 }
02376 CATCH_ALL;
02377 }
02378
02379 extern "C" Prolog_foreign_return_type
02380 ppl_Polyhedron_add_generators(Prolog_term_ref t_ph,
02381 Prolog_term_ref t_glist) {
02382 try {
02383 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02384 CHECK(ph);
02385 Generator_System gs;
02386 Prolog_term_ref g = Prolog_new_term_ref();
02387
02388 while (Prolog_is_cons(t_glist)) {
02389 Prolog_get_cons(t_glist, g, t_glist);
02390 gs.insert(build_generator(g));
02391 }
02392
02393
02394 check_nil_terminating(t_glist);
02395
02396 ph->add_generators(gs);
02397 return PROLOG_SUCCESS;
02398 }
02399 CATCH_ALL;
02400 }
02401
02402 extern "C" Prolog_foreign_return_type
02403 ppl_Polyhedron_add_generators_and_minimize(Prolog_term_ref t_ph,
02404 Prolog_term_ref t_glist) {
02405 try {
02406 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02407 CHECK(ph);
02408 Generator_System gs;
02409 Prolog_term_ref g = Prolog_new_term_ref();
02410
02411 while (Prolog_is_cons(t_glist)) {
02412 Prolog_get_cons(t_glist, g, t_glist);
02413 gs.insert(build_generator(g));
02414 }
02415
02416
02417 check_nil_terminating(t_glist);
02418
02419 if (ph->add_generators_and_minimize(gs))
02420 return PROLOG_SUCCESS;
02421 }
02422 CATCH_ALL;
02423 }
02424
02425 namespace {
02426
02427 Prolog_foreign_return_type
02428 bop_assign(Prolog_term_ref t_lhs,
02429 Prolog_term_ref t_rhs,
02430 void (Polyhedron::* bop_assign)(const Polyhedron&)) {
02431 try {
02432 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02433 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02434 CHECK(lhs);
02435 CHECK(rhs);
02436 (lhs->*bop_assign)(*rhs);
02437 return PROLOG_SUCCESS;
02438 }
02439 CATCH_ALL;
02440 }
02441
02442 Prolog_foreign_return_type
02443 bop_assign_and_minimize(Prolog_term_ref t_lhs,
02444 Prolog_term_ref t_rhs,
02445 bool (Polyhedron::*
02446 bop_assign_and_minimize)(const Polyhedron&)) {
02447 try {
02448 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02449 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02450 CHECK(lhs);
02451 CHECK(rhs);
02452 if ((lhs->*bop_assign_and_minimize)(*rhs))
02453 return PROLOG_SUCCESS;
02454 }
02455 CATCH_ALL;
02456 }
02457
02458 }
02459
02460 extern "C" Prolog_foreign_return_type
02461 ppl_Polyhedron_intersection_assign(Prolog_term_ref t_lhs,
02462 Prolog_term_ref t_rhs) {
02463 return bop_assign(t_lhs, t_rhs,
02464 &Polyhedron::intersection_assign);
02465 }
02466
02467 extern "C" Prolog_foreign_return_type
02468 ppl_Polyhedron_intersection_assign_and_minimize(Prolog_term_ref t_lhs,
02469 Prolog_term_ref t_rhs) {
02470 return bop_assign_and_minimize(t_lhs, t_rhs,
02471 &Polyhedron::intersection_assign_and_minimize);
02472 }
02473
02474 extern "C" Prolog_foreign_return_type
02475 ppl_Polyhedron_poly_hull_assign(Prolog_term_ref t_lhs,
02476 Prolog_term_ref t_rhs) {
02477 return bop_assign(t_lhs, t_rhs,
02478 &Polyhedron::poly_hull_assign);
02479 }
02480
02481 extern "C" Prolog_foreign_return_type
02482 ppl_Polyhedron_poly_hull_assign_and_minimize(Prolog_term_ref t_lhs,
02483 Prolog_term_ref t_rhs) {
02484 return bop_assign_and_minimize(t_lhs, t_rhs,
02485 &Polyhedron::poly_hull_assign_and_minimize);
02486 }
02487
02488 extern "C" Prolog_foreign_return_type
02489 ppl_Polyhedron_poly_difference_assign(Prolog_term_ref t_lhs,
02490 Prolog_term_ref t_rhs) {
02491 return bop_assign(t_lhs, t_rhs,
02492 &Polyhedron::poly_difference_assign);
02493 }
02494
02495 extern "C" Prolog_foreign_return_type
02496 ppl_Polyhedron_time_elapse_assign(Prolog_term_ref t_lhs,
02497 Prolog_term_ref t_rhs) {
02498 return bop_assign(t_lhs, t_rhs,
02499 &Polyhedron::time_elapse_assign);
02500 }
02501
02502 extern "C" Prolog_foreign_return_type
02503 ppl_Polyhedron_affine_image(Prolog_term_ref t_ph, Prolog_term_ref t_v,
02504 Prolog_term_ref t_le, Prolog_term_ref t_d) {
02505 try {
02506 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02507 CHECK(ph);
02508 ph->affine_image(term_to_Variable(t_v),
02509 build_linear_expression(t_le),
02510 term_to_Coefficient(t_d));
02511 return PROLOG_SUCCESS;
02512 }
02513 CATCH_ALL;
02514 }
02515
02516 extern "C" Prolog_foreign_return_type
02517 ppl_Polyhedron_affine_preimage(Prolog_term_ref t_ph, Prolog_term_ref t_v,
02518 Prolog_term_ref t_le, Prolog_term_ref t_d) {
02519 try {
02520 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02521 CHECK(ph);
02522 ph->affine_preimage(term_to_Variable(t_v),
02523 build_linear_expression(t_le),
02524 term_to_Coefficient(t_d));
02525 return PROLOG_SUCCESS;
02526 }
02527 CATCH_ALL;
02528 }
02529
02530 namespace {
02531
02532 Prolog_atom
02533 term_to_relation(Prolog_term_ref t) {
02534 if (Prolog_is_atom(t)) {
02535 Prolog_atom name;
02536 if (Prolog_get_atom_name(t, &name)
02537 && (name == a_equal || name == a_greater_than_equal ||
02538 name == a_equal_less_than || name == a_greater_than ||
02539 name == a_less_than))
02540 return name;
02541 }
02542 throw not_a_relation(t);
02543 }
02544
02545 Relation_Symbol
02546 term_to_relation_symbol(Prolog_term_ref t_r) {
02547 Prolog_atom ra = term_to_relation(t_r);
02548 Relation_Symbol r;
02549 if (ra == a_less_than)
02550 r = LESS_THAN;
02551 else if (ra == a_equal_less_than)
02552 r = LESS_THAN_OR_EQUAL;
02553 else if (ra == a_equal)
02554 r = EQUAL;
02555 else if (ra == a_greater_than_equal)
02556 r = GREATER_THAN_OR_EQUAL;
02557 else r = GREATER_THAN;
02558
02559 return r;
02560 }
02561
02562 }
02563
02564 extern "C" Prolog_foreign_return_type
02565 ppl_Polyhedron_generalized_affine_image(Prolog_term_ref t_ph,
02566 Prolog_term_ref t_v,
02567 Prolog_term_ref t_r,
02568 Prolog_term_ref t_le,
02569 Prolog_term_ref t_d) {
02570 try {
02571 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02572 CHECK(ph);
02573 Relation_Symbol r = term_to_relation_symbol(t_r);
02574 ph->generalized_affine_image(term_to_Variable(t_v),
02575 r,
02576 build_linear_expression(t_le),
02577 term_to_Coefficient(t_d));
02578 return PROLOG_SUCCESS;
02579 }
02580 CATCH_ALL;
02581 }
02582
02583 extern "C" Prolog_foreign_return_type
02584 ppl_Polyhedron_generalized_affine_preimage(Prolog_term_ref t_ph,
02585 Prolog_term_ref t_v,
02586 Prolog_term_ref t_r,
02587 Prolog_term_ref t_le,
02588 Prolog_term_ref t_d) {
02589 try {
02590 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02591 CHECK(ph);
02592 Relation_Symbol r = term_to_relation_symbol(t_r);
02593 ph->generalized_affine_preimage(term_to_Variable(t_v),
02594 r,
02595 build_linear_expression(t_le),
02596 term_to_Coefficient(t_d));
02597 return PROLOG_SUCCESS;
02598 }
02599 CATCH_ALL;
02600 }
02601
02602 extern "C" Prolog_foreign_return_type
02603 ppl_Polyhedron_generalized_affine_image_lhs_rhs(Prolog_term_ref t_ph,
02604 Prolog_term_ref t_lhs,
02605 Prolog_term_ref t_r,
02606 Prolog_term_ref t_rhs) {
02607 try {
02608 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02609 CHECK(ph);
02610 Relation_Symbol r = term_to_relation_symbol(t_r);
02611 ph->generalized_affine_image(build_linear_expression(t_lhs),
02612 r,
02613 build_linear_expression(t_rhs));
02614 return PROLOG_SUCCESS;
02615 }
02616 CATCH_ALL;
02617 }
02618
02619 extern "C" Prolog_foreign_return_type
02620 ppl_Polyhedron_generalized_affine_preimage_lhs_rhs(Prolog_term_ref t_ph,
02621 Prolog_term_ref t_lhs,
02622 Prolog_term_ref t_r,
02623 Prolog_term_ref t_rhs) {
02624 try {
02625 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02626 CHECK(ph);
02627 Relation_Symbol r = term_to_relation_symbol(t_r);
02628 ph->generalized_affine_preimage(build_linear_expression(t_lhs),
02629 r,
02630 build_linear_expression(t_rhs));
02631 return PROLOG_SUCCESS;
02632 }
02633 CATCH_ALL;
02634 }
02635
02636 extern "C" Prolog_foreign_return_type
02637 ppl_Polyhedron_bounded_affine_image(Prolog_term_ref t_ph,
02638 Prolog_term_ref t_v,
02639 Prolog_term_ref t_lb_le,
02640 Prolog_term_ref t_ub_le,
02641 Prolog_term_ref t_d) {
02642 try {
02643 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02644 CHECK(ph);
02645 ph->bounded_affine_image(term_to_Variable(t_v),
02646 build_linear_expression(t_lb_le),
02647 build_linear_expression(t_ub_le),
02648 term_to_Coefficient(t_d));
02649 return PROLOG_SUCCESS;
02650 }
02651 CATCH_ALL;
02652 }
02653
02654 extern "C" Prolog_foreign_return_type
02655 ppl_Polyhedron_bounded_affine_preimage(Prolog_term_ref t_ph,
02656 Prolog_term_ref t_v,
02657 Prolog_term_ref t_lb_le,
02658 Prolog_term_ref t_ub_le,
02659 Prolog_term_ref t_d) {
02660 try {
02661 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02662 CHECK(ph);
02663 ph->bounded_affine_preimage(term_to_Variable(t_v),
02664 build_linear_expression(t_lb_le),
02665 build_linear_expression(t_ub_le),
02666 term_to_Coefficient(t_d));
02667 return PROLOG_SUCCESS;
02668 }
02669 CATCH_ALL;
02670 }
02671
02672 namespace {
02673
02674 Prolog_foreign_return_type
02675 widening_assign(Prolog_term_ref t_lhs,
02676 Prolog_term_ref t_rhs,
02677 void (Polyhedron::* widening_assign)(const Polyhedron&,
02678 unsigned* tp)) {
02679 try {
02680 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02681 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02682 CHECK(lhs);
02683 CHECK(rhs);
02684 (lhs->*widening_assign)(*rhs, 0);
02685 return PROLOG_SUCCESS;
02686 }
02687 CATCH_ALL;
02688 }
02689
02690 Prolog_foreign_return_type
02691 widening_assign_with_tokens(Prolog_term_ref t_lhs,
02692 Prolog_term_ref t_rhs,
02693 Prolog_term_ref t_ti,
02694 Prolog_term_ref t_to,
02695 void (Polyhedron::*
02696 widening_assign)(const Polyhedron&,
02697 unsigned* tp)) {
02698 try {
02699 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02700 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02701 CHECK(lhs);
02702 CHECK(rhs);
02703 unsigned t = term_to_unsigned<unsigned>(t_ti);
02704 (lhs->*widening_assign)(*rhs, &t);
02705 if (unify_long(t_to, t))
02706 return PROLOG_SUCCESS;
02707 }
02708 CATCH_ALL;
02709 }
02710
02711 Prolog_foreign_return_type
02712 widening_assign_with_token(Prolog_term_ref t_lhs,
02713 Prolog_term_ref t_rhs,
02714 Prolog_term_ref t_t,
02715 void (Polyhedron::*
02716 widening_assign)(const Polyhedron&,
02717 unsigned* tp)) {
02718 try {
02719 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02720 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02721 CHECK(lhs);
02722 CHECK(rhs);
02723 unsigned t = 1;
02724 (lhs->*widening_assign)(*rhs, &t);
02725 if (unify_long(t_t, 1-t))
02726 return PROLOG_SUCCESS;
02727 }
02728 CATCH_ALL;
02729 }
02730
02731 Prolog_foreign_return_type
02732 limited_extrapolation_assign(Prolog_term_ref t_lhs,
02733 Prolog_term_ref t_rhs,
02734 Prolog_term_ref t_clist,
02735 void (Polyhedron::*
02736 limited_extrap_assign)(const Polyhedron&,
02737 const Constraint_System&,
02738 unsigned* tp)) {
02739 try {
02740 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02741 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02742 CHECK(lhs);
02743 CHECK(rhs);
02744 Constraint_System cs;
02745 Prolog_term_ref c = Prolog_new_term_ref();
02746
02747 while (Prolog_is_cons(t_clist)) {
02748 Prolog_get_cons(t_clist, c, t_clist);
02749 cs.insert(build_constraint(c));
02750 }
02751
02752
02753 check_nil_terminating(t_clist);
02754
02755 (lhs->*limited_extrap_assign)(*rhs, cs, 0);
02756 return PROLOG_SUCCESS;
02757 }
02758 CATCH_ALL;
02759 }
02760
02761 Prolog_foreign_return_type
02762 limited_extrapolation_assign_with_tokens(Prolog_term_ref t_lhs,
02763 Prolog_term_ref t_rhs,
02764 Prolog_term_ref t_clist,
02765 Prolog_term_ref t_ti,
02766 Prolog_term_ref t_to,
02767 void (Polyhedron::*
02768 limited_extrap_assign)(const Polyhedron&,
02769 const Constraint_System&,
02770 unsigned* tp)) {
02771 try {
02772 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02773 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02774 CHECK(lhs);
02775 CHECK(rhs);
02776 Constraint_System cs;
02777 Prolog_term_ref c = Prolog_new_term_ref();
02778
02779 while (Prolog_is_cons(t_clist)) {
02780 Prolog_get_cons(t_clist, c, t_clist);
02781 cs.insert(build_constraint(c));
02782 }
02783
02784
02785 check_nil_terminating(t_clist);
02786
02787 unsigned t = term_to_unsigned<unsigned>(t_ti);
02788 (lhs->*limited_extrap_assign)(*rhs, cs, &t);
02789 if (unify_long(t_to, t))
02790 return PROLOG_SUCCESS;
02791 }
02792 CATCH_ALL;
02793 }
02794
02795 }
02796
02797 extern "C" Prolog_foreign_return_type
02798 ppl_Polyhedron_BHRZ03_widening_assign_with_tokens(Prolog_term_ref t_lhs,
02799 Prolog_term_ref t_rhs,
02800 Prolog_term_ref t_ti,
02801 Prolog_term_ref t_to) {
02802 return widening_assign_with_tokens(t_lhs, t_rhs, t_ti, t_to,
02803 &Polyhedron::BHRZ03_widening_assign);
02804 }
02805
02806 extern "C" Prolog_foreign_return_type
02807 ppl_Polyhedron_BHRZ03_widening_assign_with_token(Prolog_term_ref t_lhs,
02808 Prolog_term_ref t_rhs,
02809 Prolog_term_ref t_t) {
02810 return widening_assign_with_token(t_lhs, t_rhs, t_t,
02811 &Polyhedron::BHRZ03_widening_assign);
02812 }
02813
02814 extern "C" Prolog_foreign_return_type
02815 ppl_Polyhedron_BHRZ03_widening_assign(Prolog_term_ref t_lhs,
02816 Prolog_term_ref t_rhs) {
02817 return widening_assign(t_lhs, t_rhs, &Polyhedron::BHRZ03_widening_assign);
02818 }
02819
02820 extern "C" Prolog_foreign_return_type
02821 ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(
02822 Prolog_term_ref t_lhs,
02823 Prolog_term_ref t_rhs,
02824 Prolog_term_ref t_clist,
02825 Prolog_term_ref t_ti,
02826 Prolog_term_ref t_to) {
02827 return limited_extrapolation_assign_with_tokens(t_lhs,
02828 t_rhs,
02829 t_clist,
02830 t_ti,
02831 t_to,
02832 &Polyhedron::
02833 limited_BHRZ03_extrapolation_assign);
02834 }
02835
02836 extern "C" Prolog_foreign_return_type
02837 ppl_Polyhedron_limited_BHRZ03_extrapolation_assign(Prolog_term_ref t_lhs,
02838 Prolog_term_ref t_rhs,
02839 Prolog_term_ref t_clist) {
02840 return limited_extrapolation_assign(t_lhs,
02841 t_rhs,
02842 t_clist,
02843 &Polyhedron::
02844 limited_BHRZ03_extrapolation_assign);
02845 }
02846
02847 extern "C" Prolog_foreign_return_type
02848 ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(
02849 Prolog_term_ref t_lhs,
02850 Prolog_term_ref t_rhs,
02851 Prolog_term_ref t_clist,
02852 Prolog_term_ref t_ti,
02853 Prolog_term_ref t_to) {
02854 return limited_extrapolation_assign_with_tokens(t_lhs,
02855 t_rhs,
02856 t_clist,
02857 t_ti,
02858 t_to,
02859 &Polyhedron::
02860 bounded_BHRZ03_extrapolation_assign);
02861 }
02862
02863 extern "C" Prolog_foreign_return_type
02864 ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign(Prolog_term_ref t_lhs,
02865 Prolog_term_ref t_rhs,
02866 Prolog_term_ref t_clist) {
02867 return limited_extrapolation_assign(t_lhs,
02868 t_rhs,
02869 t_clist,
02870 &Polyhedron::
02871 bounded_BHRZ03_extrapolation_assign);
02872 }
02873
02874 extern "C" Prolog_foreign_return_type
02875 ppl_Polyhedron_H79_widening_assign_with_tokens(Prolog_term_ref t_lhs,
02876 Prolog_term_ref t_rhs,
02877 Prolog_term_ref t_ti,
02878 Prolog_term_ref t_to) {
02879 return widening_assign_with_tokens(t_lhs, t_rhs, t_ti, t_to,
02880 &Polyhedron::H79_widening_assign);
02881 }
02882
02883 extern "C" Prolog_foreign_return_type
02884 ppl_Polyhedron_H79_widening_assign(Prolog_term_ref t_lhs,
02885 Prolog_term_ref t_rhs) {
02886 return widening_assign(t_lhs, t_rhs, &Polyhedron::H79_widening_assign);
02887 }
02888
02889 extern "C" Prolog_foreign_return_type
02890 ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(
02891 Prolog_term_ref t_lhs,
02892 Prolog_term_ref t_rhs,
02893 Prolog_term_ref t_clist,
02894 Prolog_term_ref t_ti,
02895 Prolog_term_ref t_to) {
02896 return limited_extrapolation_assign_with_tokens(t_lhs,
02897 t_rhs,
02898 t_clist,
02899 t_ti,
02900 t_to,
02901 &Polyhedron::
02902 limited_H79_extrapolation_assign);
02903 }
02904
02905 extern "C" Prolog_foreign_return_type
02906 ppl_Polyhedron_limited_H79_extrapolation_assign(Prolog_term_ref t_lhs,
02907 Prolog_term_ref t_rhs,
02908 Prolog_term_ref t_clist) {
02909 return limited_extrapolation_assign(t_lhs,
02910 t_rhs,
02911 t_clist,
02912 &Polyhedron::
02913 limited_H79_extrapolation_assign);
02914 }
02915
02916 extern "C" Prolog_foreign_return_type
02917 ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(
02918 Prolog_term_ref t_lhs,
02919 Prolog_term_ref t_rhs,
02920 Prolog_term_ref t_clist,
02921 Prolog_term_ref t_ti,
02922 Prolog_term_ref t_to) {
02923 return limited_extrapolation_assign_with_tokens(t_lhs,
02924 t_rhs,
02925 t_clist,
02926 t_ti,
02927 t_to,
02928 &Polyhedron::
02929 bounded_H79_extrapolation_assign);
02930 }
02931
02932 extern "C" Prolog_foreign_return_type
02933 ppl_Polyhedron_bounded_H79_extrapolation_assign(Prolog_term_ref t_lhs,
02934 Prolog_term_ref t_rhs,
02935 Prolog_term_ref t_clist) {
02936 return limited_extrapolation_assign(t_lhs,
02937 t_rhs,
02938 t_clist,
02939 &Polyhedron::
02940 bounded_H79_extrapolation_assign);
02941 }
02942
02943 extern "C" Prolog_foreign_return_type
02944 ppl_Polyhedron_add_space_dimensions_and_project(Prolog_term_ref t_ph,
02945 Prolog_term_ref t_nnd) {
02946 try {
02947 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02948 CHECK(ph);
02949 dimension_type d = term_to_unsigned<dimension_type>(t_nnd);
02950 ph->add_space_dimensions_and_project(d);
02951 return PROLOG_SUCCESS;
02952 }
02953 CATCH_ALL;
02954 }
02955
02956 extern "C" Prolog_foreign_return_type
02957 ppl_Polyhedron_add_space_dimensions_and_embed(Prolog_term_ref t_ph,
02958 Prolog_term_ref t_nnd) {
02959 try {
02960 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02961 CHECK(ph);
02962 dimension_type d = term_to_unsigned<dimension_type>(t_nnd);
02963 ph->add_space_dimensions_and_embed(d);
02964 return PROLOG_SUCCESS;
02965 }
02966 CATCH_ALL;
02967 }
02968
02969 extern "C" Prolog_foreign_return_type
02970 ppl_Polyhedron_concatenate_assign(Prolog_term_ref t_lhs,
02971 Prolog_term_ref t_rhs) {
02972 try {
02973 Polyhedron* lhs = term_to_polyhedron_handle(t_lhs);
02974 const Polyhedron* rhs = term_to_polyhedron_handle(t_rhs);
02975 CHECK(lhs);
02976 CHECK(rhs);
02977 lhs->concatenate_assign(*rhs);
02978 return PROLOG_SUCCESS;
02979 }
02980 CATCH_ALL;
02981 }
02982
02983 extern "C" Prolog_foreign_return_type
02984 ppl_Polyhedron_remove_space_dimensions(Prolog_term_ref t_ph,
02985 Prolog_term_ref t_vlist) {
02986 try {
02987 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
02988 CHECK(ph);
02989 Variables_Set dead_variables;
02990 Prolog_term_ref v = Prolog_new_term_ref();
02991 while (Prolog_is_cons(t_vlist)) {
02992 Prolog_get_cons(t_vlist, v, t_vlist);
02993 dead_variables.insert(term_to_Variable(v));
02994 }
02995
02996
02997 check_nil_terminating(t_vlist);
02998
02999 ph->remove_space_dimensions(dead_variables);
03000 return PROLOG_SUCCESS;
03001 }
03002 CATCH_ALL;
03003 }
03004
03005 extern "C" Prolog_foreign_return_type
03006 ppl_Polyhedron_remove_higher_space_dimensions(Prolog_term_ref t_ph,
03007 Prolog_term_ref t_nd) {
03008 try {
03009 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
03010 CHECK(ph);
03011 ph->remove_higher_space_dimensions(term_to_unsigned<dimension_type>(t_nd));
03012 return PROLOG_SUCCESS;
03013 }
03014 CATCH_ALL;
03015 }
03016
03017 extern "C" Prolog_foreign_return_type
03018 ppl_Polyhedron_expand_space_dimension(Prolog_term_ref t_ph,
03019 Prolog_term_ref t_v,
03020 Prolog_term_ref t_nd) {
03021 try {
03022 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
03023 CHECK(ph);
03024 ph->expand_space_dimension(term_to_Variable(t_v),
03025 term_to_unsigned<dimension_type>(t_nd));
03026 return PROLOG_SUCCESS;
03027 }
03028 CATCH_ALL;
03029 }
03030
03031 extern "C" Prolog_foreign_return_type
03032 ppl_Polyhedron_fold_space_dimensions(Prolog_term_ref t_ph,
03033 Prolog_term_ref t_vlist,
03034 Prolog_term_ref t_v) {
03035 try {
03036 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
03037 CHECK(ph);
03038 Variables_Set fold_variables;
03039 Prolog_term_ref v = Prolog_new_term_ref();
03040 while (Prolog_is_cons(t_vlist)) {
03041 Prolog_get_cons(t_vlist, v, t_vlist);
03042 fold_variables.insert(term_to_Variable(v));
03043 }
03044
03045
03046 check_nil_terminating(t_vlist);
03047
03048 ph->fold_space_dimensions(fold_variables, term_to_Variable(t_v));
03049 return PROLOG_SUCCESS;
03050 }
03051 CATCH_ALL;
03052 }
03053
03054 namespace {
03055
03056 class PFunc {
03057 private:
03058 std::set<dimension_type> codomain;
03059 std::vector<dimension_type> vec;
03060
03061 public:
03062 PFunc() {
03063 }
03064
03065 bool has_empty_codomain() const {
03066 return codomain.empty();
03067 }
03068
03069 dimension_type max_in_codomain() const {
03070 if (codomain.empty())
03071 throw unknown_interface_error("PFunc::max_in_codomain()");
03072 return *codomain.rbegin();
03073 }
03074
03075 bool maps(dimension_type i, dimension_type& j) const {
03076 if (i >= vec.size())
03077 return false;
03078 dimension_type vec_i = vec[i];
03079 if (vec_i == not_a_dimension())
03080 return false;
03081 j = vec_i;
03082 return true;
03083 }
03084
03085 bool insert(dimension_type i, dimension_type j) {
03086 std::pair<std::set<dimension_type>::iterator, bool> s
03087 = codomain.insert(j);
03088 if (!s.second)
03089
03090 return false;
03091 if (i > vec.size())
03092 vec.insert(vec.end(), i - vec.size(), not_a_dimension());
03093 if (i == vec.size()) {
03094 vec.insert(vec.end(), j);
03095 return true;
03096 }
03097 dimension_type& vec_i = vec[i];
03098 if (vec_i != not_a_dimension())
03099
03100 return false;
03101 vec_i = j;
03102 return true;
03103 }
03104 };
03105
03106 }
03107
03108 extern "C" Prolog_foreign_return_type
03109 ppl_Polyhedron_map_space_dimensions(Prolog_term_ref t_ph,
03110 Prolog_term_ref t_pfunc) {
03111 try {
03112 Polyhedron* ph = term_to_polyhedron_handle(t_ph);
03113 dimension_type space_dim = ph->space_dimension();
03114 CHECK(ph);
03115 PFunc pfunc;
03116 Prolog_term_ref t_pair = Prolog_new_term_ref();
03117 while (Prolog_is_cons(t_pfunc)) {
03118 Prolog_get_cons(t_pfunc, t_pair, t_pfunc);
03119 Prolog_atom functor;
03120 int arity;
03121 Prolog_get_compound_name_arity(t_pair, &functor, &arity);
03122 if (arity != 2 || functor != a_minus)
03123 return PROLOG_FAILURE;
03124 Prolog_term_ref t_i = Prolog_new_term_ref();
03125 Prolog_term_ref t_j = Prolog_new_term_ref();
03126 Prolog_get_arg(1, t_pair, t_i);
03127 Prolog_get_arg(2, t_pair, t_j);
03128 dimension_type i = term_to_Variable(t_i).id();
03129 dimension_type j = term_to_Variable(t_j).id();
03130 if (i >= space_dim || !pfunc.insert(i, j))
03131 return PROLOG_FAILURE;
03132 }
03133
03134
03135 check_nil_terminating(t_pfunc);
03136
03137 ph->map_space_dimensions(pfunc);
03138 return PROLOG_SUCCESS;
03139 }
03140 CATCH_ALL;
03141
03142 }
03143
03144
03145 extern "C" Prolog_foreign_return_type
03146 ppl_new_LP_Problem_trivial(Prolog_term_ref t_lp) {
03147 try {
03148 LP_Problem* lp = new LP_Problem;
03149 Prolog_term_ref tmp = Prolog_new_term_ref();
03150 Prolog_put_address(tmp, lp);
03151 if (Prolog_unify(t_lp, tmp)) {
03152 REGISTER(lp);
03153 return PROLOG_SUCCESS;
03154 }
03155 else
03156 delete lp;
03157 }
03158 CATCH_ALL;
03159 }
03160
03161 extern "C" Prolog_foreign_return_type
03162 ppl_new_LP_Problem(Prolog_term_ref t_clist,
03163 Prolog_term_ref t_le_expr,
03164 Prolog_term_ref t_opt,
03165 Prolog_term_ref t_lp) {
03166 try {
03167 Constraint_System cs;
03168 Prolog_term_ref c = Prolog_new_term_ref();
03169 while (Prolog_is_cons(t_clist)) {
03170 Prolog_get_cons(t_clist, c, t_clist);
03171 cs.insert(build_constraint(c));
03172 }
03173
03174 check_nil_terminating(t_clist);
03175
03176 const Linear_Expression le = build_linear_expression(t_le_expr);
03177 Prolog_atom opt = term_to_optimization_mode(t_opt);
03178 Optimization_Mode mode = (opt == a_max) ? MAXIMIZATION : MINIMIZATION;
03179
03180 LP_Problem* lp = new LP_Problem(cs, le, mode);
03181 Prolog_term_ref tmp = Prolog_new_term_ref();
03182 Prolog_put_address(tmp, lp);
03183 if (Prolog_unify(t_lp, tmp)) {
03184 REGISTER(lp);
03185 return PROLOG_SUCCESS;
03186 }
03187 else
03188 delete lp;
03189 }
03190 CATCH_ALL;
03191 }
03192
03193 extern "C" Prolog_foreign_return_type
03194 ppl_new_LP_Problem_from_LP_Problem(Prolog_term_ref t_lp_source,
03195 Prolog_term_ref t_lp) {
03196 try {
03197 const LP_Problem* lp_source
03198 = static_cast<const LP_Problem*>
03199 (term_to_lp_problem_handle(t_lp_source));
03200 CHECK(lp_source);
03201 LP_Problem* lp = new LP_Problem(*lp_source);
03202 Prolog_term_ref tmp = Prolog_new_term_ref();
03203 Prolog_put_address(tmp, lp);
03204 if (Prolog_unify(t_lp, tmp)) {
03205 REGISTER(lp);
03206 return PROLOG_SUCCESS;
03207 }
03208 else
03209 delete lp;
03210 }
03211 CATCH_ALL;
03212 }
03213
03214 extern "C" Prolog_foreign_return_type
03215 ppl_LP_Problem_swap(Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
03216 try {
03217 LP_Problem* lhs = term_to_lp_problem_handle(t_lhs);
03218 LP_Problem* rhs = term_to_lp_problem_handle(t_rhs);
03219 CHECK(lhs);
03220 CHECK(rhs);
03221 lhs->swap(*rhs);
03222 return PROLOG_SUCCESS;
03223 }
03224 CATCH_ALL;
03225 }
03226
03227 extern "C" Prolog_foreign_return_type
03228 ppl_delete_LP_Problem(Prolog_term_ref t_lp) {
03229 try {
03230 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03231 UNREGISTER(lp);
03232 delete lp;
03233 return PROLOG_SUCCESS;
03234 }
03235 CATCH_ALL;
03236 }
03237
03238 extern "C" Prolog_foreign_return_type
03239 ppl_LP_Problem_space_dimension(Prolog_term_ref t_lp, Prolog_term_ref t_sd) {
03240 try {
03241 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03242 CHECK(lp);
03243 if (unify_ulong(t_sd, lp->space_dimension()))
03244 return PROLOG_SUCCESS;
03245 }
03246 CATCH_ALL;
03247 }
03248
03249 extern "C" Prolog_foreign_return_type
03250 ppl_LP_Problem_constraints(Prolog_term_ref t_lp,
03251 Prolog_term_ref t_clist) {
03252 try {
03253 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03254 CHECK(lp);
03255
03256 Prolog_term_ref tail = Prolog_new_term_ref();
03257 Prolog_put_atom(tail, a_nil);
03258 const Constraint_System& cs = lp->constraints();
03259 for (Constraint_System::const_iterator i = cs.begin(),
03260 cs_end = cs.end(); i != cs_end; ++i)
03261 Prolog_construct_cons(tail, constraint_term(*i), tail);
03262
03263 if (Prolog_unify(t_clist, tail))
03264 return PROLOG_SUCCESS;
03265 }
03266 CATCH_ALL;
03267 }
03268
03269 extern "C" Prolog_foreign_return_type
03270 ppl_LP_Problem_objective_function(Prolog_term_ref t_lp,
03271 Prolog_term_ref t_le_expr) {
03272 try {
03273 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03274 CHECK(lp);
03275
03276 const Linear_Expression& le = lp->objective_function();
03277 Prolog_term_ref t = get_linear_expression(le);
03278
03279 if (Prolog_unify(t_le_expr, t))
03280 return PROLOG_SUCCESS;
03281 }
03282 CATCH_ALL;
03283 }
03284
03285 extern "C" Prolog_foreign_return_type
03286 ppl_LP_Problem_optimization_mode(Prolog_term_ref t_lp,
03287 Prolog_term_ref t_opt) {
03288 try {
03289 LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03290 CHECK(lp);
03291
03292 Optimization_Mode mode = lp->optimization_mode();
03293 Prolog_term_ref t = Prolog_new_term_ref();
03294 Prolog_atom a = (mode == MAXIMIZATION) ? a_max : a_min;
03295 Prolog_put_atom(t, a);
03296 if (Prolog_unify(t_opt, t))
03297 return PROLOG_SUCCESS;
03298 }
03299 CATCH_ALL;
03300 }
03301
03302 extern "C" Prolog_foreign_return_type
03303 ppl_LP_Problem_clear(Prolog_term_ref t_lp) {
03304 try {
03305 LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03306 CHECK(lp);
03307 lp->clear();
03308 return PROLOG_SUCCESS;
03309 }
03310 CATCH_ALL;
03311 }
03312
03313 extern "C" Prolog_foreign_return_type
03314 ppl_LP_Problem_add_constraint(Prolog_term_ref t_lp, Prolog_term_ref t_c) {
03315 try {
03316 LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03317 CHECK(lp);
03318 lp->add_constraint(build_constraint(t_c));
03319 return PROLOG_SUCCESS;
03320 }
03321 CATCH_ALL;
03322 }
03323
03324 extern "C" Prolog_foreign_return_type
03325 ppl_LP_Problem_add_constraints(Prolog_term_ref t_lp,
03326 Prolog_term_ref t_clist) {
03327 try {
03328 LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03329 CHECK(lp);
03330 Constraint_System cs;
03331 Prolog_term_ref c = Prolog_new_term_ref();
03332
03333 while (Prolog_is_cons(t_clist)) {
03334 Prolog_get_cons(t_clist, c, t_clist);
03335 cs.insert(build_constraint(c));
03336 }
03337
03338
03339 check_nil_terminating(t_clist);
03340
03341 lp->add_constraints(cs);
03342 return PROLOG_SUCCESS;
03343 }
03344 CATCH_ALL;
03345 }
03346
03347 extern "C" Prolog_foreign_return_type
03348 ppl_LP_Problem_set_objective_function(Prolog_term_ref t_lp,
03349 Prolog_term_ref t_le_expr) {
03350 try {
03351 LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03352 CHECK(lp);
03353 lp->set_objective_function(build_linear_expression(t_le_expr));
03354 return PROLOG_SUCCESS;
03355 }
03356 CATCH_ALL;
03357 }
03358
03359 extern "C" Prolog_foreign_return_type
03360 ppl_LP_Problem_set_optimization_mode(Prolog_term_ref t_lp,
03361 Prolog_term_ref t_opt) {
03362 try {
03363 LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03364 CHECK(lp);
03365
03366 Prolog_atom opt = term_to_optimization_mode(t_opt);
03367 Optimization_Mode mode = (opt == a_max) ? MAXIMIZATION : MINIMIZATION;
03368 lp->set_optimization_mode(mode);
03369 return PROLOG_SUCCESS;
03370 }
03371 CATCH_ALL;
03372 }
03373
03374 extern "C" Prolog_foreign_return_type
03375 ppl_LP_Problem_is_satisfiable(Prolog_term_ref t_lp) {
03376 try {
03377 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03378 CHECK(lp);
03379 if (lp->is_satisfiable())
03380 return PROLOG_SUCCESS;
03381 }
03382 CATCH_ALL;
03383 }
03384
03385 extern "C" Prolog_foreign_return_type
03386 ppl_LP_Problem_solve(Prolog_term_ref t_lp, Prolog_term_ref t_status) {
03387 try {
03388 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03389 CHECK(lp);
03390
03391 Prolog_atom a;
03392 switch (lp->solve()) {
03393 case UNFEASIBLE_LP_PROBLEM:
03394 a = a_unfeasible;
03395 break;
03396 case UNBOUNDED_LP_PROBLEM:
03397 a = a_unbounded;
03398 break;
03399 case OPTIMIZED_LP_PROBLEM:
03400 a = a_optimized;
03401 break;
03402 default:
03403 throw unknown_interface_error("ppl_LP_Problem_solve()");
03404 }
03405 Prolog_term_ref t = Prolog_new_term_ref();
03406 Prolog_put_atom(t, a);
03407 if (Prolog_unify(t_status, t))
03408 return PROLOG_SUCCESS;
03409 }
03410 CATCH_ALL;
03411 }
03412
03413 extern "C" Prolog_foreign_return_type
03414 ppl_LP_Problem_feasible_point(Prolog_term_ref t_lp,
03415 Prolog_term_ref t_g) {
03416 try {
03417 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03418 CHECK(lp);
03419 const Generator& g = lp->feasible_point();
03420 if (Prolog_unify(t_g, generator_term(g)))
03421 return PROLOG_SUCCESS;
03422 }
03423 CATCH_ALL;
03424 }
03425
03426 extern "C" Prolog_foreign_return_type
03427 ppl_LP_Problem_optimizing_point(Prolog_term_ref t_lp,
03428 Prolog_term_ref t_g) {
03429 try {
03430 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03431 CHECK(lp);
03432 const Generator& g = lp->optimizing_point();
03433 if (Prolog_unify(t_g, generator_term(g)))
03434 return PROLOG_SUCCESS;
03435 }
03436 CATCH_ALL;
03437 }
03438
03439 extern "C" Prolog_foreign_return_type
03440 ppl_LP_Problem_optimal_value(Prolog_term_ref t_lp,
03441 Prolog_term_ref t_n,
03442 Prolog_term_ref t_d) {
03443 try {
03444 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03445 CHECK(lp);
03446 Coefficient n;
03447 Coefficient d;
03448 lp->optimal_value(n, d);
03449 if (Prolog_unify(t_n, Coefficient_to_integer_term(n))
03450 && Prolog_unify(t_d, Coefficient_to_integer_term(d)))
03451 return PROLOG_SUCCESS;
03452 }
03453 CATCH_ALL;
03454 }
03455
03456 extern "C" Prolog_foreign_return_type
03457 ppl_LP_Problem_evaluate_objective_function(Prolog_term_ref t_lp,
03458 Prolog_term_ref t_g,
03459 Prolog_term_ref t_n,
03460 Prolog_term_ref t_d) {
03461 try {
03462 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03463 CHECK(lp);
03464 Coefficient n;
03465 Coefficient d;
03466 lp->evaluate_objective_function(build_generator(t_g), n, d);
03467 if (Prolog_unify(t_n, Coefficient_to_integer_term(n))
03468 && Prolog_unify(t_d, Coefficient_to_integer_term(d)))
03469 return PROLOG_SUCCESS;
03470 }
03471 CATCH_ALL;
03472 }
03473
03474 extern "C" Prolog_foreign_return_type
03475 ppl_LP_Problem_OK(Prolog_term_ref t_lp) {
03476 try {
03477 const LP_Problem* lp = term_to_lp_problem_handle(t_lp);
03478 CHECK(lp);
03479 if (lp->OK())
03480 return PROLOG_SUCCESS;
03481 }
03482 CATCH_ALL;
03483 }