Domanda

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?

È stato utile?

Soluzione

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.

Altri suggerimenti

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top