Prolog - 总结谓词结果

时间:2016-01-30 14:08:09

标签: prolog sum

假设我有以下谓词:

func1(X,B,R)

我为它提供了某个X和B,作为回报,它为R提供了5种不同的结果。

编辑: X和B不指定范围。相反,X指定一个整数(比如120),B指定立方体小于X的所有整数(从1开始)。 func1做的是计算R作为余数的结果。 在这种情况下,X = 120:

B = 1, R = 119 (120-1^3)
B = 2, R = 112 (120-2^3)
B = 3, R = 93 (120-3^3)
B = 4, R = 56 (120-4^3)

它不会计算B = 5,因为5 ^ 3 = 125大于120,所以它在此停止。

我如何制作谓词,如:

func2(R,S)

这会接受R给出的所有结果,将它们相加并将它们存储在S?

谢谢!

1 个答案:

答案 0 :(得分:2)

首先,由于B的值完全可以从X的值中导出,因此我不会在func1中包含两个参数。我将引入一个谓词func3/2,如果第二个参数可以从第一个派生({em>即,func3(X, B),如果B是可派生的,则为真来自X):

func1(X, R) :-
    func3(X, B),
    ...

如果您查询func1(120, R),您将获得R的一个或多个结果,会发生什么情况。然后,您可以使用我在评论中指出的findall/3

func2(X, S) :-
    findall(R, func1(X, R), Rs),
    sumlist(Rs, S).

要定义func3/2,最干净的方法是使用CLP(FD):

:- use_module(library(clpfd)).

func3(X, B) :-
    B #>= 0,
    (X - B^3) #>= 0,
    label([B]).

以下是func3所做的一个例子:

?- func3(120, B).
B = 1 ;
B = 2 ;
B = 3 ;
B = 4.

<小时/> 如果您不能使用CLP(FD),那么不太理想的方法是使用between并将B的上限定义为不超过立方根的最大整数X

func3(X, B) :-
    Limit is floor(exp(log(X) / 3)),
    between(1, Limit, B).

产生与上述相同的结果。