1/* Various tests on the Prolog interface.
2   Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3   Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5This file is part of the Parma Polyhedra Library (PPL).
6
7The PPL is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12The PPL is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software Foundation,
19Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21For the most up-to-date information see the Parma Polyhedra Library
22site: http://bugseng.com/products/ppl/ . */
23
24
25% noisy(F)
26% When F = 1, a message is displayed if a time out occurs
27% when running the `timeout'` predicate.
28% Also, the values of the PPL versions and banner are displayed.
29% When F = 0, no 'time out' message or versions are displayed.
30% When F = 2, if a test fails and the backtracking returns to a polyhedron
31% constructor, the caught error will cause the constraint and generator systems
32% for the polyhedron to be displayed.
33% noisy/1 can be reset by calling make_noisy/0 or make_quiet/0.
34
35:- dynamic(noisy/1).
36
37% check_all/0
38% This executes all the test predicates which, together, check all
39% the ppl interface predicates.
40
41check_all :-
42   (noisy(_) -> true ; make_quiet),
43   list_groups(Groups),
44   catch(run_all(Groups), Exception,
45         (print_exception_term(Exception), fail)).
46
47% check_quiet/0
48% This also executes all the test predicates with no output.
49
50check_quiet :-
51   make_quiet,
52   check_all.
53
54% check_noisy/0
55% check_extra_noisy/0
56%
57% These also execute all the test predicates but also outputs
58% information including the banner, version numbers and expected
59% output from the exception tests.
60
61check_noisy :-
62   make_noisy,
63   check_all.
64
65check_extra_noisy :-
66   make_extra_noisy,
67   check_all.
68
69% run_all/1
70% This executes all the given list of tests, catching any exceptions.
71% If any test fails then an error message is output and then it fails.
72
73run_all([Group|Groups]):-
74   ppl_initialize,
75   (catch(run_one(Group), Exception, run_exception(Group, Exception)) ->
76       ppl_finalize,
77       run_all(Groups)
78   ;
79       run_fail(Group)
80   ).
81run_all([]).
82
83% run_fail/1
84% This is used when a test in run_all/1 fails.
85% A message is output saying which group of tests has failed;
86% then it finalizes the ppl and fails.
87
88run_fail(Group) :-
89   group_predicates(Group, Predicates),
90   prolog_system(System),
91   error_message(['Error occurred while performing test', Group,
92                  'which checks predicates:', Predicates]),
93   error_message(['Prolog interface checks failed on', System,
94                  'Prolog.']),
95   ppl_finalize,
96   fail.
97
98% run_exception/2
99% This is used when a test in run_all/1 causes an exception to be thrown.
100% A message is output saying which group of tests was being run when
101% the exception was thrown and then it fails.
102
103run_exception(Group, Exception) :-
104        group_predicates(Group, Predicates),
105        (Exception = ppl_overflow_error(_) ->
106            Kind = 'Overflow exception'
107        ;
108            Kind = 'Exception'
109        ),
110        prolog_system(System),
111        display_message([Kind, 'occurred while performing test ', Group,
112                        'which checks predicates ', nl, Predicates]),
113        display_message(['Prolog interface checks failed on', System,
114                  'Prolog.']),
115        print_exception_term(Exception),
116        % Do fail for all but overflow exceptions.
117        Exception = ppl_overflow_error(_).
118
119% run_one/1
120% Runs the named group of tests.
121
122% Tests predicates that return PPL version information and the PPL banner.
123% If noisy(0) holds, there is no output but if not,
124% all the versions are printed and the banner is pretty printed.
125run_one(all_versions_and_banner) :-
126  \+ ppl_version_major(-1),
127  ppl_version_major(Vmajor),
128  ppl_version_minor(Vminor),
129  ppl_version_revision(Vrevision),
130  ppl_version_beta(Vbeta),
131  ppl_version(V),
132  ppl_banner(B),
133  (noisy(0) -> true ;
134     (
135      nl,
136      write('Version major is '), write(Vmajor), nl,
137      write('Version minor is '), write(Vminor), nl,
138      write('Version revision is '), write(Vrevision), nl,
139      write('Version beta is '), write(Vbeta), nl,
140      write('Version is '), write(V), nl,
141      banner_pp(B), nl
142     )
143  ).
144
145% Tests predicates that return the maximum allowed dimension and coefficients.
146% If noisy(0) holds, there is no output but if not, the maximums/minimums
147% are printed.
148run_one(numeric_bounds) :-
149  max_dimension,
150  coefficient_bounds,
151  set_restore_rounding,
152  set_restore_irrational_precision.
153
154run_one(new_polyhedron_from_dimension) :-
155  new_polyhedron_from_dim.
156
157run_one(new_polyhedron_from_polyhedron) :-
158  new_polyhedron_from_polyhedron.
159
160run_one(new_polyhedron_from_representations) :-
161  new_polyhedron_from_cons,
162  new_polyhedron_from_gens.
163
164run_one(swap_polyhedra) :-
165  swap.
166
167run_one(polyhedron_dimension) :-
168   space,
169   affine_dim,
170   constrains,
171   unconstrain_space_dimension,
172   unconstrain_space_dimensions.
173
174run_one(basic_operators) :-
175   inters_assign,
176   polyhull_assign,
177   polydiff_assign,
178   time_elapse,
179   top_close_assign.
180
181run_one(add_to_system) :-
182   add_con,
183   add_gen,
184   add_cons,
185   add_gens.
186
187run_one(revise_dimensions) :-
188   project,
189   embed,
190   conc_assign,
191   remove_dim,
192   remove_high_dim,
193   expand_dim,
194   map_dim,
195   fold_dims.
196
197run_one(transform_polyhedron) :-
198   affine_image,
199   affine_preimage,
200   bounded_affine_image,
201   bounded_affine_preimage,
202   affine_image_gen,
203   affine_preimage_gen,
204   affine_image_genlr,
205   affine_preimage_genlr.
206
207run_one(extrapolation_operators) :-
208   widen_BHRZ03,
209   widen_BHRZ03_with_tokens,
210   lim_extrapolate_BHRZ03,
211   lim_extrapolate_BHRZ03_with_tokens,
212   bound_extrapolate_BHRZ03,
213   bound_extrapolate_BHRZ03_with_tokens,
214   widen_H79,
215   widen_H79_with_tokens,
216   lim_extrapolate_H79,
217   lim_extrapolate_H79_with_tokens,
218   bound_extrapolate_H79,
219   bound_extrapolate_H79_with_tokens.
220
221run_one(get_system) :-
222   get_cons,
223   get_min_cons,
224   get_gens,
225   get_min_gens.
226
227run_one(check_polyhedron) :-
228   rel_cons,
229   rel_gens,
230   checks,
231   bounds_from_above,
232   bounds_from_below.
233
234run_one(minmax_polyhedron) :-
235   maximize,
236   minimize,
237   maximize_with_point,
238   minimize_with_point.
239
240run_one(compare_polyhedra) :-
241   contains,
242   strict_contains,
243   disjoint_from,
244   equals,
245   ok.
246
247run_one(catch_time) :-
248   time_out.
249
250run_one(mip_problem) :-
251   mip_problem.
252
253run_one(pip_problem) :-
254   pip_problem.
255
256% Checks how the PPL Prolog system performs with large integers
257% XSB has problems with large numbers - hence tests for XSB disallowed.
258% We catch the exception if it is caused by integer overflow in C++
259% and suppress output as this is expected when C++ uses checked_integers.
260run_one(large_integers) :-
261   prolog_system(Prolog_System),
262   (Prolog_System \== 'XSB' ->
263     catch(large_integers, ppl_overflow_error(Cause),
264        check_exception_term(ppl_overflow_error(Cause)))
265   ;
266     true
267   ).
268
269% Checks the handling of exceptions.
270run_one(handle_exceptions) :-
271   exceptions.
272
273%%%%%%%%%%%%%%%%% numeric bounds %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274
275max_dimension :-
276  ppl_max_space_dimension(M),
277  (noisy(0) -> true ;
278     display_message(['Maximum possible dimension is', M, nl])
279  ).
280
281% coefficient_bounds/0
282% This is mainly to check ppl_Coefficient_is_bounded/0,
283% ppl_Coefficient_max/1, ppl_Coefficient_min/1.
284% But it has to catch the case when the numeric bounds in the
285% prolog system are smaller than any finite bounds in C++
286% As the test does not know the configuration, all that can be tested
287% here is that the results are consistent and the bounds are
288% in a list of possible bounds.
289
290coefficient_bounds :-
291    (pl_check_prolog_flag(bounded, true) ->
292     (pl_check_prolog_flag(max_integer, PLMax),
293      pl_check_prolog_flag(min_integer, PLMin))
294   ;
295     PLMax = 0, PLMin = 0
296  ),
297  (ppl_Coefficient_is_bounded ->
298     (cpp_bounded_values(Max, Min) -> true
299      ;
300       (Max = PLMax, Min = PLMin)
301     )
302  ;
303     (cpp_unbounded_check, Max = PLMax, Min = PLMin)
304  ),
305  (noisy(0) -> true ;
306     display_message(['Maximum possible coefficient is', Max, nl]),
307     display_message(['Minimum possible coefficient is', Min, nl])
308  ).
309
310cpp_unbounded_check :-
311  \+ ppl_Coefficient_max(_),
312  \+ ppl_Coefficient_min(_).
313
314cpp_bounded_values(Max, Min) :-
315  ppl_Coefficient_max(Max),
316  ppl_Coefficient_min(Min).
317
318set_restore_rounding :-
319  ppl_set_rounding_for_PPL,
320  ppl_restore_pre_PPL_rounding.
321
322set_restore_irrational_precision :-
323  ppl_irrational_precision(Default),
324  Default == 128,
325  Non_Default = 100,
326  ppl_set_irrational_precision(Non_Default),
327  ppl_irrational_precision(Changed),
328  Changed == Non_Default,
329  ppl_set_irrational_precision(Default),
330  ppl_irrational_precision(Restored),
331  Restored == Default.
332
333%%%%%%%%%%%%%%%%% New Polyhedron %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334
335% Note that throughout the tests, all "new_Polyhedron_from_...(...,P)" calls
336% are made in such a way that, if the test fails, P is deleted.
337% This is done by using special "clean_new_Polyhedron_from_...(...,P)"
338% forms of the predicates that are defined later.
339%
340% As we also delete P on success of the test, to prevent trying to
341% delete P again when a later test fails, we always have a cut before these
342% in-line calls to ppl_Polyhedron_delete(P).
343
344% Tests new_C_Polyhedron_from_space_dimension/3,
345%       new_NNC_Polyhedron_from_space_dimension/3 and
346%       ppl_delete_Polyhedron/1.
347new_polyhedron_from_dim :-
348  new_polyhedron_from_dim(c, universe),
349  new_polyhedron_from_dim(nnc, universe),
350  new_polyhedron_from_dim(c, empty),
351  new_polyhedron_from_dim(nnc, empty).
352
353% This also uses ppl_Polyhedron_is_universe/1
354% and ppl_Polyhedron_is_empty.
355new_polyhedron_from_dim(T, Universe_Or_Empty) :-
356  \+ clean_ppl_new_Polyhedron_from_space_dimension(T, 3, Universe_Or_Empty, 0),
357  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, Universe_Or_Empty, P),
358  (Universe_Or_Empty = universe ->
359      (ppl_Polyhedron_is_universe(P),
360      \+ ppl_Polyhedron_is_empty(P))
361   ;
362      (ppl_Polyhedron_is_empty(P),
363      \+ ppl_Polyhedron_is_universe(P))
364  ),
365  !,
366  ppl_delete_Polyhedron(P).
367
368% Tests ppl_new_C_Polyhedron_from_C_Polyhedron/2,
369%       ppl_new_C_Polyhedron_from_NNC_Polyhedron/2,
370%       ppl_new_NNC_Polyhedron_from_C_Polyhedron/2, and
371%       ppl_new_NNC_Polyhedron_from_NNC_Polyhedron/2,
372new_polyhedron_from_polyhedron :-
373  new_polyhedron_from_polyhedron(c, c),
374  new_polyhedron_from_polyhedron(nnc, nnc),
375  new_polyhedron_from_polyhedron(c, nnc),
376  new_polyhedron_from_polyhedron(nnc, c).
377
378% This also uses ppl_new_Polyhedron_from_constraints/3 and
379% ppl_Polyhedron_equals_Polyhedron/2.
380new_polyhedron_from_polyhedron(T1, T2) :-
381  clean_ppl_new_Polyhedron_from_space_dimension(T1, 3, universe, P1),
382  \+ clean_ppl_new_Polyhedron_from_Polyhedron(T1, P1, T2, 0),
383  clean_ppl_new_Polyhedron_from_Polyhedron(T1, P1, T2, P2),
384  clean_ppl_new_Polyhedron_from_Polyhedron(T2, P2, T1, P1a),
385  ppl_Polyhedron_equals_Polyhedron(P1, P1a),
386  clean_ppl_new_Polyhedron_from_Polyhedron(T1, P1a, T2, P2a),
387  ppl_Polyhedron_equals_Polyhedron(P2, P2a),
388  !,
389  ppl_delete_Polyhedron(P1),
390  ppl_delete_Polyhedron(P1a),
391  ppl_delete_Polyhedron(P2),
392  ppl_delete_Polyhedron(P2a),
393  make_vars(3, [A, B, C]),
394  (T1 = c
395          -> CS = [3 >= A, 4 >= A, 4*A + B - 2*C >= 5]
396          ;  CS = [3 >= A, 4 >  A, 4*A + B - 2*C >= 5]
397  ),
398  clean_ppl_new_Polyhedron_from_constraints(T1, CS, P3),
399  clean_ppl_new_Polyhedron_from_Polyhedron(T1, P3, T2, P4),
400  clean_ppl_new_Polyhedron_from_Polyhedron(T2, P4, T1, P3a),
401  clean_ppl_new_Polyhedron_from_Polyhedron(T1, P3a, T2, P4a),
402  ppl_Polyhedron_equals_Polyhedron(P3, P3a),
403  ppl_Polyhedron_equals_Polyhedron(P4, P4a),
404  !,
405  ppl_delete_Polyhedron(P3),
406  ppl_delete_Polyhedron(P4),
407  ppl_delete_Polyhedron(P3a),
408  ppl_delete_Polyhedron(P4a).
409
410% Tests ppl_new_Polyhedron_from_constraints/2
411%       ppl_new_Polyhedron_from_constraints/2.
412new_polyhedron_from_cons :-
413  new_polyhedron_from_cons(c, [3 >= '$VAR'(1)]),
414  make_vars(4, [A, B, C, D]),
415  new_polyhedron_from_cons(c, [3 >= A, 4*A + B - 2*C >= 5, D = 1]),
416  new_polyhedron_from_cons(c, [B >= A, 4*A + B - 2*C >= 5, D = 1]),
417  new_polyhedron_from_cons(nnc, [3 > A, 4*A + B - 2*C >= 5, D = 1]),
418  new_polyhedron_from_cons(nnc, [B > A, 4*A + B - 2*C >= 5, D = 1]).
419
420new_polyhedron_from_cons(T, CS) :-
421  clean_ppl_new_Polyhedron_from_constraints(T, [], P),
422  \+ clean_ppl_new_Polyhedron_from_constraints(T, [], 0),
423  ppl_Polyhedron_is_universe(P),
424  clean_ppl_new_Polyhedron_from_constraints(T, CS, Pa),
425  \+ ppl_Polyhedron_is_universe(Pa),
426  !,
427  ppl_delete_Polyhedron(P),
428  ppl_delete_Polyhedron(Pa).
429
430% Tests ppl_new_Polyhedron_from_generators/2 and
431%       ppl_new_Polyhedron_from_generators/2.
432new_polyhedron_from_gens :-
433  make_vars(3, [A, B, C]),
434  new_polyhedron_from_gens(c,[point(A + B + C, 1), point(A + B + C)] ),
435  new_polyhedron_from_gens(nnc,  [point(A + B + C), closure_point(A + B + C)]).
436
437new_polyhedron_from_gens(T, GS) :-
438  \+ clean_ppl_new_Polyhedron_from_generators(T, [], 0),
439  clean_ppl_new_Polyhedron_from_generators(T, [], P),
440  ppl_Polyhedron_is_empty(P),
441  clean_ppl_new_Polyhedron_from_generators(T, GS, Pa),
442  \+ ppl_Polyhedron_is_empty(Pa),
443  !,
444  ppl_delete_Polyhedron(P),
445  ppl_delete_Polyhedron(Pa).
446
447
448%%%%%%%%%%%%%%%%% Swap Polyhedra %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449
450% Tests ppl_Polyhedron_swap/2.
451swap :-
452  swap(c), swap(nnc).
453
454swap(T) :-
455  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
456  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, empty, Q),
457  ppl_Polyhedron_swap(P, Q),
458  ppl_Polyhedron_is_empty(P),
459  ppl_Polyhedron_is_universe(Q),
460  !,
461  ppl_delete_Polyhedron(P),
462  ppl_delete_Polyhedron(Q).
463
464%%%%%%%%%%%%%%%%%% Poly Dimension %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465
466% Tests ppl_Polyhedron_space_dimension/2.
467space :-
468 space(c), space(nnc).
469
470space(T) :-
471  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
472  ppl_Polyhedron_space_dimension(P, N),
473  N = 3,
474  \+ ppl_Polyhedron_space_dimension(P, 4),
475  clean_ppl_new_Polyhedron_from_generators(T, [], Q),
476  ppl_Polyhedron_space_dimension(Q, M),
477  M == 0,
478  clean_ppl_new_Polyhedron_from_constraints(T, [], Q1),
479  ppl_Polyhedron_space_dimension(Q1, M1),
480  M1 == 0,
481  !,
482  ppl_delete_Polyhedron(P),
483  ppl_delete_Polyhedron(Q),
484  ppl_delete_Polyhedron(Q1).
485
486
487% Tests ppl_Polyhedron_affine_dimension/2.
488affine_dim :-
489 affine_dim(c), affine_dim(nnc).
490
491affine_dim(T) :-
492  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
493  ppl_Polyhedron_affine_dimension(P, N),
494  N == 3,
495  \+ ppl_Polyhedron_affine_dimension(P, 2),
496  clean_ppl_new_Polyhedron_from_generators(T, [], Q),
497  ppl_Polyhedron_affine_dimension(Q, M),
498  M == 0,
499  clean_ppl_new_Polyhedron_from_constraints(T, [], Q1),
500  ppl_Polyhedron_affine_dimension(Q1, M1),
501  M1 == 0,
502  !,
503  ppl_delete_Polyhedron(P),
504  ppl_delete_Polyhedron(Q),
505  ppl_delete_Polyhedron(Q1),
506  make_vars(2, [A, B]),
507  clean_ppl_new_Polyhedron_from_generators(T,
508                                     [point(A), ray(B)],
509                                     P1),
510  ppl_Polyhedron_space_dimension(P1, 2),
511  ppl_Polyhedron_affine_dimension(P1, 1),
512  clean_ppl_new_Polyhedron_from_generators(T,
513                                     [point(A + B, 2)],
514                                     P2),
515  ppl_Polyhedron_space_dimension(P2, 2),
516  ppl_Polyhedron_affine_dimension(P2, 0),
517  clean_ppl_new_Polyhedron_from_constraints(T,
518                                      [A - B >= 0, B >= 0,
519                                       A + B =< 1, B =< 0],
520                                      P3),
521  ppl_Polyhedron_space_dimension(P3, 2),
522  ppl_Polyhedron_affine_dimension(P3, 1),
523  clean_ppl_new_Polyhedron_from_constraints(T,
524                                      [A - B >= 0, B >= 1,
525                                       A + B =< 1],
526                                      P4),
527  (T = c ->
528            ppl_Polyhedron_add_constraint(P4, B =< 0)
529         ;
530            ppl_Polyhedron_add_constraint(P4, B < 1)
531  ),
532  ppl_Polyhedron_space_dimension(P4, 2),
533  ppl_Polyhedron_affine_dimension(P4, 0),
534  !,
535  ppl_delete_Polyhedron(P1),
536  ppl_delete_Polyhedron(P2),
537  ppl_delete_Polyhedron(P3),
538  ppl_delete_Polyhedron(P4).
539
540% Tests ppl_Polyhedron_constrains/2.
541constrains :-
542  constrains(c), constrains(nnc).
543
544constrains(T) :-
545  make_vars(3, [A, B, C]),
546  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
547  ppl_Polyhedron_add_constraints(P, [B >= 0, B - C >= 2]),
548  ppl_Polyhedron_constrains(P, B),
549  \+ppl_Polyhedron_constrains(P, A),
550  ppl_Polyhedron_OK(P),
551  !,
552  ppl_delete_Polyhedron(P).
553
554% Tests ppl_Polyhedron_unconstrain_space_dimension/2.
555unconstrain_space_dimension :-
556  unconstrain_space_dimension(c), unconstrain_space_dimension(nnc).
557
558unconstrain_space_dimension(T) :-
559  make_vars(3, [_A, B, C]),
560  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
561  ppl_Polyhedron_add_constraints(P, [B >= 0, B - C >= 2]),
562  ppl_Polyhedron_unconstrain_space_dimension(P, B),
563  \+ppl_Polyhedron_constrains(P, B),
564  ppl_Polyhedron_OK(P),
565  !,
566  ppl_delete_Polyhedron(P).
567
568% Tests ppl_Polyhedron_unconstrain_space_dimensions/2.
569unconstrain_space_dimensions :-
570  unconstrain_space_dimensions(c), unconstrain_space_dimensions(nnc).
571
572unconstrain_space_dimensions(T) :-
573  make_vars(3, [_A, B, C]),
574  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
575  ppl_Polyhedron_add_constraints(P, [B >= 0, B - C >= 2]),
576  ppl_Polyhedron_unconstrain_space_dimensions(P, []),
577  ppl_Polyhedron_constrains(P, B),
578  ppl_Polyhedron_unconstrain_space_dimensions(P, [B]),
579  \+ppl_Polyhedron_constrains(P, B),
580  ppl_Polyhedron_unconstrain_space_dimensions(P, [B]),
581  \+ppl_Polyhedron_constrains(P, B),
582  ppl_Polyhedron_OK(P),
583  !,
584  ppl_delete_Polyhedron(P).
585
586%%%%%%%%%%%%%%%% Basic Operators %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587
588% Tests ppl_Polyhedron_intersection_assign/2.
589inters_assign :-
590  inters_assign(c), inters_assign(nnc).
591
592inters_assign(T) :-
593  make_vars(2, [A, B]),
594  clean_ppl_new_Polyhedron_from_generators(T,
595                                     [point(0), point(B),
596                                      point(A), point(A, 2)],
597                                     P1),
598  clean_ppl_new_Polyhedron_from_generators(T,
599                                     [point(0), point(A),
600                                      point(A + B), point(A, 2)],
601                                     P2),
602  ppl_Polyhedron_intersection_assign(P1, P2),
603  clean_ppl_new_Polyhedron_from_generators(T,
604                                     [point(A + B, 2),
605                                      point(A), point(0)],
606                                     P1a),
607  clean_ppl_new_Polyhedron_from_constraints(T,
608                                      [A - B >= 0, B >= 0,
609                                       A + B =< 1],
610                                      P1b),
611  ppl_Polyhedron_equals_Polyhedron(P1, P1a),
612  ppl_Polyhedron_equals_Polyhedron(P1, P1b),
613  clean_ppl_new_Polyhedron_from_constraints(T, [A =< -1, B =< -1], P3),
614  ppl_Polyhedron_intersection_assign(P1, P3),
615  ppl_Polyhedron_is_empty(P1),
616  !,
617  ppl_delete_Polyhedron(P1),
618  ppl_delete_Polyhedron(P2),
619  ppl_delete_Polyhedron(P3),
620  ppl_delete_Polyhedron(P1a),
621  ppl_delete_Polyhedron(P1b).
622
623% Tests ppl_Polyhedron_concatenate_assign/2.
624conc_assign :-
625  conc_assign(c), conc_assign(nnc).
626
627conc_assign(T) :-
628  make_vars(5, [A, B, C, D, E]),
629  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
630  clean_ppl_new_Polyhedron_from_constraints(T, [A >= 1, B >= 0, C >= 0], Q),
631  ppl_Polyhedron_concatenate_assign(P, Q),
632  clean_ppl_new_Polyhedron_from_constraints(T,
633                                      [C >= 1, D >= 0, E >= 0],
634                                      P1),
635  ppl_Polyhedron_equals_Polyhedron(P, P1),
636  !,
637  ppl_delete_Polyhedron(P1),
638  ppl_delete_Polyhedron(P),
639  ppl_delete_Polyhedron(Q).
640
641% Tests ppl_Polyhedron_poly_hull_assign/2.
642polyhull_assign :-
643  polyhull_assign(c), polyhull_assign(nnc).
644
645polyhull_assign(T) :-
646  make_vars(2, [A, B]),
647  clean_ppl_new_Polyhedron_from_generators(T,
648                                     [point(0), point(B),
649                                      point(A), point(A,2)],
650                                     P1),
651  clean_ppl_new_Polyhedron_from_generators(T,
652                                     [point(0), point(A),
653                                      point(A + B), point(A, 2)],
654                                     P2),
655  ppl_Polyhedron_poly_hull_assign(P1, P2),
656  clean_ppl_new_Polyhedron_from_generators(T,
657      [point(1*A+1*B), point(1*A, 2), point(1*A), point(1*B), point(0)], P1a),
658  clean_ppl_new_Polyhedron_from_constraints(T,
659      [1*A>=0, 1*B>=0, -1*B>= -1, -1*A>= -1], P1b),
660  ppl_Polyhedron_equals_Polyhedron(P1, P1a),
661  ppl_Polyhedron_equals_Polyhedron(P1, P1b),
662  !,
663  ppl_delete_Polyhedron(P1),
664  ppl_delete_Polyhedron(P2),
665  ppl_delete_Polyhedron(P1a),
666  ppl_delete_Polyhedron(P1b).
667
668% Tests ppl_Polyhedron_poly_difference_assign/2.
669polydiff_assign :-
670  make_vars(2, [A, B]),
671  GS0 = [point(2*A)],
672  GS1 = [point(0), point(2*A)],
673  GS2 = [point(0), point(A)],
674  GS3 = [point(A), point(2*A)],
675  GS4 = [closure_point(A), point(2*A)],
676  GS4a = [closure_point(A), point(3*A, 2), closure_point(2*A)],
677  polydiff_assign(c, GS1, GS2, GS3),
678  polydiff_assign(c, GS1, GS3, GS2),
679  polydiff_assign(c, GS3, GS0, GS3),
680  polydiff_assign(nnc, GS1, GS2, GS4),
681  polydiff_assign(nnc, GS1, GS4, GS2),
682  polydiff_assign(nnc, GS4, GS0, GS4a),
683  GS5 = [point(0), point(B), point(A)],
684  GS6 = [point(0), point(A), point(A + B)],
685  GS6a = [point(0), point(A), point(A + B, 2)],
686  GS7 = [point(A + B, 2), point(B), point(0)],
687  GS8 = [closure_point(A + B, 2), point(B), closure_point(0)],
688  polydiff_assign(c, GS5, GS6, GS7),
689  polydiff_assign(c, GS5, GS7, GS6a),
690  polydiff_assign(nnc, GS5, GS6, GS8),
691  polydiff_assign(nnc, GS5, GS8, GS6a),
692  GS_empty = [],
693  polydiff_assign(c, GS0, GS0, GS_empty),
694  polydiff_assign(nnc, GS4, GS4, GS_empty),
695  polydiff_assign(nnc, GS4, GS3, GS_empty).
696
697polydiff_assign(T, GS1, GS2, GS3) :-
698  clean_ppl_new_Polyhedron_from_generators(T, GS1, P1),
699  ppl_Polyhedron_space_dimension(P1, Dim),
700  clean_ppl_new_Polyhedron_from_space_dimension(T, Dim, empty, P2),
701  ppl_Polyhedron_add_generators(P2, GS2),
702  ppl_Polyhedron_poly_difference_assign(P1, P2),
703  clean_ppl_new_Polyhedron_from_space_dimension(T, Dim, empty, P3),
704  ppl_Polyhedron_add_generators(P3, GS3),
705  ppl_Polyhedron_equals_Polyhedron(P1, P3),
706  !,
707  ppl_delete_Polyhedron(P1),
708  ppl_delete_Polyhedron(P2),
709  ppl_delete_Polyhedron(P3).
710
711% Tests ppl_Polyhedron_time_elapse_assign/2.
712time_elapse :-
713  time_elapse(c), time_elapse(nnc).
714
715% Tests ppl_Polyhedron_time_elapse for C Polyhedra.
716time_elapse(T) :-
717  make_vars(2, [A, B]),
718  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
719  ppl_Polyhedron_add_constraints(P,
720                          [A >= 1, A =< 3, B >= 1, B =< 3]),
721  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, Q),
722  ppl_Polyhedron_add_constraints(Q, [B = 5]),
723  ppl_Polyhedron_time_elapse_assign(P, Q),
724  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, Pa),
725  ppl_Polyhedron_add_constraints(Pa, [B >= 1]),
726  clean_ppl_new_Polyhedron_from_constraints(T, [B = 5], Qa),
727  ppl_Polyhedron_equals_Polyhedron(Q, Qa),
728  ppl_Polyhedron_equals_Polyhedron(P, Pa),
729  !,
730  ppl_delete_Polyhedron(P),
731  ppl_delete_Polyhedron(Q),
732  ppl_delete_Polyhedron(Pa),
733  ppl_delete_Polyhedron(Qa).
734
735% Tests ppl_Polyhedron_topological_closure_assign/1.
736top_close_assign :-
737  make_vars(3, [A, B, C]),
738  GS_close = [point(A + B), point(0), ray(A), ray(B)],
739  GS_not_close = [point(A + B), closure_point(0), ray(A), ray(B)],
740  CS_close = [4*A + B + -2*C >= 5, A =< 3],
741  CS_not_close = [4*A + B - 2*C >= 5, A < 3],
742  top_close_assign(c, gensys, GS_close, GS_close),
743  top_close_assign(nnc, gensys, GS_not_close, GS_close),
744  top_close_assign(c, consys, CS_close, CS_close),
745  top_close_assign(nnc, consys, CS_not_close, CS_close).
746
747top_close_assign(T, gensys, GS, GS_close) :-
748  clean_ppl_new_Polyhedron_from_generators(T, GS, P),
749  ppl_Polyhedron_topological_closure_assign(P),
750  clean_ppl_new_Polyhedron_from_generators(T, GS_close, Pa),
751  ppl_Polyhedron_equals_Polyhedron(P, Pa),
752  !,
753  ppl_delete_Polyhedron(P),
754  ppl_delete_Polyhedron(Pa).
755
756top_close_assign(T, consys, CS, CS_close) :-
757  clean_ppl_new_Polyhedron_from_constraints(T, CS, P),
758  ppl_Polyhedron_topological_closure_assign(P),
759  clean_ppl_new_Polyhedron_from_constraints(T, CS_close, Pa),
760  ppl_Polyhedron_equals_Polyhedron(P, Pa),
761  !,
762  ppl_delete_Polyhedron(P),
763  ppl_delete_Polyhedron(Pa).
764
765
766%%%%%%%%%%%%%%%%%% Add Constraints or Generators %%%%%%%%%%%%%%%%%%%
767
768% Tests ppl_Polyhedron_add_constraint/2.
769add_con :-
770  add_con(c), add_con(nnc).
771
772add_con(T) :-
773  make_vars(2, [A, B]),
774  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
775  ppl_Polyhedron_add_constraint(P, A - B >= 1),
776  clean_ppl_new_Polyhedron_from_constraints(T,
777                                      [A - B >= 1],
778                                      Pa),
779  ppl_Polyhedron_equals_Polyhedron(P, Pa),
780  ppl_Polyhedron_add_constraint(P, A = 0),
781  clean_ppl_new_Polyhedron_from_constraints(T,
782                                      [A = 0, B =< -1],
783                                      Pb),
784  ppl_Polyhedron_equals_Polyhedron(P, Pb),
785  ppl_Polyhedron_add_constraint(P, A = 1),
786  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, empty, Pc),
787  ppl_Polyhedron_equals_Polyhedron(P, Pc),
788  !,
789  ppl_delete_Polyhedron(P),
790  ppl_delete_Polyhedron(Pa),
791  ppl_delete_Polyhedron(Pb),
792  ppl_delete_Polyhedron(Pc).
793
794% Tests ppl_Polyhedron_add_generator/2.
795add_gen :-
796  add_gen(c), add_gen(nnc).
797
798add_gen(T) :-
799  make_vars(2, [A, B]),
800  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
801  ppl_Polyhedron_add_generator(P, point(A + B)),
802  clean_ppl_new_Polyhedron_from_generators(T,
803                                     [point(A + B), point(0),
804                                      line(A), line(B)], P1),
805  ppl_Polyhedron_equals_Polyhedron(P, P1),
806  !,
807  ppl_delete_Polyhedron(P),
808  ppl_delete_Polyhedron(P1).
809
810% Tests ppl_Polyhedron_add_constraints/2.
811add_cons :-
812  make_vars(3, [A, B, C]),
813  add_cons(c, [A >= 1, B >= 0, 4*A + B - 2*C >= 5], [A =< 0]),
814  add_cons(nnc, [A > 1, B >= 0, 4*A + B - 2*C > 5], [A < 0]).
815
816add_cons(T, CS, CS1) :-
817  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
818  ppl_Polyhedron_add_constraints(P, CS),
819  clean_ppl_new_Polyhedron_from_constraints(T, CS, P1),
820  ppl_Polyhedron_equals_Polyhedron(P, P1),
821  ppl_Polyhedron_add_constraints(P, CS1),
822  ppl_Polyhedron_is_empty(P),
823  !,
824  ppl_delete_Polyhedron(P),
825  ppl_delete_Polyhedron(P1).
826
827% Tests ppl_Polyhedron_add_generators/2.
828add_gens :-
829  make_vars(3, [A, B, C]),
830  add_gens(c, [point(A + B + C), ray(A), ray(2*A), point(A + B + C, 1),
831               point(100*A + 5*B, -8)]),
832  add_gens(nnc, [point(A + B + C), ray(A), ray(2*A), point(A + B + C, 1),
833                 closure_point(100*A + 5*B, -8)]).
834
835add_gens(T, GS) :-
836  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P),
837  ppl_Polyhedron_add_generators(P, GS),
838  clean_ppl_new_Polyhedron_from_generators(T, GS, P1),
839  ppl_Polyhedron_equals_Polyhedron(P, P1),
840  !,
841  ppl_delete_Polyhedron(P),
842  ppl_delete_Polyhedron(P1).
843
844%%%%%%%%%%%%%%%%%% Change Dimensions %%%%%%%%%%%%%%%%%%%%%%%%%%
845
846% Tests ppl_Polyhedron_add_space_dimensions_and_project/2.
847project :-
848  project(c), project(nnc).
849
850project(T) :-
851  make_vars(4, [A, B, C, D]),
852  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
853  ppl_Polyhedron_add_constraints(P, [A >= 1, B >= 0]),
854  ppl_Polyhedron_add_space_dimensions_and_project(P, 0),
855  clean_ppl_new_Polyhedron_from_constraints(T,
856                                      [A >= 1, B >= 0],
857                                      P0),
858  ppl_Polyhedron_equals_Polyhedron(P, P0),
859  ppl_delete_Polyhedron(P0),
860  ppl_Polyhedron_add_space_dimensions_and_project(P, 2),
861  clean_ppl_new_Polyhedron_from_constraints(T,
862                                      [A >= 1, B >= 0, C = 0, D = 0],
863                                      P1),
864  ppl_Polyhedron_equals_Polyhedron(P, P1),
865  !,
866  ppl_delete_Polyhedron(P1),
867  ppl_delete_Polyhedron(P).
868
869% Tests ppl_Polyhedron_add_space_dimensions_and_embed/2.
870embed :-
871  embed(c), embed(nnc).
872
873embed(T) :-
874  make_vars(2, [A, B]),
875  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
876  ppl_Polyhedron_add_constraints(P, [A >= 1, B >= 0]),
877  ppl_Polyhedron_add_space_dimensions_and_embed(P, 0),
878  clean_ppl_new_Polyhedron_from_constraints(T,
879                                      [A >= 1, B >= 0],
880                                      P0),
881  ppl_Polyhedron_equals_Polyhedron(P, P0),
882  ppl_delete_Polyhedron(P0),
883  ppl_Polyhedron_add_space_dimensions_and_embed(P, 2),
884  clean_ppl_new_Polyhedron_from_space_dimension(T, 4, universe, P1),
885  ppl_Polyhedron_add_constraints(P1, [A >= 1, B >= 0]),
886  ppl_Polyhedron_equals_Polyhedron(P, P1),
887  !,
888  ppl_delete_Polyhedron(P1),
889  ppl_delete_Polyhedron(P).
890
891% Tests ppl_Polyhedron_remove_space_dimensions/2.
892remove_dim :-
893  remove_dim(c), remove_dim(nnc).
894
895remove_dim(T) :-
896  make_vars(3, [A, B, C]),
897  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
898  ppl_Polyhedron_add_constraints(P, [A >= 1, B >= 0, C >= 2]),
899  ppl_Polyhedron_remove_space_dimensions(P, []),
900  clean_ppl_new_Polyhedron_from_constraints(T,
901                                      [A >= 1, B >= 0, C >= 2],
902                                      P0),
903  ppl_Polyhedron_equals_Polyhedron(P, P0),
904  ppl_delete_Polyhedron(P0),
905  ppl_Polyhedron_remove_space_dimensions(P,[B]),
906  clean_ppl_new_Polyhedron_from_constraints(T,
907                                      [A >= 1, B >= 2],
908                                      P1),
909  ppl_Polyhedron_equals_Polyhedron(P, P1),
910  ppl_delete_Polyhedron(P1),
911  % Note: now 'B' refers to the old 'C' variable.
912  ppl_Polyhedron_remove_space_dimensions(P,[A, B]),
913  ppl_Polyhedron_space_dimension(P, 0),
914  !,
915  ppl_delete_Polyhedron(P).
916
917% Tests ppl_Polyhedron_remove_higher_space_dimensions/2.
918remove_high_dim :-
919  remove_high_dim(c), remove_high_dim(nnc).
920
921remove_high_dim(T) :-
922  make_vars(3, [A, B, C]),
923  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
924  ppl_Polyhedron_add_constraints(P, [A >= 1, B >= 0, C >= 0]),
925  clean_ppl_new_Polyhedron_from_constraints(T,
926                                      [A >= 1, B >= 0, C >= 0],
927                                      P1),
928  ppl_Polyhedron_equals_Polyhedron(P, P1),
929  ppl_Polyhedron_remove_higher_space_dimensions(P, 1),
930  clean_ppl_new_Polyhedron_from_constraints(T,
931                                      [A >= 1],
932                                      P2),
933  ppl_Polyhedron_equals_Polyhedron(P, P2),
934  ppl_Polyhedron_remove_higher_space_dimensions(P, 1),
935  ppl_Polyhedron_equals_Polyhedron(P, P2),
936  ppl_Polyhedron_remove_higher_space_dimensions(P, 0),
937  ppl_Polyhedron_space_dimension(P, 0),
938  !,
939  ppl_delete_Polyhedron(P1),
940  ppl_delete_Polyhedron(P2),
941  ppl_delete_Polyhedron(P).
942
943% Tests ppl_Polyhedron_expand_space_dimension/3.
944expand_dim :-
945  expand_dim(c), expand_dim(nnc).
946
947expand_dim(T) :-
948  make_vars(4, [A, B, C, D]),
949  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
950  ppl_Polyhedron_add_constraints(P, [A >= 1, B >= 0, C >= 2]),
951  ppl_Polyhedron_expand_space_dimension(P, B, 1),
952  ppl_Polyhedron_space_dimension(P, 4),
953  clean_ppl_new_Polyhedron_from_constraints(T,
954                                      [A >= 1, B >= 0, C >= 2, D >= 0],
955                                      P1),
956  ppl_Polyhedron_equals_Polyhedron(P, P1),
957  ppl_delete_Polyhedron(P1),
958  ppl_Polyhedron_remove_higher_space_dimensions(P, 2),
959  ppl_Polyhedron_expand_space_dimension(P, A, 2),
960  clean_ppl_new_Polyhedron_from_constraints(T,
961                                      [D >= 1, C >= 1, A >= 1, B >= 0],
962                                      P2),
963  ppl_Polyhedron_equals_Polyhedron(P, P2),
964  ppl_delete_Polyhedron(P2),
965  ppl_Polyhedron_space_dimension(P, 4),
966  !,
967  ppl_delete_Polyhedron(P),
968% Example taken from [GopanDMDRS04], page 519.
969  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, empty, Ptacas),
970  ppl_Polyhedron_add_generators(Ptacas,
971       [point(A + 2*B), point(A + 3*B), point(A + 4*B)]),
972  ppl_Polyhedron_expand_space_dimension(Ptacas, B, 1),
973  ppl_Polyhedron_space_dimension(Ptacas, 3),
974  clean_ppl_new_Polyhedron_from_generators(T,
975       [point(A + 2*B + 2*C), point(A + 2*B + 3*C), point(A + 2*B + 4*C),
976        point(A + 3*B + 2*C), point(A + 3*B + 3*C), point(A + 3*B + 4*C),
977        point(A + 4*B + 2*C), point(A + 4*B + 3*C), point(A + 4*B + 4*C)],
978                                      Ptacas1),
979  ppl_Polyhedron_equals_Polyhedron(Ptacas, Ptacas1),
980  !,
981  ppl_delete_Polyhedron(Ptacas1),
982  ppl_delete_Polyhedron(Ptacas).
983
984% Tests ppl_Polyhedron_fold_space_dimension/3.
985fold_dims :-
986  fold_dims(c), fold_dims(nnc).
987
988fold_dims(T) :-
989  make_vars(4, [A, B, C, D]),
990  clean_ppl_new_Polyhedron_from_space_dimension(T, 4, universe, P),
991  ppl_Polyhedron_add_constraints(P, [A >= 1, B >= 0, C >= 2, D >= 0]),
992  ppl_Polyhedron_fold_space_dimensions(P, [D], B),
993  ppl_Polyhedron_space_dimension(P, 3),
994  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P1),
995  ppl_Polyhedron_add_constraints(P1, [A >= 1, B >= 0, C >= 2]),
996  ppl_Polyhedron_equals_Polyhedron(P, P1),
997  !,
998  ppl_delete_Polyhedron(P1),
999  ppl_Polyhedron_fold_space_dimensions(P, [A, C], B),
1000  clean_ppl_new_Polyhedron_from_space_dimension(T, 1, universe, P2),
1001  ppl_Polyhedron_add_constraints(P2, [A >= 0]),
1002  ppl_Polyhedron_equals_Polyhedron(P, P2),
1003  ppl_delete_Polyhedron(P2),
1004  ppl_Polyhedron_space_dimension(P, 1),
1005  !,
1006  ppl_delete_Polyhedron(P),
1007  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, Ptacas),
1008  ppl_Polyhedron_add_constraints(Ptacas, [A >= 1, A =< 3, B >= 7, B =< 12]),
1009  ppl_Polyhedron_fold_space_dimensions(Ptacas, [A], B),
1010  ppl_Polyhedron_space_dimension(Ptacas, 1),
1011  clean_ppl_new_Polyhedron_from_space_dimension(T, 1, universe, Ptacas1),
1012  ppl_Polyhedron_add_constraints(Ptacas1, [A >= 1, A =< 12]),
1013  ppl_Polyhedron_equals_Polyhedron(Ptacas, Ptacas1),
1014  !,
1015  ppl_delete_Polyhedron(Ptacas1),
1016  ppl_delete_Polyhedron(Ptacas).
1017
1018% Tests ppl_Polyhedron_map_space_dimensions/2.
1019map_dim:-
1020  map_dim(c), map_dim(nnc).
1021
1022map_dim(T) :-
1023  make_vars(7, [A, B, C, D, E, F, G]),
1024  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
1025  ppl_Polyhedron_add_constraints(P, [A >= 2, B >= 1, C >= 0]),
1026  ppl_Polyhedron_map_space_dimensions(P, [A-B, B-C, C-A]),
1027  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, Q),
1028  ppl_Polyhedron_add_constraints(Q, [A >= 0, B >= 2, C >= 1]),
1029  ppl_Polyhedron_equals_Polyhedron(P, Q),
1030  !,
1031  ppl_delete_Polyhedron(P),
1032  ppl_delete_Polyhedron(Q),
1033  clean_ppl_new_Polyhedron_from_space_dimension(T, 4, empty, P0),
1034  ppl_Polyhedron_add_generators(P0, [point(2*C), line(A+B), ray(A+C)]),
1035  ppl_delete_Polyhedron(P0),
1036  clean_ppl_new_Polyhedron_from_space_dimension(T, 4, empty, P1),
1037  ppl_Polyhedron_add_generators(P1, [point(2*C), line(A+B), ray(A+C)]),
1038  ppl_Polyhedron_map_space_dimensions(P1, [A-C, C-A, B-B]),
1039  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, Q1),
1040  ppl_Polyhedron_add_generators(Q1, [point(2*A), ray(A+C), line(B+C)]),
1041  ppl_Polyhedron_equals_Polyhedron(P1, Q1),
1042  !,
1043  ppl_delete_Polyhedron(P1),
1044  ppl_delete_Polyhedron(Q1),
1045  clean_ppl_new_Polyhedron_from_space_dimension(T, 5, universe, P2),
1046  ppl_Polyhedron_add_constraints(P2, [B = 2, E = 8]),
1047  ppl_Polyhedron_add_space_dimensions_and_embed(P2, 2),
1048  ppl_Polyhedron_map_space_dimensions(P2, [A-A, B-B, C-E, D-F, E-G, F-C, G-D]),
1049  clean_ppl_new_Polyhedron_from_space_dimension(T, 7, universe, Q2),
1050  ppl_Polyhedron_add_constraints(Q2, [B = 2, G = 8]),
1051  ppl_Polyhedron_equals_Polyhedron(P2, Q2),
1052  !,
1053  ppl_delete_Polyhedron(P2),
1054  ppl_delete_Polyhedron(Q2).
1055
1056
1057%%%%%%%%%%%%%%%%%% Affine Transformations %%%%%%%%%%%%%%%%%%%
1058
1059% Tests ppl_Polyhedron_affine_image/4.
1060affine_image :-
1061  affine_image(c), affine_image(nnc).
1062
1063affine_image(T) :-
1064  make_vars(2, [A, B]),
1065  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1066  ppl_Polyhedron_add_constraint(P, A - B = 1),
1067  clean_ppl_new_Polyhedron_from_constraints(T,
1068                                      [A - B = 1],
1069                                      P1),
1070  ppl_Polyhedron_equals_Polyhedron(P, P1),
1071  ppl_Polyhedron_affine_image(P, A, A + 1, 1),
1072  clean_ppl_new_Polyhedron_from_constraints(T,
1073                                      [A - B = 2],
1074                                      P2),
1075  ppl_Polyhedron_equals_Polyhedron(P, P2),
1076  !,
1077  ppl_delete_Polyhedron(P1),
1078  ppl_delete_Polyhedron(P2),
1079  ppl_delete_Polyhedron(P).
1080
1081% Tests ppl_Polyhedron_affine_preimage/4.
1082affine_preimage :-
1083  affine_preimage(c), affine_preimage(nnc).
1084
1085affine_preimage(T) :-
1086  make_vars(2, [A, B]),
1087  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1088  ppl_Polyhedron_add_constraint(P, A + B >= 10),
1089  clean_ppl_new_Polyhedron_from_constraints(T,
1090                                      [A + B >= 10],
1091                                      P1),
1092  ppl_Polyhedron_equals_Polyhedron(P, P1),
1093  ppl_Polyhedron_affine_preimage(P, A, A + 1, 1),
1094  clean_ppl_new_Polyhedron_from_constraints(T,
1095                                      [A + B >= 9],
1096                                      P2),
1097  ppl_Polyhedron_equals_Polyhedron(P, P2),
1098  !,
1099  ppl_delete_Polyhedron(P1),
1100  ppl_delete_Polyhedron(P2),
1101  ppl_delete_Polyhedron(P).
1102
1103% Tests ppl_Polyhedron_bounded_affine_image/5
1104bounded_affine_image :-
1105  bounded_affine_image(c), bounded_affine_image(nnc).
1106
1107bounded_affine_image(T) :-
1108  make_vars(2, [A, B]),
1109  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1110  ppl_Polyhedron_add_constraint(P, A - B = 1),
1111  ppl_Polyhedron_bounded_affine_image(P, B, A - 1, A + 1, 2),
1112  clean_ppl_new_Polyhedron_from_constraints(T,
1113                                      [A - 2*B =< 1, 2*B - A =< 1],
1114                                      P1),
1115  ppl_Polyhedron_equals_Polyhedron(P, P1),
1116  !,
1117  ppl_delete_Polyhedron(P1),
1118  ppl_delete_Polyhedron(P).
1119
1120% Tests ppl_Polyhedron_bounded_affine_preimage/5
1121bounded_affine_preimage :-
1122  bounded_affine_preimage(c), bounded_affine_preimage(nnc).
1123
1124bounded_affine_preimage(T) :-
1125  make_vars(3, [A, B, C]),
1126  clean_ppl_new_Polyhedron_from_constraints(T,
1127            [A >= 0, A =< 4, B >= 0, B =< 4, A - B =< 2, A - B >= -2],
1128            P),
1129  clean_ppl_new_Polyhedron_from_Polyhedron(T, P, T, P1),
1130  ppl_Polyhedron_add_space_dimensions_and_embed(P1, 1),
1131  ppl_Polyhedron_bounded_affine_preimage(P, B, 7 - A, A + 3, 1),
1132  ppl_Polyhedron_add_constraint(P1, 7 - A =< B),
1133  ppl_Polyhedron_add_constraint(P1, B =< A + 3),
1134  ppl_Polyhedron_remove_space_dimensions(P1, [B]),
1135  ppl_Polyhedron_equals_Polyhedron(P, P1),
1136  !,
1137  ppl_delete_Polyhedron(P1),
1138  ppl_delete_Polyhedron(P),
1139  clean_ppl_new_Polyhedron_from_constraints(T,
1140            [A >= 0, A =< 4, B >= 0, B =< 4, A - B =< 2, A - B >= -2],
1141            Q),
1142  clean_ppl_new_Polyhedron_from_Polyhedron(T, Q, T, Q1),
1143  ppl_Polyhedron_add_space_dimensions_and_embed(Q1, 1),
1144  ppl_Polyhedron_bounded_affine_preimage(Q, B, 7 - 3*A + 2*B, B + 5*A - 3, 1),
1145  ppl_Polyhedron_add_constraint(Q1, 7 - 3*A + 2*C =< B),
1146  ppl_Polyhedron_add_constraint(Q1, B =< C + 5*A - 3),
1147  ppl_Polyhedron_remove_space_dimensions(Q1, [B]),
1148  ppl_Polyhedron_equals_Polyhedron(Q, Q1),
1149  !,
1150  ppl_delete_Polyhedron(Q1),
1151  ppl_delete_Polyhedron(Q).
1152
1153% Tests ppl_Polyhedron_generalized_affine_image/5.
1154affine_image_gen :-
1155  affine_image_gen(c), affine_image_gen(nnc).
1156
1157affine_image_gen(T) :-
1158  make_vars(2, [A, B]),
1159  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1160  ppl_Polyhedron_add_constraint(P, A - B = 1),
1161  ppl_Polyhedron_generalized_affine_image(P, A, =<, A + 1, 1),
1162  clean_ppl_new_Polyhedron_from_constraints(T,
1163                                      [A - B =< 2],
1164                                      P1),
1165  ppl_Polyhedron_equals_Polyhedron(P, P1),
1166  !,
1167  ppl_delete_Polyhedron(P1),
1168  ppl_delete_Polyhedron(P).
1169
1170% Tests ppl_Polyhedron_generalized_affine_preimage/5.
1171affine_preimage_gen :-
1172  affine_preimage_gen(c), affine_preimage_gen(nnc).
1173
1174affine_preimage_gen(T) :-
1175  make_vars(2, [A, B]),
1176  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1177  ppl_Polyhedron_add_constraints(P, [A >= 0, A =< 4, B =< 5, A =< B]),
1178  ppl_Polyhedron_generalized_affine_preimage(P, B, >=, A+2, 1),
1179  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P1),
1180  ppl_Polyhedron_add_constraints(P1, [A >= 0, A =< 3]),
1181  ppl_Polyhedron_equals_Polyhedron(P, P1),
1182  !,
1183  ppl_delete_Polyhedron(P1),
1184  ppl_delete_Polyhedron(P).
1185
1186% Tests ppl_Polyhedron_generalized_affine_image_lhs_rhs/4.
1187affine_image_genlr :-
1188  make_vars(2, [A, B]),
1189  affine_image_genlr(c, =<, [B - A =< 2], [A,B]),
1190  affine_image_genlr(c, =, [B - A = 2], [A,B]),
1191  affine_image_genlr(nnc, <, [B - A < 2], [A,B]),
1192  affine_image_genlr(nnc, =<, [B - A =< 2], [A,B]).
1193
1194affine_image_genlr(T, R, CS, [A,B]) :-
1195  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1196  ppl_Polyhedron_add_constraint(P, A - B = 1),
1197  ppl_Polyhedron_generalized_affine_image_lhs_rhs(P, B - 1, R, A + 1),
1198  clean_ppl_new_Polyhedron_from_constraints(T, CS, P1),
1199  ppl_Polyhedron_equals_Polyhedron(P, P1),
1200  !,
1201  ppl_delete_Polyhedron(P1),
1202  ppl_delete_Polyhedron(P).
1203
1204% % Tests ppl_Polyhedron_generalized_affine_preimage_lhs_rhs/4.
1205affine_preimage_genlr :-
1206  make_vars(2, [A, B]),
1207  affine_preimage_genlr(c, B - 1, =<,  A + 1,
1208      [A >= 0, A =< 4, B >= 0, B =< A], [A,B]),
1209  affine_preimage_genlr(c, B + 1, =, A + 1,
1210      [A >= 0, A =< 4, B >= 0, B =< A], [A,B]),
1211  affine_preimage_genlr(nnc, B - 1, <, A + 1,
1212      [A >= 0, A =< 4, B >= 0, B =< A], [A,B]),
1213  affine_preimage_genlr(nnc, B - 1, =<, A + 1,
1214      [A >= 0, A =< 4, B >= 0, B =< A], [A,B]).
1215
1216affine_preimage_genlr(T, LHS, R, RHS, CS, [A,_B]) :-
1217  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1218  ppl_Polyhedron_add_constraints(P, CS),
1219  ppl_Polyhedron_generalized_affine_preimage_lhs_rhs(P, LHS, R, RHS),
1220  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P1),
1221  ppl_Polyhedron_add_constraints(P1, [A >= 0, A =< 4]),
1222  ppl_Polyhedron_equals_Polyhedron(P, P1),
1223  !,
1224  ppl_delete_Polyhedron(P1),
1225  ppl_delete_Polyhedron(P).
1226
1227%%%%%%%%%%%%%%%%%% Widen and Extrapolation Operators %%%%%%%%%%%%%%%%%%%
1228
1229% Tests ppl_Polyhedron_BHRZ03_widening_assign/2.
1230widen_BHRZ03 :-
1231  make_vars(2, [A, B]),
1232  widen_BHRZ03(c, [A >= 1, B >= 0], [A >= 1, B >= 1],
1233                  [A >= 1],         [A >= 1, B >= 1]
1234              ),
1235  widen_BHRZ03(nnc, [A > 1, B > 0], [A > 1, B > 1],
1236                    [A > 1],        [A > 1, B > 1]
1237              ).
1238
1239widen_BHRZ03(Topology, CS_P, CS_Q, CS_Pa, CS_Qa) :-
1240  widen_extrapolation_init(P, CS_P, Topology),
1241  widen_extrapolation_init(Q, CS_Q, Topology),
1242  ppl_Polyhedron_BHRZ03_widening_assign(P, Q),
1243  widen_extrapolation_final(P, CS_Pa, Topology),
1244  widen_extrapolation_final(Q, CS_Qa, Topology).
1245
1246% Tests ppl_Polyhedron_BHRZ03_widening_assign_with_tokens/4.
1247widen_BHRZ03_with_tokens :-
1248  make_vars(2, [A, B]),
1249  widen_BHRZ03_with_tokens(c, [A >= 1], [A >= 1, B >= 1],
1250                             [A >= 1], [A >= 1, B >= 1], 1, 1
1251                         ),
1252  widen_BHRZ03_with_tokens(c, [A >= 1, B >= 0], [A >= 1, B >= 1],
1253                             [A >= 1], [A >= 1, B >= 1], 1, 0
1254                         ),
1255  widen_BHRZ03_with_tokens(nnc, [A > 1], [A > 1, B > 1],
1256                               [A > 1], [A > 1, B > 1], 2, 2
1257                         ),
1258  widen_BHRZ03_with_tokens(nnc, [A > 1, B >= 0], [A > 1, B >= 1],
1259                               [A > 1, B >= 0], [A > 1, B >= 1], 3, 1
1260                         ).
1261
1262widen_BHRZ03_with_tokens(Topology,
1263                      CS_P, CS_Q, CS_Pa, CS_Qa, Token_i, Token_o) :-
1264  widen_extrapolation_init(P, CS_P, Topology),
1265  widen_extrapolation_init(Q, CS_Q, Topology),
1266  \+ ppl_Polyhedron_BHRZ03_widening_assign_with_tokens(P, Q,
1267                                            Token_i, 4),
1268  \+ ppl_Polyhedron_BHRZ03_widening_assign_with_tokens(P, Q,
1269                                            Token_i, not_a_number),
1270  ppl_Polyhedron_BHRZ03_widening_assign_with_tokens(P, Q, Token_i, X),
1271  ppl_Polyhedron_BHRZ03_widening_assign_with_tokens(P, Q, X, Y),
1272  Y == Token_o,
1273  widen_extrapolation_final(P, CS_Pa, Topology),
1274  widen_extrapolation_final(Q, CS_Qa, Topology), !.
1275
1276% Tests ppl_Polyhedron_limited_BHRZ03_extrapolation_assign/3.
1277lim_extrapolate_BHRZ03 :-
1278  make_vars(2, [A, B]),
1279  lim_extrapolate_BHRZ03(c, [A >= 1, B >= 0], [A >= 2, B >= 1],
1280                            [A >= 1, B >= 0], [A >= 1, B >= 0]
1281                        ),
1282  lim_extrapolate_BHRZ03(c, [A >= 1, B >= 0], [A >= 2, B >= 1],
1283                            [A >= 2],         []
1284                        ),
1285  lim_extrapolate_BHRZ03(nnc, [A > 1, B > 0], [A > 2, B > 1],
1286                              [A > 1, B > 0], [A > 1, B > 0]
1287                        ),
1288  lim_extrapolate_BHRZ03(nnc, [A > 1, B >= 0], [A > 2, B >= 1],
1289                              [A >= 2],        []
1290                        ).
1291
1292lim_extrapolate_BHRZ03(Topology, CS_P, CS_Q, CS_lim, CS_Pa)  :-
1293  widen_extrapolation_init(P, CS_P, Topology),
1294  widen_extrapolation_init(Q, CS_Q, Topology),
1295  ppl_Polyhedron_limited_BHRZ03_extrapolation_assign(P, Q, CS_lim),
1296  widen_extrapolation_final(P, CS_Pa, Topology),
1297  !,
1298  ppl_delete_Polyhedron(Q).
1299
1300% Tests ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens/5.
1301lim_extrapolate_BHRZ03_with_tokens :-
1302  make_vars(2, [A, B]),
1303  lim_extrapolate_BHRZ03_with_tokens(c,
1304                  [A >= 1, B >= 0], [A >= 1, B >= 1],
1305                  [A >= 1, B >= 0], [A >= 1, B >= 0], 1, 0
1306                                   ),
1307  lim_extrapolate_BHRZ03_with_tokens(nnc,
1308                    [A > 1, B > 0], [A > 1, B > 1],
1309                    [A > 1, B > 0], [A > 1, B > 0], 1, 0
1310                                   ).
1311
1312lim_extrapolate_BHRZ03_with_tokens(Topology,
1313                 CS_P, CS_Q, CS_lim, CS_Pa, Token_i, Token_o) :-
1314  widen_extrapolation_init(P, CS_P, Topology),
1315  widen_extrapolation_init(Q, CS_Q, Topology),
1316  Wrong_Token is Token_i + 1,
1317  \+ ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1318                                            CS_lim, Token_i, Wrong_Token),
1319  \+ ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1320                                            CS_lim, Token_i, not_a_number),
1321  ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1322                                            CS_lim, Token_i, X),
1323  ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1324                                            CS_lim, X, Y),
1325  Y == Token_o,
1326  widen_extrapolation_final(P, CS_Pa, Topology),
1327  !,
1328  ppl_delete_Polyhedron(Q).
1329
1330
1331% Tests ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign/3.
1332bound_extrapolate_BHRZ03 :-
1333  make_vars(2, [A, B]),
1334  bound_extrapolate_BHRZ03(c, [A >= 1, B >= 0], [A >= 2, B >= 1],
1335                              [A >= 1, B >= 0], [A >= 1, B >= 0]
1336                          ),
1337  bound_extrapolate_BHRZ03(c, [A >= 1, B >= 0], [A >= 2, B >= 1],
1338                              [A >= 2],         [A >= 1, B >= 0]
1339                          ),
1340  bound_extrapolate_BHRZ03(nnc, [A > 1, B > 0], [A > 2, B > 1],
1341                                [A > 1, B > 0], [A > 1, B > 0]
1342                          ),
1343  bound_extrapolate_BHRZ03(nnc, [A > 1, B >= 0], [A > 2, B >= 1],
1344                                [A >= 2],        [A > 1, B >= 0]
1345                          ).
1346
1347bound_extrapolate_BHRZ03(Topology, CS_P, CS_Q, CS_lim, CS_Pa)  :-
1348  widen_extrapolation_init(P, CS_P, Topology),
1349  widen_extrapolation_init(Q, CS_Q, Topology),
1350  ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign(P, Q, CS_lim),
1351  widen_extrapolation_final(P, CS_Pa, Topology),
1352  !,
1353  ppl_delete_Polyhedron(Q).
1354
1355% Tests ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens/5.
1356bound_extrapolate_BHRZ03_with_tokens :-
1357  make_vars(2, [A, B]),
1358  bound_extrapolate_BHRZ03_with_tokens(c,
1359                            [A >= 1, B >= 0], [A >= 1, B >= 1],
1360                            [A >= 1, B >= 0], [A >= 1, B >= 0], 1, 0
1361                                     ),
1362  bound_extrapolate_BHRZ03_with_tokens(nnc,
1363                            [A > 1, B > 0], [A > 1, B > 1],
1364                            [A > 1, B > 0], [A > 1, B > 0], 1, 0
1365                                     ).
1366
1367bound_extrapolate_BHRZ03_with_tokens(Topology,
1368                 CS_P, CS_Q, CS_lim, CS_Pa, Token_i, Token_o) :-
1369  widen_extrapolation_init(P, CS_P, Topology),
1370  widen_extrapolation_init(Q, CS_Q, Topology),
1371  Wrong_Token is Token_i + 1,
1372  \+ ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1373                                         CS_lim, Token_i, Wrong_Token),
1374  \+ ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1375                                         CS_lim, Token_i, not-a_number),
1376  ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1377                                         CS_lim, Token_i, X),
1378  ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(P, Q,
1379                                         CS_lim, X, Y),
1380  Y == Token_o,
1381  widen_extrapolation_final(P, CS_Pa, Topology),
1382  !,
1383  ppl_delete_Polyhedron(Q).
1384
1385% Tests ppl_Polyhedron_H79_widening_assign/2.
1386widen_H79 :-
1387  make_vars(2, [A, B]),
1388  widen_H79(c,   [A >= 1, B >= 0], [A >= 1, B >= 1],
1389                 [A >= 1],         [A >= 1, B >= 1]
1390           ),
1391  widen_H79(nnc, [A > 1, B > 0], [A > 1, B > 1],
1392                 [A > 1], [A > 1, B > 1]
1393           ),
1394  widen_H79(c,   [A >= 0, A =< 1], [A = 0],
1395                 [A >= 0],         [A = 0]
1396           ),
1397  widen_H79(nnc, [A >= 0, A =< 1], [A = 0],
1398                 [A >= 0],         [A = 0]
1399           ).
1400
1401widen_H79(Topology, CS_P, CS_Q, CS_Pa, CS_Qa) :-
1402  widen_extrapolation_init(P, CS_P, Topology),
1403  widen_extrapolation_init(Q, CS_Q, Topology),
1404  ppl_Polyhedron_H79_widening_assign(P, Q),
1405  widen_extrapolation_final(P, CS_Pa, Topology),
1406  widen_extrapolation_final(Q, CS_Qa, Topology).
1407
1408% Tests ppl_Polyhedron_H79_widening_assign_with_tokens/4.
1409widen_H79_with_tokens :-
1410  make_vars(2, [A, B]),
1411  widen_H79_with_tokens(c, [A >= 1], [A >= 1, B >= 1],
1412                             [A >= 1], [A >= 1, B >= 1], 1, 1
1413                         ),
1414  widen_H79_with_tokens(c, [A >= 1, B >= 0], [A >= 1, B >= 1],
1415                             [A >= 1], [A >= 1, B >= 1], 1, 0
1416                         ),
1417  widen_H79_with_tokens(nnc, [A > 1], [A > 1, B > 1],
1418                               [A > 1], [A > 1, B > 1], 2, 2
1419                         ),
1420  widen_H79_with_tokens(nnc, [A > 1, B >= 0], [A > 1, B >= 1],
1421                               [A > 1, B >= 0], [A > 1, B >= 1], 3, 1
1422                         ).
1423
1424widen_H79_with_tokens(Topology,
1425                      CS_P, CS_Q, CS_Pa, CS_Qa, Token_i, Token_o) :-
1426  widen_extrapolation_init(P, CS_P, Topology),
1427  widen_extrapolation_init(Q, CS_Q, Topology),
1428  \+ ppl_Polyhedron_H79_widening_assign_with_tokens(P, Q,
1429                                            Token_i, 4),
1430  \+ ppl_Polyhedron_H79_widening_assign_with_tokens(P, Q,
1431                                            Token_i, not_a_number),
1432  ppl_Polyhedron_H79_widening_assign_with_tokens(P, Q, Token_i, X),
1433  ppl_Polyhedron_H79_widening_assign_with_tokens(P, Q, X, Y),
1434  Y == Token_o,
1435  widen_extrapolation_final(P, CS_Pa, Topology),
1436  widen_extrapolation_final(Q, CS_Qa, Topology), !.
1437
1438% Tests ppl_Polyhedron_limited_H79_extrapolation_assign/3.
1439lim_extrapolate_H79 :-
1440  make_vars(2, [A, B]),
1441  lim_extrapolate_H79(c,   [A >= 1, B >= 0], [A >= 2, B >= 1],
1442                           [A >= 1, B >= 0], [A >= 1, B >= 0]
1443                     ),
1444  lim_extrapolate_H79(c,   [A >= 1, B >= 0], [A >= 2, B >= 1],
1445                           [A >= 2],         []
1446                     ),
1447  lim_extrapolate_H79(nnc, [A > 1, B > 0], [A > 2, B > 1],
1448                           [A > 1, B > 0], [A > 1, B > 0]
1449                     ),
1450  lim_extrapolate_H79(nnc, [A > 1, B >= 0], [A > 2, B >= 1],
1451                           [A >= 2],        []
1452                     ),
1453  lim_extrapolate_H79(c,   [A >= 0, A =< 1], [A = 0],
1454                           [A >= 0], [A >= 0]
1455                     ),
1456  lim_extrapolate_H79(nnc, [A >= 0, A =< 1], [A = 0],
1457                           [A >= 0], [A >= 0]
1458                    ).
1459
1460lim_extrapolate_H79(Topology, CS_P, CS_Q, CS_lim, CS_Pa)  :-
1461  widen_extrapolation_init(P, CS_P, Topology),
1462  widen_extrapolation_init(Q, CS_Q, Topology),
1463  ppl_Polyhedron_limited_H79_extrapolation_assign(P, Q, CS_lim),
1464  widen_extrapolation_final(P, CS_Pa, Topology),
1465  !,
1466  ppl_delete_Polyhedron(Q).
1467
1468% Tests ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens/5.
1469lim_extrapolate_H79_with_tokens :-
1470  make_vars(2, [A, B]),
1471  lim_extrapolate_H79_with_tokens(c,
1472                  [A >= 1, B >= 0], [A >= 1, B >= 1],
1473                  [A >= 1, B >= 0], [A >= 1, B >= 0], 1, 0
1474                                   ),
1475  lim_extrapolate_H79_with_tokens(nnc,
1476                    [A > 1, B > 0], [A > 1, B > 1],
1477                    [A > 1, B > 0], [A > 1, B > 0], 1, 0
1478                                   ).
1479
1480lim_extrapolate_H79_with_tokens(Topology,
1481                 CS_P, CS_Q, CS_lim, CS_Pa, Token_i, Token_o) :-
1482  widen_extrapolation_init(P, CS_P, Topology),
1483  widen_extrapolation_init(Q, CS_Q, Topology),
1484  Wrong_Token is Token_i + 1,
1485  \+ ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(P, Q,
1486                                            CS_lim, Token_i, Wrong_Token),
1487  \+ ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(P, Q,
1488                                            CS_lim, Token_i, not_a_number),
1489  ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(P, Q,
1490                                            CS_lim, Token_i, X),
1491  ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(P, Q,
1492                                            CS_lim, X, Y),
1493  Y == Token_o,
1494  widen_extrapolation_final(P, CS_Pa, Topology),
1495  !,
1496  ppl_delete_Polyhedron(Q).
1497
1498
1499% Tests ppl_Polyhedron_bounded_H79_extrapolation_assign/3.
1500bound_extrapolate_H79 :-
1501  make_vars(2, [A, B]),
1502  bound_extrapolate_H79(c,   [A >= 1, B >= 0], [A >= 2, B >= 1],
1503                             [A >= 1, B >= 0], [A >= 1, B >= 0]
1504                       ),
1505  bound_extrapolate_H79(c,   [A >= 1, B >= 0], [A >= 2, B >= 1],
1506                             [A >= 2],         [A >= 1, B >= 0]
1507                       ),
1508  bound_extrapolate_H79(nnc, [A > 1, B > 0], [A > 2, B > 1],
1509                             [A > 1, B > 0], [A > 1, B > 0]
1510                       ),
1511  bound_extrapolate_H79(nnc, [A > 1, B >= 0], [A > 2, B >= 1],
1512                             [A >= 2],        [A > 1, B >= 0]
1513                       ).
1514
1515bound_extrapolate_H79(Topology, CS_P, CS_Q, CS_lim, CS_Pa)  :-
1516  widen_extrapolation_init(P, CS_P, Topology),
1517  widen_extrapolation_init(Q, CS_Q, Topology),
1518  ppl_Polyhedron_bounded_H79_extrapolation_assign(P, Q, CS_lim),
1519  widen_extrapolation_final(P, CS_Pa, Topology),
1520  !,
1521  ppl_delete_Polyhedron(Q).
1522
1523
1524% Tests ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens/5.
1525bound_extrapolate_H79_with_tokens :-
1526  make_vars(2, [A, B]),
1527  bound_extrapolate_H79_with_tokens(c,
1528                            [A >= 1, B >= 0], [A >= 1, B >= 1],
1529                            [A >= 1, B >= 0], [A >= 1, B >= 0], 1, 0
1530                                     ),
1531  bound_extrapolate_H79_with_tokens(nnc,
1532                            [A > 1, B > 0], [A > 1, B > 1],
1533                            [A > 1, B > 0], [A > 1, B > 0], 1, 0
1534                                     ).
1535
1536bound_extrapolate_H79_with_tokens(Topology,
1537                 CS_P, CS_Q, CS_lim, CS_Pa, Token_i, Token_o) :-
1538  widen_extrapolation_init(P, CS_P, Topology),
1539  widen_extrapolation_init(Q, CS_Q, Topology),
1540  Wrong_Token is Token_i + 1,
1541  \+ ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(P, Q,
1542                                         CS_lim, Token_i, Wrong_Token),
1543  \+ ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(P, Q,
1544                                         CS_lim, Token_i, not_a_number),
1545  ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(P, Q,
1546                                         CS_lim, Token_i, X),
1547  ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(P, Q,
1548                                         CS_lim, X, Y),
1549  Y == Token_o,
1550  widen_extrapolation_final(P, CS_Pa, Topology),
1551  !,
1552  ppl_delete_Polyhedron(Q).
1553
1554% widen_extrapolation_init/3 and widen_extrapolation_final/3
1555% are used in the tests for widening and extrapolation predicates.
1556widen_extrapolation_init(P, CS, Topology):-
1557  clean_ppl_new_Polyhedron_from_space_dimension(Topology, 2, universe, P),
1558  ppl_Polyhedron_add_constraints(P, CS).
1559
1560widen_extrapolation_final(P,CS, Topology):-
1561  clean_ppl_new_Polyhedron_from_space_dimension(Topology, 2, universe, P1),
1562  ppl_Polyhedron_add_constraints(P1, CS),
1563  ppl_Polyhedron_equals_Polyhedron(P, P1),
1564  !,
1565  ppl_delete_Polyhedron(P),
1566  ppl_delete_Polyhedron(P1).
1567
1568%%%%%%%%%%%%%%%%%% Get Constraint or Generator System %%%%%%%%%%%%%%%%%%%
1569
1570% Tests ppl_Polyhedron_get_constraints/2.
1571get_cons :-
1572  get_cons(c), get_cons(nnc).
1573
1574get_cons(T) :-
1575  make_vars(2, [A, B]),
1576  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1577  ppl_Polyhedron_get_constraints(P, []),
1578  ppl_Polyhedron_add_constraint(P, A - B >= 1),
1579  \+  ppl_Polyhedron_get_constraints(P, []),
1580  ppl_Polyhedron_get_constraints(P, [C]),
1581  clean_ppl_new_Polyhedron_from_constraints(T, [C], Q),
1582  ppl_Polyhedron_equals_Polyhedron(P, Q),
1583  !,
1584  ppl_delete_Polyhedron(P),
1585  ppl_delete_Polyhedron(Q).
1586
1587% Tests ppl_Polyhedron_get_minimized_constraints/2.
1588get_min_cons :-
1589  get_min_cons(c), get_min_cons(nnc).
1590
1591get_min_cons(T) :-
1592  make_vars(2, [A, B]),
1593  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, universe, P),
1594  ppl_Polyhedron_get_minimized_constraints(P, []),
1595  ppl_Polyhedron_add_constraints(P, [A - B >= 1, A - B >= 0]),
1596  ppl_Polyhedron_get_minimized_constraints(P, [C]),
1597  clean_ppl_new_Polyhedron_from_constraints(T, [C], Q),
1598  ppl_Polyhedron_equals_Polyhedron(P, Q),
1599  ppl_Polyhedron_add_constraints(P, [A - B =< 0]),
1600  \+ppl_Polyhedron_get_minimized_constraints(P, [C]),
1601  !,
1602  ppl_delete_Polyhedron(P),
1603  ppl_delete_Polyhedron(Q).
1604
1605% Tests ppl_Polyhedron_get_generators/2.
1606get_gens :-
1607  get_gens(c), get_gens(nnc).
1608
1609get_gens(T) :-
1610  make_vars(2, [A, B]),
1611  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, empty, P),
1612  ppl_Polyhedron_get_generators(P, []),
1613  \+ ppl_Polyhedron_get_generators(P, [_]),
1614  ppl_Polyhedron_add_generator(P, point(A+B)),
1615  ppl_Polyhedron_get_generators(P, [G]),
1616  clean_ppl_new_Polyhedron_from_generators(T, [G], Q),
1617  ppl_Polyhedron_equals_Polyhedron(P, Q),
1618  ppl_Polyhedron_add_generator(P, point(A+B, 2)),
1619  ppl_Polyhedron_get_generators(P, GS1),
1620  ppl_Polyhedron_add_generators(Q, GS1),
1621  ppl_Polyhedron_equals_Polyhedron(P, Q),
1622  ppl_Polyhedron_add_generator(P, line(A)),
1623  ppl_Polyhedron_get_generators(P, GS2),
1624  ppl_Polyhedron_add_generators(Q, GS2),
1625  ppl_Polyhedron_equals_Polyhedron(P, Q),
1626  !,
1627  ppl_delete_Polyhedron(P),
1628  ppl_delete_Polyhedron(Q).
1629
1630% Tests ppl_Polyhedron_get_minimized_generators/2.
1631get_min_gens :-
1632  get_min_gens(c), get_min_gens(nnc).
1633
1634get_min_gens(T) :-
1635  make_vars(2, [A, B]),
1636  clean_ppl_new_Polyhedron_from_space_dimension(T, 2, empty, P),
1637  ppl_Polyhedron_add_generators(P, [point(2*A), point(A+B), point(2*B)]),
1638  \+ ppl_Polyhedron_get_minimized_generators(P, [_]),
1639  ppl_Polyhedron_get_minimized_generators(P, [G1, G2]),
1640  clean_ppl_new_Polyhedron_from_generators(T, [G1, G2], Q),
1641  ppl_Polyhedron_equals_Polyhedron(P, Q),
1642  !,
1643  ppl_delete_Polyhedron(P),
1644  ppl_delete_Polyhedron(Q).
1645
1646
1647%%%%%%%%%%%%%%%%%% Polyhedral Relations %%%%%%%%%%%%%%%%%%%%%%%%%%
1648
1649% Tests ppl_Polyhedron_relation_with_constraint/3.
1650rel_cons :-
1651  make_vars(3, [A, B, C]),
1652  rel_cons(c, [A >= 1, B >= 0, C = 0], [A, B, C]),
1653  rel_cons(nnc, [A > 1, B >= 0, C = 0], [A, B, C]).
1654
1655rel_cons(T, CS, [A, B, C]) :-
1656  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
1657  ppl_Polyhedron_add_constraints(P, CS),
1658  \+ ppl_Polyhedron_relation_with_constraint(P, A = 0, x),
1659  ppl_Polyhedron_relation_with_constraint(P, A = 0, R),
1660  R = [is_disjoint],
1661  ppl_Polyhedron_relation_with_constraint(P, B = 0, R1),
1662  R1 = [strictly_intersects],
1663  ppl_Polyhedron_relation_with_constraint(P, A >= 0, R2),
1664  R2 = [is_included],
1665  ppl_Polyhedron_relation_with_constraint(P, C >= 0, R3),
1666  (R3 = [is_included, saturates] ; R3 = [saturates, is_included]),
1667  ppl_Polyhedron_relation_with_constraint(P, A = B, R4),
1668  R4 = [strictly_intersects],
1669  ppl_Polyhedron_add_constraint(P, A = B),
1670  ppl_Polyhedron_relation_with_constraint(P, A = B, R5),
1671  (R5 = [is_included, saturates] ; R5 = [saturates, is_included]),
1672  !,
1673  ppl_delete_Polyhedron(P).
1674
1675% Tests ppl_Polyhedron_relation_with_generator/3.
1676rel_gens :-
1677  make_vars(3, [A, B, C]),
1678  rel_gens(c, [point(A + B + C), ray(A)], [A, B, C]),
1679  rel_gens(nnc, [point(A + B + C), ray(A)], [A, B, C]).
1680
1681rel_gens(T, GS, [A, _, _]) :-
1682  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P),
1683  ppl_Polyhedron_add_generators(P, GS),
1684  \+ppl_Polyhedron_relation_with_generator(P, point(A), x),
1685  ppl_Polyhedron_relation_with_generator(P, point(A), R),
1686  R = [],
1687  ppl_Polyhedron_relation_with_generator(P, ray(A), R1),
1688  R1 = [subsumes],
1689  !,
1690  ppl_delete_Polyhedron(P).
1691
1692%%%%%%%%%%%%%%%%%% Check Properties %%%%%%%%%%%%%%%%%%%%%%%%%%
1693
1694%  tests ppl_Polyhedron_is_universe/1,
1695%        ppl_Polyhedron_is_empty/1,
1696%        ppl_Polyhedron_is_bounded/1,
1697%        ppl_Polyhedron_is_topologically_closed/1,
1698%        ppl_Polyhedron_contains_integer_point/2.
1699checks :-
1700  checks(c), checks(nnc).
1701
1702checks(T) :-
1703  make_vars(3, [A, B, C]),
1704  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P),
1705  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P1),
1706  ppl_Polyhedron_is_universe(P),
1707  ppl_Polyhedron_is_empty(P1),
1708  \+ppl_Polyhedron_is_universe(P1),
1709  \+ppl_Polyhedron_is_empty(P),
1710  \+ppl_Polyhedron_contains_integer_point(P1),
1711  ppl_Polyhedron_contains_integer_point(P),
1712  ppl_Polyhedron_add_generators(P1, [point(A + B + C, 2)]),
1713  \+ppl_Polyhedron_contains_integer_point(P1),
1714  ppl_Polyhedron_add_generators(P1, [point(A + B + C)]),
1715  ppl_Polyhedron_is_bounded(P1),
1716  ppl_Polyhedron_contains_integer_point(P1),
1717  ppl_Polyhedron_add_generators(P1, [ray(A + B + C)]),
1718  \+ ppl_Polyhedron_is_bounded(P1),
1719  ppl_Polyhedron_add_constraints(P, [A >= 1, B =< 3, A =< 2]),
1720  ppl_Polyhedron_contains_integer_point(P),
1721  ppl_Polyhedron_is_topologically_closed(P),
1722   (T = nnc ->
1723     (ppl_Polyhedron_add_constraints(P, [A > 1, B =< 3, A =< 2]),
1724      \+ ppl_Polyhedron_is_topologically_closed(P),
1725      ppl_Polyhedron_contains_integer_point(P),
1726      ppl_Polyhedron_add_constraints(P, [A > 2]),
1727      ppl_Polyhedron_is_topologically_closed(P))
1728   ; true
1729   ),
1730  !,
1731  ppl_delete_Polyhedron(P),
1732  ppl_delete_Polyhedron(P1).
1733
1734% Tests ppl_Polyhedron_contains_Polyhedron/2.
1735contains :-
1736  contains(c), contains(nnc).
1737
1738contains(T) :-
1739  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P1),
1740  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P2),
1741  ppl_Polyhedron_contains_Polyhedron(P1, P2),
1742  \+ppl_Polyhedron_contains_Polyhedron(P2, P1),
1743  ppl_delete_Polyhedron(P1),
1744  ppl_delete_Polyhedron(P2).
1745
1746% Tests ppl_Polyhedron_strictly_contains_Polyhedron for C/2.
1747strict_contains :-
1748  strict_contains(c), strict_contains(nnc).
1749
1750strict_contains(T) :-
1751  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P1),
1752  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P2),
1753  ppl_Polyhedron_strictly_contains_Polyhedron(P1, P2),
1754  \+ppl_Polyhedron_strictly_contains_Polyhedron(P1, P1),
1755  !,
1756  ppl_delete_Polyhedron(P1),
1757  ppl_delete_Polyhedron(P2).
1758
1759% Tests ppl_Polyhedron_is_disjoint_from_Polyhedron/2.
1760disjoint_from :-
1761  disjoint_from(c), disjoint_from(nnc).
1762
1763disjoint_from(T) :-
1764  make_vars(3, [A, B, C]),
1765  clean_ppl_new_Polyhedron_from_constraints(T,
1766                                      [3 >= A, 4*A + B - 2*C >= 5],
1767                                      P1),
1768  clean_ppl_new_Polyhedron_from_constraints(T,
1769                                      [4 =< A, 4*A + B - 2*C >= 5],
1770                                      P2),
1771  ppl_Polyhedron_is_disjoint_from_Polyhedron(P1, P2),
1772  \+ppl_Polyhedron_is_disjoint_from_Polyhedron(P1, P1),
1773  (T = nnc ->
1774     (clean_ppl_new_Polyhedron_from_constraints(nnc,
1775                                      [3 < A, 4*A + B - 2*C >= 5],
1776                                      P2a),
1777    ppl_Polyhedron_is_disjoint_from_Polyhedron(P1, P2a),
1778    ppl_delete_Polyhedron(P2a))
1779  ; true
1780  ),
1781  !,
1782  ppl_delete_Polyhedron(P1),
1783  ppl_delete_Polyhedron(P2).
1784
1785% Tests ppl_Polyhedron_equals_Polyhedron/2.
1786equals :-
1787  equals(c), equals(nnc).
1788
1789equals(T) :-
1790  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P1),
1791  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P2),
1792  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P3),
1793  ppl_Polyhedron_equals_Polyhedron(P1, P2),
1794  \+ ppl_Polyhedron_equals_Polyhedron(P1, P3),
1795  !,
1796  ppl_delete_Polyhedron(P1),
1797  ppl_delete_Polyhedron(P2),
1798  ppl_delete_Polyhedron(P3).
1799
1800% Tests ppl_Polyhedron_OK/1.
1801ok :-
1802  ok(c), ok(nnc).
1803
1804ok(T) :-
1805  clean_ppl_new_Polyhedron_from_space_dimension(T, 0, universe, P1),
1806  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, universe, P2),
1807  clean_ppl_new_Polyhedron_from_space_dimension(T, 0, empty, P3),
1808  clean_ppl_new_Polyhedron_from_space_dimension(T, 3, empty, P4),
1809  ppl_Polyhedron_OK(P1),
1810  ppl_Polyhedron_OK(P2),
1811  ppl_Polyhedron_OK(P3),
1812  ppl_Polyhedron_OK(P4),
1813  !,
1814  ppl_delete_Polyhedron(P1),
1815  ppl_delete_Polyhedron(P2),
1816  ppl_delete_Polyhedron(P3),
1817  ppl_delete_Polyhedron(P4).
1818
1819% Tests ppl_termination_test_C_Polyhedron_MS/2,
1820%       ppl_termination_test_C_Polyhedron_PR/2.
1821%       ppl_termination_test_NNC_Polyhedron_MS/2,
1822%       ppl_termination_test_NNC_Polyhedron_PR/2.
1823termination_test :-
1824  make_vars(4, [A, B, C, D]),
1825  clean_ppl_new_Polyhedron_from_constraints(c,
1826                                            [A - C >= 0,
1827                                             -A + C >= 0,
1828                                             -B + D >= 1,
1829                                             B >= 0,
1830                                             A >= 1], P1),
1831  ppl_termination_test_C_Polyhedron_MS(P1),
1832  ppl_termination_test_C_Polyhedron_PR(P1),
1833  clean_ppl_new_Polyhedron_from_constraints(nnc,
1834                                            [A - C >= 0,
1835                                             -A + C >= 0,
1836                                             -B + D >= 1,
1837                                             B >= 0],
1838                                            P2),
1839  ppl_termination_test_NNC_Polyhedron_MS(P2),
1840  ppl_termination_test_NNC_Polyhedron_PR(P2),
1841  !,
1842  ppl_delete_Polyhedron(P1),
1843  ppl_delete_Polyhedron(P2).
1844
1845%%%%%%%%%%%%%%%%%%%%%%%%% Polyhedron Bounding Values %%%%%%%%%%%%%%%%%%%%%%%
1846
1847% Tests ppl_Polyhedron_bounds_from_above/2.
1848bounds_from_above :-
1849  make_vars(2, [A, B]),
1850  bounds_from_above(c, [A >= 1, B >= 0], [B =< 2], B),
1851  bounds_from_above(nnc, [A > 1, B > 0, B < 1], [A < 2], A).
1852
1853bounds_from_above(T, CS1, CS2, Var) :-
1854  clean_ppl_new_Polyhedron_from_constraints(T, CS1, P),
1855  \+ ppl_Polyhedron_bounds_from_above(P, Var),
1856  ppl_Polyhedron_add_constraints(P, CS2),
1857  ppl_Polyhedron_bounds_from_above(P, Var),
1858  !,
1859  ppl_delete_Polyhedron(P).
1860
1861% Tests ppl_Polyhedron_bounds_from_below/2.
1862bounds_from_below :-
1863  make_vars(2, [A, B]),
1864  bounds_from_below(c, [B >= 0, B =< 1], [A >= 1], A),
1865  bounds_from_below(nnc, [B > 0, B < 1], [A > 2], A).
1866
1867bounds_from_below(T, CS1, CS2, Var) :-
1868  clean_ppl_new_Polyhedron_from_constraints(T, CS1, P),
1869  \+ ppl_Polyhedron_bounds_from_below(P, Var),
1870  ppl_Polyhedron_add_constraints(P, CS2),
1871  ppl_Polyhedron_bounds_from_below(P, Var),
1872  ppl_delete_Polyhedron(P).
1873
1874%%%%%%%%%%%%%%%%%%%%%%%%% Maximize and Minimize %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1875
1876% Tests ppl_Polyhedron_maximize/5.
1877maximize :-
1878  make_vars(2, [A, B]),
1879  maximize(c, [A >= -1, A =< 1, B >= -1, B =< 1], A + B, 2, 1, true),
1880  maximize(c, [B >= -1, B =< 1], B, 1, 1, true),
1881  maximize(nnc, [A > -1, A < 1, B > -1, B < 1], A + B -1, 1, 1, false),
1882  maximize(nnc, [B > -1, B < 1], B, 1, 1, false).
1883
1884maximize(T, CS, LE, N, D, Max) :-
1885  clean_ppl_new_Polyhedron_from_constraints(T, CS, P),
1886  ppl_Polyhedron_maximize(P, LE, N, D, Max),
1887  ppl_Polyhedron_add_generator(P, ray(LE)),
1888  \+ ppl_Polyhedron_maximize(P, LE, _, _, _),
1889  !,
1890  ppl_delete_Polyhedron(P).
1891
1892% Tests ppl_Polyhedron_maximize_with_point/5.
1893maximize_with_point :-
1894  make_vars(2, [A, B]),
1895  maximize_with_point(c, [A >= -1, A =< 1, B >= -1, B =< 1],
1896                                        A + B, 2, 1, true, point(A+B)),
1897  maximize_with_point(c, [A =< 0],
1898                                        A, 0, 1, true, point(0)),
1899  maximize_with_point(nnc, [A > -1, A < 1, B > -1, B < 1],
1900                                        A + B -1, 1, 1, false, point(A+B)).
1901
1902maximize_with_point(T, CS, LE, N, D, Max, Point) :-
1903  clean_ppl_new_Polyhedron_from_constraints(T, CS, P),
1904  ppl_Polyhedron_maximize_with_point(P, LE, N, D, Max, Point_Max),
1905  (Point_Max = closure_point(E) ; Point_Max = point(E)),
1906  clean_ppl_new_Polyhedron_from_generators(T, [point(E)], Pm),
1907  clean_ppl_new_Polyhedron_from_generators(T, [Point], Qm),
1908  ppl_Polyhedron_equals_Polyhedron(Pm, Qm),
1909  !,
1910  ppl_delete_Polyhedron(Pm),
1911  ppl_delete_Polyhedron(Qm),
1912  \+ ppl_Polyhedron_maximize_with_point(P, LE, _N, 0, _, _),
1913  !,
1914  ppl_delete_Polyhedron(P).
1915
1916
1917% Tests ppl_Polyhedron_minimize/5.
1918minimize :-
1919  make_vars(2, [A, B]),
1920  minimize(c, [A >= -1, A =< 1, B >= -1, B =< 1], A + B, -2, 1, true),
1921  minimize(c, [B >= -1, B =< 1], B, -1, 1, true),
1922  minimize(nnc, [A > -2, A =< 2, B > -2, B =< 2], A + B + 1, -3, 1, false),
1923  minimize(nnc, [B > -1, B < 1], B, -1, 1, false).
1924
1925minimize(T, CS, LE, N, D, Min) :-
1926  clean_ppl_new_Polyhedron_from_constraints(T, CS, P),
1927  ppl_Polyhedron_minimize(P, LE, N, D, Min),
1928  ppl_Polyhedron_add_generator(P, ray(-LE)),
1929  \+ ppl_Polyhedron_minimize(P, LE, _, _, _),
1930  !,
1931  ppl_delete_Polyhedron(P).
1932
1933% Tests ppl_Polyhedron_minimize_with_point/5.
1934minimize_with_point :-
1935  make_vars(2, [A, B]),
1936  minimize_with_point(c, [A >= -1, A =< 1, B >= -1, B =< 1],
1937                                        A + B, -2, 1, true, point(-A-B)),
1938  minimize_with_point(c, [A >= 0],
1939                                        A, 0, 1, true, point(0)),
1940  minimize_with_point(nnc, [A > -2, A =< 2, B > -2, B =< 2],
1941                                        A + B, -4, 1, false, point(-2*A-2*B)).
1942
1943minimize_with_point(T, CS, LE, N, D, Min, Point) :-
1944  clean_ppl_new_Polyhedron_from_constraints(T, CS, P),
1945  ppl_Polyhedron_minimize_with_point(P, LE, N, D, Min, Point_Min),
1946  (Point_Min = closure_point(E) ; Point_Min = point(E)),
1947  clean_ppl_new_Polyhedron_from_generators(T, [point(E)], Pm),
1948  clean_ppl_new_Polyhedron_from_generators(T, [Point], Qm),
1949  ppl_Polyhedron_equals_Polyhedron(Pm, Qm),
1950  !,
1951  ppl_delete_Polyhedron(Pm),
1952  ppl_delete_Polyhedron(Qm),
1953   \+ ppl_Polyhedron_minimize_with_point(P, LE, _N, 0, _, _),
1954  !,
1955  ppl_delete_Polyhedron(P).
1956
1957%%%%%%%%%%%%%%%%% Watchdog tests %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1958
1959% Tests Watchdog predicates
1960% ppl_set_timeout/1
1961% ppl_set_timeout_exception_atom/1
1962% ppl_timeout_exception_atom/1
1963% ppl_reset_timeout/0
1964%
1965
1966time_out :-
1967  %% FIXME!
1968  %% Ciao does not throw a timeout exception.
1969  prolog_system('Ciao'), !.
1970time_out :-
1971  time_out(c), time_out(nnc).
1972
1973add_constraints_and_get_minimized_constraints(P, CS) :-
1974    ppl_Polyhedron_add_constraints(P, CS),
1975    ppl_Polyhedron_get_minimized_constraints(P, _).
1976
1977% Find the constraints for a hypercube for a given dimension.
1978build_hypercube_constraints(0, [], []).
1979build_hypercube_constraints(Dim, [V|Vars], [V >= 0, V =< 1|CS]) :-
1980    Dim1 is Dim - 1,
1981    build_hypercube_constraints(Dim1, Vars, CS).
1982
1983% Find the dimension and constraints for
1984% a hypercube that causes a timeout exception.
1985compute_timeout_hypercube(Csecs, T, Dim_in, Dim_out, CS_out) :-
1986    Dim_in =< 100,
1987    clean_ppl_new_Polyhedron_from_space_dimension(T, Dim_in, universe, P),
1988    make_vars(Dim_in, Vars),
1989    build_hypercube_constraints(Dim_in, Vars, CS),
1990    ppl_timeout_exception_atom(Time_Out_Atom),
1991    catch((ppl_set_timeout(Csecs),
1992           add_constraints_and_get_minimized_constraints(P, CS)),
1993          Time_Out_Atom, Catch_Exception = ok),
1994    ppl_reset_timeout,
1995    (Catch_Exception == ok ->
1996        Dim_out = Dim_in,
1997        ppl_delete_Polyhedron(P),
1998        CS_out = CS
1999    ;
2000        Dim1 is Dim_in+1,
2001        ppl_delete_Polyhedron(P),
2002        compute_timeout_hypercube(Csecs, T, Dim1, Dim_out, CS_out)
2003    ).
2004
2005time_out(T) :-
2006  ppl_set_timeout_exception_atom(pl_time_out),
2007  \+  ppl_timeout_exception_atom(pl_x),
2008  ppl_timeout_exception_atom(pl_time_out),
2009  compute_timeout_hypercube(10, T, 1, Dim, CS),
2010  !,
2011  N1 is 1,
2012  clean_ppl_new_Polyhedron_from_space_dimension(T, Dim, universe, P),
2013  catch((ppl_set_timeout(N1),
2014         add_constraints_and_get_minimized_constraints(P, CS)),
2015        pl_time_out, Catch_Exception = ok),
2016  ppl_reset_timeout,
2017  (Catch_Exception == ok ->
2018      display_message(['while testing time_out, polyhedron with topology',
2019                 T, 'timeout after', N1, ms])
2020  ;
2021      display_message(['while testing time_out, polyhedron with topology',
2022                 T, 'no timeout after', N1, ms]),
2023      fail
2024  ),
2025  ppl_Polyhedron_OK(P),
2026  !,
2027  ppl_delete_Polyhedron(P),
2028  N2 is 40,
2029  clean_ppl_new_Polyhedron_from_space_dimension(T, Dim, universe, Q),
2030  catch((ppl_set_timeout(N2),
2031         ppl_Polyhedron_is_universe(Q)),
2032        pl_time_out, Catch_Exception = not_ok),
2033  ppl_reset_timeout,
2034  (Catch_Exception == not_ok ->
2035      display_message(['while testing time_out, polyhedron with topology',
2036                 T, 'timeout after', N2, ms]),
2037      fail
2038  ;
2039      display_message(['while testing time_out, polyhedron with topology',
2040                 T, 'no timeout after', N2, ms])
2041  ),
2042  ppl_Polyhedron_OK(Q),
2043  !,
2044  ppl_delete_Polyhedron(Q).
2045
2046%%%%%%%%%%%%%%%%% MIP_Problem tests %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2047
2048mip_problem :-
2049  mip_from_cons,
2050  mip_from_mip,
2051  mip_swap,
2052  mip_get,
2053  mip_control_parameters,
2054  mip_clear,
2055  mip_satisfiable,
2056  mip_add,
2057  mip_set,
2058  mip_solve,
2059  mip_eval.
2060
2061mip_from_cons :-
2062  make_vars(3, [A, B, C]),
2063  clean_ppl_new_MIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], C, max, MIP),
2064  ppl_MIP_Problem_space_dimension(MIP, 3),
2065  ppl_MIP_Problem_constraints(MIP, CS),
2066  ppl_MIP_Problem_objective_function(MIP, Obj),
2067  compare_lin_expressions(Obj, C),
2068  ppl_MIP_Problem_optimization_mode(MIP, max),
2069  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2070  clean_ppl_new_Polyhedron_from_constraints(c,
2071       [A >= -1, B >= 5, C >= 0, C =< 3], Expect_PH),
2072  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2073  !,
2074  ppl_delete_Polyhedron(PH),
2075  ppl_delete_Polyhedron(Expect_PH),
2076  ppl_delete_MIP_Problem(MIP).
2077
2078mip_from_mip :-
2079  make_vars(3, [A, B, C]),
2080  clean_ppl_new_MIP_Problem(
2081    3, [A >= -1, B >= 5, C >= 0, C =< 3], C, max, MIP1),
2082  clean_ppl_new_MIP_Problem_from_MIP_Problem(MIP1, MIP),
2083  ppl_MIP_Problem_objective_function(MIP, Obj),
2084  compare_lin_expressions(Obj, C),
2085  ppl_MIP_Problem_optimization_mode(MIP, max),
2086  ppl_MIP_Problem_constraints(MIP, CS),
2087  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2088  ppl_MIP_Problem_constraints(MIP1, Expect_CS),
2089  clean_ppl_new_Polyhedron_from_constraints(c, Expect_CS, Expect_PH),
2090  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2091  !,
2092  ppl_delete_Polyhedron(PH),
2093  ppl_delete_Polyhedron(Expect_PH),
2094  ppl_delete_MIP_Problem(MIP1),
2095  ppl_delete_MIP_Problem(MIP).
2096
2097mip_swap :-
2098  make_vars(3, [A, B, C]),
2099  clean_ppl_new_MIP_Problem(0, [], 0, max, MIP),
2100  clean_ppl_new_MIP_Problem(
2101    3, [A >= -1, B >= 5, C >= 0, C =< 3], C, max, MIP1),
2102  ppl_MIP_Problem_swap(MIP, MIP1),
2103  ppl_MIP_Problem_constraints(MIP, CS),
2104  ppl_MIP_Problem_constraints(MIP1, CS1),
2105  clean_ppl_new_Polyhedron_from_constraints(c, CS1, PH1),
2106  ppl_Polyhedron_is_universe(PH1),
2107  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2108  clean_ppl_new_Polyhedron_from_constraints(c,
2109       [A >= -1, B >= 5, C >= 0, C =< 3], Expect_PH),
2110  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2111  !,
2112  ppl_delete_Polyhedron(PH),
2113  ppl_delete_Polyhedron(PH1),
2114  ppl_delete_Polyhedron(Expect_PH),
2115  ppl_delete_MIP_Problem(MIP1),
2116  ppl_delete_MIP_Problem(MIP).
2117
2118mip_get :-
2119  make_vars(3, [A, B, C]),
2120
2121  ppl_new_MIP_Problem(3, [], A + 3, min, MIP0),
2122  ppl_MIP_Problem_objective_function(MIP0, Obj0),
2123  compare_lin_expressions(Obj0, A + 3),
2124
2125  ppl_new_MIP_Problem(3, [], 3, min, MIP1),
2126  ppl_MIP_Problem_objective_function(MIP1, Obj1),
2127  compare_lin_expressions(Obj1, 3),
2128
2129  clean_ppl_new_MIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], C, max, MIP),
2130  ppl_MIP_Problem_constraints(MIP, CS),
2131  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2132  clean_ppl_new_Polyhedron_from_constraints(c,
2133       [A >= -1, B >= 5, C >= 0, C =< 3], Expect_PH),
2134  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2135  ppl_MIP_Problem_objective_function(MIP, Obj),
2136  compare_lin_expressions(Obj, C),
2137  ppl_MIP_Problem_optimization_mode(MIP, Opt),
2138  Opt = max,
2139  !,
2140  ppl_delete_Polyhedron(PH),
2141  ppl_delete_Polyhedron(Expect_PH),
2142  ppl_delete_MIP_Problem(MIP0),
2143  ppl_delete_MIP_Problem(MIP1),
2144  ppl_delete_MIP_Problem(MIP).
2145
2146mip_control_parameters :-
2147  make_vars(1, [A]),
2148
2149  ppl_new_MIP_Problem(3, [], A + 3, min, MIP0),
2150  clean_ppl_new_MIP_Problem_from_MIP_Problem(MIP0, MIP1),
2151  ppl_MIP_Problem_get_control_parameter(MIP0, pricing, Cp_value0),
2152  ppl_MIP_Problem_set_control_parameter(MIP1, Cp_value0),
2153  ppl_MIP_Problem_get_control_parameter(MIP1, pricing, Cp_value1),
2154  Cp_value0 == Cp_value1,
2155  ppl_MIP_Problem_set_control_parameter(MIP0, pricing_steepest_edge_float),
2156  ppl_MIP_Problem_get_control_parameter(MIP0, pricing, Cp_value2),
2157  Cp_value2 == pricing_steepest_edge_float,
2158  ppl_MIP_Problem_set_control_parameter(MIP0, pricing_steepest_edge_exact),
2159  ppl_MIP_Problem_get_control_parameter(MIP0, pricing, Cp_value3),
2160  Cp_value3 == pricing_steepest_edge_exact,
2161  ppl_MIP_Problem_set_control_parameter(MIP0, pricing_textbook),
2162  ppl_MIP_Problem_get_control_parameter(MIP0, pricing, Cp_value4),
2163  Cp_value4 == pricing_textbook,
2164  !,
2165  ppl_delete_MIP_Problem(MIP0),
2166  ppl_delete_MIP_Problem(MIP1).
2167
2168mip_clear :-
2169  make_vars(3, [A, B, C]),
2170  clean_ppl_new_MIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], C, min, MIP),
2171  ppl_MIP_Problem_clear(MIP),
2172  ppl_MIP_Problem_space_dimension(MIP, D),
2173  D == 0,
2174  ppl_MIP_Problem_constraints(MIP, CS),
2175  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2176  ppl_Polyhedron_is_universe(PH),
2177  ppl_MIP_Problem_objective_function(MIP, Obj),
2178  compare_lin_expressions(Obj, 0),
2179  ppl_MIP_Problem_optimization_mode(MIP, Opt),
2180  Opt == max,
2181  !,
2182  ppl_delete_Polyhedron(PH),
2183  ppl_delete_MIP_Problem(MIP).
2184
2185mip_satisfiable :-
2186  make_vars(3, [A, B, C]),
2187  clean_ppl_new_MIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], C, max, MIP),
2188  ppl_MIP_Problem_is_satisfiable(MIP),
2189  ppl_MIP_Problem_add_constraint(MIP, A + B =< 0),
2190  \+ ppl_MIP_Problem_is_satisfiable(MIP),
2191  !,
2192  ppl_delete_MIP_Problem(MIP).
2193
2194mip_add :-
2195  make_vars(3, [A, B, C]),
2196  clean_ppl_new_MIP_Problem_from_space_dimension(0, MIP),
2197  ppl_MIP_Problem_add_space_dimensions_and_embed(MIP, 1),
2198  ppl_MIP_Problem_add_constraint(MIP, A >= 0),
2199  ppl_MIP_Problem_add_space_dimensions_and_embed(MIP, 2),
2200  ppl_MIP_Problem_add_constraints(
2201    MIP,[A =< 3, A + B + C >= 9, B >= 5, C =< 5]),
2202  clean_ppl_new_MIP_Problem(
2203    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], 2*B-C, max, MIP1),
2204  ppl_MIP_Problem_solve(MIP, Status),
2205  Status == optimized,
2206  ppl_MIP_Problem_solve(MIP1, Status1),
2207  Status1 == unbounded,
2208  ppl_MIP_Problem_optimal_value(MIP, N, D),
2209  N == 0,
2210  D == 1,
2211  ppl_MIP_Problem_constraints(MIP, CS),
2212  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2213  ppl_MIP_Problem_constraints(MIP1, Expect_CS),
2214  clean_ppl_new_Polyhedron_from_constraints(c, Expect_CS, Expect_PH),
2215  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2216  !,
2217  ppl_delete_Polyhedron(PH),
2218  ppl_delete_Polyhedron(Expect_PH),
2219  ppl_delete_MIP_Problem(MIP),
2220  ppl_delete_MIP_Problem(MIP1).
2221
2222mip_set :-
2223  make_vars(3, [A, B, C]),
2224  clean_ppl_new_MIP_Problem(
2225    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], 0, max, MIP),
2226  ppl_MIP_Problem_objective_function(MIP, 0),
2227  ppl_MIP_Problem_optimization_mode(MIP, max),
2228  ppl_MIP_Problem_set_objective_function(MIP, 2*B-C),
2229  ppl_MIP_Problem_set_optimization_mode(MIP, min),
2230  ppl_MIP_Problem_objective_function(MIP, Obj),
2231  compare_lin_expressions(Obj, 2*B-C),
2232  ppl_MIP_Problem_optimization_mode(MIP, min),
2233  ppl_MIP_Problem_solve(MIP, optimized),
2234  !,
2235  ppl_delete_MIP_Problem(MIP).
2236
2237mip_solve :-
2238  make_vars(3, [A, B, C]),
2239  clean_ppl_new_MIP_Problem(
2240    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], 0, max, MIP),
2241  ppl_MIP_Problem_objective_function(MIP, 0),
2242  ppl_MIP_Problem_optimization_mode(MIP, max),
2243  ppl_MIP_Problem_set_objective_function(MIP, 2*B-C),
2244  ppl_MIP_Problem_set_optimization_mode(MIP, min),
2245  ppl_MIP_Problem_solve(MIP, optimized),
2246  ppl_MIP_Problem_set_objective_function(MIP, C),
2247  ppl_MIP_Problem_solve(MIP, unbounded),
2248  ppl_MIP_Problem_add_constraint(MIP, B = 0),
2249  ppl_MIP_Problem_solve(MIP, unfeasible),
2250  \+ppl_MIP_Problem_solve(MIP, invalid_status),
2251  !,
2252  ppl_delete_MIP_Problem(MIP).
2253
2254mip_eval :-
2255  make_vars(3, [A, B, C]),
2256  clean_ppl_new_MIP_Problem(
2257    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], 2*B-C, min, MIP),
2258  \+ ppl_MIP_Problem_optimizing_point(MIP, closure_point(_X)),
2259  ppl_MIP_Problem_optimizing_point(MIP, Point),
2260  ppl_MIP_Problem_feasible_point(MIP, Point),
2261  \+ ppl_MIP_Problem_feasible_point(MIP, point(B)),
2262  clean_ppl_new_Polyhedron_from_generators(c, [Point], PH),
2263  clean_ppl_new_Polyhedron_from_generators(c, [point(5*B+5*C)], Expect_PH),
2264  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2265  \+ ppl_MIP_Problem_optimal_value(MIP, 2, 1),
2266  ppl_MIP_Problem_optimal_value(MIP, N, D),
2267  \+ ppl_MIP_Problem_evaluate_objective_function(MIP, Point, 2, 1),
2268  ppl_MIP_Problem_evaluate_objective_function(MIP, Point, N1, D1),
2269  N == N1,
2270  D == D1,
2271  ppl_MIP_Problem_OK(MIP),
2272  !,
2273  ppl_delete_MIP_Problem(MIP),
2274  ppl_delete_Polyhedron(Expect_PH),
2275  ppl_delete_Polyhedron(PH).
2276
2277%%%%%%%%%%%%%%%%% PIP_Problem tests %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2278
2279pip_problem :-
2280  pip_from_cons,
2281  pip_from_pip,
2282  pip_swap,
2283  pip_control_parameters,
2284  pip_clear,
2285  pip_satisfiable,
2286  pip_add,
2287  pip_set,
2288  pip_solve,
2289  pip_solution.
2290
2291pip_from_cons :-
2292  make_vars(3, [A, B, C]),
2293  clean_ppl_new_PIP_Problem_from_space_dimension(3, PIP1),
2294  ppl_PIP_Problem_space_dimension(PIP1, 3),
2295  ppl_PIP_Problem_OK(PIP1),
2296  clean_ppl_new_PIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], [C], PIP),
2297  ppl_PIP_Problem_space_dimension(PIP, 3),
2298  ppl_PIP_Problem_parameter_space_dimensions(PIP, [C]),
2299  ppl_PIP_Problem_constraints(PIP, CS),
2300  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2301  clean_ppl_new_Polyhedron_from_constraints(c,
2302       [A >= -1, B >= 5, C >= 0, C =< 3], Expect_PH),
2303  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2304  !,
2305  ppl_delete_Polyhedron(PH),
2306  ppl_delete_Polyhedron(Expect_PH),
2307  ppl_delete_PIP_Problem(PIP1),
2308  ppl_delete_PIP_Problem(PIP).
2309
2310pip_from_pip :-
2311  make_vars(3, [A, B, C]),
2312  clean_ppl_new_PIP_Problem(
2313    3, [A >= -1, B >= 5, C >= 0, C =< 3], [C], PIP1),
2314  clean_ppl_new_PIP_Problem_from_PIP_Problem(PIP1, PIP),
2315  ppl_PIP_Problem_constraints(PIP, CS),
2316  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2317  ppl_PIP_Problem_constraints(PIP1, Expect_CS),
2318  clean_ppl_new_Polyhedron_from_constraints(c, Expect_CS, Expect_PH),
2319  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2320  !,
2321  ppl_delete_Polyhedron(PH),
2322  ppl_delete_Polyhedron(Expect_PH),
2323  ppl_delete_PIP_Problem(PIP1),
2324  ppl_delete_PIP_Problem(PIP).
2325
2326pip_swap :-
2327  make_vars(3, [A, B, C]),
2328  clean_ppl_new_PIP_Problem_from_space_dimension(0, PIP),
2329  clean_ppl_new_PIP_Problem(
2330    3, [A >= -1, B >= 5, C >= 0, C =< 3], [C], PIP1),
2331  ppl_PIP_Problem_swap(PIP, PIP1),
2332  ppl_PIP_Problem_constraints(PIP, CS),
2333  ppl_PIP_Problem_constraints(PIP1, CS1),
2334  clean_ppl_new_Polyhedron_from_constraints(c, CS1, PH1),
2335  ppl_Polyhedron_is_universe(PH1),
2336  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2337  clean_ppl_new_Polyhedron_from_constraints(c,
2338       [A >= -1, B >= 5, C >= 0, C =< 3], Expect_PH),
2339  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2340  !,
2341  ppl_delete_Polyhedron(PH),
2342  ppl_delete_Polyhedron(PH1),
2343  ppl_delete_Polyhedron(Expect_PH),
2344  ppl_delete_PIP_Problem(PIP1),
2345  ppl_delete_PIP_Problem(PIP).
2346
2347pip_control_parameters :-
2348  make_vars(1, [A]),
2349
2350  ppl_new_PIP_Problem(3, [], [A], PIP0),
2351  clean_ppl_new_PIP_Problem_from_PIP_Problem(PIP0, PIP1),
2352  ppl_PIP_Problem_get_control_parameter(PIP0, cutting_strategy, Cp_value0),
2353  ppl_PIP_Problem_set_control_parameter(PIP1, Cp_value0),
2354  ppl_PIP_Problem_get_control_parameter(PIP1, cutting_strategy, Cp_value1),
2355  Cp_value0 == Cp_value1,
2356  ppl_PIP_Problem_set_control_parameter(PIP0, cutting_strategy_first),
2357  ppl_PIP_Problem_get_control_parameter(PIP0, cutting_strategy, Cp_value2),
2358  Cp_value2 == cutting_strategy_first,
2359  ppl_PIP_Problem_set_control_parameter(PIP0, cutting_strategy_deepest),
2360  ppl_PIP_Problem_get_control_parameter(PIP0, cutting_strategy, Cp_value3),
2361  Cp_value3 == cutting_strategy_deepest,
2362  ppl_PIP_Problem_set_control_parameter(PIP0, cutting_strategy_all),
2363  ppl_PIP_Problem_get_control_parameter(PIP0, cutting_strategy, Cp_value4),
2364  Cp_value4 == cutting_strategy_all,
2365
2366  ppl_PIP_Problem_get_control_parameter(PIP0, pivot_row_strategy, Cp_value5),
2367  ppl_PIP_Problem_set_control_parameter(PIP1, Cp_value5),
2368  ppl_PIP_Problem_get_control_parameter(PIP1, pivot_row_strategy, Cp_value6),
2369  Cp_value5 == Cp_value6,
2370  ppl_PIP_Problem_set_control_parameter(PIP0, pivot_row_strategy_first),
2371  ppl_PIP_Problem_get_control_parameter(PIP0, pivot_row_strategy, Cp_value7),
2372  Cp_value7 == pivot_row_strategy_first,
2373  ppl_PIP_Problem_set_control_parameter(PIP0, pivot_row_strategy_max_column),
2374  ppl_PIP_Problem_get_control_parameter(PIP0, pivot_row_strategy, Cp_value8),
2375  Cp_value8 == pivot_row_strategy_max_column,
2376 !,
2377  ppl_delete_PIP_Problem(PIP0),
2378  ppl_delete_PIP_Problem(PIP1).
2379
2380pip_clear :-
2381  make_vars(3, [A, B, C]),
2382  clean_ppl_new_PIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], [C], PIP),
2383  ppl_PIP_Problem_clear(PIP),
2384  ppl_PIP_Problem_space_dimension(PIP, D),
2385  D == 0,
2386  ppl_PIP_Problem_constraints(PIP, CS),
2387  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2388  ppl_Polyhedron_is_universe(PH),
2389  !,
2390  ppl_delete_Polyhedron(PH),
2391  ppl_delete_PIP_Problem(PIP).
2392
2393pip_satisfiable :-
2394  make_vars(3, [A, B, C]),
2395  clean_ppl_new_PIP_Problem(3, [A >= -1, B >= 5, C >= 0, C =< 3], [C], PIP),
2396  ppl_PIP_Problem_is_satisfiable(PIP),
2397  ppl_PIP_Problem_add_constraint(PIP, A + B =< 0),
2398  \+ ppl_PIP_Problem_is_satisfiable(PIP),
2399  !,
2400  ppl_delete_PIP_Problem(PIP).
2401
2402pip_add :-
2403  make_vars(4, [A, B, C, D]),
2404  clean_ppl_new_PIP_Problem_from_space_dimension(0, PIP),
2405  ppl_PIP_Problem_add_space_dimensions_and_embed(PIP, 1, 0),
2406  ppl_PIP_Problem_add_constraint(PIP, A >= 0),
2407  ppl_PIP_Problem_add_space_dimensions_and_embed(PIP, 2, 1),
2408  ppl_PIP_Problem_add_constraints(
2409    PIP, [A =< 3, A + B + C >= 9, B >= 5, C =< 5]),
2410  clean_ppl_new_PIP_Problem(
2411    4, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], [D], PIP1),
2412  ppl_PIP_Problem_constraints(PIP, CS),
2413  clean_ppl_new_Polyhedron_from_constraints(c, CS, PH),
2414  ppl_PIP_Problem_constraints(PIP1, Expect_CS),
2415  clean_ppl_new_Polyhedron_from_constraints(c, Expect_CS, Expect_PH),
2416  ppl_Polyhedron_equals_Polyhedron(PH, Expect_PH),
2417  !,
2418  ppl_delete_Polyhedron(PH),
2419  ppl_delete_Polyhedron(Expect_PH),
2420  ppl_delete_PIP_Problem(PIP),
2421  ppl_delete_PIP_Problem(PIP1).
2422
2423pip_set :-
2424  make_vars(3, [A, B, C]),
2425  clean_ppl_new_PIP_Problem(
2426    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], [B], PIP),
2427  \+ ppl_PIP_Problem_has_big_parameter_dimension(PIP, _X),
2428  ppl_PIP_Problem_solve(PIP, optimized),
2429  !,
2430  ppl_delete_PIP_Problem(PIP),
2431
2432  make_vars(4, [X, Y, P, M]),
2433  clean_ppl_new_PIP_Problem(
2434    4, [Y - M >= -2*X + 2*M - 4, 2*Y - 2*M =< X - M + 2*P], [P, M], PIP1),
2435  ppl_PIP_Problem_set_big_parameter_dimension(PIP1, 3),
2436  ppl_PIP_Problem_has_big_parameter_dimension(PIP1, 3),
2437  ppl_PIP_Problem_solve(PIP1, optimized),
2438  !,
2439  ppl_delete_PIP_Problem(PIP1).
2440
2441pip_solve :-
2442  make_vars(3, [A, B, C]),
2443  clean_ppl_new_PIP_Problem(
2444    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], [B], PIP),
2445  ppl_PIP_Problem_solve(PIP, Status),
2446  Status == optimized,
2447  clean_ppl_new_PIP_Problem(
2448    3, [A >= 0, A =< 3, A + B + C >= 9, B >= 5, C =< 5], [B,C], PIP1),
2449  ppl_PIP_Problem_add_constraint(PIP1, C >= 6),
2450  ppl_PIP_Problem_solve(PIP1, Status1),
2451  Status1 == unfeasible,
2452  ppl_PIP_Problem_add_constraint(PIP, B = 0),
2453  ppl_PIP_Problem_solve(PIP, unfeasible),
2454  \+ppl_PIP_Problem_solve(PIP, invalid_status),
2455  !,
2456  ppl_delete_PIP_Problem(PIP),
2457  ppl_delete_PIP_Problem(PIP1).
2458
2459pip_solution :-
2460  make_vars(4, [I, J, M, N]),
2461  clean_ppl_new_PIP_Problem(
2462    4, [3*J >= -2*I + 8, J =< 4*I - 4, J =< M, I =< N], [M,N], PIP),
2463  ppl_PIP_Problem_solution(PIP, Node),
2464  ppl_PIP_Tree_Node_artificials(Node, Artificials),
2465  Artificials = [],
2466  \+ ppl_PIP_Tree_Node_is_solution(Node),
2467  ppl_PIP_Tree_Node_constraints(Node, _CS),
2468  ppl_PIP_Tree_Node_is_decision(Node),
2469  ppl_PIP_Tree_Node_constraints(Node, _CS1),
2470  ppl_PIP_Tree_Node_true_child(Node, TChild),
2471  ppl_PIP_Tree_Node_false_child(Node, _FChild),
2472  ppl_PIP_Tree_Node_is_decision(TChild),
2473  ppl_PIP_Tree_Node_true_child(TChild, TTChild),
2474  \+ ppl_PIP_Tree_Node_is_decision(TTChild),
2475  ppl_PIP_Tree_Node_is_solution(TTChild),
2476  ppl_PIP_Tree_Node_parametric_values(TTChild, I, _TPV),
2477  ppl_PIP_Tree_Node_false_child(TChild, FTChild),
2478  ppl_PIP_Tree_Node_artificials(FTChild, FTChild_Artificials),
2479  FTChild_Artificials = [Art_LinExpr/Art_Den],
2480  compare_lin_expressions(Art_LinExpr, M),
2481  Art_Den = 2,
2482  ppl_PIP_Tree_Node_is_solution(FTChild),
2483  ppl_PIP_Tree_Node_parametric_values(FTChild, I, _FPV),
2484  ppl_PIP_Problem_OK(PIP),
2485  ppl_PIP_Tree_Node_OK(Node),
2486  !,
2487  ppl_delete_PIP_Problem(PIP).
2488
2489%%%%%%%%%%%%%%%% Tool to compare linear expressions %%%%%%%%%%%%%%%%%%%%%%%
2490
2491% compare_lin_expressions/2 checks if 2 linear expressions
2492% are semantically the same.
2493%
2494% If we need to compare 2 linear expressions, then this is better
2495% than a syntactic check- since we want 1*C equal to C.
2496
2497compare_lin_expressions(LE1, LE2) :-
2498  clean_ppl_new_Polyhedron_from_constraints(c, [LE1 = 0], PH1),
2499  clean_ppl_new_Polyhedron_from_constraints(c, [LE2 = 0], PH2),
2500  ppl_Polyhedron_equals_Polyhedron(PH1, PH2),
2501  !,
2502  ppl_delete_Polyhedron(PH1),
2503  ppl_delete_Polyhedron(PH2).
2504
2505%%%%%%%%%%%%%%%% Check C++ <--> Prolog numbers %%%%%%%%%%%%%%%%%%%%%%%
2506
2507/*
2508 This test checks the transfer of large numbers between Prolog and C++.
2509 We test all numbers (BigNum) which are +/- (2^E +/- A) where E is one of
2510 the numbers in the list defined by large_integers_exponents/1 and
2511 A is one of the numbers in the list defined by large_integers_additions/1.
2512
2513 Thus we pass a BigNum from the Prolog to C++ and construct a polyhedron
2514 P (space dimension = 1) consisting of a single point A = BigNum.
2515 We also get the constraint defining P and then construct a second
2516 polyhedron P1 from this constraint; P is then compared with P1.
2517 To ensure that errors from Prolog to C++ and C++ to Prolog do not cancel
2518 each other out, we also construct a polyhedron P2 consisting of just
2519 the point A = 1 and use affine transformations (on polyhedra) to change P2
2520 to a polyhedron with the point A = BigNum; then P2 is compared with P.
2521
2522 To see exactly which numbers are tested, first make the test "extra noisy"
2523 using make_extra_noisy/0; i.e., type:
2524 make_extra_noisy, large_integers.
2525*/
2526
2527large_integers_exponents([0, 7, 8, 15, 16, 27, 28, 29, 30, 31, 32, 63, 64]).
2528
2529large_integers_additions([-3, -2, -1, 0, 1, 2, 3]).
2530
2531large_integers :-
2532  large_integers_exponents(Exps),
2533  large_integers_additions(Adds),
2534  out(large_int, init),
2535  pl_check_prolog_flag(bounded, Y),
2536  (Y == true ->
2537     large_integers_prolog_cpp_bounded(Exps, Adds, 0),
2538     out(sys_large_int, init),
2539     large_integers_sys_prolog_cpp(Adds)
2540   ;
2541     large_integers_prolog_cpp_unbounded(Exps, Adds)
2542  ).
2543
2544large_integers_prolog_cpp_bounded([], _, _).
2545large_integers_prolog_cpp_bounded([Exp|Exps], Adds, Prev_value) :-
2546  /* If the test value is too large, it may be wrap.
2547     So we compare it with the previous value that was ok
2548     as well as checking it against the maximum value. */
2549  Test_value is 1 << Exp + 3,
2550  ( ( Test_value =< Prev_value ;
2551      (pl_check_prolog_flag(max_integer, Max_int),
2552         Max_int >> 1 =< Test_value)
2553    ) ->
2554     true
2555   ;
2556     large_integers_prolog_cpp1(Adds, Exp),
2557     large_integers_prolog_cpp_bounded(Exps, Adds, Test_value)
2558  ).
2559
2560large_integers_prolog_cpp_unbounded([], _).
2561large_integers_prolog_cpp_unbounded([Exp|Exps], Adds) :-
2562   large_integers_prolog_cpp1(Adds, Exp),
2563   large_integers_prolog_cpp_unbounded(Exps, Adds).
2564
2565large_integers_prolog_cpp1([], _).
2566large_integers_prolog_cpp1([Add|Adds], Exp) :-
2567  large_integers_prolog_cpp2(Exp, Add, 1),
2568  large_integers_prolog_cpp2(Exp, Add, -1),
2569  large_integers_prolog_cpp1(Adds, Exp).
2570
2571large_integers_prolog_cpp2(Exp, Add, Sign) :-
2572  Inhomo is Sign * ((1 << Exp) + Add),
2573  out(large_int, Inhomo, Sign, Add, Exp),
2574  make_vars(1, [A]),
2575  clean_ppl_new_Polyhedron_from_space_dimension(c, 1, universe, P),
2576  ppl_Polyhedron_add_constraints(P, [A = Inhomo]),
2577  ppl_Polyhedron_get_constraints(P, CS),
2578  clean_ppl_new_Polyhedron_from_space_dimension(c, 1, universe, P1),
2579  ppl_Polyhedron_add_constraints(P1, CS),
2580  ppl_Polyhedron_equals_Polyhedron(P, P1),
2581  clean_ppl_new_Polyhedron_from_space_dimension(c, 1, universe, P2),
2582  ppl_Polyhedron_add_constraint(P2, A = 1),
2583  large_integers_affine_transform_loop(Exp, P2, A),
2584  ppl_Polyhedron_affine_image(P2, A, Sign * (A + Add), 1),
2585  ppl_Polyhedron_equals_Polyhedron(P, P2),
2586  !,
2587  ppl_delete_Polyhedron(P),
2588  ppl_delete_Polyhedron(P1),
2589  ppl_delete_Polyhedron(P2).
2590
2591large_integers_sys_prolog_cpp([]).
2592large_integers_sys_prolog_cpp([Add|Adds]) :-
2593  pl_check_prolog_flag(max_integer, Max_int),
2594  pl_check_prolog_flag(min_integer, Min_int),
2595  Max is Max_int-3,
2596  Min is Min_int+3,
2597  large_integers_sys_prolog_cpp2(Max, Add, 1),
2598  large_integers_sys_prolog_cpp2(Min, Add, -1),
2599  large_integers_sys_prolog_cpp(Adds).
2600
2601large_integers_sys_prolog_cpp2(MaxMin, Add, Sign) :-
2602  make_vars(1, [A]),
2603  Inhomo is MaxMin + Sign* Add,
2604  out(sys_large_int, Inhomo),
2605  clean_ppl_new_Polyhedron_from_space_dimension(c, 1, universe, P),
2606  ppl_Polyhedron_add_constraints(P, [A = Inhomo]),
2607  ppl_Polyhedron_get_constraints(P, CS),
2608  clean_ppl_new_Polyhedron_from_space_dimension(c, 1, universe, P1),
2609  ppl_Polyhedron_add_constraints(P1, CS),
2610  ppl_Polyhedron_equals_Polyhedron(P, P1),
2611  clean_ppl_new_Polyhedron_from_space_dimension(c, 1, universe, P2),
2612  InhomoDiv2 is Inhomo // 2,
2613  InhomoMod2 is Inhomo mod 2,
2614  ppl_Polyhedron_add_constraint(P2, A = InhomoDiv2),
2615  ppl_Polyhedron_affine_image(P2, A, 2*A + Sign* InhomoMod2, 1),
2616  ppl_Polyhedron_equals_Polyhedron(P, P2),
2617  !,
2618  ppl_delete_Polyhedron(P),
2619  ppl_delete_Polyhedron(P1),
2620  ppl_delete_Polyhedron(P2).
2621
2622large_integers_affine_transform_loop(0, _P, _).
2623large_integers_affine_transform_loop(Exp, P, A) :-
2624  Exp >= 1,
2625  ppl_Polyhedron_affine_image(P, A, 2*A, 1),
2626  Exp1 is Exp - 1,
2627  large_integers_affine_transform_loop(Exp1, P, A).
2628
2629%%%%%%%%%%%%%%%%% Exceptions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2630
2631% exceptions/0 tests both Prolog and C++ exceptions using:
2632%
2633% exception_prolog(+N, +V)
2634% exception_sys_prolog(+N, +V)
2635% exception_cplusplus(+N, +V)
2636%
2637% N is the number of the test while V is a list of 3 PPL variables
2638%
2639% In exceptions/0, the calls to these predicates should fail
2640% so that all the tests are tried on backtracking.
2641% When all the tests have been tried,
2642% (and, for the Prolog interface, providing the correct
2643% exception message),
2644% the call to exceptions/0 succeeds.
2645% If one of the tests succeeds or a Prolog interface exception
2646% has a wrong exception message, then exceptions/0 will fail.
2647
2648exceptions :-
2649   pl_check_prolog_flag(bounded, Y),
2650   make_vars(3, V),
2651   exception_prolog(V),
2652   ((Y == true,\+prolog_system('XSB'))  -> exception_sys_prolog(V) ; true),
2653   exception_cplusplus(V),
2654   !.
2655exceptions :-
2656   prolog_system('XSB').
2657
2658%% TEST: Prolog_unsigned_out_of_range
2659exception_yap :-
2660     I = 21474836470, J = 3, K = 0,
2661     ppl_new_C_Polyhedron_from_generators(
2662        [point('$VAR'(I)),point('$VAR'(J))], P),
2663     ppl_Polyhedron_get_generators(P, GS),
2664     nl, write(GS), nl,
2665     ppl_new_C_Polyhedron_from_generators(
2666        [point('$VAR'(I)),point('$VAR'(K))], P1),
2667     ppl_Polyhedron_get_generators(P1, GS1),
2668     nl, write(GS1), nl,
2669     ppl_delete_Polyhedron(P),
2670     ppl_delete_Polyhedron(P1).
2671
2672% exception_prolog(+N, +V) checks exceptions thrown by the Prolog interface.
2673% It does not check those that are dependent on a specific Prolog system.
2674
2675exception_prolog(V) :-
2676   exception_prolog1(14, V).
2677
2678exception_prolog1(0, _) :- !.
2679exception_prolog1(N, V) :-
2680   exception_prolog(N, V),
2681   N1 is N - 1,
2682   exception_prolog1(N1, V).
2683
2684%% TEST: Prolog_unsigned_out_of_range.
2685%% This test accepts any one of three exceptions:
2686%% ppl_invalid_argument: with a 32 bit system, the number 1 << 59 is expected
2687%%                       to throw this Prolog exception;
2688%% out_of_memory:        with a 64 bit system, the number 1 << 59 does not
2689%%                       throw an exception on the Prolog side, but the
2690%%                       large number of dimensions will cause a bad_alloc
2691%%                       exception in C++.
2692%%
2693exception_prolog(1, _) :-
2694    pl_check_prolog_flag(bounded, Y),
2695   (Y == true ->
2696     true
2697    ;
2698     (I is 1 << 59,
2699        must_catch(ppl_new_C_Polyhedron_from_generators([point('$VAR'(I))], _),
2700                   prolog_exception_error)
2701      )
2702   ).
2703
2704%% TEST: not_unsigned_integer
2705exception_prolog(2, _) :-
2706  must_catch(ppl_new_C_Polyhedron_from_space_dimension(n, universe, _),
2707             ppl_invalid_argument),
2708  must_catch(ppl_new_C_Polyhedron_from_space_dimension(-1, universe,  _),
2709             ppl_invalid_argument),
2710  must_catch(ppl_new_C_Polyhedron_from_generators([point('$VAR'(n))], _),
2711             ppl_invalid_argument),
2712  must_catch(ppl_new_C_Polyhedron_from_generators([point('$VAR'(-1))], _),
2713             ppl_invalid_argument).
2714
2715%% TEST: not_unsigned_integer
2716exception_prolog(3, _) :-
2717    must_catch(ppl_set_timeout(-1), ppl_invalid_argument).
2718
2719%% TEST: not_unsigned_integer
2720exception_prolog(4, _) :-
2721  clean_ppl_new_Polyhedron_from_space_dimension(c, 3, universe, P),
2722  clean_ppl_new_Polyhedron_from_space_dimension(c, 3, universe, Q),
2723  must_catch(ppl_Polyhedron_BHRZ03_widening_assign_with_tokens(
2724             Q, P, -1, _), ppl_invalid_argument),
2725  must_catch(ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(
2726             Q, P, [], -1, _), ppl_invalid_argument),
2727  must_catch(ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(
2728             Q, P, [], -1, _), ppl_invalid_argument),
2729  must_catch(ppl_Polyhedron_H79_widening_assign_with_tokens(
2730             Q, P, -1, _), ppl_invalid_argument),
2731  must_catch(ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(
2732             Q, P, [], -1, _), ppl_invalid_argument),
2733  must_catch(ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(
2734             Q, P, [], -1, _), ppl_invalid_argument),
2735  !,
2736  ppl_delete_Polyhedron(P),
2737  ppl_delete_Polyhedron(Q).
2738
2739%% TEST: non_linear
2740exception_prolog(5, [A,B,C]) :-
2741  must_catch(ppl_new_C_Polyhedron_from_generators([point(B + A*C)], _),
2742             ppl_invalid_argument),
2743  must_catch(ppl_new_C_Polyhedron_from_generators(
2744                     [point(C), ray(B + C, 1)], _), ppl_invalid_argument),
2745  must_catch(ppl_new_C_Polyhedron_from_generators(
2746                     [point], _), ppl_invalid_argument),
2747  must_catch(ppl_new_C_Polyhedron_from_generators(
2748                     [point(_D)], _), ppl_invalid_argument),
2749  must_catch(ppl_new_C_Polyhedron_from_constraints(
2750                     [_E >= 3], _), ppl_invalid_argument),
2751  must_catch(ppl_new_C_Polyhedron_from_constraints(
2752                     [A*B = 0], _), ppl_invalid_argument),
2753  must_catch(ppl_new_C_Polyhedron_from_constraints(
2754                     [A], _), ppl_invalid_argument).
2755
2756%% TEST: not_a_variable
2757exception_prolog(6, [A,_,_]) :-
2758  clean_ppl_new_Polyhedron_from_space_dimension(c, 3, universe, P),
2759  must_catch(ppl_Polyhedron_remove_space_dimensions(P, [A,1]),
2760             ppl_invalid_argument),
2761  !,
2762  ppl_delete_Polyhedron(P).
2763
2764%% TEST: not_an_integer
2765exception_prolog(7, [A,B,_]) :-
2766  clean_ppl_new_Polyhedron_from_generators(c,
2767               [point(A + B), ray(A), ray(B)], P),
2768  must_catch(ppl_Polyhedron_affine_image(P, A, A + B + 1, i),
2769             ppl_invalid_argument),
2770  !,
2771  ppl_delete_Polyhedron(P).
2772
2773%% TEST: not_a_polyhedron_handle
2774exception_prolog(8, _) :-
2775  must_catch(ppl_Polyhedron_space_dimension(_, _N), ppl_invalid_argument).
2776
2777%% TEST: not_a_complexity_class
2778exception_prolog(9, [A, _, _]) :-
2779   clean_ppl_new_Polyhedron_from_generators(c,
2780               [point(A)], P),
2781   must_catch(
2782     clean_ppl_new_Polyhedron_from_Polyhedron_with_complexity(a, c, P,
2783                                                              c, _P_copy),
2784              ppl_invalid_argument),
2785   !,
2786   ppl_delete_Polyhedron(P).
2787
2788%% TEST: not_universe_or_empty
2789exception_prolog(10, _) :-
2790  must_catch(ppl_new_C_Polyhedron_from_space_dimension(3, xxx, _),
2791             ppl_invalid_argument).
2792
2793%% TEST: not_relation
2794exception_prolog(11, [A, B, _]) :-
2795  clean_ppl_new_Polyhedron_from_generators(c,
2796               [point(A)], P),
2797  must_catch(ppl_Polyhedron_generalized_affine_image(P, A, x, A + 1, 1),
2798             ppl_invalid_argument),
2799  must_catch(
2800     ppl_Polyhedron_generalized_affine_image_lhs_rhs(P, B - 1, x, A + 1),
2801             ppl_invalid_argument),
2802  must_catch(
2803     ppl_Polyhedron_generalized_affine_image_lhs_rhs(P, B - 1, x + y, A + 1),
2804             ppl_invalid_argument),
2805   !,
2806   ppl_delete_Polyhedron(P).
2807
2808%% TEST: not_a_nil_terminated_list
2809exception_prolog(12, [A, B, C]) :-
2810  must_catch(ppl_new_C_Polyhedron_from_generators(
2811     [point(A + B + C, 1) | not_a_list], _), ppl_invalid_argument),
2812  must_catch(ppl_new_C_Polyhedron_from_constraints(
2813     [A = 0, B >= C | not_a_list], _), ppl_invalid_argument),
2814  clean_ppl_new_Polyhedron_from_space_dimension(nnc, 3, universe, P),
2815  must_catch(ppl_Polyhedron_add_constraints(P, _), ppl_invalid_argument),
2816  must_catch(ppl_Polyhedron_add_constraints(P, not_a_list),
2817             ppl_invalid_argument),
2818  must_catch(ppl_Polyhedron_add_generators(P, not_a_list),
2819             ppl_invalid_argument),
2820  must_catch(ppl_Polyhedron_add_generators(P, _), ppl_invalid_argument),
2821  clean_ppl_new_Polyhedron_from_space_dimension(c, 3, empty, Q),
2822  must_catch(ppl_Polyhedron_map_space_dimensions(Q, not_a_list),
2823             ppl_invalid_argument),
2824  must_catch(ppl_Polyhedron_fold_space_dimensions(Q, not_a_list, B),
2825             ppl_invalid_argument),
2826  must_catch(ppl_Polyhedron_remove_space_dimensions(Q, not_a_list),
2827             ppl_invalid_argument),
2828  must_catch(ppl_Polyhedron_limited_H79_extrapolation_assign(
2829             Q, P, not_a_list), ppl_invalid_argument),
2830  must_catch(ppl_Polyhedron_limited_H79_extrapolation_assign_with_tokens(
2831             Q, P, not_a_list, 1, _), ppl_invalid_argument),
2832  must_catch(ppl_Polyhedron_bounded_H79_extrapolation_assign(
2833             Q, P, not_a_list), ppl_invalid_argument),
2834  must_catch(ppl_Polyhedron_bounded_H79_extrapolation_assign_with_tokens(
2835             Q, P, not_a_list, 1, _), ppl_invalid_argument),
2836  must_catch(ppl_Polyhedron_limited_BHRZ03_extrapolation_assign(
2837             Q, P, not_a_list), ppl_invalid_argument),
2838  must_catch(ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_tokens(
2839             Q, P, not_a_list, 1, _), ppl_invalid_argument),
2840  must_catch(ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign(
2841             Q, P, not_a_list), ppl_invalid_argument),
2842  must_catch(ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_tokens(
2843             Q, P, not_a_list, 1, _), ppl_invalid_argument),
2844  !,
2845  ppl_delete_Polyhedron(P),
2846  ppl_delete_Polyhedron(Q).
2847
2848%% TEST: not_an_mip_problem_handle
2849exception_prolog(13, _) :-
2850  must_catch(ppl_MIP_Problem_space_dimension(_, _N), ppl_invalid_argument),
2851  must_catch(ppl_MIP_Problem_constraints(p, []), ppl_invalid_argument).
2852
2853%% TEST: not_an_pip_problem_handle
2854exception_prolog(14, _) :-
2855  must_catch(ppl_PIP_Problem_space_dimension(_, _N), ppl_invalid_argument),
2856  must_catch(ppl_PIP_Problem_constraints(p, []), ppl_invalid_argument).
2857
2858% exception_sys_prolog(+N, +V) checks exceptions thrown by Prolog interfaces
2859% that are dependent on a specific Prolog system.
2860% These are only checked if current_prolog_flag(bounded, true) holds.
2861
2862exception_sys_prolog(V) :-
2863   exception_sys_prolog1(4, V).
2864
2865exception_sys_prolog1(0, _) :- !.
2866exception_sys_prolog1(N, V) :-
2867   exception_sys_prolog(N, V),
2868   N1 is N - 1,
2869   exception_sys_prolog1(N1, V).
2870
2871exception_sys_prolog(1, [A,B,_]) :-
2872  pl_check_prolog_flag(max_integer, Max_Int),
2873  catch((
2874          clean_ppl_new_Polyhedron_from_constraints(c,
2875               [Max_Int * A - B =< 0, 3 >= A], P),
2876          must_catch(ppl_Polyhedron_get_generators(P, _GS),
2877                ppl_sys_prolog_error),
2878          !,
2879          ppl_delete_Polyhedron(P)
2880        ),
2881        ppl_overflow_error(Cause),
2882        check_exception_term(ppl_overflow_error(Cause))
2883       ).
2884
2885 exception_sys_prolog(2, [A,B,_]) :-
2886  pl_check_prolog_flag(min_integer, Min_Int),
2887  catch((
2888          clean_ppl_new_Polyhedron_from_constraints(c,
2889               [Min_Int * A - B =< 0, 2 >= A], P),
2890          must_catch(ppl_Polyhedron_get_generators(P, _GS),
2891                ppl_sys_prolog_error),
2892          !,
2893          ppl_delete_Polyhedron(P)
2894        ),
2895        ppl_overflow_error(Cause),
2896        check_exception_term(ppl_overflow_error(Cause))
2897       ).
2898
2899exception_sys_prolog(3, [A,B,_]) :-
2900  pl_check_prolog_flag(max_integer, Max_Int),
2901  catch((
2902          clean_ppl_new_Polyhedron_from_generators(c,
2903               [point(Max_Int * A + B)], P),
2904          ppl_Polyhedron_affine_image(P, A, A + 1, 1),
2905          must_catch(ppl_Polyhedron_get_generators(P, _GS),
2906                ppl_sys_prolog_error),
2907          !,
2908          ppl_delete_Polyhedron(P)
2909        ),
2910        ppl_overflow_error(Cause),
2911        check_exception_term(ppl_overflow_error(Cause))
2912       ).
2913
2914exception_sys_prolog(4, [A,_,_]) :-
2915   pl_check_prolog_flag(min_integer, Min_Int),
2916   catch((
2917          clean_ppl_new_Polyhedron_from_generators(c,
2918                                                   [point(Min_Int*A)], P),
2919          ppl_Polyhedron_affine_image(P, A, A - 1, 1),
2920          must_catch(ppl_Polyhedron_get_generators(P, _GS),
2921                     ppl_sys_prolog_error),
2922          !,
2923          ppl_delete_Polyhedron(P)
2924         ),
2925         ppl_overflow_error(Cause),
2926         check_exception_term(ppl_overflow_error(Cause))
2927        ).
2928
2929% exception_cplusplus(+N, +V) checks exceptions thrown by the C++
2930% interface for the PPL.
2931
2932exception_cplusplus(V) :-
2933   exception_cplusplus1(10, V).
2934
2935exception_cplusplus1(0, _) :- !.
2936exception_cplusplus1(N, V) :-
2937   exception_cplusplus(N, V),
2938   N1 is N - 1,
2939   exception_cplusplus1(N1, V).
2940
2941exception_cplusplus(1, [A, B, C]) :-
2942  must_catch(ppl_new_C_Polyhedron_from_generators([point(A + B + C, 0)], _),
2943             cpp_error).
2944
2945exception_cplusplus(2, [A, B, _]) :-
2946  clean_ppl_new_Polyhedron_from_generators(c,
2947               [point(A + B), ray(A), ray(B)], P),
2948  must_catch(ppl_Polyhedron_affine_image(P, A, A + B + 1, 0),
2949             cpp_error),
2950  !,
2951  ppl_delete_Polyhedron(P).
2952
2953exception_cplusplus(3, [A, B, _]) :-
2954  clean_ppl_new_Polyhedron_from_space_dimension(c, 0, universe, P1),
2955  clean_ppl_new_Polyhedron_from_generators(c,
2956               [point(A + B)], P2),
2957  must_catch(ppl_Polyhedron_poly_hull_assign(P1, P2),
2958             cpp_error),
2959  !,
2960  ppl_delete_Polyhedron(P1),
2961  ppl_delete_Polyhedron(P2).
2962
2963exception_cplusplus(4, [A, B, C]) :-
2964   must_catch(ppl_new_C_Polyhedron_from_generators([line(A + B + C)], _),
2965             cpp_error).
2966
2967exception_cplusplus(5, [A,B,C]) :-
2968  clean_ppl_new_Polyhedron_from_generators(c, [point(B + 2*C)], P),
2969  ppl_Polyhedron_remove_space_dimensions(P, [C]),
2970  must_catch(ppl_Polyhedron_remove_space_dimensions(P, [A, C]),
2971             cpp_error),
2972  !,
2973  ppl_delete_Polyhedron(P).
2974
2975exception_cplusplus(6, [A, B, _]) :-
2976  clean_ppl_new_Polyhedron_from_constraints(c,
2977               [A >= 1], P),
2978  must_catch(ppl_Polyhedron_affine_image(P, B, A + 1, 1),
2979             cpp_error),
2980  !,
2981  ppl_delete_Polyhedron(P).
2982
2983exception_cplusplus(7, [A, B, C]) :-
2984  clean_ppl_new_Polyhedron_from_constraints(c,
2985               [A >= 1, B>= 1], P),
2986  must_catch(ppl_Polyhedron_affine_image(P, B, A + C + 1, 1),
2987             cpp_error),
2988  !,
2989  ppl_delete_Polyhedron(P).
2990
2991exception_cplusplus(8, [A, B, _]) :-
2992  clean_ppl_new_Polyhedron_from_constraints(c,
2993               [A >= B], P),
2994  must_catch(ppl_Polyhedron_affine_preimage(P, A, A + B + 1, 0),
2995             cpp_error),
2996  !,
2997  ppl_delete_Polyhedron(P).
2998
2999exception_cplusplus(9, [A, B, C]) :-
3000  clean_ppl_new_Polyhedron_from_generators(c,
3001               [point(0), ray(A + B), ray(A)], P),
3002  must_catch(ppl_Polyhedron_affine_preimage(P, C, A + 1, 1),
3003             cpp_error),
3004  !,
3005  ppl_delete_Polyhedron(P).
3006
3007
3008exception_cplusplus(10, [A, B, C]) :-
3009  clean_ppl_new_Polyhedron_from_generators(c,
3010               [point(0), point(A), line(A + B)], P),
3011  must_catch(ppl_Polyhedron_affine_preimage(P, B, A + C, 1),
3012             cpp_error),
3013  !,
3014  ppl_delete_Polyhedron(P).
3015
3016% must_catch(+Call) calls Call using catch and checks exception.
3017% If expected exception is caught, it succeeds and fails if not.
3018
3019must_catch(Call, prolog_exception_error) :-
3020    !,
3021    catch( Call, Message, format_exception_message( Message ) ),
3022    ( \+var(Message) ->
3023        ((
3024          Message =.. [ppl_invalid_argument|_]
3025         ;
3026          Message =.. [ppl_length_error|_]
3027         ;
3028          Message = out_of_memory
3029         ) ->
3030            true
3031        ;
3032            check_exception_term(Message)
3033        )
3034    ;
3035        fail
3036    ).
3037must_catch(Call, cpp_error) :-
3038    !,
3039    catch( Call, Message, format_exception_message( cpp_error(Message) ) ),
3040    ( ( \+ var(Message),
3041          functor(Message, ppl_invalid_argument, _) ) ->
3042        true
3043    ;
3044        fail
3045    ).
3046must_catch(Call, ppl_sys_prolog_error) :-
3047    !,
3048    catch( Call, Message, format_exception_message(Message) ),
3049    ( ( \+ var(Message),
3050          (Message =.. [ppl_representation_error|_] )) ->
3051        true
3052    ;
3053        fail
3054    ).
3055must_catch(Call, Expected) :-
3056    catch(Call, Message, format_exception_message(Message) ),
3057    (\+ var(Message), Message = ppl_overflow_error(_) ->
3058        true
3059    ;
3060        ( \+ var(Message), Message =.. [Expected|_] ->
3061            true
3062        ;
3063            fail
3064        )
3065    ).
3066
3067%%%%%%%%%%%% predicate for making list of ppl variables %%%%%%
3068
3069% make_var_list(+I,+Dimension,?Variable_List)
3070% constructs a list of variables with indices from I to Dimension - 1.
3071% It is assumed that I =< Dimension.
3072
3073make_vars(Dim, Var_List):-
3074  make_var_list(0, Dim, Var_List).
3075make_var_list(Dim,Dim,[]):- !.
3076make_var_list(I,Dim,['$VAR'(I)|Var_List]):-
3077  I1 is I + 1,
3078  make_var_list(I1,Dim,Var_List).
3079
3080%%%%%%%%%%%% predicate for safely deleting polyhedra on failure %
3081
3082cleanup_ppl_Polyhedron(_).
3083cleanup_ppl_Polyhedron(P) :-
3084  out(cs, P),
3085  out(gs, P),
3086  ppl_delete_Polyhedron(P), fail.
3087
3088cleanup_ppl_Polyhedra([]).
3089cleanup_ppl_Polyhedra([_|_]).
3090cleanup_ppl_Polyhedra([P|Ps]) :-
3091  delete_all_ppl_Polyhedra([P|Ps]).
3092
3093delete_all_ppl_Polyhedra([]).
3094delete_all_ppl_Polyhedra([P|Ps]) :-
3095  ppl_delete_Polyhedron(P),
3096  delete_all_ppl_Polyhedra(Ps).
3097
3098cleanup_ppl_MIP_Problem(_).
3099cleanup_ppl_MIP_Problem(MIP) :-
3100  out(mip, MIP),
3101  ppl_delete_MIP_Problem(MIP), fail.
3102
3103cleanup_ppl_PIP_Problem(_).
3104cleanup_ppl_PIP_Problem(PIP) :-
3105  out(pip, PIP),
3106  ppl_delete_PIP_Problem(PIP), fail.
3107
3108out(cs, P):-
3109  ((noisy(N), N < 2) -> true ;
3110    ppl_Polyhedron_get_constraints(P, CS),
3111    nl, write(CS), nl
3112  ).
3113
3114out(gs, P):-
3115  ((noisy(N), N < 2) -> true ;
3116    ppl_Polyhedron_get_generators(P, GS),
3117    nl, write(GS), nl
3118  ).
3119
3120out(mip, MIP):-
3121  ((noisy(N), N < 2) -> true ;
3122    ppl_MIP_Problem_constraints(MIP, CS),
3123    ppl_MIP_Problem_objective_function(MIP, Obj),
3124    ppl_MIP_Problem_optimization_mode(MIP, Opt),
3125    ppl_MIP_Problem_get_control_parameter(MIP, pricing, Cp_value),
3126    nl,
3127    write(' constraint system is: '), write(CS), nl,
3128    write(' objective function is: '), write(Obj), nl,
3129    write(' optimization mode is: '), write(Opt),
3130    write(' control_parameter_value is: '), write(Cp_value),
3131    nl
3132  ).
3133
3134out(pip, PIP):-
3135  ((noisy(N), N < 2) -> true ;
3136    ppl_PIP_Problem_constraints(PIP, CS),
3137    ppl_PIP_Problem_parameter_space_dimensions(PIP, Dims),
3138    ppl_PIP_Problem_get_control_parameter(PIP, cutting_strategy, Cp_value),
3139    nl,
3140    write(' constraint system is: '), write(CS), nl,
3141    write(' parameter space dimensions are: '), write(Dims), nl,
3142    write(' control_parameter_value is: '), write(Cp_value),
3143    nl
3144  ).
3145
3146out(sys_large_int, init):-
3147  !,
3148  prolog_system(System),
3149  ((noisy(N), N < 2) -> true ;
3150    nl, write_all([' At the Prolog/C++ interface, for', System, 'Prolog', nl,
3151       ' the extra numbers tested are: ']),
3152    nl
3153  ).
3154
3155out(sys_large_int, Num):-
3156  ((noisy(N), N < 2) -> true ;
3157      write_all([Num, ',  '])
3158  ).
3159
3160out(large_int, init):-
3161  !,
3162  ((noisy(N), N < 2) -> true ;
3163    nl, write(' At the Prolog/C++ interface, the numbers tested are: '),
3164    nl
3165  ).
3166
3167out(large_int, Num, Sign, Add, Exp):-
3168  ((noisy(N), N < 2) -> true ;
3169    write_all([Num, ' = ', Sign, ' * ', '((1 << ', Exp, ') + ', Add, '),  '])
3170  ).
3171
3172%%% predicates for ensuring new polyhedra are always deleted on failure %
3173
3174clean_ppl_new_Polyhedron_from_space_dimension(T, D, Universe_or_Empty, P) :-
3175  (T = c ->
3176    ppl_new_C_Polyhedron_from_space_dimension(D, Universe_or_Empty, P)
3177  ;
3178    ppl_new_NNC_Polyhedron_from_space_dimension(D, Universe_or_Empty, P)
3179  ),
3180  cleanup_ppl_Polyhedron(P).
3181
3182clean_ppl_new_Polyhedron_from_constraints(T, CS, P) :-
3183  (T = c ->
3184    ppl_new_C_Polyhedron_from_constraints(CS, P)
3185   ;
3186    ppl_new_NNC_Polyhedron_from_constraints(CS, P)
3187  ),
3188  cleanup_ppl_Polyhedron(P).
3189
3190clean_ppl_new_Polyhedron_from_generators(T, GS, P) :-
3191  (T = c ->
3192    ppl_new_C_Polyhedron_from_generators(GS, P)
3193   ;
3194    ppl_new_NNC_Polyhedron_from_generators(GS, P)
3195  ),
3196  cleanup_ppl_Polyhedron(P).
3197
3198clean_ppl_new_Polyhedron_from_Polyhedron(TQ, Q, TP, P) :-
3199  ((TP == c, TQ == c) ->
3200    ppl_new_C_Polyhedron_from_C_Polyhedron(Q, P)
3201   ;
3202    ((TP == c, TQ == nnc) ->
3203      ppl_new_C_Polyhedron_from_NNC_Polyhedron(Q, P)
3204    ;
3205      ((TP == nnc, TQ == c) ->
3206        ppl_new_NNC_Polyhedron_from_C_Polyhedron(Q, P)
3207      ;
3208        ppl_new_NNC_Polyhedron_from_NNC_Polyhedron(Q, P)
3209      )
3210    )
3211  ),
3212  cleanup_ppl_Polyhedron(P).
3213
3214clean_ppl_new_Polyhedron_from_Polyhedron_with_complexity(C, TQ, Q, TP, P) :-
3215  ((TP == c, TQ == c) ->
3216    ppl_new_C_Polyhedron_from_C_Polyhedron_with_complexity(C, Q, P)
3217   ;
3218    ((TP == c, TQ == nnc) ->
3219      ppl_new_C_Polyhedron_from_NNC_Polyhedron_with_complexity(C, Q, P)
3220    ;
3221      ((TP == nnc, TQ == c) ->
3222        ppl_new_NNC_Polyhedron_from_C_Polyhedron_with_complexity(C, Q, P)
3223      ;
3224        ppl_new_NNC_Polyhedron_from_NNC_Polyhedron_with_complexity(C, Q, P)
3225      )
3226    )
3227  ),
3228  cleanup_ppl_Polyhedron(P).
3229
3230clean_ppl_new_MIP_Problem_from_space_dimension(Dim, MIP) :-
3231  ppl_new_MIP_Problem_from_space_dimension(Dim, MIP),
3232  cleanup_ppl_MIP_Problem(MIP).
3233
3234clean_ppl_new_MIP_Problem(Dim, CS, Obj, Opt, MIP) :-
3235  ppl_new_MIP_Problem(Dim, CS, Obj, Opt, MIP),
3236  cleanup_ppl_MIP_Problem(MIP).
3237
3238clean_ppl_new_MIP_Problem_from_MIP_Problem(MIP1, MIP) :-
3239  ppl_new_MIP_Problem_from_MIP_Problem(MIP1, MIP),
3240  cleanup_ppl_MIP_Problem(MIP).
3241
3242clean_ppl_new_PIP_Problem_from_space_dimension(Dim, PIP) :-
3243  ppl_new_PIP_Problem_from_space_dimension(Dim, PIP),
3244  cleanup_ppl_PIP_Problem(PIP).
3245
3246clean_ppl_new_PIP_Problem(Dim, CS, Vars, PIP) :-
3247  ppl_new_PIP_Problem(Dim, CS, Vars, PIP),
3248  cleanup_ppl_PIP_Problem(PIP).
3249
3250clean_ppl_new_PIP_Problem_from_PIP_Problem(PIP1, PIP) :-
3251  ppl_new_PIP_Problem_from_PIP_Problem(PIP1, PIP),
3252  cleanup_ppl_PIP_Problem(PIP).
3253
3254%%%%%%%%%%%% predicates for switching on/off output messages %
3255
3256make_extra_noisy :-
3257  (retract(noisy(_)) ->
3258      make_extra_noisy
3259  ;
3260      assertz(noisy(2))
3261  ).
3262
3263make_noisy :-
3264  (retract(noisy(_)) ->
3265      make_noisy
3266  ;
3267      assertz(noisy(1))
3268  ).
3269
3270make_quiet :-
3271  (retract(noisy(_)) ->
3272      make_quiet
3273   ; assertz(noisy(0))
3274  ).
3275
3276%%%%%%%%%%%% predicates for pretty printing the PPL banner %%%%%%%%%%
3277%
3278% The banner is read as an atom with"/n" denoting where there should
3279% new lines. Here we print the banner as intended with new lines instead
3280% of "/n".
3281%
3282
3283banner_pp(B) :-
3284  name(B,Bcodes),
3285  nl,
3286  !,
3287  format_banner(Bcodes).
3288
3289format_banner([]) :- nl.
3290format_banner([C]) :- put_code(C), nl.
3291format_banner([C,C1|Chars]):-
3292  ([C,C1] == "/n" ->
3293     (nl,
3294     format_banner(Chars))
3295   ;
3296     (put_code(C),
3297     format_banner([C1|Chars]))
3298  ).
3299
3300%%%%%%%%%%%% predicate for handling an unintended exception %%%%
3301
3302check_exception_term(ppl_overflow_error(Cause)) :-
3303  ((Cause == 'Negative overflow.'; Cause == 'Positive overflow.') ->
3304    true
3305  ;
3306    print_exception_term(ppl_overflow_error(Cause))
3307  ),
3308  !.
3309
3310print_exception_term(ppl_overflow_error(Cause)) :-
3311  nl,
3312  write('Error: an overflow has been detected by the PPL: '),
3313  write(Cause),
3314  nl,
3315  !.
3316
3317print_exception_term(Exception) :-
3318  write('exception'), nl,
3319  nl,
3320  writeq(Exception),
3321  nl.
3322
3323%%%%%%%%%%%% predicate for printing exception messages %%%%%%%%%%
3324
3325format_exception_message(
3326             ppl_invalid_argument( found(F), expected(E), where(W))
3327                        ) :-
3328  !,
3329  display_message(['PPL Prolog Interface Exception:', nl, '   ',
3330                   F, 'is an invalid argument for', W, nl, '   ',
3331                  F, 'should be', E, '.']).
3332
3333format_exception_message(ppl_length_error(Error)) :-
3334  !,
3335  display_message(['PPL Prolog Interface Exception: ', nl, '   ',
3336                   'ppl_length_error', Error]).
3337
3338format_exception_message(
3339             ppl_representation_error(I, where(W))
3340                        ) :-
3341  !,
3342  display_message(['PPL Prolog Interface Exception:', nl, '   ',
3343                   'This Prolog system has bounded integers', nl, '   ',
3344                   I, 'is not in the allowed range of integers', nl, '   ',
3345                   'in call to', W, '.']).
3346
3347format_exception_message(out_of_memory) :-
3348  !,
3349  display_message(['PPL Prolog Interface Exception: ', nl, '   ',
3350                   'out of memory']).
3351
3352format_exception_message(ppl_overflow_error(Type)) :-
3353  !,
3354  display_message(['PPL Prolog Interface Exception: ', nl, '   ',
3355                   'ppl_overflow_error: ', Type]).
3356
3357format_exception_message(cpp_error(Error)) :-
3358  !,
3359  display_message(['PPL C++ Interface Exception:', nl, '   ', Error]).
3360
3361format_exception_message(Error) :-
3362  display_message(['Unknown exception: ', Error]), fail.
3363
3364%%%%%%%%%%%% predicates for output messages %%%%%%%%%%%%%%%%%%
3365
3366error_message(Message):-
3367   write_all(Message).
3368
3369display_message(Message):-
3370    noisy(_),
3371    (noisy(0) -> true ;
3372     (nl, write_all(Message))
3373    ).
3374
3375write_all([]) :- nl.
3376write_all([Phrase|Phrases]):-
3377   (Phrase == nl ->
3378      nl
3379   ;
3380      write(Phrase),
3381      write(' ')
3382   ),
3383   write_all(Phrases).
3384
3385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386
3387% list_groups(G)
3388% The interface predicates are partitioned into related sets called
3389% groups and here is a list of the groups.
3390
3391list_groups( [
3392   large_integers,
3393   all_versions_and_banner,
3394   numeric_bounds,
3395   new_polyhedron_from_dimension,
3396   new_polyhedron_from_polyhedron,
3397   new_polyhedron_from_representations,
3398   swap_polyhedra,
3399   polyhedron_dimension,
3400   basic_operators,
3401%   transform_polyhedron,
3402   extrapolation_operators,
3403   get_system,
3404%   add_to_system,
3405   revise_dimensions,
3406   check_polyhedron,
3407   minmax_polyhedron,
3408   compare_polyhedra,
3409   mip_problem,
3410   pip_problem,
3411   transform_polyhedron,
3412   add_to_system,
3413   catch_time,
3414   handle_exceptions
3415             ] ).
3416
3417% group_predicates(G, P)
3418% P is a list of the interface predicates checked by test for group G.
3419% This is used to generate more informative error and exception messages.
3420
3421group_predicates(all_versions_and_banner,
3422  [ppl_version_major/1,
3423   ppl_version_minor/1,
3424   ppl_version_revision/1,
3425   ppl_version_beta/1,
3426   ppl_version/1,
3427   ppl_banner/1
3428  ]).
3429
3430group_predicates(numeric_bounds,
3431  [ppl_max_space_dimension/1,
3432   ppl_Coefficient_is_bounded/0,
3433   ppl_Coefficient_max/1,
3434   ppl_Coefficient_min/1,
3435   ppl_set_rounding_for_PPL/0,
3436   ppl_restore_pre_PPL_rounding/0
3437  ]).
3438
3439group_predicates(new_polyhedron_from_dimension,
3440  [ppl_new_C_Polyhedron_from_space_dimension/4,
3441   ppl_new_NNC_Polyhedron_from_space_dimension/4,
3442   ppl_Polyhedron_is_universe/1,
3443   ppl_Polyhedron_is_empty/1,
3444   ppl_delete_polyhedron/1
3445  ]).
3446
3447group_predicates(new_polyhedron_from_polyhedron,
3448  [ppl_new_C_Polyhedron_from_C_Polyhedron/3,
3449   ppl_new_C_Polyhedron_from_NNC_Polyhedron/3,
3450   ppl_new_NNC_Polyhedron_from_C_Polyhedron/3,
3451   ppl_new_NNC_Polyhedron_from_NNC_Polyhedron/3,
3452   ppl_new_C_Polyhedron_from_constraints/2,
3453   ppl_new_NNC_Polyhedron_from_constraints/2,
3454   ppl_Polyhedron_equals_Polyhedron/2
3455  ]).
3456
3457group_predicates(new_polyhedron_from_representations,
3458  [ppl_new_C_Polyhedron_from_constraints/2,
3459   ppl_new_NNC_Polyhedron_from_constraints/2,
3460   ppl_new_C_Polyhedron_from_generators/2,
3461   ppl_new_NNC_Polyhedron_from_generators/2
3462  ]).
3463
3464group_predicates(swap_polyhedra,
3465  [ppl_Polyhedron_swap/2
3466  ]).
3467
3468group_predicates(polyhedron_dimension,
3469  [ppl_Polyhedron_affine_dimension/2,
3470   ppl_Polyhedron_space_dimension/2,
3471   ppl_Polyhedron_constrains/2,
3472   ppl_Polyhedron_unconstrain_space_dimension/2,
3473   ppl_Polyhedron_unconstrain_space_dimensions/2]).
3474
3475group_predicates(basic_operators,
3476  [ppl_Polyhedron_intersection_assign/2,
3477   ppl_Polyhedron_poly_hull_assign/2,
3478   ppl_Polyhedron_poly_difference_assign/2,
3479   ppl_Polyhedron_time_elapse_assign/2,
3480   ppl_Polyhedron_topological_closure_assign/1
3481  ]).
3482
3483group_predicates(add_to_system,
3484  [ppl_Polyhedron_add_constraint/2,
3485   ppl_Polyhedron_add_generator/2,
3486   ppl_Polyhedron_add_constraints/2,
3487   ppl_Polyhedron_add_generators/2
3488  ]).
3489
3490group_predicates(revise_dimensions,
3491  [ppl_Polyhedron_remove_space_dimensions/2,
3492   ppl_Polyhedron_remove_higher_space_dimensions/2,
3493   ppl_Polyhedron_expand_space_dimension/3,
3494   ppl_Polyhedron_fold_space_dimensions/3,
3495   ppl_Polyhedron_map_space_dimensions/2,
3496   ppl_Polyhedron_concatenate_assign/2
3497  ]).
3498
3499group_predicates(transform_polyhedron,
3500  [ppl_Polyhedron_affine_image/4,
3501   ppl_Polyhedron_affine_preimage/4,
3502   ppl_Polyhedron_bounded_affine_image/5,
3503   ppl_Polyhedron_bounded_affine_preimage/5,
3504   ppl_Polyhedron_generalized_affine_image/5,
3505   ppl_Polyhedron_generalized_affine_preimage/5,
3506   ppl_Polyhedron_generalized_affine_image_lhs_rhs/4,
3507   ppl_Polyhedron_generalized_affine_preimage_lhs_rhs/4
3508  ]).
3509
3510group_predicates(extrapolation_operators,
3511  [ppl_Polyhedron_BHRZ03_widening_assign_with_token/3,
3512   ppl_Polyhedron_BHRZ03_widening_assign/2,
3513   ppl_Polyhedron_limited_BHRZ03_extrapolation_assign_with_token/4,
3514   ppl_Polyhedron_limited_BHRZ03_extrapolation_assign/3,
3515   ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign_with_token/4,
3516   ppl_Polyhedron_bounded_BHRZ03_extrapolation_assign/3,
3517   ppl_Polyhedron_H79_widening_assign_with_token/3,
3518   ppl_Polyhedron_H79_widening_assign/2,
3519   ppl_Polyhedron_limited_H79_extrapolation_assign_with_token/4,
3520   ppl_Polyhedron_limited_H79_extrapolation_assign/3,
3521   ppl_Polyhedron_bounded_H79_extrapolation_assign_with_token/4,
3522   ppl_Polyhedron_bounded_H79_extrapolation_assign/3
3523  ]).
3524
3525group_predicates(get_system,
3526  [ppl_Polyhedron_get_constraints/2,
3527   ppl_Polyhedron_get_minimized_constraints/2,
3528   ppl_Polyhedron_get_generators/2,
3529   ppl_Polyhedron_get_minimized_generators/2
3530  ]).
3531
3532group_predicates(check_polyhedron,
3533  [ppl_Polyhedron_relation_with_constraint/3,
3534   ppl_Polyhedron_relation_with_generator/3,
3535   ppl_Polyhedron_is_topologically_closed/1,
3536   ppl_Polyhedron_is_universe,
3537   ppl_Polyhedron_is_empty,
3538   ppl_Polyhedron_is_bounded,
3539   ppl_Polyhedron_contains_integer_point,
3540   ppl_Polyhedron_contains_Polyhedron/2,
3541   ppl_Polyhedron_strictly_contains_Polyhedron/2,
3542   ppl_Polyhedron_is_disjoint_from_Polyhedron/2,
3543   ppl_Polyhedron_equals_Polyhedron/2,
3544   ppl_Polyhedron_termination_test_MS/2,
3545   ppl_Polyhedron_termination_test_PR/2,
3546   ppl_Polyhedron_OK/1
3547  ]).
3548
3549group_predicates(minmax_polyhedron,
3550  [ppl_Polyhedron_maximize/5,
3551   ppl_Polyhedron_maximize_with_point/6,
3552   ppl_Polyhedron_minimize/5,
3553   ppl_Polyhedron_minimize_with_point/6
3554  ]).
3555
3556group_predicates(compare_polyhedra,
3557  [ppl_Polyhedron_contains_Polyhedron/2,
3558   ppl_Polyhedron_strictly_contains_Polyhedron/2,
3559   ppl_Polyhedron_is_disjoint_from_Polyhedron/2,
3560   ppl_Polyhedron_equals_Polyhedron/2
3561  ]).
3562
3563group_predicates(catch_time,
3564  [ppl_set_timeout_exception_atom/1,
3565   ppl_timeout_exception_atom/1,
3566   ppl_set_timeout/1,
3567   ppl_reset_timeout/0
3568  ]).
3569
3570group_predicates(mip_problem,
3571  ['all MIP_Prolog predicates'
3572  ]).
3573
3574group_predicates(pip_problem,
3575  ['all PIP_Prolog predicates'
3576  ]).
3577
3578group_predicates(large_integers,
3579  ['large integer tests '
3580  ]).
3581
3582group_predicates(handle_exceptions,
3583  'all predicates'' exception handling.'
3584  ).
3585
3586%%%%%%%%%%%%%%%%%%%%%%% System flags %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3587%
3588% pl_check_prolog_flag/2
3589% returns true or false (if the 1st argument is 'bounded')
3590% or (if the 1st argument is 'max_integer' or  'min_integer')
3591% the maximum or minimum integer for Prolog
3592% systems that have bounded integers.
3593% Note that 268435456 is 2^28.
3594
3595pl_check_prolog_flag(bounded, TF) :-
3596  current_prolog_flag(bounded, TF).
3597
3598pl_check_prolog_flag(max_integer, Max_Int) :-
3599  \+ prolog_system('XSB'),
3600  current_prolog_flag(max_integer, Max_Int).
3601
3602pl_check_prolog_flag(max_integer, Max_Int) :-
3603  prolog_system('XSB'), Max_Int is 268435455.
3604
3605pl_check_prolog_flag(min_integer, Min_Int) :-
3606  \+ prolog_system('XSB'),
3607  current_prolog_flag(min_integer, Min_Int).
3608
3609pl_check_prolog_flag(min_integer, Min_Int) :-
3610  prolog_system('XSB'), Min_Int is -268435456.
3611