我遇到了一个具体的问题,但我会尝试提出一个普遍的问题,以便其他人也可以从中受益......
我有一个返回许多解决方案的谓词,即
X=5;
X=2;
X=7
并且我想要一个获得每个解决方案的谓词并将它们作为Prolog事实断言然后我在这种情况下得到三个事实,例如。
fact(5)
fact(2)
fact(7)
所以调用fact(5)
是正确的,但调用fact(8)
将是错误的,因为我们从未声明它,因为它不是解决方案。
但是我不希望有一个谓词,你必须继续要求解决方案断言每一个事实。我想调用一个谓词并让它在后台通过所有解决方案,断言它们就是这样。
解决这个问题的一种方法是使用findall将所有解决方案放入列表中,然后通过列表断言列表中的每个元素。但是,我不认为这很优雅。必须有一个更好的方法来做到这一点,而不是摆弄列表。
答案 0 :(得分:5)
使用故障驱动的循环强制回溯所有解决方案:
?- computation(X), false.
您可以使用ignore / 1忽略此查询的声明性错误真值:
?- ignore((computation(X),false)).
答案 1 :(得分:3)
可以使用setof和制作二阶谓词来实现此功能。
:- dynamic fact/1.
isAns(5).
isAns(2).
isAns(7).
computation(F) :- setof(X,call(F,X),S),factify(S).
factify([X|Xs]) :- assert(fact(X)),factify(Xs).
factify([]).
然后,当我们去询问有关事实时,我们得到了:
computation(isAns), fact(X).
X = 5;
X = 2;
X = 7;
false