1dnl  -*- C++ -*-
2m4_divert(-1)
3
4This m4 file contains the program code for generating the
5files ppl_prolog_DOMAIN.cc for each interface domain DOMAIN
6in ppl_interface instantiations.m4.
7
8dnl Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
9dnl Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
10dnl
11dnl This file is part of the Parma Polyhedra Library (PPL).
12dnl
13dnl The PPL is free software; you can redistribute it and/or modify it
14dnl under the terms of the GNU General Public License as published by the
15dnl Free Software Foundation; either version 3 of the License, or (at your
16dnl option) any later version.
17dnl
18dnl The PPL is distributed in the hope that it will be useful, but WITHOUT
19dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20dnl FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21dnl for more details.
22dnl
23dnl You should have received a copy of the GNU General Public License
24dnl along with this program; if not, write to the Free Software Foundation,
25dnl Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
26dnl
27dnl For the most up-to-date information see the Parma Polyhedra Library
28dnl site: http://bugseng.com/products/ppl/ .
29
30m4_define(`ppl_new_@TOPOLOGY@@CLASS@_from_space_dimension_code',
31`extern "C" Prolog_foreign_return_type
32ppl_new_@TOPOLOGY@@CLASS@_from_space_dimension(Prolog_term_ref t_nd,
33                                               Prolog_term_ref t_uoe,
34                                               Prolog_term_ref t_ph) {
35  static const char* where = "ppl_new_@TOPOLOGY@@CLASS@_from_space_dimension/3";
36  try {
37    @TOPOLOGY@@CPP_CLASS@* ph;
38    Prolog_atom uoe = term_to_universe_or_empty(t_uoe, where);
39
40    if (uoe == a_empty)
41      ph = new @TOPOLOGY@@CPP_CLASS@(term_to_unsigned<dimension_type>(t_nd,
42                                                                      where),
43                                     EMPTY);
44    else
45      ph = new @TOPOLOGY@@CPP_CLASS@(term_to_unsigned<dimension_type>(t_nd,
46                                                                      where),
47                                     UNIVERSE);
48
49      Prolog_term_ref tmp = Prolog_new_term_ref();
50      Prolog_put_address(tmp, ph);
51      if (Prolog_unify(t_ph, tmp)) {
52        PPL_REGISTER(ph);
53        return PROLOG_SUCCESS;
54      }
55      else
56        delete ph;
57  }
58  CATCH_ALL;
59}
60
61')
62
63  m4_define(`ppl_new_@TOPOLOGY@@CLASS@_from_@FRIEND@_code',
64`extern "C" Prolog_foreign_return_type
65ppl_new_@TOPOLOGY@@CLASS@_from_@FRIEND@
66(Prolog_term_ref t_ph_source, Prolog_term_ref t_ph)
67{
68  static const char* where
69    = "ppl_new_@TOPOLOGY@@CLASS@_from_@FRIEND@/2";
70  try {
71    @TOPOLOGY@@CPP_CLASS@* ph;
72    const @B_FRIEND@* const ph_source
73      = static_cast<const @B_FRIEND@*>
74        (term_to_handle<@B_FRIEND@ >(t_ph_source, where));
75    PPL_CHECK(ph_source);
76    ph = new @TOPOLOGY@@CPP_CLASS@(*ph_source);
77    Prolog_term_ref tmp = Prolog_new_term_ref();
78    Prolog_put_address(tmp, ph);
79    if (Prolog_unify(t_ph, tmp)) {
80      PPL_REGISTER(ph);
81      return PROLOG_SUCCESS;
82    }
83    else
84      delete ph;
85  }
86  CATCH_ALL;
87}
88
89')
90
91  m4_define(`ppl_new_@TOPOLOGY@@CLASS@_from_@FRIEND@_with_complexity_code',
92`extern "C" Prolog_foreign_return_type
93ppl_new_@TOPOLOGY@@CLASS@_from_@FRIEND@_with_complexity(
94                     Prolog_term_ref t_ph_source,
95                     Prolog_term_ref t_ph,
96                     Prolog_term_ref t_cc)
97{
98  static const char* where =
99                   "ppl_new_@TOPOLOGY@@CLASS@_from_@FRIEND@_with_complexity/3";
100  try {
101    @TOPOLOGY@@CPP_CLASS@* ph;
102    const @B_FRIEND@* ph_source
103        = static_cast<const @B_FRIEND@*>
104        (term_to_handle<@B_FRIEND@ >(t_ph_source, where));
105
106    Prolog_atom p_cc = term_to_complexity_class(t_cc, where);
107    Complexity_Class cc;
108    if (p_cc == a_polynomial)
109      cc = POLYNOMIAL_COMPLEXITY;
110    else if (p_cc == a_simplex)
111      cc = SIMPLEX_COMPLEXITY;
112    else
113      cc = ANY_COMPLEXITY;
114
115    PPL_CHECK(ph_source);
116    ph = new @TOPOLOGY@@CPP_CLASS@(*ph_source, cc);
117
118    Prolog_term_ref tmp = Prolog_new_term_ref();
119    Prolog_put_address(tmp, ph);
120    if (Prolog_unify(t_ph, tmp)) {
121      PPL_REGISTER(ph);
122      return PROLOG_SUCCESS;
123    }
124    else
125      delete ph;
126  }
127  CATCH_ALL;
128}
129
130')
131
132m4_define(`ppl_new_@TOPOLOGY@@CLASS@_from_@BUILD_REPRESENT@s_code',
133  `extern "C" Prolog_foreign_return_type
134  ppl_new_@TOPOLOGY@@CLASS@_from_@BUILD_REPRESENT@s(Prolog_term_ref t_clist,
135                                                    Prolog_term_ref t_ph)
136{
137  static const char* where =
138    "ppl_new_@TOPOLOGY@@CLASS@_from_@BUILD_REPRESENT@s/2";
139  try {
140    @!BUILD_REPRESENT@_System cs;
141    Prolog_term_ref c = Prolog_new_term_ref();
142
143    while (Prolog_is_cons(t_clist)) {
144      Prolog_get_cons(t_clist, c, t_clist);
145      cs.insert(build_@BUILD_REPRESENT@(c, where));
146    }
147
148    // Check the list is properly terminated.
149    check_nil_terminating(t_clist, where);
150
151    @TOPOLOGY@@CPP_CLASS@* ph;
152    ph = new @TOPOLOGY@@CPP_CLASS@(cs@RECYCLE@);
153    Prolog_term_ref tmp = Prolog_new_term_ref();
154    Prolog_put_address(tmp, ph);
155    if (Prolog_unify(t_ph, tmp)) {
156      PPL_REGISTER(ph);
157      return PROLOG_SUCCESS;
158    }
159    else
160      delete ph;
161  }
162  CATCH_ALL;
163}
164
165')
166
167  m4_define(`ppl_@CLASS@_swap_code',
168  `extern "C" Prolog_foreign_return_type
169  ppl_@CLASS@_swap(Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
170  static const char* where = "ppl_@CLASS@_swap/2";
171  try {
172    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
173    @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
174    PPL_CHECK(lhs);
175    PPL_CHECK(rhs);
176    swap(*lhs, *rhs);
177    return PROLOG_SUCCESS;
178  }
179  CATCH_ALL;
180}
181
182')
183
184m4_define(`ppl_delete_@CLASS@_code',
185  `extern "C" Prolog_foreign_return_type
186  ppl_delete_@CLASS@(Prolog_term_ref t_ph) {
187  static const char* where = "ppl_delete_@CLASS@/1";
188  try {
189    const @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
190    PPL_UNREGISTER(ph);
191    delete ph;
192    return PROLOG_SUCCESS;
193  }
194  CATCH_ALL;
195}
196
197')
198
199m4_define(`ppl_@CLASS@_@DIMENSION@_code',
200  `extern "C" Prolog_foreign_return_type
201  ppl_@CLASS@_@DIMENSION@(Prolog_term_ref t_ph, Prolog_term_ref t_sd) {
202  static const char* where = "ppl_@CLASS@_@DIMENSION@/2";
203  try {
204    const @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
205    PPL_CHECK(ph);
206    if (unify_ulong(t_sd, ph->@DIMENSION@()))
207      return PROLOG_SUCCESS;
208  }
209  CATCH_ALL;
210}
211
212')
213
214m4_define(`ppl_@CLASS@_get_@CLASS_REPRESENT@s_code',
215  `extern "C" Prolog_foreign_return_type
216  ppl_@CLASS@_get_@CLASS_REPRESENT@s(Prolog_term_ref t_ph,
217                                   Prolog_term_ref t_glist) {
218  static const char* where = "ppl_@CLASS@_get_@CLASS_REPRESENT@s/2";
219  try {
220    const @CPP_CLASS@* const ph
221      = term_to_handle<@CPP_CLASS@ >(t_ph, where);
222    PPL_CHECK(ph);
223
224    Prolog_term_ref tail = Prolog_new_term_ref();
225    Prolog_put_nil(tail);
226    const @!CLASS_REPRESENT@_System& gs = ph->@CLASS_REPRESENT@s();
227    for (@!CLASS_REPRESENT@_System::const_iterator i = gs.begin(),
228           gs_end = gs.end(); i != gs_end; ++i)
229      Prolog_construct_cons(tail, @CLASS_REPRESENT@_term(*i), tail);
230
231    if (Prolog_unify(t_glist, tail))
232      return PROLOG_SUCCESS;
233  }
234  CATCH_ALL;
235}
236
237')
238
239m4_define(`ppl_@CLASS@_get_minimized_@CLASS_REPRESENT@s_code',
240  `extern "C" Prolog_foreign_return_type
241  ppl_@CLASS@_get_minimized_@CLASS_REPRESENT@s(Prolog_term_ref t_ph,
242                                             Prolog_term_ref t_glist) {
243  static const char* where = "ppl_@CLASS@_get_minimized_@CLASS_REPRESENT@s/2";
244  try {
245    const @CPP_CLASS@* const ph
246      = term_to_handle<@CPP_CLASS@ >(t_ph, where);
247    PPL_CHECK(ph);
248
249    Prolog_term_ref tail = Prolog_new_term_ref();
250    Prolog_put_nil(tail);
251    const @!CLASS_REPRESENT@_System& gs = ph->minimized_@CLASS_REPRESENT@s();
252    for (@!CLASS_REPRESENT@_System::const_iterator i = gs.begin(),
253           gs_end = gs.end(); i != gs_end; ++i)
254      Prolog_construct_cons(tail, @CLASS_REPRESENT@_term(*i), tail);
255
256    if (Prolog_unify(t_glist, tail))
257      return PROLOG_SUCCESS;
258  }
259  CATCH_ALL;
260}
261
262')
263
264m4_define(`ppl_@CLASS@_@BEGINEND@_iterator_code',
265  `extern "C" Prolog_foreign_return_type
266  ppl_@CLASS@_@BEGINEND@_iterator(Prolog_term_ref t_pps,
267                                  Prolog_term_ref t_it) {
268  static const char* where = "ppl_@CLASS@_@BEGINEND@_iterator/2";
269  try {
270    @CPP_CLASS@* pps = term_to_handle<@CPP_CLASS@ >(t_pps, where);
271    PPL_CHECK(pps);
272
273    @CPP_CLASS@::iterator* i = new @CPP_CLASS@::iterator(pps->@BEGINEND@());
274    Prolog_term_ref t_i = Prolog_new_term_ref();
275    Prolog_put_address(t_i, i);
276
277    if (Prolog_unify(t_it, t_i)) {
278      PPL_REGISTER(i);
279      return PROLOG_SUCCESS;
280    }
281    else
282      delete i;
283  }
284  CATCH_ALL;
285}
286
287')
288
289m4_define(`ppl_new_@CLASS@_iterator_from_iterator_code',
290`extern "C" Prolog_foreign_return_type
291ppl_new_@CLASS@_iterator_from_iterator(Prolog_term_ref t_source,
292                                       Prolog_term_ref t_it) {
293  static const char* where = "ppl_new_@CLASS@_iterator_from_iterator/2";
294  try {
295    const @CPP_CLASS@::iterator* source
296      = term_to_handle<const @CPP_CLASS@::iterator>(t_source, where);
297    PPL_CHECK(source);
298
299    @CPP_CLASS@::iterator* it = new @CPP_CLASS@::iterator(*source);
300    Prolog_term_ref t_i = Prolog_new_term_ref();
301    Prolog_put_address(t_i, it);
302
303    if (Prolog_unify(t_it, t_i)) {
304      PPL_REGISTER(it);
305      return PROLOG_SUCCESS;
306    }
307    else
308      delete it;
309  }
310  CATCH_ALL;
311}
312
313')
314
315m4_define(`ppl_delete_@CLASS@_iterator_code',
316  `extern "C" Prolog_foreign_return_type
317  ppl_delete_@CLASS@_iterator(Prolog_term_ref t_it) {
318  static const char* where = "ppl_delete_@CLASS@_iterator/1";
319  try {
320    const @CPP_CLASS@::iterator* it
321      = term_to_handle<@CPP_CLASS@::iterator >(t_it, where);
322    PPL_UNREGISTER(it);
323    delete it;
324    return PROLOG_SUCCESS;
325  }
326  CATCH_ALL;
327}
328
329')
330
331m4_define(`ppl_@CLASS@_@INCDEC@_iterator_code',
332  `extern "C" Prolog_foreign_return_type
333  ppl_@CLASS@_@INCDEC@_iterator(Prolog_term_ref t_it) {
334  static const char* where = "ppl_@CLASS@_@INCDEC@_iterator/2";
335  try {
336    @CPP_CLASS@::iterator* it
337      = term_to_handle<@CPP_CLASS@::iterator >(t_it, where);
338    PPL_CHECK(it);
339    @B_INCDEC@(*it);
340    return PROLOG_SUCCESS;
341  }
342  CATCH_ALL;
343}
344
345')
346
347m4_define(`ppl_@CLASS@_iterator_equals_iterator_code',
348  `extern "C" Prolog_foreign_return_type
349  ppl_@CLASS@_iterator_equals_iterator(Prolog_term_ref t_it1,
350                                       Prolog_term_ref t_it2) {
351  static const char* where = "ppl_@CLASS@_iterator_equals_iterator/2";
352  try {
353    @CPP_CLASS@::iterator* it1
354      = term_to_handle<@CPP_CLASS@::iterator >(t_it1, where);
355    PPL_CHECK(it1);
356    @CPP_CLASS@::iterator* it2
357      = term_to_handle<@CPP_CLASS@::iterator >(t_it2, where);
358    PPL_CHECK(it2);
359    if (*it1 == *it2)
360      return PROLOG_SUCCESS;
361    else
362      return PROLOG_FAILURE;
363  }
364  CATCH_ALL;
365}
366
367')
368
369m4_define(`ppl_@CLASS@_get_disjunct_code',
370  `extern "C" Prolog_foreign_return_type
371  ppl_@CLASS@_get_disjunct(Prolog_term_ref t_it,
372                           Prolog_term_ref t_disj) {
373  static const char* where = "ppl_@CLASS@_get_disjunct/2";
374  try {
375    const @CPP_CLASS@::iterator* it
376      = term_to_handle<@CPP_CLASS@::iterator >(t_it, where);
377    PPL_CHECK(it);
378
379    @DISJUNCT_TOPOLOGY@@A_DISJUNCT@* disj
380      = const_cast<@DISJUNCT_TOPOLOGY@@A_DISJUNCT@*>(&((*it)->pointset()));
381    Prolog_term_ref t_d = Prolog_new_term_ref();
382    Prolog_put_address(t_d, disj);
383
384    if (Prolog_unify(t_disj, t_d)) {
385      PPL_WEAK_REGISTER(disj);
386      return PROLOG_SUCCESS;
387    }
388  }
389  CATCH_ALL;
390}
391
392')
393
394m4_define(`ppl_@CLASS@_drop_disjunct_code',
395  `extern "C" Prolog_foreign_return_type
396  ppl_@CLASS@_drop_disjunct(Prolog_term_ref t_pps,
397                            Prolog_term_ref t_it) {
398  static const char* where = "ppl_@CLASS@_drop_disjuncts/2";
399  try {
400    @CPP_CLASS@* pps = term_to_handle<@CPP_CLASS@ >(t_pps, where);
401    PPL_CHECK(pps);
402
403    @CPP_CLASS@::iterator* it
404      = term_to_handle<@CPP_CLASS@::iterator >(t_it, where);
405    PPL_CHECK(it);
406
407    @CPP_CLASS@::iterator& i = *it;
408    i = pps->drop_disjunct(i);
409
410    return PROLOG_SUCCESS;
411  }
412  CATCH_ALL;
413}
414
415')
416
417m4_define(`ppl_@CLASS@_drop_disjuncts_code',
418  `extern "C" Prolog_foreign_return_type
419  ppl_@CLASS@_drop_disjuncts(Prolog_term_ref t_pps,
420                             Prolog_term_ref t_it1,
421                             Prolog_term_ref t_it2) {
422  static const char* where = "ppl_@CLASS@_drop_disjuncts/3";
423  try {
424    @CPP_CLASS@* pps = term_to_handle<@CPP_CLASS@ >(t_pps, where);
425    PPL_CHECK(pps);
426
427    @CPP_CLASS@::iterator* it1
428      = term_to_handle<@CPP_CLASS@::iterator >(t_it1, where);
429    PPL_CHECK(it1);
430    @CPP_CLASS@::iterator* it2
431      = term_to_handle<@CPP_CLASS@::iterator >(t_it2, where);
432    PPL_CHECK(it2);
433
434    @CPP_CLASS@::iterator& i1 = *it1;
435    @CPP_CLASS@::iterator& i2 = *it2;
436    pps->drop_disjuncts(i1, i2);
437
438    return PROLOG_SUCCESS;
439  }
440  CATCH_ALL;
441}
442
443')
444
445m4_define(`ppl_@CLASS@_add_disjunct_code',
446  `extern "C" Prolog_foreign_return_type
447  ppl_@CLASS@_add_disjunct(Prolog_term_ref t_ph, Prolog_term_ref t_d) {
448  static const char* where = "ppl_@CLASS@_add_disjunct/2";
449  try {
450    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
451    PPL_CHECK(ph);
452    @DISJUNCT_TOPOLOGY@@A_DISJUNCT@* d =
453      static_cast<@DISJUNCT_TOPOLOGY@@A_DISJUNCT@*>
454      (term_to_handle<@DISJUNCT_TOPOLOGY@@A_DISJUNCT@ >(t_d, where));
455    PPL_CHECK(d);
456    ph->add_disjunct(*d);
457    return PROLOG_SUCCESS;
458  }
459  CATCH_ALL;
460}
461
462')
463
464m4_define(`ppl_@CLASS@_linear_@PARTITION@_code',
465`dnl
466extern "C" Prolog_foreign_return_type
467ppl_@CLASS@_linear_@PARTITION@(Prolog_term_ref t_ph,
468                             Prolog_term_ref t_qh,
469                             Prolog_term_ref t_inters,
470                             Prolog_term_ref t_pset) {
471  try {
472    static const char* where = "ppl_@CLASS@_linear_partition/4";
473    @CPP_CLASS@* rfh;
474    Pointset_Powerset<NNC_Polyhedron>* rsh;
475`m4_ifelse(m4_current_interface, `Polyhedron',
476  `m4_linear_partition_for_polyhedron_domains',
477           `m4_linear_partition_for_non_polyhedron_domains')'
478    Prolog_term_ref t_r_first = Prolog_new_term_ref();
479    Prolog_term_ref t_r_second = Prolog_new_term_ref();
480    Prolog_put_address(t_r_first, rfh);
481    Prolog_put_address(t_r_second, rsh);
482    if (Prolog_unify(t_inters, t_r_first)
483        && Prolog_unify(t_pset, t_r_second)) {
484      PPL_REGISTER(rfh);
485      PPL_REGISTER(rsh);
486      return PROLOG_SUCCESS;
487    }
488    else {
489      delete rfh;
490      delete rsh;
491    }
492  }
493  CATCH_ALL;
494}
495
496')
497
498m4_define(`m4_linear_partition_for_polyhedron_domains',
499`    const Polyhedron* xph = term_to_handle<Polyhedron>(t_ph, where);
500    if (Interfaces::is_necessarily_closed_for_interfaces(*xph)) {
501      const C_Polyhedron* ph = term_to_handle<C_Polyhedron>(t_ph, where);
502      const C_Polyhedron* qh = term_to_handle<C_Polyhedron>(t_qh, where);
503      PPL_CHECK(ph);
504      PPL_CHECK(qh);
505      std::pair<C_Polyhedron|COMMA| Pointset_Powerset<NNC_Polyhedron> >
506        r = linear_partition(*ph, *qh);
507      rfh = new C_Polyhedron(0, EMPTY);
508      rsh = new Pointset_Powerset<NNC_Polyhedron>(0, EMPTY);
509      swap(*rfh, r.first);
510      swap(*rsh, r.second);
511    }
512    else {
513      const NNC_Polyhedron* ph = term_to_handle<NNC_Polyhedron>(t_ph, where);
514      const NNC_Polyhedron* qh = term_to_handle<NNC_Polyhedron>(t_qh, where);
515      PPL_CHECK(ph);
516      PPL_CHECK(qh);
517      std::pair<NNC_Polyhedron|COMMA| Pointset_Powerset<NNC_Polyhedron> >
518        r = linear_partition(*ph, *qh);
519      rfh = new NNC_Polyhedron(0, EMPTY);
520      rsh = new Pointset_Powerset<NNC_Polyhedron>(0, EMPTY);
521      swap(*rfh, r.first);
522      swap(*rsh, r.second);
523    }
524')
525
526m4_define(`m4_linear_partition_for_non_polyhedron_domains',
527`  const @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
528  const @CPP_CLASS@* qh = term_to_handle<@CPP_CLASS@ >(t_qh, where);
529  PPL_CHECK(ph);
530  PPL_CHECK(qh);
531  std::pair<@CPP_CLASS@|COMMA| Pointset_Powerset<NNC_Polyhedron> >
532    r = linear_partition(*ph, *qh);
533  rfh = new @CPP_CLASS@(0, EMPTY);
534  rsh = new Pointset_Powerset<NNC_Polyhedron>(0, EMPTY);
535  swap(*rfh, r.first);
536  swap(*rsh, r.second);
537')
538
539m4_define(`ppl_@CLASS@_approximate_@PARTITION@_code',
540  `dnl
541  extern "C" Prolog_foreign_return_type
542  ppl_@CLASS@_approximate_@PARTITION@(Prolog_term_ref t_ph,
543                                    Prolog_term_ref t_qh,
544                                    Prolog_term_ref t_finite,
545                                    Prolog_term_ref t_inters,
546                                    Prolog_term_ref t_pset) {
547  static const char* where = "ppl_@CLASS@_approximate_partition/5";
548  try {
549    const @CLASS@* ph =
550      term_to_handle<@CLASS@ >(t_ph, where);
551    PPL_CHECK(ph);
552    const @CLASS@* qh =
553      term_to_handle<@CLASS@ >(t_qh, where);
554    PPL_CHECK(qh);
555    bool finite;
556
557    std::pair<@CLASS@|COMMA| Pointset_Powerset<Grid> > r =
558      approximate_partition(*ph, *qh, finite);
559
560    @CLASS@* rfh = new @CLASS@(EMPTY);
561    swap(*rfh, r.first);
562
563    Pointset_Powerset<Grid>* rsh =
564      new Pointset_Powerset<Grid>(EMPTY);
565    swap(*rsh, r.second);
566
567    Prolog_term_ref t_b = Prolog_new_term_ref();
568    Prolog_term_ref t_r_first = Prolog_new_term_ref();
569    Prolog_term_ref t_r_second = Prolog_new_term_ref();
570    Prolog_atom a = (finite ? a_true : a_false);
571    Prolog_put_atom(t_b, a);
572
573    Prolog_put_address(t_r_first, rfh);
574    Prolog_put_address(t_r_second, rsh);
575
576    if (Prolog_unify(t_inters, t_r_first)
577        && Prolog_unify(t_pset, t_r_second
578                        && Prolog_unify(t_finite, t_b)))
579      return PROLOG_SUCCESS;
580  }
581  CATCH_ALL;
582}
583
584')
585
586m4_define(`ppl_@CLASS@_relation_with_@RELATION_REPRESENT@_code',
587  `extern "C" Prolog_foreign_return_type
588  ppl_@CLASS@_relation_with_@RELATION_REPRESENT@(Prolog_term_ref t_ph,
589                                                 Prolog_term_ref t_c,
590                                                 Prolog_term_ref t_r) {
591  static const char* where =
592    "ppl_@CLASS@_relation_with_@RELATION_REPRESENT@/3";
593  try {
594    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
595    PPL_CHECK(ph);
596relation_with_@RELATION_REPRESENT@_code
597      if (Prolog_unify(t_r, tail))
598        return PROLOG_SUCCESS;
599  }
600  CATCH_ALL;
601}
602
603')
604
605m4_define(`relation_with_constraint_code', `
606  Poly_Con_Relation r = ph->relation_with(build_constraint(t_c, where));
607
608  Prolog_term_ref tail = Prolog_new_term_ref();
609  Prolog_put_nil(tail);
610  while (r != Poly_Con_Relation::nothing()) {
611    if (r.implies(Poly_Con_Relation::is_disjoint())) {
612      Prolog_term_ref t_dis = Prolog_new_term_ref();
613      Prolog_put_atom(t_dis, a_is_disjoint);
614      Prolog_construct_cons(tail, t_dis, tail);
615      r = r - Poly_Con_Relation::is_disjoint();
616    }
617    else if (r.implies(Poly_Con_Relation::strictly_intersects())) {
618      Prolog_term_ref t_sin = Prolog_new_term_ref();
619      Prolog_put_atom(t_sin, a_strictly_intersects);
620      Prolog_construct_cons(tail, t_sin, tail);
621      r = r - Poly_Con_Relation::strictly_intersects();
622    }
623    else if (r.implies(Poly_Con_Relation::is_included())) {
624      Prolog_term_ref t_inc = Prolog_new_term_ref();
625      Prolog_put_atom(t_inc, a_is_included);
626      Prolog_construct_cons(tail, t_inc, tail);
627      r = r - Poly_Con_Relation::is_included();
628    }
629    else if (r.implies(Poly_Con_Relation::saturates())) {
630      Prolog_term_ref t_sat = Prolog_new_term_ref();
631      Prolog_put_atom(t_sat, a_saturates);
632      Prolog_construct_cons(tail, t_sat, tail);
633      r = r - Poly_Con_Relation::saturates();
634    }
635   }
636')
637
638m4_define(`relation_with_congruence_code', `
639  Poly_Con_Relation r = ph->relation_with(build_congruence(t_c, where));
640
641  Prolog_term_ref tail = Prolog_new_term_ref();
642  Prolog_put_nil(tail);
643  while (r != Poly_Con_Relation::nothing()) {
644    if (r.implies(Poly_Con_Relation::is_disjoint())) {
645      Prolog_term_ref t_dis = Prolog_new_term_ref();
646      Prolog_put_atom(t_dis, a_is_disjoint);
647      Prolog_construct_cons(tail, t_dis, tail);
648      r = r - Poly_Con_Relation::is_disjoint();
649    }
650    else if (r.implies(Poly_Con_Relation::strictly_intersects())) {
651      Prolog_term_ref t_sin = Prolog_new_term_ref();
652      Prolog_put_atom(t_sin, a_strictly_intersects);
653      Prolog_construct_cons(tail, t_sin, tail);
654      r = r - Poly_Con_Relation::strictly_intersects();
655    }
656    else if (r.implies(Poly_Con_Relation::is_included())) {
657      Prolog_term_ref t_inc = Prolog_new_term_ref();
658      Prolog_put_atom(t_inc, a_is_included);
659      Prolog_construct_cons(tail, t_inc, tail);
660      r = r - Poly_Con_Relation::is_included();
661    }
662    else if (r.implies(Poly_Con_Relation::saturates())) {
663      Prolog_term_ref t_sat = Prolog_new_term_ref();
664      Prolog_put_atom(t_sat, a_saturates);
665      Prolog_construct_cons(tail, t_sat, tail);
666      r = r - Poly_Con_Relation::saturates();
667    }
668    else
669      break;
670   }
671')
672
673m4_define(`relation_with_generator_code', `
674  Poly_Gen_Relation r = ph->relation_with(build_generator(t_c, where));
675
676  Prolog_term_ref tail = Prolog_new_term_ref();
677Prolog_put_nil(tail);
678while (r != Poly_Gen_Relation::nothing()) {
679  if (r.implies(Poly_Gen_Relation::subsumes())) {
680    Prolog_term_ref t_sub = Prolog_new_term_ref();
681    Prolog_put_atom(t_sub, a_subsumes);
682    Prolog_construct_cons(tail, t_sub, tail);
683    r = r - Poly_Gen_Relation::subsumes();
684  }
685 }
686')
687
688m4_define(`relation_with_grid_generator_code', `
689  Poly_Gen_Relation r = ph->relation_with(build_grid_generator(t_c, where));
690
691  Prolog_term_ref tail = Prolog_new_term_ref();
692  Prolog_put_nil(tail);
693  while (r != Poly_Gen_Relation::nothing()) {
694    if (r.implies(Poly_Gen_Relation::subsumes())) {
695      Prolog_term_ref t_sub = Prolog_new_term_ref();
696      Prolog_put_atom(t_sub, a_subsumes);
697      Prolog_construct_cons(tail, t_sub, tail);
698      r = r - Poly_Gen_Relation::subsumes();
699    }
700   }
701')
702
703m4_define(`ppl_@CLASS@_@HAS_PROPERTY@_code',
704  `extern "C" Prolog_foreign_return_type
705  ppl_@CLASS@_@HAS_PROPERTY@(Prolog_term_ref t_ph) {
706  static const char* where = "ppl_@CLASS@_@HAS_PROPERTY@/1";
707  try {
708    const @CPP_CLASS@* const ph
709      = term_to_handle<@CPP_CLASS@ >(t_ph, where);
710    PPL_CHECK(ph);
711    if (ph->@HAS_PROPERTY@())
712      return PROLOG_SUCCESS;
713  }
714  CATCH_ALL;
715}
716
717')
718
719m4_define(`ppl_@CLASS@_@SIMPLIFY@_code',
720  `extern "C" Prolog_foreign_return_type
721  ppl_@CLASS@_@SIMPLIFY@(Prolog_term_ref t_ph) {
722  static const char* where = "ppl_@CLASS@_@SIMPLIFY@/1";
723  try {
724    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
725    PPL_CHECK(ph);
726    ph->@SIMPLIFY@();
727    return PROLOG_SUCCESS;
728  }
729  CATCH_ALL;
730}
731
732')
733
734m4_define(`ppl_@CLASS@_unconstrain_space_dimension_code',
735  `extern "C" Prolog_foreign_return_type
736  ppl_@CLASS@_unconstrain_space_dimension(Prolog_term_ref t_ph,
737                           Prolog_term_ref t_v) {
738  static const char* where = "ppl_@CLASS@__unconstrain/1";
739  try {
740    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
741    PPL_CHECK(ph);
742    ph->unconstrain(term_to_Variable(t_v, where));
743    return PROLOG_SUCCESS;
744  }
745  CATCH_ALL;
746}
747
748')
749
750m4_define(`ppl_@CLASS@_unconstrain_space_dimensions_code',
751  `extern "C" Prolog_foreign_return_type
752  ppl_@CLASS@_unconstrain_space_dimensions(Prolog_term_ref t_ph,
753                           Prolog_term_ref t_vlist) {
754  static const char* where = "ppl_@CLASS@__unconstrain/1";
755  try {
756    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
757    PPL_CHECK(ph);
758    Variables_Set unconstrain_variables;
759    Prolog_term_ref v = Prolog_new_term_ref();
760    while (Prolog_is_cons(t_vlist)) {
761      Prolog_get_cons(t_vlist, v, t_vlist);
762      unconstrain_variables.insert(term_to_Variable(v, where).id());
763    }
764
765    // Check the list is properly terminated.
766    check_nil_terminating(t_vlist, where);
767    ph->unconstrain(unconstrain_variables);
768    return PROLOG_SUCCESS;
769  }
770  CATCH_ALL;
771}
772
773')
774
775m4_define(`ppl_@CLASS@_constrains_code',
776  `extern "C" Prolog_foreign_return_type
777  ppl_@CLASS@_constrains(Prolog_term_ref t_ph,
778                          Prolog_term_ref t_v) {
779  static const char* where = "ppl_@CLASS@__constrains/1";
780  try {
781    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
782    PPL_CHECK(ph);
783    if (ph->constrains(term_to_Variable(t_v, where)))
784      return PROLOG_SUCCESS;
785  }
786  CATCH_ALL;
787}
788
789')
790
791m4_define(`ppl_@CLASS@_bounds_from_@ABOVEBELOW@_code',
792  `extern "C" Prolog_foreign_return_type
793  ppl_@CLASS@_bounds_from_@ABOVEBELOW@(Prolog_term_ref t_ph,
794                                       Prolog_term_ref t_expr) {
795  static const char* where = "ppl_@CLASS@_bounds_from_@ABOVEBELOW@/2";
796  try {
797    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
798    PPL_CHECK(ph);
799    const Linear_Expression l = build_linear_expression(t_expr, where);
800    if (ph->bounds_from_@ABOVEBELOW@(l))
801      return PROLOG_SUCCESS;
802  }
803  CATCH_ALL;
804}
805
806')
807
808m4_define(`ppl_@CLASS@_has_@UPPERLOWER@_bound_code',
809  `extern "C" Prolog_foreign_return_type
810  ppl_@CLASS@_has_@UPPERLOWER@_bound(Prolog_term_ref t_ph,
811                       Prolog_term_ref t_v,
812                       Prolog_term_ref t_n, Prolog_term_ref t_d,
813                       Prolog_term_ref t_closed) {
814  static const char* where = "ppl_@CLASS@_has_@UPPERLOWER@_bound/5";
815  try {
816    const @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
817    PPL_CHECK(ph);
818    const Variable v = term_to_Variable(t_v, where);
819    PPL_DIRTY_TEMP_COEFFICIENT(n);
820    PPL_DIRTY_TEMP_COEFFICIENT(d);
821    bool closed;
822    if (ph->has_@UPPERLOWER@_bound(v, n, d, closed)) {
823      Prolog_term_ref t = Prolog_new_term_ref();
824      Prolog_atom a = (closed ? a_true : a_false);
825      Prolog_put_atom(t, a);
826      if (Prolog_unify_Coefficient(t_n, n)
827          && Prolog_unify_Coefficient(t_d, d)
828          && Prolog_unify(t_closed, t))
829        return PROLOG_SUCCESS;
830    }
831  }
832  CATCH_ALL;
833}
834
835')
836
837m4_define(`ppl_@CLASS@_@MAXMIN@_code',
838  `extern "C" Prolog_foreign_return_type
839  ppl_@CLASS@_@MAXMIN@(Prolog_term_ref t_ph, Prolog_term_ref t_le_expr,
840                       Prolog_term_ref t_n,  Prolog_term_ref t_d,
841                       Prolog_term_ref t_maxmin) {
842  static const char* where = "ppl_@CLASS@_@MAXMIN@/5";
843  try {
844    const @CPP_CLASS@* const ph
845      = term_to_handle<@CPP_CLASS@ >(t_ph, where);
846    PPL_CHECK(ph);
847    const Linear_Expression le = build_linear_expression(t_le_expr, where);
848    PPL_DIRTY_TEMP_COEFFICIENT(n);
849    PPL_DIRTY_TEMP_COEFFICIENT(d);
850    bool maxmin;
851    if (ph->@MAXMIN@(le, n, d, maxmin)) {
852      Prolog_term_ref t = Prolog_new_term_ref();
853      const Prolog_atom a = (maxmin ? a_true : a_false);
854      Prolog_put_atom(t, a);
855      if (Prolog_unify_Coefficient(t_n, n)
856          && Prolog_unify_Coefficient(t_d, d)
857          && Prolog_unify(t_maxmin, t))
858        return PROLOG_SUCCESS;
859    }
860  }
861  CATCH_ALL;
862}
863
864')
865
866m4_define(`ppl_@CLASS@_@MAXMIN@_with_point_code',
867`extern "C" Prolog_foreign_return_type
868ppl_@CLASS@_@MAXMIN@_with_point
869(Prolog_term_ref t_ph,
870 Prolog_term_ref t_le_expr,
871 Prolog_term_ref t_n, Prolog_term_ref t_d,
872 Prolog_term_ref t_maxmin, Prolog_term_ref t_g) {
873  static const char* where = "ppl_@CLASS@_@MAXMIN@_with_point/6";
874  try {
875    const @CPP_CLASS@* const ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
876    PPL_CHECK(ph);
877    const Linear_Expression le = build_linear_expression(t_le_expr, where);
878    PPL_DIRTY_TEMP_COEFFICIENT(n);
879    PPL_DIRTY_TEMP_COEFFICIENT(d);
880    bool maxmin;
881    Generator g(point());
882    if (ph->@MAXMIN@(le, n, d, maxmin, g)) {
883      Prolog_term_ref t = Prolog_new_term_ref();
884      const Prolog_atom a = (maxmin ? a_true : a_false);
885      Prolog_put_atom(t, a);
886      if (Prolog_unify_Coefficient(t_n, n)
887          && Prolog_unify_Coefficient(t_d, d)
888          && Prolog_unify(t_maxmin, t)
889          && Prolog_unify(t_g, generator_term(g)))
890        return PROLOG_SUCCESS;
891    }
892  }
893  CATCH_ALL;
894}
895
896')
897
898m4_define(`ppl_@CLASS@_@COMPARISON@_@CLASS@_code',
899  `extern "C" Prolog_foreign_return_type
900  ppl_@CLASS@_@COMPARISON@_@CLASS@(Prolog_term_ref t_lhs,
901                                   Prolog_term_ref t_rhs) {
902  static const char* where = "ppl_@CLASS@_@COMPARISON@_@CLASS@/2";
903  try {
904    const @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
905    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
906    PPL_CHECK(lhs);
907    PPL_CHECK(rhs);
908    if (lhs->@COMPARISON@(*rhs))
909      return PROLOG_SUCCESS;
910  }
911  CATCH_ALL;
912}
913
914')
915
916m4_define(`ppl_@CLASS@_equals_@CLASS@_code',
917  `extern "C" Prolog_foreign_return_type
918  ppl_@CLASS@_equals_@CLASS@(Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
919  static const char* where = "ppl_@CLASS@_equals_@CLASS@/2";
920  try {
921    const @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
922    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
923    PPL_CHECK(lhs);
924    PPL_CHECK(rhs);
925    if (*lhs == *rhs)
926      return PROLOG_SUCCESS;
927  }
928  CATCH_ALL;
929}
930
931')
932
933m4_define(`ppl_@CLASS@_OK_code',
934  `extern "C" Prolog_foreign_return_type
935  ppl_@CLASS@_OK(Prolog_term_ref t_ph) {
936  static const char* where = "ppl_@CLASS@_OK/1";
937  try {
938    const @CPP_CLASS@* const ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
939    PPL_CHECK(ph);
940    if (ph->OK())
941      return PROLOG_SUCCESS;
942  }
943  CATCH_ALL;
944}
945
946')
947
948m4_define(`ppl_@CLASS@_add_@CLASS_REPRESENT@_code',
949  `extern "C" Prolog_foreign_return_type
950  ppl_@CLASS@_add_@CLASS_REPRESENT@(Prolog_term_ref t_ph, Prolog_term_ref t_c) {
951  static const char* where = "ppl_@CLASS@_add_@CLASS_REPRESENT@/2";
952  try {
953    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
954    PPL_CHECK(ph);
955    ph->add_@CLASS_REPRESENT@(build_@CLASS_REPRESENT@(t_c, where));
956    return PROLOG_SUCCESS;
957  }
958  CATCH_ALL;
959}
960
961')
962
963m4_define(`ppl_@CLASS@_refine_with_@REFINE_REPRESENT@_code',
964  `extern "C" Prolog_foreign_return_type
965  ppl_@CLASS@_refine_with_@REFINE_REPRESENT@(Prolog_term_ref t_ph,
966                                             Prolog_term_ref t_c) {
967  static const char* where = "ppl_@CLASS@_refine_with_@REFINE_REPRESENT@/2";
968  try {
969    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
970    PPL_CHECK(ph);
971    ph->refine_with_@REFINE_REPRESENT@(build_@REFINE_REPRESENT@(t_c, where));
972    return PROLOG_SUCCESS;
973  }
974  CATCH_ALL;
975}
976
977')
978
979m4_define(`ppl_@CLASS@_add_@CLASS_REPRESENT@s_code',
980  `extern "C" Prolog_foreign_return_type
981  ppl_@CLASS@_add_@CLASS_REPRESENT@s(Prolog_term_ref t_ph,
982                                   Prolog_term_ref t_clist) {
983  static const char* where = "ppl_@CLASS@_add_@CLASS_REPRESENT@s/2";
984  try {
985    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
986    PPL_CHECK(ph);
987    @!CLASS_REPRESENT@_System cs;
988    Prolog_term_ref c = Prolog_new_term_ref();
989
990    while (Prolog_is_cons(t_clist)) {
991      Prolog_get_cons(t_clist, c, t_clist);
992      cs.insert(build_@CLASS_REPRESENT@(c, where));
993    }
994
995    // Check the list is properly terminated.
996    check_nil_terminating(t_clist, where);
997
998    ph->add_@CLASS_REPRESENT@s(cs);
999    return PROLOG_SUCCESS;
1000  }
1001  CATCH_ALL;
1002}
1003
1004')
1005
1006m4_define(`ppl_@CLASS@_refine_with_@REFINE_REPRESENT@s_code',
1007  `extern "C" Prolog_foreign_return_type
1008  ppl_@CLASS@_refine_with_@REFINE_REPRESENT@s(Prolog_term_ref t_ph,
1009                                   Prolog_term_ref t_clist) {
1010  static const char* where = "ppl_@CLASS@_refine_with_@REFINE_REPRESENT@s/2";
1011  try {
1012    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1013    PPL_CHECK(ph);
1014    @!REFINE_REPRESENT@_System cs;
1015    Prolog_term_ref c = Prolog_new_term_ref();
1016
1017    while (Prolog_is_cons(t_clist)) {
1018      Prolog_get_cons(t_clist, c, t_clist);
1019      cs.insert(build_@REFINE_REPRESENT@(c, where));
1020    }
1021
1022    // Check the list is properly terminated.
1023    check_nil_terminating(t_clist, where);
1024
1025    ph->refine_with_@REFINE_REPRESENT@s(cs);
1026    return PROLOG_SUCCESS;
1027  }
1028  CATCH_ALL;
1029}
1030
1031')
1032
1033m4_define(`bop_assign_code',
1034`namespace Parma_Polyhedra_Library {
1035
1036namespace Interfaces {
1037
1038namespace Prolog {
1039
1040Prolog_foreign_return_type
1041bop_assign(Prolog_term_ref t_lhs,
1042           Prolog_term_ref t_rhs,
1043           void (@CPP_CLASS@::* bop_assign)(const @CPP_CLASS@&),
1044           const char* where) {
1045  try {
1046    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1047    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1048    PPL_CHECK(lhs);
1049    PPL_CHECK(rhs);
1050    (lhs->*bop_assign)(*rhs);
1051    return PROLOG_SUCCESS;
1052  }
1053  CATCH_ALL;
1054}
1055
1056} // namespace Prolog
1057
1058} // namespace Interfaces
1059
1060} // namespace Parma_Polyhedra_Library
1061
1062using namespace Parma_Polyhedra_Library::Interfaces::Prolog;
1063
1064')
1065
1066m4_define(`ppl_@CLASS@_@BINOP@_code',
1067  `extern "C" Prolog_foreign_return_type
1068  ppl_@CLASS@_@BINOP@
1069  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1070  static const char* where = "ppl_@CLASS@_@BINOP@";
1071  try {
1072    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1073    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1074    PPL_CHECK(lhs);
1075    PPL_CHECK(rhs);
1076    lhs->@BINOP@(*rhs);
1077    return PROLOG_SUCCESS;
1078  }
1079  CATCH_ALL;
1080}
1081
1082')
1083
1084m4_define(`ppl_@CLASS@_positive_time_elapse_assign_code',
1085  `extern "C" Prolog_foreign_return_type
1086  ppl_@CLASS@_positive_time_elapse_assign
1087  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1088  static const char* where = "ppl_@CLASS@_positive_time_elapse_assign";
1089  try {
1090    const Polyhedron* xlhs = term_to_handle<Polyhedron >(t_lhs, where);
1091    if (Interfaces::is_necessarily_closed_for_interfaces(*xlhs)) {
1092      C_Polyhedron* lhs = term_to_handle<C_Polyhedron >(t_lhs, where);
1093      const C_Polyhedron* rhs = term_to_handle<C_Polyhedron >(t_rhs, where);
1094      PPL_CHECK(lhs);
1095      PPL_CHECK(rhs);
1096      lhs->positive_time_elapse_assign(*rhs);
1097    }
1098    else {
1099      NNC_Polyhedron* lhs = term_to_handle<NNC_Polyhedron >(t_lhs, where);
1100      const NNC_Polyhedron* rhs = term_to_handle<NNC_Polyhedron >(t_rhs, where);
1101      PPL_CHECK(lhs);
1102      PPL_CHECK(rhs);
1103      lhs->positive_time_elapse_assign(*rhs);
1104    }
1105    return PROLOG_SUCCESS;
1106  }
1107  CATCH_ALL;
1108}
1109
1110')
1111
1112m4_define(`ppl_@CLASS@_simplify_using_context_assign_code',
1113  `extern "C" Prolog_foreign_return_type
1114  ppl_@CLASS@_simplify_using_context_assign
1115  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs, Prolog_term_ref t_b) {
1116  static const char* where = "ppl_@CLASS@_simplify_using_context_assign";
1117  try {
1118    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1119    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1120    PPL_CHECK(lhs);
1121    PPL_CHECK(rhs);
1122    Prolog_term_ref t_is_intersect = Prolog_new_term_ref();
1123    Prolog_atom is_intersect
1124      = (lhs->simplify_using_context_assign(*rhs) ? a_true : a_false);
1125    Prolog_put_atom(t_is_intersect, is_intersect);
1126    if (Prolog_unify(t_b, t_is_intersect))
1127      return PROLOG_SUCCESS;
1128  }
1129  CATCH_ALL;
1130}
1131
1132')
1133
1134m4_define(`ppl_@CLASS@_@UB_EXACT@_code',
1135  `extern "C" Prolog_foreign_return_type
1136  ppl_@CLASS@_@UB_EXACT@
1137  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1138  static const char* where = "ppl_@CLASS@_@UB_EXACT@";
1139  try {
1140`m4_ifelse(m4_current_interface, `Polyhedron',
1141  `m4_ub_exact_for_polyhedron_domains',
1142           `m4_ub_exact_for_non_polyhedron_domains')'
1143  }
1144  CATCH_ALL;
1145}
1146
1147')
1148
1149m4_define(`m4_ub_exact_for_polyhedron_domains',
1150`   const Polyhedron* xlhs = term_to_handle<Polyhedron >(t_lhs, where);
1151 if (Interfaces::is_necessarily_closed_for_interfaces(*xlhs)) {
1152     C_Polyhedron* lhs = term_to_handle<C_Polyhedron >(t_lhs, where);
1153     const C_Polyhedron* rhs = term_to_handle<C_Polyhedron >(t_rhs, where);
1154     PPL_CHECK(lhs);
1155     PPL_CHECK(rhs);
1156     return lhs->@UB_EXACT@(*rhs) ? PROLOG_SUCCESS : PROLOG_FAILURE;
1157   }
1158   else {
1159     NNC_Polyhedron* lhs = term_to_handle<NNC_Polyhedron >(t_lhs, where);
1160     const NNC_Polyhedron* rhs = term_to_handle<NNC_Polyhedron >(t_rhs, where);
1161     PPL_CHECK(lhs);
1162     PPL_CHECK(rhs);
1163     return lhs->@UB_EXACT@(*rhs) ? PROLOG_SUCCESS : PROLOG_FAILURE;
1164   }
1165')
1166
1167m4_define(`m4_ub_exact_for_non_polyhedron_domains',
1168`   @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1169    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1170    PPL_CHECK(lhs);
1171    PPL_CHECK(rhs);
1172    return lhs->@UB_EXACT@(*rhs) ? PROLOG_SUCCESS : PROLOG_FAILURE;
1173')
1174
1175m4_define(`ppl_@CLASS@_@AFFIMAGE@_code',
1176  `extern "C" Prolog_foreign_return_type
1177  ppl_@CLASS@_@AFFIMAGE@
1178  (Prolog_term_ref t_ph,
1179   Prolog_term_ref t_v, Prolog_term_ref t_le, Prolog_term_ref t_d) {
1180  const char* where = "ppl_@CLASS@_@AFFIMAGE@/4";
1181  try {
1182    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1183    PPL_CHECK(ph);
1184    ph->@AFFIMAGE@(term_to_Variable(t_v, where),
1185                   build_linear_expression(t_le, where),
1186                   term_to_Coefficient(t_d, where));
1187    return PROLOG_SUCCESS;
1188  }
1189  CATCH_ALL;
1190}
1191
1192')
1193
1194m4_define(`ppl_@CLASS@_generalized_@AFFIMAGE@_with_congruence_code',
1195  `extern "C" Prolog_foreign_return_type
1196  ppl_@CLASS@_generalized_@AFFIMAGE@_with_congruence
1197  (Prolog_term_ref t_ph,
1198   Prolog_term_ref t_v, Prolog_term_ref t_r, Prolog_term_ref t_le,
1199   Prolog_term_ref t_d, Prolog_term_ref t_m) {
1200  static const char* where = "ppl_@CLASS@_generalized_@AFFIMAGE@/6";
1201  try {
1202    @CLASS@* ph = term_to_handle<@CLASS@>(t_ph, where);
1203    PPL_CHECK(ph);
1204    ph->generalized_@AFFIMAGE@(term_to_Variable(t_v, where),
1205                               term_to_relation_symbol(t_r, where),
1206                               build_linear_expression(t_le, where),
1207                               term_to_Coefficient(t_d, where),
1208                               term_to_Coefficient(t_m, where));
1209    return PROLOG_SUCCESS;
1210  }
1211  CATCH_ALL;
1212}
1213
1214')
1215
1216m4_define(`ppl_@CLASS@_generalized_@AFFIMAGE@_code',
1217  `extern "C" Prolog_foreign_return_type
1218  ppl_@CLASS@_generalized_@AFFIMAGE@
1219  (Prolog_term_ref t_ph,
1220   Prolog_term_ref t_v, Prolog_term_ref t_r, Prolog_term_ref t_le,
1221   Prolog_term_ref t_d) {
1222  static const char* where = "ppl_@CLASS@_generalized_@AFFIMAGE@/5";
1223  try {
1224    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1225    PPL_CHECK(ph);
1226    ph->generalized_@AFFIMAGE@(term_to_Variable(t_v, where),
1227                               term_to_relation_symbol(t_r, where),
1228                               build_linear_expression(t_le, where),
1229                               term_to_Coefficient(t_d, where));
1230    return PROLOG_SUCCESS;
1231  }
1232  CATCH_ALL;
1233}
1234
1235')
1236
1237m4_define(`ppl_@CLASS@_generalized_@AFFIMAGE@_lhs_rhs_with_congruence_code',
1238  `extern "C" Prolog_foreign_return_type
1239  ppl_@CLASS@_generalized_@AFFIMAGE@_lhs_rhs_with_congruence
1240  (Prolog_term_ref t_ph,
1241   Prolog_term_ref t_lhs, Prolog_term_ref t_r, Prolog_term_ref t_rhs,
1242   Prolog_term_ref t_m) {
1243  static const char* where = "ppl_@CLASS@_generalized_@AFFIMAGE@_lhs_rhs/5";
1244  try {
1245    @CLASS@* ph = term_to_handle<@CLASS@>(t_ph, where);
1246    PPL_CHECK(ph);
1247    ph->generalized_@AFFIMAGE@(build_linear_expression(t_lhs, where),
1248                               term_to_relation_symbol(t_r, where),
1249                               build_linear_expression(t_rhs, where),
1250                               term_to_Coefficient(t_m, where));
1251    return PROLOG_SUCCESS;
1252  }
1253  CATCH_ALL;
1254}
1255
1256')
1257
1258m4_define(`ppl_@CLASS@_generalized_@AFFIMAGE@_lhs_rhs_code',
1259  `extern "C" Prolog_foreign_return_type
1260  ppl_@CLASS@_generalized_@AFFIMAGE@_lhs_rhs
1261  (Prolog_term_ref t_ph,
1262   Prolog_term_ref t_lhs, Prolog_term_ref t_r, Prolog_term_ref t_rhs) {
1263  static const char* where = "ppl_@CLASS@_generalized_@AFFIMAGE@_lhs_rhs/4";
1264  try {
1265    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1266    PPL_CHECK(ph);
1267    Relation_Symbol r = term_to_relation_symbol(t_r, where);
1268    ph->generalized_@AFFIMAGE@(build_linear_expression(t_lhs, where),
1269                               r,
1270                               build_linear_expression(t_rhs, where));
1271    return PROLOG_SUCCESS;
1272  }
1273  CATCH_ALL;
1274}
1275
1276')
1277
1278m4_define(`ppl_@CLASS@_bounded_@AFFIMAGE@_code',
1279  `extern "C" Prolog_foreign_return_type
1280  ppl_@CLASS@_bounded_@AFFIMAGE@
1281  (Prolog_term_ref t_ph,
1282   Prolog_term_ref t_v, Prolog_term_ref t_lb_le, Prolog_term_ref t_ub_le,
1283   Prolog_term_ref t_d) {
1284  static const char* where = "ppl_@CLASS@_bounded_@AFFIMAGE@/5";
1285  try {
1286    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1287    PPL_CHECK(ph);
1288    ph->bounded_@AFFIMAGE@(term_to_Variable(t_v, where),
1289                           build_linear_expression(t_lb_le, where),
1290                           build_linear_expression(t_ub_le, where),
1291                           term_to_Coefficient(t_d, where));
1292    return PROLOG_SUCCESS;
1293  }
1294  CATCH_ALL;
1295}
1296
1297')
1298
1299m4_define(`ppl_termination_test_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_code',
1300  `extern "C" Prolog_foreign_return_type
1301  ppl_termination_test_@TERMINATION_ID@_@TOPOLOGY@@CLASS@
1302  (Prolog_term_ref t_pset) {
1303  static const char* where = "ppl_termination_test_@TERMINATION_ID@_@TOPOLOGY@@CLASS@/1";
1304  try {
1305    @TOPOLOGY@@CPP_CLASS@* pset = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset, where);
1306    PPL_CHECK(pset);
1307    if (Parma_Polyhedra_Library::termination_test_@TERMINATION_ID@(*pset))
1308      return PROLOG_SUCCESS;
1309  }
1310  CATCH_ALL;
1311}
1312
1313')
1314
1315m4_define(`ppl_termination_test_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2_code',
1316  `extern "C" Prolog_foreign_return_type
1317  ppl_termination_test_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2
1318  (Prolog_term_ref t_pset_before, Prolog_term_ref t_pset_after) {
1319  static const char* where
1320      = "ppl_termination_test_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2/2";
1321  try {
1322    @TOPOLOGY@@CPP_CLASS@* pset_before
1323       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_before, where);
1324    @TOPOLOGY@@CPP_CLASS@* pset_after
1325       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_after, where);
1326    PPL_CHECK(pset_before);
1327    PPL_CHECK(pset_after);
1328    if (Parma_Polyhedra_Library
1329        ::termination_test_@TERMINATION_ID@_2(*pset_before, *pset_after))
1330      return PROLOG_SUCCESS;
1331  }
1332  CATCH_ALL;
1333}
1334
1335')
1336
1337m4_define(`ppl_one_affine_ranking_function_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_code',
1338  `extern "C" Prolog_foreign_return_type
1339  ppl_one_affine_ranking_function_@TERMINATION_ID@_@TOPOLOGY@@CLASS@
1340  (Prolog_term_ref t_pset,
1341   Prolog_term_ref t_g) {
1342  static const char* where
1343     = "ppl_one_affine_ranking_function_@TERMINATION_ID@_@TOPOLOGY@@CLASS@/2";
1344  try {
1345    @TOPOLOGY@@CPP_CLASS@* pset = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset, where);
1346    Generator gg(point());
1347    PPL_CHECK(pset);
1348    if (Parma_Polyhedra_Library
1349        ::one_affine_ranking_function_@TERMINATION_ID@(*pset, gg)
1350        && Prolog_unify(t_g, generator_term(gg)))
1351      return PROLOG_SUCCESS;
1352  }
1353  CATCH_ALL;
1354}
1355
1356')
1357
1358m4_define(`ppl_one_affine_ranking_function_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2_code',
1359  `extern "C" Prolog_foreign_return_type
1360  ppl_one_affine_ranking_function_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2
1361  (Prolog_term_ref t_pset_before,
1362   Prolog_term_ref t_pset_after,
1363   Prolog_term_ref t_g) {
1364  static const char* where
1365     = "ppl_one_affine_ranking_function_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2/3";
1366  try {
1367    @TOPOLOGY@@CPP_CLASS@* pset_before
1368       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_before, where);
1369    @TOPOLOGY@@CPP_CLASS@* pset_after
1370       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_after, where);
1371    Generator gg(point());
1372    PPL_CHECK(pset_before);
1373    PPL_CHECK(pset_after);
1374    if (Parma_Polyhedra_Library
1375        ::one_affine_ranking_function_@TERMINATION_ID@_2(*pset_before,
1376                                                         *pset_after,
1377                                                         gg)
1378        && Prolog_unify(t_g, generator_term(gg)))
1379      return PROLOG_SUCCESS;
1380  }
1381  CATCH_ALL;
1382}
1383
1384')
1385
1386m4_define(`ppl_all_affine_ranking_functions_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_code',
1387  `extern "C" Prolog_foreign_return_type
1388  ppl_all_affine_ranking_functions_@TERMINATION_ID@_@TOPOLOGY@@CLASS@
1389  (Prolog_term_ref t_pset,
1390   Prolog_term_ref t_ph) {
1391  static const char* where =
1392      "ppl_all_affine_ranking_functions_@TERMINATION_ID@_@TOPOLOGY@@CLASS@/2";
1393  try {
1394    @TOPOLOGY@@CPP_CLASS@* pset = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset, where);
1395    PPL_CHECK(pset);
1396    @A_TERMINATION_ID@Polyhedron* ph = new @A_TERMINATION_ID@Polyhedron();
1397    Parma_Polyhedra_Library
1398      ::all_affine_ranking_functions_@TERMINATION_ID@(*pset, *ph);
1399    Prolog_term_ref tmp = Prolog_new_term_ref();
1400    Prolog_put_address(tmp, ph);
1401    if (Prolog_unify(t_ph, tmp)) {
1402      PPL_REGISTER(ph);
1403      return PROLOG_SUCCESS;
1404    }
1405    else
1406      delete ph;
1407  }
1408  CATCH_ALL;
1409}
1410
1411')
1412
1413m4_define(`ppl_all_affine_ranking_functions_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2_code',
1414  `extern "C" Prolog_foreign_return_type
1415  ppl_all_affine_ranking_functions_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2
1416  (Prolog_term_ref t_pset_before,
1417   Prolog_term_ref t_pset_after,
1418   Prolog_term_ref t_ph) {
1419  static const char* where =
1420      "ppl_all_affine_ranking_functions_@TERMINATION_ID@_@TOPOLOGY@@CLASS@_2/3";
1421  try {
1422    @TOPOLOGY@@CPP_CLASS@* pset_before
1423       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_before, where);
1424    @TOPOLOGY@@CPP_CLASS@* pset_after
1425       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_after, where);
1426    PPL_CHECK(pset_before);
1427    PPL_CHECK(pset_after);
1428    @A_TERMINATION_ID@Polyhedron* ph = new @A_TERMINATION_ID@Polyhedron();
1429    Parma_Polyhedra_Library
1430      ::all_affine_ranking_functions_@TERMINATION_ID@_2(*pset_before,
1431                                                        *pset_after,
1432                                                        *ph);
1433    Prolog_term_ref tmp = Prolog_new_term_ref();
1434    Prolog_put_address(tmp, ph);
1435    if (Prolog_unify(t_ph, tmp)) {
1436      PPL_REGISTER(ph);
1437      return PROLOG_SUCCESS;
1438    }
1439    else
1440      delete ph;
1441  }
1442  CATCH_ALL;
1443}
1444
1445')
1446
1447m4_define(`ppl_all_affine_quasi_ranking_functions_MS_@TOPOLOGY@@CLASS@_code',
1448  `extern "C" Prolog_foreign_return_type
1449  ppl_all_affine_quasi_ranking_functions_MS_@TOPOLOGY@@CLASS@
1450  (Prolog_term_ref t_pset,
1451   Prolog_term_ref t_ph_decreasing,
1452   Prolog_term_ref t_ph_bounded) {
1453  static const char* where =
1454      "ppl_all_affine_quasi_ranking_functions_MS_@TOPOLOGY@@CLASS@/3";
1455  try {
1456    @TOPOLOGY@@CPP_CLASS@* pset = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset, where);
1457    PPL_CHECK(pset);
1458    C_Polyhedron* ph_decreasing = new C_Polyhedron();
1459    C_Polyhedron* ph_bounded = new C_Polyhedron();
1460    Parma_Polyhedra_Library
1461      ::all_affine_quasi_ranking_functions_MS(*pset,
1462                                              *ph_decreasing, *ph_bounded);
1463    Prolog_term_ref tmp_decreasing = Prolog_new_term_ref();
1464    Prolog_put_address(tmp_decreasing, ph_decreasing);
1465    Prolog_term_ref tmp_bounded = Prolog_new_term_ref();
1466    Prolog_put_address(tmp_bounded, ph_bounded);
1467    if (Prolog_unify(t_ph_decreasing, tmp_decreasing)
1468        && Prolog_unify(t_ph_bounded, tmp_bounded)) {
1469      PPL_REGISTER(ph_decreasing);
1470      PPL_REGISTER(ph_bounded);
1471      return PROLOG_SUCCESS;
1472    }
1473    else {
1474      delete ph_decreasing;
1475      delete ph_bounded;
1476    }
1477  }
1478  CATCH_ALL;
1479}
1480
1481')
1482
1483m4_define(`ppl_all_affine_quasi_ranking_functions_MS_@TOPOLOGY@@CLASS@_2_code',
1484  `extern "C" Prolog_foreign_return_type
1485  ppl_all_affine_quasi_ranking_functions_MS_@TOPOLOGY@@CLASS@_2
1486  (Prolog_term_ref t_pset_before,
1487   Prolog_term_ref t_pset_after,
1488   Prolog_term_ref t_ph_decreasing,
1489   Prolog_term_ref t_ph_bounded) {
1490  static const char* where =
1491      "ppl_all_affine_quasi_ranking_functions_MS_@TOPOLOGY@@CLASS@_2/4";
1492  try {
1493    @TOPOLOGY@@CPP_CLASS@* pset_before
1494       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_before, where);
1495    @TOPOLOGY@@CPP_CLASS@* pset_after
1496       = term_to_handle<@TOPOLOGY@@CPP_CLASS@ >(t_pset_after, where);
1497    PPL_CHECK(pset_before);
1498    PPL_CHECK(pset_after);
1499    C_Polyhedron* ph_decreasing = new C_Polyhedron();
1500    C_Polyhedron* ph_bounded = new C_Polyhedron();
1501    Parma_Polyhedra_Library
1502      ::all_affine_quasi_ranking_functions_MS_2(*pset_before, *pset_after,
1503                                                *ph_decreasing, *ph_bounded);
1504    Prolog_term_ref tmp_decreasing = Prolog_new_term_ref();
1505    Prolog_put_address(tmp_decreasing, ph_decreasing);
1506    Prolog_term_ref tmp_bounded = Prolog_new_term_ref();
1507    Prolog_put_address(tmp_bounded, ph_bounded);
1508    if (Prolog_unify(t_ph_decreasing, tmp_decreasing)
1509        && Prolog_unify(t_ph_bounded, tmp_bounded)) {
1510      PPL_REGISTER(ph_decreasing);
1511      PPL_REGISTER(ph_bounded);
1512      return PROLOG_SUCCESS;
1513    }
1514    else {
1515      delete ph_decreasing;
1516      delete ph_bounded;
1517    }
1518  }
1519  CATCH_ALL;
1520}
1521
1522')
1523
1524m4_define(`ppl_@CLASS@_@WIDEN@_widening_assign_with_tokens_code',
1525  `extern "C" Prolog_foreign_return_type
1526  ppl_@CLASS@_@WIDEN@_widening_assign_with_tokens
1527  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs,
1528   Prolog_term_ref t_ti, Prolog_term_ref t_to) {
1529  static const char* where = "ppl_@CLASS@_@WIDEN@_widening_assign_with_tokens/4";
1530  try {
1531    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1532    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1533    PPL_CHECK(lhs);
1534    PPL_CHECK(rhs);
1535    unsigned t = term_to_unsigned<unsigned>(t_ti, where);
1536    lhs->@WIDEN@_widening_assign(*rhs, &t);
1537    if (unify_long(t_to, t))
1538      return PROLOG_SUCCESS;
1539  }
1540  CATCH_ALL;
1541}
1542
1543')
1544
1545m4_define(`ppl_@CLASS@_@WIDEN@_widening_assign_code',
1546  `extern "C" Prolog_foreign_return_type
1547  ppl_@CLASS@_@WIDEN@_widening_assign
1548  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1549  static const char* where = "ppl_@CLASS@_@WIDEN@_widening_assign/2";
1550  try {
1551    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1552    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1553    PPL_CHECK(lhs);
1554    PPL_CHECK(rhs);
1555    lhs->@WIDEN@_widening_assign(*rhs, 0);
1556    return PROLOG_SUCCESS;
1557  }
1558  CATCH_ALL;
1559}
1560
1561')
1562
1563m4_define(`ppl_@CLASS@_widening_assign_with_tokens_code',
1564  `extern "C" Prolog_foreign_return_type
1565  ppl_@CLASS@_widening_assign_with_tokens
1566  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs,
1567   Prolog_term_ref t_ti, Prolog_term_ref t_to) {
1568  static const char* where = "ppl_@CLASS@_widening_assign_with_tokens/4";
1569  try {
1570    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1571    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1572    PPL_CHECK(lhs);
1573    PPL_CHECK(rhs);
1574    unsigned t = term_to_unsigned<unsigned>(t_ti, where);
1575    lhs->widening_assign(*rhs, &t);
1576    if (unify_long(t_to, t))
1577      return PROLOG_SUCCESS;
1578  }
1579  CATCH_ALL;
1580}
1581
1582')
1583
1584m4_define(`ppl_@CLASS@_widening_assign_code',
1585  `extern "C" Prolog_foreign_return_type
1586  ppl_@CLASS@_widening_assign
1587  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1588  static const char* where = "ppl_@CLASS@_widening_assign/2";
1589  try {
1590    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1591    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1592    PPL_CHECK(lhs);
1593    PPL_CHECK(rhs);
1594    lhs->widening_assign(*rhs, 0);
1595    return PROLOG_SUCCESS;
1596  }
1597  CATCH_ALL;
1598}
1599
1600')
1601
1602m4_define(`ppl_@CLASS@_@EXTRAPOLATION@_extrapolation_assign_with_tokens_code',
1603  `extern "C" Prolog_foreign_return_type
1604  ppl_@CLASS@_@EXTRAPOLATION@_extrapolation_assign_with_tokens
1605  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs,
1606   Prolog_term_ref t_ti, Prolog_term_ref t_to) {
1607  static const char* where = "ppl_@CLASS@_@EXTRAPOLATION@_extrapolation_assign_with_tokens/4";
1608  try {
1609    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1610    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1611    PPL_CHECK(lhs);
1612    PPL_CHECK(rhs);
1613
1614    unsigned t = term_to_unsigned<unsigned>(t_ti, where);
1615    lhs->@EXTRAPOLATION@_extrapolation_assign(*rhs, &t);
1616    if (unify_long(t_to, t))
1617      return PROLOG_SUCCESS;
1618  }
1619  CATCH_ALL;
1620}
1621
1622')
1623
1624m4_define(`ppl_@CLASS@_@EXTRAPOLATION@_extrapolation_assign_code',
1625  `extern "C" Prolog_foreign_return_type
1626  ppl_@CLASS@_@EXTRAPOLATION@_extrapolation_assign
1627  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1628  static const char* where = "ppl_@CLASS@_@EXTRAPOLATION@_extrapolation_assign/2";
1629  try {
1630    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1631    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1632    PPL_CHECK(lhs);
1633    PPL_CHECK(rhs);
1634
1635    lhs->@EXTRAPOLATION@_extrapolation_assign(*rhs, 0);
1636    return PROLOG_SUCCESS;
1637  }
1638  CATCH_ALL;
1639}
1640
1641')
1642
1643m4_define(`ppl_@CLASS@_@EXTRAPOLATION@_narrowing_assign_code',
1644  `extern "C" Prolog_foreign_return_type
1645  ppl_@CLASS@_@EXTRAPOLATION@_narrowing_assign
1646  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1647  static const char* where = "ppl_@CLASS@_@EXTRAPOLATION@_narrowing_assign/2";
1648  try {
1649    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1650    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1651    PPL_CHECK(lhs);
1652    PPL_CHECK(rhs);
1653    lhs->@EXTRAPOLATION@_narrowing_assign(*rhs);
1654    return PROLOG_SUCCESS;
1655  }
1656  CATCH_ALL;
1657}
1658
1659')
1660
1661
1662dnl FIXME: This code is redundant as there is no options for tokens
1663dnl        in the current C++ code.
1664m4_define(`ppl_@CLASS@_BHZ03_@A_DISJUNCT_WIDEN@_@DISJUNCT_WIDEN@_widening_assign_with_tokens_code',
1665  `extern "C" Prolog_foreign_return_type
1666  ppl_@CLASS@_BHZ03_@A_DISJUNCT_WIDEN@_@DISJUNCT_WIDEN@_widening_assign_with_tokens(
1667                                                                                      Prolog_term_ref t_lhs, Prolog_term_ref t_rhs,
1668                                                                                      Prolog_term_ref t_ti, Prolog_term_ref t_to) {
1669  static const char* where = "ppl_@CLASS@_BHZ03_@A_DISJUNCT_WIDEN@_@DISJUNCT_WIDEN@_widening_assign_with_tokens/4";
1670  try {
1671    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1672    PPL_CHECK(lhs);
1673    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1674    PPL_CHECK(rhs);
1675
1676    unsigned t = term_to_unsigned<unsigned>(t_ti, where);
1677    lhs->BHZ03_widening_assign<@A_DISJUNCT_WIDEN@_Certificate>
1678      (*rhs,
1679       widen_fun_ref(&@DISJUNCT_TOPOLOGY@@A_DISJUNCT@::@DISJUNCT_WIDEN@_widening_assign),
1680       &t);
1681    if (unify_long(t_to, t))
1682      return PROLOG_SUCCESS;
1683  }
1684  CATCH_ALL;
1685}
1686
1687')
1688
1689m4_define(`ppl_@CLASS@_BHZ03_@A_DISJUNCT_WIDEN@_@DISJUNCT_WIDEN@_widening_assign_code',
1690  `extern "C" Prolog_foreign_return_type
1691
1692  ppl_@CLASS@_BHZ03_@A_DISJUNCT_WIDEN@_@DISJUNCT_WIDEN@_widening_assign(
1693                                                                          Prolog_term_ref t_lhs, Prolog_term_ref t_rhs) {
1694  static const char* where = "ppl_@CLASS@_BHZ03_@A_DISJUNCT_WIDEN@_@DISJUNCT_WIDEN@_widening_assign/2";
1695  try {
1696    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1697    PPL_CHECK(lhs);
1698    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1699    PPL_CHECK(rhs);
1700
1701    lhs->BHZ03_widening_assign<@A_DISJUNCT_WIDEN@_Certificate>
1702      (*rhs,
1703       widen_fun_ref(&@DISJUNCT_TOPOLOGY@@A_DISJUNCT@::@DISJUNCT_WIDEN@_widening_assign));
1704    return PROLOG_SUCCESS;
1705  }
1706  CATCH_ALL;
1707}
1708
1709')
1710
1711m4_define(`ppl_@CLASS@_BGP99_@DISJUNCT_WIDEN@_extrapolation_assign_code',
1712  `extern "C" Prolog_foreign_return_type
1713
1714  ppl_@CLASS@_BGP99_@DISJUNCT_WIDEN@_extrapolation_assign(
1715                                                          Prolog_term_ref t_lhs, Prolog_term_ref t_rhs,
1716                                                          Prolog_term_ref t_d) {
1717  static const char* where = "ppl_@CLASS@_BGP99_@DISJUNCT_WIDEN@_extrapolation_assign/3";
1718  try {
1719    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1720    PPL_CHECK(lhs);
1721    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1722    PPL_CHECK(rhs);
1723
1724    lhs->BGP99_extrapolation_assign
1725      (*rhs,
1726       widen_fun_ref(&@DISJUNCT_TOPOLOGY@@A_DISJUNCT@::@DISJUNCT_WIDEN@_widening_assign),
1727       term_to_unsigned<unsigned>(t_d, where));
1728    return PROLOG_SUCCESS;
1729  }
1730  CATCH_ALL;
1731}
1732
1733')
1734
1735m4_define(`ppl_@CLASS@_BGP99_@DISJUNCT_EXTRAPOLATION@_extrapolation_assign_code',
1736  `extern "C" Prolog_foreign_return_type
1737
1738  ppl_@CLASS@_BGP99_@DISJUNCT_EXTRAPOLATION@_extrapolation_assign(
1739                                                                  Prolog_term_ref t_lhs, Prolog_term_ref t_rhs,
1740                                                                  Prolog_term_ref t_d) {
1741  static const char* where = "ppl_@CLASS@_BGP99_@DISJUNCT_EXTRAPOLATION@_extrapolation_assign/3";
1742  try {
1743    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1744    PPL_CHECK(lhs);
1745    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1746    PPL_CHECK(rhs);
1747
1748    lhs->BGP99_extrapolation_assign
1749      (*rhs,
1750       widen_fun_ref(&@DISJUNCT_TOPOLOGY@@A_DISJUNCT@::@DISJUNCT_EXTRAPOLATION@_extrapolation_assign),
1751       term_to_unsigned<unsigned>(t_d, where));
1752    return PROLOG_SUCCESS;
1753  }
1754  CATCH_ALL;
1755}
1756
1757')
1758
1759m4_define(`ppl_@CLASS@_@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign_with_tokens_code',
1760  `extern "C" Prolog_foreign_return_type
1761  ppl_@CLASS@_@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign_with_tokens
1762  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs, Prolog_term_ref t_clist,
1763   Prolog_term_ref t_ti, Prolog_term_ref t_to) {
1764  static const char* where = "ppl_@CLASS@_@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign_with_tokens/5";
1765  try {
1766    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1767    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1768    PPL_CHECK(lhs);
1769    PPL_CHECK(rhs);
1770    @!CONSTRAINER@_System cs;
1771    Prolog_term_ref c = Prolog_new_term_ref();
1772
1773    while (Prolog_is_cons(t_clist)) {
1774      Prolog_get_cons(t_clist, c, t_clist);
1775      cs.insert(build_@CONSTRAINER@(c, where));
1776    }
1777
1778    // Check the list is properly terminated.
1779    check_nil_terminating(t_clist, where);
1780
1781    unsigned t = term_to_unsigned<unsigned>(t_ti, where);
1782    lhs->@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign(*rhs, cs, &t);
1783    if (unify_long(t_to, t))
1784      return PROLOG_SUCCESS;
1785  }
1786  CATCH_ALL;
1787}
1788
1789')
1790
1791m4_define(`ppl_@CLASS@_@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign_code',
1792  `extern "C" Prolog_foreign_return_type
1793  ppl_@CLASS@_@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign
1794  (Prolog_term_ref t_lhs, Prolog_term_ref t_rhs, Prolog_term_ref t_clist) {
1795  static const char* where = "ppl_@CLASS@_@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign/3";
1796  try {
1797    @CPP_CLASS@* lhs = term_to_handle<@CPP_CLASS@ >(t_lhs, where);
1798    const @CPP_CLASS@* rhs = term_to_handle<@CPP_CLASS@ >(t_rhs, where);
1799    PPL_CHECK(lhs);
1800    PPL_CHECK(rhs);
1801    @!CONSTRAINER@_System cs;
1802    Prolog_term_ref c = Prolog_new_term_ref();
1803
1804    while (Prolog_is_cons(t_clist)) {
1805      Prolog_get_cons(t_clist, c, t_clist);
1806      cs.insert(build_@CONSTRAINER@(c, where));
1807    }
1808
1809    // Check the list is properly terminated.
1810    check_nil_terminating(t_clist, where);
1811
1812    lhs->@LIMITEDBOUNDED@_@WIDENEXPN@_extrapolation_assign(*rhs, cs, 0);
1813    return PROLOG_SUCCESS;
1814  }
1815  CATCH_ALL;
1816}
1817
1818')
1819
1820m4_define(`ppl_@CLASS@_add_space_dimensions_@EMBEDPROJECT@_code',
1821  `extern "C" Prolog_foreign_return_type
1822  ppl_@CLASS@_add_space_dimensions_@EMBEDPROJECT@
1823  (Prolog_term_ref t_ph, Prolog_term_ref t_nnd) {
1824  static const char* where = "ppl_@CLASS@_add_space_dimensions_@EMBEDPROJECT@/2";
1825  try {
1826    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1827    PPL_CHECK(ph);
1828    dimension_type d = term_to_unsigned<dimension_type>(t_nnd, where);
1829    ph->add_space_dimensions_@EMBEDPROJECT@(d);
1830    return PROLOG_SUCCESS;
1831  }
1832  CATCH_ALL;
1833}
1834
1835')
1836
1837m4_define(`ppl_@CLASS@_remove_space_dimensions_code',
1838  `extern "C" Prolog_foreign_return_type
1839  ppl_@CLASS@_remove_space_dimensions
1840  (Prolog_term_ref t_ph, Prolog_term_ref t_vlist) {
1841  static const char* where = "ppl_@CLASS@_remove_space_dimensions/2";
1842  try {
1843    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1844    PPL_CHECK(ph);
1845    Variables_Set dead_variables;
1846    Prolog_term_ref v = Prolog_new_term_ref();
1847    while (Prolog_is_cons(t_vlist)) {
1848      Prolog_get_cons(t_vlist, v, t_vlist);
1849      dead_variables.insert(term_to_Variable(v, where).id());
1850    }
1851
1852    // Check the list is properly terminated.
1853    check_nil_terminating(t_vlist, where);
1854
1855    ph->remove_space_dimensions(dead_variables);
1856    return PROLOG_SUCCESS;
1857  }
1858  CATCH_ALL;
1859}
1860
1861')
1862
1863m4_define(`ppl_@CLASS@_remove_higher_space_dimensions_code',
1864  `extern "C" Prolog_foreign_return_type
1865  ppl_@CLASS@_remove_higher_space_dimensions
1866  (Prolog_term_ref t_ph, Prolog_term_ref t_nd) {
1867  static const char* where = "ppl_@CLASS@_remove_higher_space_dimensions/2";
1868  try {
1869    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1870    PPL_CHECK(ph);
1871    ph->remove_higher_space_dimensions(term_to_unsigned<dimension_type>(t_nd,
1872                                                                        where));
1873    return PROLOG_SUCCESS;
1874  }
1875  CATCH_ALL;
1876}
1877
1878')
1879
1880m4_define(`ppl_@CLASS@_expand_space_dimension_code',
1881  `extern "C" Prolog_foreign_return_type
1882  ppl_@CLASS@_expand_space_dimension
1883  (Prolog_term_ref t_ph, Prolog_term_ref t_v, Prolog_term_ref t_nd) {
1884  static const char* where = "ppl_@CLASS@_expand_space_dimension/3";
1885  try {
1886    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1887    PPL_CHECK(ph);
1888    ph->expand_space_dimension(term_to_Variable(t_v, where),
1889                               term_to_unsigned<dimension_type>(t_nd, where));
1890    return PROLOG_SUCCESS;
1891  }
1892  CATCH_ALL;
1893}
1894
1895')
1896
1897m4_define(`ppl_@CLASS@_fold_space_dimensions_code',
1898  `extern "C" Prolog_foreign_return_type
1899  ppl_@CLASS@_fold_space_dimensions
1900  (Prolog_term_ref t_ph, Prolog_term_ref t_vlist, Prolog_term_ref t_v) {
1901  static const char* where = "ppl_@CLASS@_fold_space_dimensions/3";
1902  try {
1903    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1904    PPL_CHECK(ph);
1905    Variables_Set fold_variables;
1906    Prolog_term_ref v = Prolog_new_term_ref();
1907    while (Prolog_is_cons(t_vlist)) {
1908      Prolog_get_cons(t_vlist, v, t_vlist);
1909      fold_variables.insert(term_to_Variable(v, where).id());
1910    }
1911
1912    // Check the list is properly terminated.
1913    check_nil_terminating(t_vlist, where);
1914
1915    ph->fold_space_dimensions(fold_variables, term_to_Variable(t_v, where));
1916    return PROLOG_SUCCESS;
1917  }
1918  CATCH_ALL;
1919}
1920
1921')
1922
1923m4_define(`ppl_@CLASS@_map_space_dimensions_code',
1924  `extern "C" Prolog_foreign_return_type
1925  ppl_@CLASS@_map_space_dimensions
1926  (Prolog_term_ref t_ph, Prolog_term_ref t_pfunc) {
1927  static const char* where = "ppl_@CLASS@_map_space_dimensions/2";
1928  try {
1929    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1930    dimension_type space_dim = ph->space_dimension();
1931    PPL_CHECK(ph);
1932    Partial_Function pfunc;
1933    Prolog_term_ref t_pair = Prolog_new_term_ref();
1934    while (Prolog_is_cons(t_pfunc)) {
1935      Prolog_get_cons(t_pfunc, t_pair, t_pfunc);
1936      Prolog_atom functor;
1937      int arity;
1938      Prolog_get_compound_name_arity(t_pair, &functor, &arity);
1939      if (arity != 2 || functor != a_minus)
1940        return PROLOG_FAILURE;
1941      Prolog_term_ref t_i = Prolog_new_term_ref();
1942      Prolog_term_ref t_j = Prolog_new_term_ref();
1943      Prolog_get_arg(1, t_pair, t_i);
1944      Prolog_get_arg(2, t_pair, t_j);
1945      dimension_type i = term_to_Variable(t_i, where).id();
1946      dimension_type j = term_to_Variable(t_j, where).id();
1947      if (i >= space_dim)
1948        return PROLOG_FAILURE;
1949      pfunc.insert(i, j);
1950    }
1951
1952    // Check the list is properly terminated.
1953    check_nil_terminating(t_pfunc, where);
1954
1955    ph->map_space_dimensions(pfunc);
1956    return PROLOG_SUCCESS;
1957  }
1958  CATCH_ALL;
1959}
1960
1961')
1962
1963m4_define(`ppl_@CLASS@_drop_some_non_integer_points_code',
1964  `extern "C" Prolog_foreign_return_type
1965  ppl_@CLASS@_drop_some_non_integer_points
1966  (Prolog_term_ref t_ph, Prolog_term_ref t_cc) {
1967  static const char* where = "ppl_@CLASS@_drop_some_non_integer_points/2";
1968  try {
1969    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1970    PPL_CHECK(ph);
1971    Prolog_atom p_cc = term_to_complexity_class(t_cc, where);
1972    Complexity_Class cc;
1973    if (p_cc == a_polynomial)
1974      cc = POLYNOMIAL_COMPLEXITY;
1975    else if (p_cc == a_simplex)
1976      cc = SIMPLEX_COMPLEXITY;
1977    else
1978      cc = ANY_COMPLEXITY;
1979
1980    ph->drop_some_non_integer_points(cc);
1981    return PROLOG_SUCCESS;
1982  }
1983  CATCH_ALL;
1984}
1985
1986')
1987
1988m4_define(`ppl_@CLASS@_drop_some_non_integer_points_2_code',
1989  `extern "C" Prolog_foreign_return_type
1990  ppl_@CLASS@_drop_some_non_integer_points_2
1991  (Prolog_term_ref t_ph, Prolog_term_ref t_vlist, Prolog_term_ref t_cc) {
1992  static const char* where = "ppl_@CLASS@_drop_some_non_integer_points_2/3";
1993  try {
1994    @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
1995    PPL_CHECK(ph);
1996    Variables_Set variables;
1997    Prolog_term_ref v = Prolog_new_term_ref();
1998    while (Prolog_is_cons(t_vlist)) {
1999      Prolog_get_cons(t_vlist, v, t_vlist);
2000      variables.insert(term_to_Variable(v, where).id());
2001    }
2002
2003    // Check the list is properly terminated.
2004    check_nil_terminating(t_vlist, where);
2005
2006    Prolog_atom p_cc = term_to_complexity_class(t_cc, where);
2007    Complexity_Class cc;
2008    if (p_cc == a_polynomial)
2009      cc = POLYNOMIAL_COMPLEXITY;
2010    else if (p_cc == a_simplex)
2011      cc = SIMPLEX_COMPLEXITY;
2012    else
2013      cc = ANY_COMPLEXITY;
2014
2015    ph->drop_some_non_integer_points(variables, cc);
2016    return PROLOG_SUCCESS;
2017  }
2018  CATCH_ALL;
2019}
2020
2021')
2022
2023m4_define(`ppl_@CLASS@_ascii_dump_code',
2024  `extern "C" Prolog_foreign_return_type
2025  ppl_@CLASS@_ascii_dump
2026  (Prolog_term_ref t_ph) {
2027  static const char* where = "ppl_@CLASS@_ascii_dump/1";
2028  try {
2029    const @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
2030    PPL_CHECK(ph);
2031    ph->ascii_dump(std::cout);
2032    return PROLOG_SUCCESS;
2033  }
2034  CATCH_ALL;
2035}
2036
2037')
2038
2039m4_define(`ppl_@CLASS@_@MEMBYTES@_code',
2040  `extern "C" Prolog_foreign_return_type
2041  ppl_@CLASS@_@MEMBYTES@(Prolog_term_ref t_pps,
2042                         Prolog_term_ref t_m) {
2043  static const char* where = "ppl_@CLASS@_@MEMBYTES@/2";
2044  try {
2045    @CPP_CLASS@* pps = term_to_handle<@CPP_CLASS@ >(t_pps, where);
2046    PPL_CHECK(pps);
2047
2048    if (unify_ulong(t_m, pps->@MEMBYTES@()))
2049      return PROLOG_SUCCESS;
2050  }
2051  CATCH_ALL;
2052}
2053
2054')
2055
2056m4_define(`ppl_@CLASS@_wrap_assign_code',
2057  `extern "C" Prolog_foreign_return_type
2058  ppl_@CLASS@_wrap_assign
2059     (Prolog_term_ref t_ph,
2060      Prolog_term_ref t_vars,
2061      Prolog_term_ref t_w,
2062      Prolog_term_ref t_r,
2063      Prolog_term_ref t_o,
2064      Prolog_term_ref t_cs,
2065      Prolog_term_ref t_complexity,
2066      Prolog_term_ref t_ind) {
2067  static const char* where = "ppl_@CLASS@_wrap_assign/8";
2068  try {
2069    @CPP_CLASS@* pph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
2070
2071    Variables_Set vars;
2072    Prolog_term_ref v = Prolog_new_term_ref();
2073    while (Prolog_is_cons(t_vars)) {
2074      Prolog_get_cons(t_vars, v, t_vars);
2075      vars.insert(term_to_Variable(v, where).id());
2076    }
2077    // Check the list is properly terminated.
2078    check_nil_terminating(t_vars, where);
2079
2080    Prolog_atom p_w = term_to_bounded_integer_type_width(t_w, where);
2081    Bounded_Integer_Type_Width w;
2082    if (p_w == a_bits_8)
2083      w = BITS_8;
2084    else if (p_w == a_bits_16)
2085      w = BITS_16;
2086    else if (p_w == a_bits_32)
2087      w = BITS_32;
2088    else if (p_w == a_bits_64)
2089      w = BITS_64;
2090    else
2091      w = BITS_128;
2092
2093    Prolog_atom p_r = term_to_bounded_integer_type_representation(t_r, where);
2094    Bounded_Integer_Type_Representation r;
2095    if (p_r == a_unsigned)
2096      r = UNSIGNED;
2097    else
2098      r = SIGNED_2_COMPLEMENT;
2099    Prolog_atom p_o = term_to_bounded_integer_type_overflow(t_o, where);
2100    Bounded_Integer_Type_Overflow o;
2101    if (p_o == a_overflow_wraps)
2102      o = OVERFLOW_WRAPS;
2103    else if (p_o == a_overflow_undefined)
2104      o = OVERFLOW_UNDEFINED;
2105    else
2106      o = OVERFLOW_IMPOSSIBLE;
2107
2108    Constraint_System cs;
2109    Prolog_term_ref c = Prolog_new_term_ref();
2110    while (Prolog_is_cons(t_cs)) {
2111      Prolog_get_cons(t_cs, c, t_cs);
2112      cs.insert(build_constraint(c, where));
2113    }
2114    // Check the list is properly terminated.
2115    check_nil_terminating(t_cs, where);
2116
2117    unsigned complexity = term_to_unsigned<unsigned>(t_complexity, where);
2118
2119    Prolog_atom p_ind = term_to_boolean(t_ind, where);
2120    bool ind = (p_ind == a_true) ? true : false;
2121
2122    pph->wrap_assign(vars, w, r, o, &cs, complexity, ind);
2123    return PROLOG_SUCCESS;
2124  }
2125  CATCH_ALL;
2126 }
2127
2128')
2129
2130m4_define(`ppl_@CLASS@_frequency_code',
2131  `extern "C" Prolog_foreign_return_type
2132  ppl_@CLASS@_frequency(Prolog_term_ref t_ph,
2133                        Prolog_term_ref t_le_expr,
2134                        Prolog_term_ref t_freqn, Prolog_term_ref t_freqd,
2135                        Prolog_term_ref t_valn, Prolog_term_ref t_vald) {
2136  static const char* where = "ppl_@CLASS@_frequency/6";
2137  try {
2138    const @CPP_CLASS@* ph = term_to_handle<@CPP_CLASS@ >(t_ph, where);
2139    PPL_CHECK(ph);
2140    const Linear_Expression le = build_linear_expression(t_le_expr, where);
2141    PPL_DIRTY_TEMP_COEFFICIENT(freqn);
2142    PPL_DIRTY_TEMP_COEFFICIENT(freqd);
2143    PPL_DIRTY_TEMP_COEFFICIENT(valn);
2144    PPL_DIRTY_TEMP_COEFFICIENT(vald);
2145    if (ph->frequency(le, freqn, freqd, valn, vald)) {
2146      if (Prolog_unify_Coefficient(t_freqn, freqn)
2147          && Prolog_unify_Coefficient(t_freqd, freqd)
2148          && Prolog_unify_Coefficient(t_valn, valn)
2149          && Prolog_unify_Coefficient(t_vald, vald))
2150        return PROLOG_SUCCESS;
2151    }
2152  }
2153  CATCH_ALL;
2154}
2155
2156')
2157