Interesting results with library(clpfd)


I have a very simple program using library(clpfd) but I am confused as to why a possible answer is not being reported. The program is as follows:

:- use_module(library(clpfd)).

solution1(A, D, B) :-
    B #= A + (A // D),
    D #> 0, D #< 101,
    A mod D #= 0,
    A #> 99,
    A #< 1000,
    A #< B,
    label([A, D, B]).
solution2(A, N, D, B) :-
    B #= A + (A * N) // D,
    N #> 0, N #< 100,
    D #> 0, D #< 101,
    N #< D,
    (A * N) mod D #= 0,
    A #> 99,
    A #< 1000,
    A #< B,
    label([A, N, D, B]).

When I set B to a specific value, I get the following answers:

2 ?- solution1(A, D, 749).
A = 642,
D = 6 ;

3 ?- solution2(A, N, D, 749).
A = 378,
N = 53,
D = 54 ;
A = 385,
N = 52,
D = 55 .

As you can see… solution2 is where the constraint has the numerator (N) and denominator (D) specified, but solution1 is where N = 1 and so the constraints are simplified.

What I don’t understand is why doesn’t solution2 report a solution for N = 1 and D = 6? I have probably done something very silly but I can’t see it.

Hi @sits, I’m not sure why you think your solution2 doesn’t report the solution N = 1 && D = 6.
In fact, since you have the doubt you could have checked directly:

?- solution2(A, 1, 6, 749).
A = 642.

When you issue the more general query solution2(A, N, D, 749). you have to continue generating new solutions till you find the one you’re interested in. Note that since you’re using label([A, N, D, B]). in the definition of solution2, the solutions are found in increasing lexicographic order, which means in particular increasing values of A. So you have to generate quite a few of them to get to A = 642 and see the other correct assignments.

Ugh… my bad it seems. I was using swipl from a plain emacs shell buffer and for some reason after I pressed ‘;’ the second time it seemed to stop emitting answers. I just tried using swipl from a terminal window outside emacs and all works correctly. I have no idea what emacs shell is doing here, but that is nasty! Anyway… good to see clpfd is working correctly.

Awesome! Side note: if you’re using emacs, I’d suggest to check out Triska’s ediprolog mode instead:

Indeed - I have just been lazy setting it up. I can certainly use ansi-mode fine though, but shell-mode (with its line-orientated input) is clearly dangerous to use with prolog in some situations like mine.

If you’re running swipl under emacs shell, do it with swipl --no-tty. More details here: SWI-Prolog -- Manual

Many thanks Peter - that is handy to know.