Prolog clpfd :: operator expected - prolog

Dear Stackoverflow Community,
I just wanted to test out the constrained logic programming library (clpfd) for Prolog.
So I am including the library by calling
:- use_module(library(clpfd)).
Then I want to do sth like the following.
[X,Y] :: [1..2], X #\= Y, X+Y #\= 3.
But I always get the answer that
ERROR: Syntax error: Operator expected
ERROR: [X,Y]
ERROR: ** here **
ERROR: :: [1..2], X #\= Y, X+Y #\= 3 .
The same happens when executing the following example
? member(X,[42,1,17]), [X,Y] :: [0..20].
ERROR: Syntax error: Operator expected
ERROR: member(X,[42,1,17]), [X,Y]
ERROR: ** here **
ERROR: :: [0..20] .
Seems like Prolog does not recognise the :: operator properly.
Any help is appreciated

As far as I know, there is no (::)/2 predicate in the clpfd library. You are probably looking for the ins/2 predicate. For example:
?- [X,Y] ins 1..2, X #\= Y, X+Y #\= 3, label([X,Y]).
false.
?- [X,Y] ins 1..3, X #\= Y, X+Y #\= 3, label([X,Y]).
X = 1,
Y = 3 ;
X = 2,
Y = 3 ;
X = 3,
Y = 1 .
So if X and Y are in 1..2, then there is no solution, since your first constraint says X should be different from Y, and the second constraint says that X + Y should be different from 3.
In case we add 3 to the result, then there are solutions.
We can here use ins/2 to filter as well:
?- member(X,[42,1,17]), [X,Y] ins 0..20.
X = 1,
Y in 0..20 ;
X = 17,
Y in 0..20.

Related

How do I fix this triangular sequence (recursion) in prolog Arguments are not sufficiently instantiated?

