【问题标题】:Why no division in CLP(FD) in Prolog?为什么 Prolog 中的 CLP(FD) 没有除法?
【发布时间】:2016-07-05 08:42:21
【问题描述】:

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

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

【问题讨论】:

  • 你应该使用整数除法'//'
  • 将所有输入缩放 10000,然后发布所有约束。如果需要,缩小结果。
  • 这可能是实数与本质上有限的生物和机器不匹配的原因,我们需要尽力而为。例如,在 SWI-Prolog 和 YAP 中,“有限域”可以增长到可用 RAM 的数量。对于我见过的大多数 Prolog 应用程序中出现的数字,这足以将它们乘以你需要使用 CLP(FD) 约束在 整数 上执行所有计算所需的因子,即使您稍后将这些数字视为小数,并在显示它们时在某处插入一个小数点。
  • 正如我所说,最好的方法是使用浮点数。您不能相信结果,因为编程语言无法检查浮点数推理时必不可少的关键细节。使用有理数整数或询问、支付或等待更好的格式(如小数)。整数足以满足几乎所有用例。在许多情况下,您可以简单地将所有数字相乘,并在您的大部分程序中处理整数。使用 CLP(FD) 约束对整数进行推理。
  • 在 Prolog 中使用浮点的最佳方法是什么? 这个问题可能对于一个单一的答案来说太宽泛了。如果您需要做的只是取一些浮点数并用它们计算一个新的结果,那么这可以在 Prolog 中使用任何其他语言中的数字表达式并使用 is/2 来完成,例如,产生一个结果。但是一般的浮点数不能很好地适应 Prolog 的关系方面。

标签: prolog swi-prolog clpfd


【解决方案1】:

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

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

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.

如果你有一个没有 (//)/2 运算符的 CLP(FD),你可以模拟它。你可以写成 X*Z+R #= Y, 0 #=

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

?- 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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    相关资源
    最近更新 更多