previous_group previous up next next_group
Previous: 5. Clarity of terminology Up: 1. Emptiness Test and Next: 7. Conclusion:

6. Incompatibilities:

In $C^3$, the implementation of the emptiness test is complicated. The boolean sc_empty_p() and boolean sc_rn_p() functions quickly test whether the constraint system is the constant sc_empty or sc_universe [*], whereas the full rational and integer tests, which implement several algorithms such as Fourier-Motzkin, Simplex and cutting plane methods (see the author's thesis for these methods), are also available. These functions are: boolean sc_feasibility_ofl_ctrl(Psysteme sc), boolean sc_rational_feasibil
ity_ofl_ctrl(Psysteme sc)
, boolean sc_integer_feasibility_ofl_ctrl(Psysteme sc). Inside these functions, heuristics are implemented for the selection of algorithms, which are based on the number of the constraints of the polyhedron in question.

It is somehow simpler in the other three libraries: there are no integer or rational signatures, no quick test signature and there is only one algorithm for this operator. Nonetheless, there are two different versions of the emptiness test which are not available in $C^3$ but in the others: in Octagon, we have bool oct_is_empty(oct_t* m), tbool oct_is_empty_lazy(oct_t* m); in New POLKA, we have bool poly_is_empty (const poly_t* po), tbool poly_is_empty_lazy (const poly_t* po). The lazy version is used in order to delay the closure computation, which is rather expensive. The similar technique is also applied in PPL with the and_minimized version.

Which value to return at the end of a function's execution also raises a compatibility problem since New POLKA uses the triple true, false and dontknow in case of exceptions. This links to its chosen policy for exception handling; meanwhile $C^3$ uses true for semantic true and false for dontknow [*]. We notice here that sc_empty_p is semantically different from not sc_not_empty_p because of exceptional cases. It then needs a is_not_empty test, knowing that not_is_empty is different from is_not_empty. We can also use is_known_not_empty and is_known_empty.

We remark that each implementation has its own naming convention; for example in $C^3$, is_xxx_p is different from is_xxx where the suffix _p is used for boolean test, p stands for predicate; in New POLKA, suffix _t is used for type, etc.

In the same way, the mechanism handling exceptions changes the operator's signature: some have exception handlers, e.g. $C^3$; some do not, e.g. New POLKA. The PPL library in its C interface proposes the standard returned codes of integer type, which tells the status of the operation: result or exception code. Otherwise, we can deal with internal errors, i.e. at lower level than the interface, while hiding exception-related issues from the interface's signatures.

When dealing with multiple algorithms for one operator, beside the interface problems, we expect to see some algorithms destroy the inputs by side effects, while some behave functionally. For example, there are several algorithms for solving the emptiness test, among which the Simplex and the Fourier-Motzkin methods. The former builds a hash table and then works on this table without modifying the given input which, in this case, is a constraint system, whereas the latter performs transformations of the corresponding constraint system, hence modifies its input. For this reason, we may have destructive and/or non-destructive functions. If we make a copy of each input, which helps the debugging process inside the library [*], the copying will penalize the overall speed performance.

Then the question of exposing or not the destructive functions (PPL uses the name recycle) directly impacts the interface, as well as the memory management by reference counters. However, weIn HQ, we have decided to use the destructive function alongside with the standard one.


previous_group previous up next next_group
Previous: 5. Clarity of terminology Up: 1. Emptiness Test and Next: 7. Conclusion:
Nguyen Que Duong
2006-09-16