Prolog predicate that retrieves all words immediately after a word in a given wordlist

As the title says, I need to get all words after the word specialc in the prologue, for example:

?- find([in, house, car, in, shop, no, more, apples, in, table], in , X).

X = [house, shop, table] ;

No

      

This is the code I have written so far:

find([H,H_1|_],H,[H_1]).
find([Head,Head_1|Tail], Term, [Head|Result]) :-
     find(Tail, Term, Result).

      

After running, I get:

X = [house] ;

X = [in, car, shop, more, table] ;

No

      

+3


source to share


2 answers


The main problem is probably here:

find([H,H_1|_],H,[H_1]).
      

This code concatenates the list with the first element after the match. Then you concatenate the third parameter (which is used here as "result") with a list containing one occurrence.

Note that it is also possible that we have reached the end of the list. So in this case the predicate will fail as well.

Basically, there are four cases here:

  • we reach the end of the list, the "result" parameter must be combined with an empty list;
  • we found an item and there is another item (this is also a match), we take one step and continue our search;
  • we found an item and there is a next item (this is not a match), we add this item and continue our search;
  • The chapter does not match, we continue our search.


We can implement these capabilities as:

find([],_,[]).            % we reach the end of the list


find([H,H|T],H,T2) :-     % there is a match, the successor is also a match
    find([H|T],H,T2).     % perform one hop

find([H,N|T],H,[N|T2]) :- % there is a match, add the next element
    N \= H,
    find(T,H,T2).         % and continue

find([N|T],H,T2) :-       % there is no match
    N \= H,
    find(T,H,T2).         % we continue

      

This gives:

?- find([in, house, car, in, shop, no, more, apples, in, table], in , X).
X = [house, shop, table] ;
false.

?- find([a,b,c],c,X).
false.

?- find([a,b,c,a,d],a,X).
X = [b, d] ;
false.

?- find([a,a,b],a,X).
X = [b] ;
false.

      

( Yes

/ No

are in true/false

).

0


source


There is nothing better than writing simple language learning programs. Once you understand the basics, you may be interested in a more idiomatic approach:



find(L,W,Fs) :- findall(F, append(_,[W,F|_],L), Fs).

      

+1


source







All Articles