【问题标题】:Make Prolog return one solution and stop showing the query option让 Prolog 返回一个解决方案并停止显示查询选项
【发布时间】:2013-11-24 20:07:32
【问题描述】:

我是 prolog 的新手,正在尝试如何让它在找到一个答案后停止查询。我正在使用此代码:

member1(L,[L|_]).                    
member1(L,[_|RS]) :- member1(L,RS),!.      

结果是:

| ?- member1(3,[3,2,3]).

true ? a

yes

我不知道如何让 Prolog 停止打印“true”?而是打印“是”。我尝试过使用 if/else 构造和 format 函数,但它仍然打印“true ?”。有什么想法吗?

【问题讨论】:

  • 您只想要一个答案?一个true? Τrue 表示 3 列表 [3,2,3] 的成员。第二个事实是查询在列表中再次找到它。 ` member1(2,[3,2,3]).` 只会给你一个真值。
  • 如果你在第一个 true 之后按回车(而不是;),它将停止回溯

标签: prolog format prolog-cut prolog-toplevel


【解决方案1】:

你剪错了地方。在基础条件之后切入,即“一旦满足基础,就不再回溯”:

member1(L,[L|_]) :- !.                   
member1(L,[_|RS]) :- member1(L,RS).    

If-then 对我有用,也许你实现它的方式不同? (在 swi-prolog 上)

member1(X,[Y|RS]) :-
    ( X = Y         -> true
    ; member1(X,RS) -> true
    ; false
    ) .

Swi 也有谓词once/1

已编辑以解决 false 指出的错误。

【讨论】:

  • @false 啊!我忽略了第一个元素匹配的明显情况。现在修好了。感谢您指出这一点。
【解决方案2】:

根据您显示的输出,我假设您使用的是 GNU Prolog。但是,首先要说一句重要的话:

您放置的切口没有按您的意愿切割!事实上,它甚至不阻止只有一个答案。这是证据:

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

X = 1 ? ;

X = 2

yes

所以你还有两个答案。根据经验:递归目标后的剪切经常会做一些意想不到的事情。

如果您坚持要得到第一个答案,只需说once(member(X,[1,2,3]))once/1 实际上也是一个剪裁,但完全是伪装的。它被驯服只做一件事。是的,您也可以将切入到递归规则中,但对于初学者来说,最好留到以后的课程中。

在这一切的背后还有另一点不太明显:如果 GNU Prolog 的顶层 shell 看到一个开放的替代方案(行话:choicepoint),它会要求您提供进一步的解决方案。因此,当 GNU 要求您提供更多信息时,它知道某些部分尚未探索,但不能保证实际上还有另一个答案:

?- member(1-X,[1-a,2-b,3-c]). 

X = a ? ;

no

在这里,顶层会看到一个开放的选择点,因此会询问您是否要进一步探索查询。唉,这个搜索是有规律的......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多