Prolog返回结果

时间:2011-11-22 08:17:26

标签: syntax prolog prolog-dif

对于家庭作业,所以没有明确的,请:

有没有办法让Prolog只返回程序找到的第一个目标而忽略找到的其他目标?

为了说明的目的,给出了程序:

permutation([X|Xs],Zs):-permutation(Xs,Ys), insert(X,Ys,Zs).
permutation([],[]).

有没有办法让程序只返回第一个排列作为唯一的解决方案?在以下情况中:

| ?- permutation([1,2,3],X).

X = [1,2,3] ? ;

X = [1,3,2] ? ;

X = [2,1,3] ? ;

X = [2,3,1] ? ;

X = [3,1,2] ? ;

X = [3,2,1] ? ;

no

我们可以

吗?
X = [1,2,3] ?;
no

作为解决方案?

3 个答案:

答案 0 :(得分:6)

剪切它是您正在寻找的控件。把它放在需要提交解决方案的地方(我猜这里是顶级的)。还有内置的一次/ 1 ,它允许在本地限制提交的范围(例如在findall / 3中内联的连接中很有用)。

答案 1 :(得分:4)

每当搜索树中的替代分支成为可能时,Prolog就会设置选择点。为了避免回溯到选择点并探索这些替代方案,您必须添加一个剪切(!/0)。

您必须检查程序中选择点的位置,并在该调用后添加剪切。

答案 2 :(得分:2)

坚持第一个解决方案的最佳方法是once/1,因为这会使效果尽可能保持在本地。使用!/0通常会产生意想不到的影响,因为!/0的范围更大。我们来看一个非常简单的例子:

中的查询( X = 1 ; X = 2 ; X = 3 )
p(X) :- ( X = 1 ; X = 2 ; X = 3 ).
p(4).

使用once/1我们得到:

p1(X) :- once( ( X = 1 ; X = 2 ; X = 3 ) ).
p1(4).

?- p1(X).
X = 1 ;
X = 4.

使用!,我们只得到一个答案:

p2(X) :- ( X = 1 ; X = 2 ; X = 3 ), !.
p2(4).

?- p2(X).
X = 1.

这通常不是故意的。

但是提交第一个解决方案存在一个更普遍的问题。

?- p1(2).
true.

?- dif(X,1),p1(X).
X = 2 ;
X = 4.

那么,2现在也是第一个解决方案吗?出于这样的原因,必须非常小心地使用承诺。显示与p1/1类似行为的谓词缺乏坚定性。这样的谓词不能被理解为关系,因为它根据实际查询改变其含义。