1

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

有没有办法让 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

作为解决方案?

4

3 回答 3

6

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

于 2011-11-22T08:21:14.637 回答
4

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

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

于 2011-11-22T08:27:50.313 回答
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表现出与缺乏坚定性相似行为的谓词。这样的谓词不能理解为关系,因为它会根据实际查询改变其含义。

于 2011-11-22T18:04:15.910 回答