Prolog初学者:如何与算术比较运算符统一或如何将set var设置为值范围

时间:2010-06-05 16:55:39

标签: prolog clpfd

我是Prolog的新手。我需要编写一个整数加法器,将0-9之间的数字加到其他数字0-9,并产生0-18的解。这就是我想要做的事情:

% pseudo code
add(in1, in2, out) :-
    in1 < 10,
    in2 < 10,
    out < 18.

我希望能够这样称呼它:

检查它是否是有效的补充:

?- add(1,2,3).
true.
?- add(1,2,4).
false.

有一个缺失变量:

?- add(X,2,3).
X = 1.
?- add(1,4,X).
X = 5.

有多个缺失变量:

?- add(X,Y,Z).
% Some output that would make sense.  Some examples could be:
X=1, Y=1, Z=2 ;
X=2, Y=1, Z=3 ......

我意识到这可能是一个相当简单的问题,它可能非常简单。但是,根据我使用的Prolog tutorial

  

“与统一不同算术比较运算符运算符不能用于给变量赋值。只有在每一个项的每个项都被实例化时才能计算。”

3 个答案:

答案 0 :(得分:6)

所有现代Prolog系统都提供有限域约束,这些约束可以在所有方向上使用(与更低级别的算术谓词如is / 2和&gt; / 2相反)。在SWI-Prolog:

:- use_module(library(clpfd)).

plus(X, Y, Z) :-
        [X,Y] ins 0..9,
        X + Y #= Z.

您的示例的结果:

?- plus(1,2,3).
true.

?- plus(1,2,4).
false.

?- plus(X,2,3).
X = 1.

?- plus(1,4,X).
X = 5.

?- plus(X,Y,Z).
X in 0..9,
X+Y#=Z,
Y in 0..9,
Z in 0..18.

由于谓词可以在所有方向上使用,因此将其称为“add / 3”不再有意义,因为这意味着方向,但谓词真正描述了关系何时成立并因此更为通用。

答案 1 :(得分:1)

这个怎么样?:

add(X,Y,Z) :-
        Z is X + Y,
        X < 10,
        Y < 10,
        Z < 19.

问题:这适用于add(1,1,X)格式的查询,因为Z<调用之前已实例化,但在您add(X,1,2)时请求失败。您可以使用var/1来区分查询类型(var/1告诉您变量是否未实例化),但这听起来很痛苦。

答案 2 :(得分:0)

解决方案:

lessThanTen(9).
lessThanTen(8).
lessThanTen(7).
lessThanTen(6).
lessThanTen(5).
lessThanTen(4).
lessThanTen(3).
lessThanTen(2).
lessThanTen(1).
lessThanTen(0).

addSimple(Add1,Add2,Sol) :-
    lessThanTen(Add1),
    lessThanTen(Add2),
    Sol is Add1+Add2.