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 <gprolog.h>
00026 #include <cassert>
00027
00028 typedef PlTerm Prolog_term_ref;
00029 typedef int Prolog_atom;
00030 typedef Bool Prolog_foreign_return_type;
00031
00032 namespace {
00033
00034 const Prolog_foreign_return_type PROLOG_SUCCESS = TRUE;
00035 const Prolog_foreign_return_type PROLOG_FAILURE = FALSE;
00036
00037 }
00038
00039 #include "../exceptions.hh"
00040
00041 namespace PPL = Parma_Polyhedra_Library;
00042
00043 namespace {
00044
00045 Prolog_atom a_dollar_address;
00046 Prolog_atom a_throw;
00047
00051 bool Prolog_has_unbounded_integers;
00052
00058 long Prolog_min_integer;
00059
00065 long Prolog_max_integer;
00066
00067 #include <iostream>
00068 using namespace std;
00069
00073 void
00074 ppl_Prolog_sysdep_init() {
00075 Prolog_has_unbounded_integers = false;
00076 Prolog_min_integer = INT_LOWEST_VALUE;
00077 Prolog_max_integer = INT_GREATEST_VALUE;
00078
00079 a_dollar_address = Create_Allocate_Atom("$address");
00080 a_throw = Find_Atom("throw");
00081 }
00082
00086 void
00087 ppl_Prolog_sysdep_deinit() {
00088 }
00089
00093 inline Prolog_term_ref
00094 Prolog_new_term_ref() {
00095 return 0;
00096 }
00097
00102 inline int
00103 Prolog_put_term(Prolog_term_ref& t, Prolog_term_ref u) {
00104 t = u;
00105 return 1;
00106 }
00107
00111 inline int
00112 Prolog_put_long(Prolog_term_ref& t, long l) {
00113 if (l < Prolog_min_integer || l > Prolog_max_integer)
00114 throw PPL_integer_out_of_range(l);
00115 t = Mk_Integer(l);
00116 return 1;
00117 }
00118
00122 inline int
00123 Prolog_put_ulong(Prolog_term_ref& t, unsigned long ul) {
00124 if (ul > static_cast<unsigned long>(Prolog_max_integer))
00125 throw PPL_integer_out_of_range(ul);
00126 t = Mk_Integer(ul);
00127 return 1;
00128 }
00129
00134 inline int
00135 Prolog_put_atom_chars(Prolog_term_ref& t, const char* s) {
00136
00137
00138
00139 t = Mk_Atom(Create_Allocate_Atom(const_cast<char*>(s)));
00140 return 1;
00141 }
00142
00146 inline int
00147 Prolog_put_atom(Prolog_term_ref& t, Prolog_atom a) {
00148 t = Mk_Atom(a);
00149 return 1;
00150 }
00151
00155 Prolog_atom
00156 Prolog_atom_from_string(const char* s) {
00157
00158 return Create_Allocate_Atom(const_cast<char*>(s));
00159 }
00160
00161 Prolog_term_ref args[4];
00162
00167 inline int
00168 Prolog_construct_compound(Prolog_term_ref& t, Prolog_atom f,
00169 Prolog_term_ref a1) {
00170 args[0] = a1;
00171 t = Mk_Compound(f, 1, args);
00172 return 1;
00173 }
00174
00179 inline int
00180 Prolog_construct_compound(Prolog_term_ref& t, Prolog_atom f,
00181 Prolog_term_ref a1, Prolog_term_ref a2) {
00182 args[0] = a1;
00183 args[1] = a2;
00184 t = Mk_Compound(f, 2, args);
00185 return 1;
00186 }
00187
00192 inline int
00193 Prolog_construct_compound(Prolog_term_ref& t, Prolog_atom f,
00194 Prolog_term_ref a1, Prolog_term_ref a2,
00195 Prolog_term_ref a3) {
00196 args[0] = a1;
00197 args[1] = a2;
00198 args[2] = a3;
00199 t = Mk_Compound(f, 3, args);
00200 return 1;
00201 }
00202
00207 inline int
00208 Prolog_construct_compound(Prolog_term_ref& t, Prolog_atom f,
00209 Prolog_term_ref a1, Prolog_term_ref a2,
00210 Prolog_term_ref a3, Prolog_term_ref a4) {
00211 args[0] = a1;
00212 args[1] = a2;
00213 args[2] = a3;
00214 args[3] = a4;
00215 t = Mk_Compound(f, 4, args);
00216 return 1;
00217 }
00218
00222 inline int
00223 Prolog_construct_cons(Prolog_term_ref& c,
00224 Prolog_term_ref h, Prolog_term_ref t) {
00225 args[0] = h;
00226 args[1] = t;
00227 c = Mk_List(args);
00228 return 1;
00229 }
00230
00234 inline int
00235 Prolog_put_address(Prolog_term_ref& t, void* p) {
00236 union {
00237 unsigned long l;
00238 unsigned short s[2];
00239 } u;
00240 u.l = reinterpret_cast<unsigned long>(p);
00241 return Prolog_construct_compound(t, a_dollar_address,
00242 Mk_Positive(u.s[0]), Mk_Positive(u.s[1]));
00243 }
00244
00248 inline void
00249 Prolog_raise_exception(Prolog_term_ref t) {
00250 Pl_Exec_Continuation(a_throw, 1, &t);
00251 }
00252
00256 inline int
00257 Prolog_is_variable(Prolog_term_ref t) {
00258 return Blt_Var(t) != FALSE;
00259 }
00260
00264 inline int
00265 Prolog_is_atom(Prolog_term_ref t) {
00266 return Blt_Atom(t) != FALSE;
00267 }
00268
00272 inline int
00273 Prolog_is_integer(Prolog_term_ref t) {
00274 return Blt_Integer(t) != FALSE;
00275 }
00276
00280 inline int
00281 Prolog_is_compound(Prolog_term_ref t) {
00282 return Blt_Compound(t) != FALSE;
00283 }
00284
00288 inline int
00289 Prolog_is_cons(Prolog_term_ref t) {
00290 if (Blt_Compound(t) == FALSE)
00291 return 0;
00292 Prolog_atom name;
00293 int arity;
00294 Rd_Compound(t, &name, &arity);
00295 return name == ATOM_CHAR('.') && arity == 2;
00296 }
00297
00304 inline int
00305 Prolog_get_long(Prolog_term_ref t, long* lp) {
00306 assert(Prolog_is_integer(t));
00307 *lp = Rd_Integer_Check(t);
00308 return 1;
00309 }
00310
00314 inline int
00315 Prolog_is_address(Prolog_term_ref t) {
00316 if (!Prolog_is_compound(t))
00317 return 0;
00318 Prolog_atom name;
00319 int arity;
00320 Prolog_term_ref* a = Rd_Compound_Check(t, &name, &arity);
00321 if (name != a_dollar_address || arity != 2)
00322 return 0;
00323 for (int i = 0; i <= 1; ++i) {
00324 if (!Prolog_is_integer(a[i]))
00325 return 0;
00326 long l;
00327 if (!Prolog_get_long(a[i], &l))
00328 return 0;
00329 if (l < 0 || l > USHRT_MAX)
00330 return 0;
00331 }
00332 return 1;
00333 }
00334
00340 inline int
00341 Prolog_get_address(Prolog_term_ref t, void** vpp) {
00342 assert(Prolog_is_address(t));
00343 static Prolog_atom dummy_name;
00344 static int dummy_arity;
00345 Prolog_term_ref* a = Rd_Compound_Check(t, &dummy_name, &dummy_arity);
00346 union {
00347 unsigned long l;
00348 unsigned short s[2];
00349 } u;
00350 u.s[0] = Rd_Integer_Check(a[0]);
00351 u.s[1] = Rd_Integer_Check(a[1]);
00352 *vpp = reinterpret_cast<void*>(u.l);
00353 return 1;
00354 }
00355
00360 inline int
00361 Prolog_get_atom_name(Prolog_term_ref t, Prolog_atom* ap) {
00362 assert(Prolog_is_atom(t));
00363 *ap = Rd_Atom_Check(t);
00364 return 1;
00365 }
00366
00372 inline int
00373 Prolog_get_compound_name_arity(Prolog_term_ref t, Prolog_atom* ap, int* ip) {
00374 assert(Prolog_is_compound(t));
00375 Rd_Compound_Check(t, ap, ip);
00376 return 1;
00377 }
00378
00385 inline int
00386 Prolog_get_arg(int i, Prolog_term_ref t, Prolog_term_ref& a) {
00387 assert(Prolog_is_compound(t));
00388 static Prolog_atom dummy_name;
00389 static int dummy_arity;
00390 a = Rd_Compound_Check(t, &dummy_name, &dummy_arity)[i-1];
00391 return 1;
00392 }
00393
00399 inline int
00400 Prolog_get_cons(Prolog_term_ref c, Prolog_term_ref& h, Prolog_term_ref& t) {
00401 assert(Prolog_is_cons(c));
00402 Prolog_term_ref* ht = Rd_List_Check(c);
00403 h = ht[0];
00404 t = ht[1];
00405 return 1;
00406 }
00407
00412 inline int
00413 Prolog_unify(Prolog_term_ref t, Prolog_term_ref u) {
00414 return Unify(t, u) != FALSE;
00415 }
00416
00417 PPL::Coefficient
00418 integer_term_to_Coefficient(Prolog_term_ref t) {
00419 long v;
00420 Prolog_get_long(t, &v);
00421 return PPL::Coefficient(v);
00422 }
00423
00424 Prolog_term_ref
00425 Coefficient_to_integer_term(const PPL::Coefficient& n) {
00426 long l = 0;
00427 if (PPL::assign_r(l, n, PPL::ROUND_NOT_NEEDED) != PPL::V_EQ)
00428 throw PPL_integer_out_of_range(n);
00429 Prolog_term_ref t = Prolog_new_term_ref();
00430 Prolog_put_long(t, l);
00431 return t;
00432 }
00433
00434 }
00435
00436 #undef CS
00437
00438 #include "../ppl_prolog.icc"