Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use cut in Prolog to define a once_member/2 function

Disclaimer: This is informal and non-assessed coursework to do in my own time. I have tried it myself, failed and am now looking for some guidance.

I am trying to implement a version of the member/2 function which will only return members for a list once.

For example:

| ?- member(X, [1,2,3,1]).
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 1 ? ;

I would like it to only print out each number a maximum of once.

| ?- once_member(X, [1,2,3,1]).
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
no

We have been told to do this with the cut '!' operator but I have looked over the notes for my course for cut and more online and yet still can't make it click in my head!

So far I have managed to get:

once_member(E, [E | L]) :- !.
once_member(E, [_, L]) :-
    once_member(E, L).

Which returns 1 and then nothing else, I feel like my cut is in the wrong place and preventing a backtrack for each possible match but I'm really not sure where to go with it next.

I have looked in my course notes and also at: http://www.cs.ubbcluj.ro/~csatol/log_funk/prolog/slides/5-cuts.pdf and Programming in Prolog (Google Books)

Guidance on how to logically apply the cut would be most useful, but the answer might help me figure that out myself.

We have also been told to do another method which uses '\+' negation by failure but hopefully this may be simpler once cut has twigged for me?

like image 348
Pete Hamilton Avatar asked Nov 26 '11 23:11

Pete Hamilton


People also ask

What is the use of cut in Prolog?

The cut, in Prolog, is a goal, written as !, which always succeeds, but cannot be backtracked. Cuts can be used to prevent unwanted backtracking, which could add unwanted solutions and/or space/time overhead to a query. The cut should be used sparingly.

What is cut and negation in Prolog?

To cut or not to cut - Negation We can query prolog for round(earth) and as expected the answer is false. The negation predicate in prolog is \+ and therefore \+ round(earth) returns true. This limitation of prolog that is a goal cannot be proved then it is false, is called the close world assumption (CWA).

What is member function in Prolog?

If Term is a variable and List is a list, all the members of the list List are found on backtracking. If List is not instantiated, member/2 binds List to a new partial list containing the element Term. The definition of this Prolog library predicate is: member(X,[X|_]). member(X,[Y|T]) :- member(X,T).

What are the usage of not fail and cut predicate in Prolog?

We can use the same idea of “cut/fail” to define the predicate not, which takes a term as an argument. not will “call” the term, that is evaluate it as though it is a goal: not(G) fails if G succeeds not(G) succeeds if G does not succeed. In Prolog, not(G) :- call(G), !, fail.


1 Answers

Remove redundant answers and stay pure!

We define memberd/2 based on if_/3 and (=)/3:

memberd(X, [E|Es]) :-
   if_(X = E, true, memberd(X, Es)).

Particularly with meta-predicates, a different argument order may come in handy sometimes:

list_memberd(Es, X) :-
   memberd(X, Es).

Sample query:

?- memberd(X, [1,2,3,1]).
X = 1 ;
X = 2 ;
X = 3 ;
false.
like image 190
repeat Avatar answered Oct 01 '22 16:10

repeat