Trying to calculate the triangular number sequence in Prolog.
This is my solution:
where X is the nth position of the sequence and Y is the result.
triang(1, 1).
triang(X, Y) :-
X>0,
A is X - 1,
triang(A, B),
Y is B + X.
?- triang(5,X).
X = 15
But when i try to do for example triang(X,10) I receive an error
Arguments are not sufficiently instantiated.
I guess this is because X is not defined in the consult.
is there any recommendation how to solve this problem,thank you.
First of all, the result you got is not that bad. It says: sorry, I am unable to come to a conclusion and before producing an incorrect result, I prefer to produce an error.
The actual reason is the following goal
?- X > 0.
error(instantiation_error,(is)/2).
So here we ask for X that are greater than zero. And there are many, in fact infinitely many. There is no direct way to enumerate that set for this built-in and thus it prefers the error.
However, with library(clpz) or clpfd, there is a better way:
:- use_module(library(clpz)). % use clpfd for SWI instead
:- op(150, fx, #).
triang(0, 0).
triang(X, Y) :-
#X #>0,
#Y #>0,
#A #= #X - 1,
#Y #= #B + #X,
triang(A, B).
?- triang(X,15).
X = 5
; false.
?- triang(X,14).
false.
?- triang(X,X).
X = 0
; X = 1
; false.
?- triang(X,Y).
X = 0, Y = 0
; X = 1, Y = 1
; X = 2, Y = 3
; X = 3, Y = 6
; X = 4, Y = 10
; X = 5, Y = 15
; X = 6, Y = 21
; ... .
?- #X #> 0.
clpz:(X in 1..sup).
So now there is an answer to #X #> 0. The answer is often called a constraint. In this case it tells us that X must be in the interval 1 up to (kind of) infinity.

Prolog: How do I list the different values that X and Y could be using prolog's clpfd library?

test(X, Y) :-
X ins 1..3,
Y ins 1..3,
X #\= Y.
Here is my attempt at doing it. The goal would be to type this into SWI-Prolog so that this output comes out.
?- test(X, Y).
X = 1
Y = 2 ;
X = 2,
Y = 1;
X = 3,
Y = 1 ;
... etc.
I'm actually trying to solve the 8-queens problem using prolog and have this so far.
eight_queens(Qs, L) :-
Qs = [ [X1,Y1], [X2, Y2], [X3, Y3], [X4, Y4], [X5, Y5], [X6, Y6], [X7, Y7], [X8, Y8], [X9, Y9] ],
Qs ins 1..9,
X1 #\= X2,
X1 #\= X3,
...
etc.
But I keep getting this error: "Arguments are not sufficiently instantiated" for both the test function and the eight_queens problem.
Besides the observation about in/2 and ins/2 posted by #coder, that solve your imminent problem, I would add the following points that are good to keep in mind when using CLP(FD):
1. Always make labeling the last goal
First let's observe the answers for the variant marked as 2nd way using ins in #coder's post but without the goal label/1:
test(X, Y) :-
[X,Y] ins 1..3,
X #\= Y.
?- test(X,Y).
X in 1..3, % residual goal
X#\=Y, % residual goal
Y in 1..3. % residual goal
Since there is no unique answer to the query, Prolog answers with residual goals (see section A.8.8 of the CLP(FD) manual) for more information). These residual goals are constraints that are being propagated and with every additional (non-redundant) constraint the domain is narrowed. If this does not lead to a unique solution like in the example above you can get concrete values by labeling the constrained variables (e.g. with label/1). This observation suggests to use labeling as the last goal:
?- test(X,Y), label([X,Y]).
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
X = 2,
Y = 1 ;
X = 2,
Y = 3 ;
X = 3,
Y = 1 ;
X = 3,
Y = 2.
This is obviously the same result as with #coders version but the three pairs (X,Y) = (1,1) ∨ (2,2) ∨ (3,3) are not considered when labeling due to the constraint X#\=Y being posted before the goal label([X,Y]). In #coder's version it is the other way around: label([X,Y]) is delivering all three pairs as possible solutions and the last goal X#\=Y is eliminating them subsequently. To see this just leave the last goal as a comment and query the predicate:
test(X,Y):- [X,Y] ins 1..3, label([X,Y]). %, X#\=Y.
?- test(X,Y).
X = Y, Y = 1 ; % <- (1,1)
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
X = 2,
Y = 1 ;
X = Y, Y = 2 ; % <- (2,2)
X = 2,
Y = 3 ;
X = 3,
Y = 1 ;
X = 3,
Y = 2 ;
X = Y, Y = 3. % <- (3,3)
The difference is minuscule in this example, so there's nothing wrong with #coder's version. But in general this might lead to a big difference if the constraints posted after labeling exclude a lot of candidates. So it's good practice to always put labeling as the last goal.
2. Separate labeling from the actual relation
Coming from the previous observations it is opportune to divide the predicate into a core relation that is posting all the constraints and labeling. Consider the restructured predicate test/2 as a template:
test(X,Y) :-
test_(X,Y,L), % the core relation
label(L). % labeling
test_(X,Y,L) :-
L=[X,Y], % variables to be labeled in a flat list
L ins 1..3,
X#\=Y.
The predicate test_/3 is describing the actual relation by posting all the necessary constraints and has a list as an additional argument that contains all the variables to be labeled. Obtaining the latter might not be trivial, depending on the data structures your arguments come with (consider for example a list of lists as an argument that you want to turn into a flat list for labeling). So the predicate test/2 is only calling test_/3 and subsequently the labeling goal. This way you have a clean and easily readable separation.
3. Try different labeling strategies
The goal label(L) is the simplest way to do labeling. It is equivalent to labeling([],L). The first argument of labeling/2 is a list of options that gives you some control over the search process, e.g. labeling([ff],L) labels the leftmost variable with the smallest domain next, in order to detect infeasibility early. Depending on the problem you are trying to solve different labeling strategies can lead to results faster or slower. See the documentation of labeling/2 for available labeling strategies and further examples.
ins is used for lists, in is used for single variable so in your example:
test(X, Y) :-
X ins 1..3,
Y ins 1..3,
X #\= Y.
X,Y are assumed to be lists. This does not produces a syntax error, but produces error when trying to run it with X,Y not being lists.
Also when using in Low..High doesn't mean that the variable is int just X=<High and X>=Low. In order to put the constraint to be integers use label/1:
:- use_module(library(clpfd)).
%using in/
test(X,Y):- X in 1..3,Y in 1..3,label([X,Y]), X#\=Y.
%2nd way using ins
test(X,Y):- [X,Y] ins 1..3, label([X,Y]), X#\=Y.
Example:
?- test(X,Y).
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
X = 2,
Y = 1 ;
X = 2,
Y = 3 ;
X = 3,
Y = 1 ;
X = 3,
Y = 2 ;
false.

