Prolog返回结果

发布于 2024-12-17 12:29:22 字数 501 浏览 1 评论 0原文

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

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

作为解决方案吗?

For homework, so nothing explicit, please:

Is there a way to get Prolog to return only the first Goal found by the program while ignoring the other Goals that are found?

For illustrative purposes, given the program:

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

Is there a way to make the program only return the first permutation as its only solution? In the following case:

| ?- 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

Can we just have

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

as the solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

从此见与不见 2024-12-24 12:29:22

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

The cut it's the control you are looking for. Place it where you need to commit to a solution (here on toplevel, I guess). There is also the builtin once/1, that allows to restrict the scope of the commit 'locally' (useful for instance inside a conjunction inlined in a findall/3).

橘亓 2024-12-24 12:29:22

只要搜索树中可能存在替代分支,Prolog 就会设置选择点。为了避免回溯到选择点并探索此类替代方案,您必须添加剪切 (!/0)。

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

Prolog sets choicepoints whenever an alternative branch in the search tree is possible. In order to avoid backtracking to a choicepoint and exploring such alternatives, you have to add a cut (!/0).

You have to check where in your program the choicepoint is set, and add the cut after that call.

清晨说晚安 2024-12-24 12:29:22

坚持第一个解决方案的最佳方法是 once/1 因为这可以使效果尽可能局部化。使用 !/0 通常会产生意想不到的效果,因为 !/0 的范围更大。 中的查询 ( X = 1 ; X = 2 ; X = 3 )

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

让我们举一个非常简单的例子: Using once/1

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

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

我们得到: Using !< /code>,我们只得到一个答案:

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 类似行为的谓词缺乏稳定性。这样的谓词不能被理解为关系,因为它根据实际查询改变其含义。

The best way to stick to the first solution is once/1 since this keeps the effects as local as possible. Using !/0 often has already unintended effects, since the scope of !/0 is larger. Let's take a very simple example: The query ( X = 1 ; X = 2 ; X = 3 ) in

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

Using once/1 we get:

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

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

Using !, we get only a single answer:

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

?- p2(X).
   X = 1.

Often this is not intended.

But there is a more general problem with committing to the first solution.

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

So, also 2 is now a first solution? It is for such reasons that committing must be used quite cautiously. A predicate that shows similar behavior as p1/1 lacks steadfastness. Such a predicate cannot be understood as a relation since it changes its meaning depending on the actual query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文