[PPL-devel] On using PPL (powersets) from SWI Prolog

j.c.vandepol at utwente.nl j.c.vandepol at utwente.nl
Mon Aug 7 17:37:32 CEST 2017


Hi Roberto, other developers,

Thanks for the package PPL! I'm just going to use it for the first time, and I have read
some documentation, but it looks really great.

I had some issues when installing and using the Parma Polyhedra Library for the first time.
Everything seems to be working now, so I hope you can use my experience to improve the
documentation a bit (which is already quite extensive!).

What I need are disjunctions of conjunctions of inequations, so I decided to go for the
pointset powerset domain. I was already using CLP, so I decided to go for the SWI Prolog
bindings. (Probably not directly the easiest path into using PPL)

At the end, some suggestion how a “more Prolog-like” interface could look like.

I really hope this helps you and future users.

Kind regards,
Jaco van de Pol


I am using PPL version 1.2, on a Mac Notebook with MacOS Sierra 10.12.6, with SWI Prolog version 7.2.3.

I was using the following documentation:
- http://bugseng.com/products/ppl/documentation//user/ppl-user-prolog-interface-1.2-html/domains_predicates.html

Here are some issues:
1. "brew install ppl" nicely installs PPL, but it doesn't provide the SWI bindings / library,
so I decided to install it myself from the source code.

2. The documentation suggests that SWI bindings should be generated automatically if swipl is on the path.
This was not true: I had to explicitly add: --enable-interfaces=SWI_PROLOG  (and this was not documented a.f.a.i.k.)

3. The library is called "*.so", where swipl expects it to be called "*.dylib". I found a comment on the web about it,
but the documentation didn't mention it. It requires either making a ln -s link manually, or loading the library with
:- load_foreign_library('<prefix>/lib/ppl/libppl_swiprolog.so').

4. I found it hard to understand how variables are handled. Apparently I need something like '$Var'(VarId).
It appears in the grammar ("predicate specifications") but it is not explained what this is supposed to mean
and what the rules are.

5. I found it hard to get started with disjunctions (Pointset_Powerset). The documentation seems incomplete,
and it was not clear what the various +Iterators and +Handles are referring to exactly.

6. The feature I was lacking most was how to create an initial Pointset_Powerset.
I found out that the following was working, but this function seems to be missing entirely
from the documentation. I understand that this follows a general pattern, but it makes
it hard to get started with powerset domains:
ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension(0,empty,R),

7. The documentation says:
ppl_Pointset_Powerset_C_Polyhedron_iterator_get_disjunct(+Iterator, -Handle)
Unifies with Handle a reference to the disjunct referred to by Iterator_1.
However, the real name appears to be: ppl_Pointset_Powerset_C_Polyhedron_get_disjunct

8. The documentation says:
ppl_Pointset_Powerset_C_Polyhedron_iterator_increment(+Iterator)
Increments the iterator referenced by Iterator so that it "points" to the next disjunct.
However, the real name appears to be: ppl_Pointset_Powerset_C_Polyhedron_increment_iterator
8b. (probably similar with decrement; I didn't check it)

9. It would help to add some code examples, if only in the test scripts for PPL, but preferably to the documentation.
It seems that example code (with prolog) is missing throughout the documentation. Here is my first example,
maybe you can use it. (In particular: nice to see how the two boxes are glued together in a single box!)

load_foreign_library('/Users/vdpol/lib/ppl/libppl_swiprolog.so').
X='$VAR'(0),
Y='$VAR'(1),
ppl_new_C_Polyhedron_from_constraints([X>=2, Y>=1, 5-X >= Y],P),
ppl_new_C_Polyhedron_from_constraints([X=<4, Y=<3, Y >= 5-X],Q),
ppl_Polyhedron_get_constraints(P,LP),
ppl_Polyhedron_get_constraints(Q,LQ),
ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension(2,empty,R),
ppl_Pointset_Powerset_C_Polyhedron_add_disjunct(R,P),
ppl_Pointset_Powerset_C_Polyhedron_add_disjunct(R,Q),
ppl_Pointset_Powerset_C_Polyhedron_pairwise_reduce(R),
ppl_Pointset_Powerset_C_Polyhedron_begin_iterator(R,I),
ppl_Pointset_Powerset_C_Polyhedron_get_disjunct(I,P1),
ppl_Polyhedron_get_constraints(P1,L1).

9. Handling handles and iterators is quite error-prone
(in particular handling their side effects, and the implicit typing rules).
This can even lead to segfaults, consider the following (wrong) attempt
(there is no second disjunct after pairwise_reduce):
load_foreign_library('/Users/vdpol/lib/ppl/libppl_swiprolog.so').
X='$VAR'(0),
Y='$VAR'(1),
ppl_new_C_Polyhedron_from_constraints([X>=2, Y>=1, 5-X >= Y],P),
ppl_new_C_Polyhedron_from_constraints([X=<4, Y=<3, Y >= 5-X],Q),
ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension(2,empty,R),
ppl_Pointset_Powerset_C_Polyhedron_add_disjunct(R,P),
ppl_Pointset_Powerset_C_Polyhedron_add_disjunct(R,P),
ppl_Pointset_Powerset_C_Polyhedron_pairwise_reduce(R),
ppl_Pointset_Powerset_C_Polyhedron_begin_iterator(R,I),
ppl_Pointset_Powerset_C_Polyhedron_increment_iterator(I),
ppl_Pointset_Powerset_C_Polyhedron_get_disjunct(I,P2),
ppl_Polyhedron_get_constraints(P2,L).
(I ran into quite some more segfaults from SWI-Prolog (!))

10. Handling handles and iterators is quite un-Prolog-like (side effects).
To me, it seems more natural to provide a Prolog-interface at the level
of "conjunctions from lists of constraints" and
"disjunctions from lists of conjunctions".
With some simple auxiliary functions I can write code like:
X='$VAR'(0),
Y='$VAR'(1),
conjunction([X>=2, Y>=1, 5-X >= Y],P),
conjunction([X=<4, Y=<3, Y >= 5-X],Q),
disjunction([P,Q],2,R),
get_disjuncts(R,D).

The code to get the disjuncts reads as follows. (Maybe I shouldn't have called
ppl_Polyhedron_get_constraints in this code; I'm not yet sure if I want to
encapsulate the handles, or keep them in my prolog program)

get_all_disjuncts(_,Begin,End,[]) :-
    ppl_Pointset_Powerset_C_Polyhedron_iterator_equals_iterator(Begin,End),
    !,
    ppl_delete_Pointset_Powerset_C_Polyhedron_iterator(Begin),
    ppl_delete_Pointset_Powerset_C_Polyhedron_iterator(End).

get_all_disjuncts(D,Begin,End,[Cs|L]) :-
    ppl_Pointset_Powerset_C_Polyhedron_get_disjunct(Begin,C),
    ppl_Polyhedron_get_constraints(C,Cs),
    ppl_Pointset_Powerset_C_Polyhedron_increment_iterator(Begin),
    get_all_disjuncts(D,Begin,End,L).

get_disjuncts(D,L) :-
    ppl_Pointset_Powerset_C_Polyhedron_begin_iterator(D,B),
    ppl_Pointset_Powerset_C_Polyhedron_end_iterator(D,E),
    get_all_disjuncts(D,B,E,L).

--
Prof. Jaco van de Pol
University of Twente (NL)
Formal Methods and Tools
http://www.cs.utwente.nl/~vdpol

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cs.unipr.it/pipermail/ppl-devel/attachments/20170807/865eca80/attachment.htm>


More information about the PPL-devel mailing list