Haki Terror
Haki Terror

Reputation: 363

Prolog , check if a pair of elements appears in a list

Given a list L I would like to see if a pair P, appears in the list. If the element is found, then print *Found*.

For example:

L = [3,1,2,5,4,7].
P = (2,5).

Given this example, I should get *Found* as 2,5 appears on 2nd and 3rd position in list L.

Here is my approach , but I am getting a false answer.

search_pair([_|[]],_).
search_pair([X|T],(F,L)) :-
   first(Y, T),
   write('searching: '),write(F),write(' '),write(L),nl,
   write('trying: '),write(X),write(' '),write(Y),nl,
   ((F == L , L = Y) -> (write('Found'))
   search_pair(T,(F,L),R).

Upvotes: 1

Views: 1509

Answers (1)

tas
tas

Reputation: 8140

The actual relation is quite easy to describe. There are two cases:

  • case 1: The list starts with the given pair. In this case we're done.

  • case 2: Otherwise we need to keep searching in the tail of the list.

This can be written with if_/3 and (',')/3 like so:

pair_in((X,Y),[A,B|Cs]) :-
   if_((X=A,Y=B),
       true,                    % <- case 1
       pair_in((X,Y),[B|Cs])).  % <- case 2

Querying this with your example and a counterexample:

   ?- pair_in((2,5),[3,1,2,5,4,7]).
yes
   ?- pair_in((2,4),[3,1,2,5,4,7]).
no

If you want to output the message *Found* in the case of success, I would suggest to relocate that to a calling predicate, e.g. your predicate search_pair/2:

search_pair(L,P) :-        % <- calling predicate
   pair_in(P,L),           % <- actual relation
   format('*Found*~n').    % <- output

Now let's query this predicate with the above examples:

   ?- search_pair([3,1,2,5,4,7],(2,5)).
*Found*
yes
   ?- search_pair([3,1,2,5,4,7],(2,4)).
no

As you can see *Found* is only displayed in the case of success. That is because in case the goal pair_in(P,L) fails, Prolog doesn't move on to the next goal, since the rule cannot become true any more.

Upvotes: 3

Related Questions