prologswi-prologconstraint-programmingclpfd

Maximize distance between variables' value in SWI-Prolog(clpfd)


I want to maximize the difference between two variables:

:- use_module(library(clpfd)).
maximize(X) :- 
    X = [A,B],
    X ins 1..5,
    % I want to write a constraint to have maximum difference between A and B.

Solution

  • There is no constraint to express maximum difference. Nor any constraint to express a maximum1. To permit such a construct some form of quantification would be necessary. And/or problems with monotonicity would arise.

    However, there is something related: you might want to generate values such that the largest value is produced first:

    :- use_module(library(clpfd)).
    maximize(Xs) :- 
        Xs = [A,B],
        Xs ins 1..5,
        labeling([max(abs(A-B))],Xs).
    
    ?- maximize(Xs).
       Xs = [1,5]
    ;  Xs = [5,1]
    ;  Xs = [1,4]
    ;  Xs = [2,5]
    ;  Xs = [4,1]
    ; ... .
    

    So it starts with the biggest distance and then lowers it one-by one.

    At first this behavior might surprise you, but recall what the manual states

    Labeling is always complete, always terminates, and yields no redundant solutions.

    This is a very strong guarantee!

    If you now want just the first solution, wrap a once/1 around labeling/2 but keep in mind that you then left the realm of pure, monotonic programs.


    Footnote 1: It is possible to express the maximum of two variables max(X,Y) but this does not constrain the maximum to be the largest possible value! It will be only the largest value of X and Y.