Why no division in CLP(FD) in Prolog?

I could not find division (/) symbol on this page of CLP(FD): http://www.swi-prolog.org/man/clpfd.html
Also this simple code give error:
:-use_module(library(clpfd)).
afn(A,B,C):-
C #= B / A.
?- afn(23, 56, C).
ERROR: Domain error: `clpfd_expression' expected, found `56/23'
Where is the problem and how can this be solved? Thanks.
In ISO Prolog (/)/2 yields a float result. SWI-Prolog is not ISO compliant here, it casts to an integer where possible. But basically (/)/2 is viewed as an operation between machine real numbers, that gives a new approximated machine real number.
On the other hand CLP(FD) works only with integers. Therefore, I guess, this is the reason that CLP(FD) usually don't support the (/)/2 operator. On the otherhand the div operator (//)/2 from ISO Prolog, works also for CLP(FD). Supported are:
Expr // Expr Truncated integer division
Expr div Expr Floored integer division
Here is an example run:
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)
?- use_module(library(clpfd)).
true.
?- X #= 100 // Y, Y = 7.
X = 14,
Y = 7.
?- X #= Z // 7, X = 14.
X = 14,
Z in 98..104.
If you have a CLP(FD) without the (//)/2 operator, you can simulate it. Instead of X #= Y//Z, you can write X*Z+R #= Y, 0 #=< R, R #< Z. When negative arguments are involved you need a more complex formula.
Here are some example runs that show that this approach also works:
?- X*Y+R #= 100, 0 #=< R, R #< Y, Y = 7.
X = 14,
Y = 7,
R = 2.
?- X*7+R #= Z, 0 #=< R, R #< 7, X = 14.
X = 14,
R in 0..6,
-98+Z#=R,
Z in 98..104.

#< Symbol In Prolog

I want to know what #< means in Prolog?
I encountered this symbol in this line of code while reading about the Bridge and Torch Problem:
select_one_or_two(L, [Sel1,Sel2], L2) :-
select(Sel1, L, NewL),
select(Sel2, NewL, L2),
Sel1 #< Sel2.
The comparative operators that start with # are more general than the ones that don't. With operators such as </2, you can only compare numeric values and expressions (involving literal numerics and variables that are instantiated with numeric values). So, with </2 you can do this:
?- X = 2, Y = 3, X + Y < 2*Y.
X = 2,
Y = 3.
?- X = 2, Y = 3, X + Y > 2*Y.
false.
?-
But you will get an error in the following cases if the expressions don't evaluate to a known numeric:
?- Y = 3, X + Y < 2*Y.
ERROR: </2: Arguments are not sufficiently instantiated
Or:
?- a < b.
ERROR: </2: Arithmetic: `a/0' is not a function
However, using #</2 you can compare lots of different types of objects in prolog. The comparison evaluation follows the rules described in the link that #Ankur gave. To understand these rules, you'll need to know what Prolog terminology means, such as term, functor, atom, etc (see, for example, Prolog Terms)
Looking at some examples:
?- a #< b.
true.
?- a(1) #< a(2).
true.
?- b(1) #< a(2).
false.
?- 20 #< a.
true.
These are pretty straight-forward, following the rules. Here's a more interesting case (from above):
?- Y = 3, X + Y #< 2*Y.
false.
Why would X + Y be considered "not less than" 2*Y? Prolog would internally look at this as:
`+(X,3) #< *(2,3).`
(Note Y is instantiated to 3.) These are compound terms (they aren't individual atoms or variables). If we look through the comparison rules, the matching rule is:
Compound terms are first checked on their arity, then on their functor
name (alphabetically) and finally recursively on their arguments,
leftmost argument first.
The arity of both terms is 2. The functor names are + and * respectively. Those are different. And in teh ASCII collating sequence, + comes after *. Therefore it is not true that + "is less than" *, and therefore not true that +(X,3) #< *(2,3). Thus, it is not true that Y = 3, X + Y #< 2 * Y.
Note also that #</2 doesn't evaluate numeric expressions. So even with X and Y instantiated as values, you will get:
?- X = 2, Y = 3, X + Y #< 2*Y.
false.
Whereas, when we had </2 here, this is true, since the expression X + Y < 2*Y, when evaluated, is true. When variables are simply unified, it understands that, however, so you would have:
| ?- X #< Y.
yes
But on the other hand:
| ?- X = 2, Y = 1, X #< Y.
no
In this case X #< Y is seen as 2 #< 1 due to the unification of X with 2 and Y with 1 and the numeric rule kicks in.
Having said all that, the use of #</2 in the predicate select_one_or_two enables that predicate to be usable on lists of all sorts of objects, not just numbers or fully instantiated numeric expressions. If it had used </2, then the following would work:
?- select_one_or_two([2,1,3], X, Y).
X = [2, 3],
Y = [1] ;
X = [1, 2],
Y = [3] ;
X = [1, 3],
Y = [2] ;
false.
But the following fails:
?- select_one_or_two([b,a,c], X, Y).
ERROR: </2: Arithmetic: `b/0' is not a function
?-
However, with the #< operator, it works:
?- select_one_or_two([b,a,c], X, Y).
X = [b, c],
Y = [a] ;
X = [a, b],
Y = [c] ;
X = [a, c],
Y = [b] ;
false.

Understanding prolog [lists]

I am to write a program that does this:
?- pLeap(2,5,X,Y).
X = 2,
Y = 3 ;
X = 3,
Y = 4 ;
X = 4,
Y = 5 ;
X = 5,
Y = 5 ;
false.
(gives all pairs X,X+1 between 2 and 5, plus the special case at the end).
This is supposedly the solution. I don't really understand how it works, could anyone guide me through it?
pLeap(X,X,X,X).
pLeap(L,H,X,Y) :-
L<H,
X is L,
Y is X+1.
pLeap(L,H,X,Y) :-
L=<H,
L1 is L+1,
pLeap(L1,H,X,Y).
I'd do it simply like this:
pLeap(L,H,X,Y) :-
X >= L,
X =< H,
Y is X+1.
Why doesn't it work (ignoring the special case at the end)?
You could use library clpfd for you problem.
:- use_module(library(clpfd)).
pLeap(L,H,X,Y) :-
X in L..H,
Y #= min(H, X+1),
label([X]).
Here is the output:
?- pLeap(2,5,X,Y).
X = 2,
Y = 3 ;
X = 3,
Y = 4 ;
X = 4,
Y = 5 ;
X = 5,
Y = 5.
The >= and =< operators don't instantiate their arguments, and you can only use them once the arguments have already been instantiated.
Put another way, in the given solution, X and Y are given values with is, and the < and =< operators are only used on L and H, whose values are given by the user. (On the given solution, try pLeap(L,H,2,3) and you'll get the same problem as you're having.)
In your case, though, you try to use >= and =< on X, which has no value yet, and so the interpreter complains.

Resources