如何将forall与关系方法结合起来产生结果

时间:2017-12-07 15:15:47

标签: prolog

我写了一个谓词aux_cond1(Assoc0, X, Assoc1),它作为输入X,在图表上进行了一些搜索,如果某个条件cond1保持将{X}插入Assoc0,则生成一个新的{ {1}}。

要遍历图表,我想使用forall / 2,例如:

Assoc1

然而,这不起作用,因为对于找到的模式(X,Y),每次成功应用Cond1 / 3时,Assoc0应该更改为Assoc1。

关系谓词(如cond1 / 3)的首选forall模式是什么,因此对于每个模式(X,Y),都会标识一个新的,可能是可回溯的Assoc1。

编辑:

我认为我发现了一种可行的模式:

而不是使用forall / 2,我可以使用findall / 3,生成结果列表,然后使用生成的列表调用aux_cond1 - aux_cond1依次将列表拆分为head和tail,并为每个头调用cond1 。

只要生成的findall列表相当短,这似乎没问题。

1 个答案:

答案 0 :(得分:0)

forall / 2不适合链接任务,因为它将撤消变量绑定。定义如下:

 forall(C, A) :- \+ (C, \+ A).

您是对的,您可能会对findall / 3取得更大的成功。如果将聚合器写为cond1(X,Assoc0,Assoc1),则甚至可以使用foldl / 4并转移到所谓的高阶编程中。示例:

p(1).
p(2).
p(3).
p(4).

cond(X, [X|L], L) :- X > 2, !.
cond(_, L, L).

我们现在可以查询:

?- findall(X, p(X), L), foldl(cond, L, R, []).
L = [1, 2, 3, 4],
R = [3, 4].