Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Prolog return one solution and stop showing the query option

I'm new to prolog, and am experimenting with how to get it to stop querying after it finds one answer. I'm using this code:

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

The result is:

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

true ? a

yes

I'm lost as to how I could get Prolog to stop printing "true ?" and just print "yes" instead. I've tried using if/else construct and the format function but it still prints "true ?". Any ideas?

like image 525
user3026297 Avatar asked Nov 24 '13 20:11

user3026297


2 Answers

You're cutting the wrong place. Cut after the base condition, which says, "once the base is met, don't backtrack any more":

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

If-then does work for me, perhaps you implemented it different? (on swi-prolog)

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

Swi also has the predicate once/1.

edited to account for the error pointed out by false.

like image 62
Shon Avatar answered Oct 19 '22 02:10

Shon


From the output you show, I assume you are using GNU Prolog. But, first just an important remark:

The cut you placed does not cut as you intend it! In fact, it does not even prevent that there is a single answer. Here is evidence for that:

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

X = 1 ? ;

X = 2

yes

So you still have two answers. As a rule of thumb: a cut after a recursive goal often does some unexpected things.

If you insist to have exactly the first answer, simply say once(member(X,[1,2,3])). The once/1 is effectively a cut, too, but quite in disguise. It is tamed to do exactly one thing. Yes, you can place also cuts into recursive rules, but for a beginner, better leave that to a later lesson.

Behind all this there is another point, which is less visible: The toplevel shell of GNU Prolog will ask you for further solutions if it sees an open alternative (jargon: choicepoint). So when GNU asks you for more, it knows that some part has yet to be explored, but there is no guarantee, that there is actually another answer:

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

X = a ? ;

no

Here, the toplevel sees an open choicepoint and thus asks if you want to explore the query any further. Alas, this search is in vein...

like image 2
false Avatar answered Oct 19 '22 02:10

false