如何将函数的输出转换为列表?

时间:2011-12-03 07:07:41

标签: list prolog

我有一个输出符合特定约束的名称的函数。这个功能很好。

但是我需要使用该函数来创建另一个函数,将前一个函数的输出转换为一个列表。作为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).

感谢任何帮助。

3 个答案:

答案 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/3findall/4bagof/3setof/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].