为什么 Prolog 中的 CLP(FD) 没有除法?

Why no division in CLP(FD) in Prolog?

我在 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'

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

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

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

Expr // Expr Truncated integer division
Expr div Expr Floored integer division

这是一个例子运行:

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.

如果你有一个没有 (//)/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.