假设我有以下谓词:
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?
中谢谢!
答案 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).
产生与上述相同的结果。