2011-09-18 122 views
0

所以我有几次返回true的谓词。谓词返回。 Prolog

% true returns several times and i need to press ';' 
?- get_all_transformed_moves. 
true ; 
true ; 
true. 

是否swi prolog有一些方法可以帮助我运行此谓词而不键入';'?

% Wished version 
?- get_all_transformed_moves. 
true. 

回答

2

考虑以下几点:

likes(prolog). 
likes(haskell). 
likes(erlang). 

likes_something:- 
    likes(_Something). 

如果现在你问:

?- likes_something. 

你会得到

true ; 
true ; 
true. 

出现这种情况是因为序言发现三种方式来满足likes_something/0谓词(包括prolog,haskell和erlang),所以它回答三次。

这不完全是一个问题;随时可以按,prolog将停止尝试找到答案(当有很多结果时,这非常方便)。

同样的事情发生在你的谓词上:有三种解决方案,并按下;你强迫序言找到他们。因为Rocha建议你可以使用findall/3。例如,你可以写:

likes_something:- 
    findall(X, likes(X), _). 

,这将只返回一个yes

但是,它并没有提供比以前的版本的详细信息;相反,它隐藏了这样的事实,即有三种解决方案和浪费时间试图找到更多,而答案不会改变。 出于这个原因,我认为你应该使用的findall/3,如果你真的想看到结果:

likes_all(L):- 
    findall(X,likes(X),L). 
当然

,你是否需要看到的结果或不取决于你的决定(或者更确切地说,这个问题你正在试图解决:p)

另一种选择是使用切:!/0 例如:

likes_something:- 
    likes(_Something), 
    !. 

这将prolo停止克从寻找更多的解决方案,你会得到一个真实的。但是请注意,剪切可能会非常棘手。

总而言之: 如果你想让序言搜索所有的答案(如果你决定把它们放在一个列表中或者你的谓词有副作用或者你只是想要它):findall/3

,如果你不希望有以寻找更多的答案选项:(!/ 0)使用切割

否则只是按enter键代替;

0

可以使用的findall/3谓词:

的findall(对象,目标,列表)。 产生一个列表满足目标Goal的所有对象Object。通常,Object只是一个变量,在这种情况下,查询可以被读为:给我一个包含满足Goal的Object的所有实例的列表。

我想这就是你想要的。

0

如果您希望谓词最多成功一次,那么您可以使用SWI提供的一次/ 1。

在您的例子:

?- once(get_all_transformed_moves). 
true.