rnso
rnso

Reputation: 24555

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.

Upvotes: 6

Views: 1005

Answers (1)

user502187
user502187

Reputation:

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.

Upvotes: 1

Related Questions