实数在 Prolog 中不起作用

Real numbers not working in Prolog

我有以下代码:

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

它适用于整数但不适用于小数:

43 ?- afn(20, 10, C).
C = 200.

44 ?- afn(20, -10, C).
C = -200.

45 ?- afn(20, -10.5, C).
ERROR: Domain error: `clpfd_expression' expected, found `-10.5'
46 ?- 

我如何在这里也使用小数?谢谢

编辑:我发现以下内容适用于小数:

afn(A,B,C):-
    C is B * A.

67 ?- afn(20.895, 40.5, C).
C = 846.2475.

'is' 是正确的方法吗?!

CLP(FD) 实现对整数的推理。

要将声明性算术扩展到十进制数,基本上有两个选择:

  1. rationals 上使用专用的约束求解器。参见 CLP(Q)
  2. 缩放所有数字,以便只有 整数 出现并继续使用 CLP(FD).

我已经看到这两种方法都成功应用了。选项 (2) 有时更可取,因为 CLP(FD) 更广泛可用,还因为您可以使用它在有限域上成功求解非线性约束。

编辑:在您的情况下,合适的查询可能如下所示:

?- afn(200, -105, C).
C = -21000.

最后,您必须再次缩放结果。这样,你就可以通过整数来模拟小数了。

请注意,求助于 floats 根本不是一个好的解决方案,因为您不能真正相信结果。因此,只要更高级的格式尚未在 Prolog 系统中广泛使用,就可以使用有理数或整数。

你要分清楚

函数式(或"moded")算术。这是您熟悉的其他编程语言:您知道哪些参数是输入,哪些是输出,您只需根据输入计算输出即可。这就是你从 is/2(它是标准 Prolog 的一部分)中得到的,如果这就是你想要做的,坚持下去。

?- A=3, B=1.5, C is B * A.
C = 4.5

?- A=3, C=4.5, C is B * A.
instantiation fault                 <<< input B not kown

关系运算。在这里,您陈述了一个方程式或不等式,该方程式或不等式必须在所涉及的变量之间成立。没有 input/output 参数的概念。相反,系统的工作是确保在提出变量的解决方案时所有规定的关系都成立。

有许多不同的方法可以实现关系算术,而且许多方法只适用于问题的子集(例如只适用于整数,或只适用于线性表达式),因此这些功能通常以库的形式提供。

实数上通用关系算术的一个可用实现是 ECLiPSe's library(ic) (see 2, 3),它将实数表示为浮点区间:

?- A=3, C=4.5, C $= B * A.
B = 1.5__1.5                            <<< precise result

?- C $= B * A, C=1, A=10.
B = 0.099999999999999992__0.1           <<< imprecise but accurate result
There are 2 delayed goals.

?- ln(X) $>= sin(X).
X = X{0.36787944117144228 .. 1.0Inf}    <<< partially solved
There are 3 delayed goals.

话虽如此,使用区间算术和正确解释结果并不总是那么简单,这就是为什么 @mat 建议的那种变通方法可能有用(如果适用)。