为什么在Prolog中CLP(FD)中没有划分?

rns*_*nso 6 prolog clpfd

:我不能这个页面CLP(FD)的上找到除法(/)符号http://www.swi-prolog.org/man/clpfd.html

同样,这个简单的代码也会给出错误:

:-use_module(library(clpfd)). 
afn(A,B,C):-
    C #= B / A.


?- afn(23, 56, C).
ERROR: Domain error: `clpfd_expression' expected, found `56/23'
Run Code Online (Sandbox Code Playgroud)

问题在哪里,如何解决?谢谢。

小智 1

在 ISO Prolog 中 (/)/2 产生浮点结果。SWI-Prolog 在这里不符合 ISO,它会尽可能转换为整数。但基本上 (/)/2 被视为机器实数之间的运算,它给出了新的近似机器实数。

另一方面,CLP(FD) 仅适用于整数。因此,我猜想,这就是CLP(FD)通常不支持(/)/2运算符的原因。另一方面,ISO Prolog 中的 div 运算符 (//)/2 也适用于 CLP(FD)。支持的有:

Expr // Expr 截断整数除法
Expr div Expr 下限整数除法

这是一个运行示例:

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.
Run Code Online (Sandbox Code Playgroud)

如果您有一个不带 (//)/2 运算符的 CLP(FD),则可以对其进行模拟。您可以写 X*Z+R #= Y, 0 #=< R, R #< Z,而不是 X #= Y//Z。当涉及负参数时,您需要更复杂的公式。

以下是一些运行示例,表明这种方法也有效:

?- 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.
Run Code Online (Sandbox Code Playgroud)