使Prolog返回一个解决方案并停止显示查询选项

时间:2013-11-24 20:07:33

标签: prolog format prolog-cut prolog-toplevel

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

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

结果是:

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

true ? a

yes

我迷失了如何让Prolog停止打印“真的吗?”而只是打印“是”。我尝试过使用if / else构造和格式函数,但它仍然打印“true?”。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

你正在切错地方。在基本条件之后切割,即“一旦满足基础,不再回溯”:

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也有谓词{{​​1}}。

编辑以说明false指出的错误。

答案 1 :(得分:2)

从您显示的输出中,我假设您正在使用GNU Prolog。但是,首先只是一个重要的评论:

你放置的剪裁不会像你想要的那样剪裁!事实上,它甚至没有阻止只有一个答案。这是证据:

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

X = 1 ? ;

X = 2

yes

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

如果您坚持要获得第一个答案,只需说出once(member(X,[1,2,3]))即可。 once/1实际上也是一种削减,但却是伪装的。完全可以做一件事。是的,您也可以放入递归规则,但对于初学者,最好将其留待以后的课程。

在所有这些背后还有另外一点,这是不太明显的:如果它看到一个开放的替代品(行话:选择点),GNU Prolog的顶层外壳会要求你提供进一步的解决方案。因此,当GNU要求您提供更多内容时,它知道某些部分尚未被探索,但无法保证,实际上还有另一个答案:

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

X = a ? ;

no

在这里,toplevel看到一个开放的选择点,因此询问您是否要进一步探索查询。唉,这次搜索正在进行中......