我有一个输出符合特定约束的名称的函数。这个功能很好。
但是我需要使用该函数来创建另一个函数,将前一个函数的输出转换为一个列表。作为Prolog的完全初学者,我不知道如何做到这一点。
我的问题是我不知道如何迭代输出以将其附加到累加器。输出名称的功能就是这样,然后按“;”或SPACE,它输出下一个答案,直到它没有答案。我想这意味着我必须多次调用该函数然后追加它。但我不知道有多少次我需要调用它,因为我不能像[Head | Tail]列表那样迭代它。
这是我到目前为止所做的事情(虽然这可能是错误的):
%p1(L,X) determines if chemicals in List X are in any of the products and stores those products in L
p1(L,X) :- p1_helper(L,X,[]).
p1_helper(L,X,Acc) :- has_chemicals(A,X),append(Acc,[A],K),L=K, p1_helper(L,X,K).
使用查询has_chemicals(X,[化学品列表])输出名称的函数。:
%has_chemicals(X,Is) determines if the chemicals in List Is are in the chemical list of X.
has_chemicals(X,Is) :- chemicals(X,Y), hc(Y,Is).
%hc(X,Y) determines if elements of Y are in elements of X.
hc(Y,[]).
hc(Y,[C|D]) :- isin(C,Y), hc(Y,D).
感谢任何帮助。
答案 0 :(得分:3)
但是我需要使用该函数来创建另一个函数,将前一个函数的输出转换为一个列表。作为Prolog的完全初学者,我不知道如何做到这一点。
findall(+Template, :Goal, -Bag)
:
创建一个实例化列表Template
连续回溯Goal
并将结果与Bag
统一。
例如,如何从1到15收集所有奇数:
odd( X ) :-
X rem 2 =:= 1.
我们可以逐一获得所有可能性。
?- between( 1, 15, X ), odd( X ).
X = 1 ;
X = 3 ;
X = 5 ;
X = 7 ;
X = 9 ;
X = 11 ;
X = 13 ;
X = 15.
我们可以将它们收集到列表中:
?- findall(X, (between( 1, 15, X ), odd( X )), List).
List = [1, 3, 5, 7, 9, 11, 13, 15].
答案 1 :(得分:2)
我认为您正在寻找捕获isin / 2输出的方法。然后你可以使用内置with_output_to/2,并将其与findall / 3结合使用,如其他答案所示。
答案 2 :(得分:0)
我鼓励您访问this page,特别是如果您使用swi-prolog。
有4个谓词符合您的要求:findall/3
,findall/4
,bagof/3
和setof/3
。
总结一下,这是我将要使用的测试谓词:
test(0, 3).
test(1, 3).
test(2, 5).
test(3, 4).
首先,最简单的,findall / 3和findall / 4:
?- findall(C, test(X, C), Cs).
Cs = [3, 3, 5, 4].
?- findall(C, test(X, C), Cs, TailCs).
Cs = [3, 3, 5, 4|TailCs].
他们只返回所有替代品,带有重复项,没有排序,没有绑定其他自由变量,作为findall/3
的常规列表和findall/4
的差异列表。当列表为空时,findall
个谓词都成功。
然后,bagof。基本上,bagof/3
用作findall/3
但绑定自由变量。这意味着与上面相同的查询但bagof/3
返回:
?- bagof(C, test(X, C), Cs).
X = 0,
Cs = [3] ;
X = 1,
Cs = [3] ;
X = 2,
Cs = [5] ;
X = 3,
Cs = [4].
告诉bagof/3
不要绑定所有自由变量,你获得findall/3
:
?- bagof(C, X^test(X, C), Cs).
Cs = [3, 3, 5, 4].
仍然需要注意,bagof/3
在结果为空时失败,而findall/3
则没有。
最后,setof/3
。它基本上是bagof/3
,但结果已排序且没有重复:
?- setof(C, X^test(X, C), Cs).
Cs = [3, 4, 5].