Search code examples
prologclpfd

Which operators and predicates can be used with clp(fd)?


Firstly, the clp(fd) documentation mentions:

In modern Prolog systems, arithmetic constraints subsume and supersede low-level predicates over integers. The main advantage of arithmetic constraints is that they are true relations and can be used in all directions. For most programs, arithmetic constraints are the only predicates you will ever need from this library.

Secondly, on a previously asked question, it was mentioned that include/3 is incompatible with clp(fd).

Does that mean that only clp(fd) operators and clp(fd) predicates can be used when writing prolog with the clp(fd) library?

Furthermore, for example, why is include/3 incompatible with clp(fd)? Is it because it does not use clp(fd) operators? To use include/3 in clp(fd) code, would one need to rewrite a version that uses clp(fd) operators and constraints?


Solution

  • include/3 doesn't have to be incompatible with clpfd (or any other use of attributed variables) - depends on the safe (for the purposes of the program, rather than necessarily "logically pure") usage of the attributed variables. E.g.:

    :- use_module(library(clpfd)).
    
    test_include(F) :-
        L = [N1, N2, N3, N4],
        N1 #< 2,
        N2 #> 5,
        N3 #< 3,
        N4 #> 8,
        include(gt_3_fd, L, F).
    
    gt_3_fd(I) :-
        I #> 3.
    

    Result in swi-prolog:

    ?- test_include(F).
    F = [_A, _B],
    _A in 6..sup,
    _B in 9..sup.
    

    The above code is safe, because the variables being used with clpfd are being used consistently with clpfd, and the specified constraints result in reification of gt_3_fd being unnecessary.

    Once the variables are nonvar/ground depending on the use-case (clpfd deals with integers, rather than e.g. compound terms, so nonvar is good enough), then the variables can also be used outside of clpfd. Example:

    ?- I = 5,  I > 4, I @> 4, I #> 4.
    I = 5.
    

    An operator such as > uses the actual value of the variable, and ignores any attributes which might have been added to the variable by e.g. clpfd.

    Logical purity, e.g. adding constraints to the elements in list L after the include/3 rather than before, is a separate issue, and applies to non-attributed variables also.

    In summary: A program may be using some integers with clpfd, and some integers outside of clpfd, i.e. a mixture. That is OK, as long as the inside-or-outside distinction is consistently applied, while it is relevant (because e.g. labeling will produce actual values).