2

Prolog predicate next(X, List,List1), that returns in List1 the next element(s) from List that follows X, e.g., next(a,[a,b,c,a,d],List1), will return List1=[b,d].

I have tried following:

next(X, [X,Y|List], [Y|List1]) :-   % X is the head of the list
    next(X, [Y|List], List1).
next(X, [Y|List], List1) :-         % X is not the head of the list
    X \== Y,
    next(X, List, List1).
next(_,[], []).
repeat
  • 18,496
  • 4
  • 54
  • 166
PK ARYA
  • 21
  • 3
  • 3
    I'm voting to close this question as off-topic because it doesn't comply with item 3 of [What topics can I ask about here?](http://stackoverflow.com/help/on-topic). I don't see an attempt and a specific question here. – lurker Mar 15 '15 at 17:58
  • 1
    What results are you seeing that you don't expect? Did you try doing a `trace`? – lurker Mar 16 '15 at 12:30
  • one liner: `next(X,List,List1) :- findall(Y,(nth1(I,List,X),succ(I,J),nth1(J,List,Y)),List1).` – CapelliC Jun 02 '15 at 08:07

2 Answers2

1

First, whenever possible, use for expressing term inequality!

Second, the question you asked is vague about corner cases: In particular, it is not clear how next(E,Xs,Ys) should behave if there are multiple neighboring Es in Xs or if Xs ends with E.

That being said, here's my shot at your problem:

next(E,Xs,Ys) :-
   list_item_nexts(Xs,E,Ys).

list_item_nexts([],_,[]).
list_item_nexts([E],E,[]).
list_item_nexts([I|Xs],E,Ys) :-
   dif(E,I),
   list_item_nexts(Xs,E,Ys).
list_item_nexts([E,X|Xs],E,[X|Ys]) :-
   list_item_nexts(Xs,E,Ys).

Let's see some queries!

?- next(a,[a,b,c,a,d],List1).
List1 = [b,d] ;
false.

?- next(a,[a,a,b,c,a,d],List1).
List1 = [a,d] ;
false.

?- next(a,[a,a,b,c,a,d,a],List1).
List1 = [a,d] ;
false.

Note that above queries succeed, but leave behind useless choicepoints. This inefficiency can be dealt with, but I suggest figuring out more complete specs first:)

repeat
  • 18,496
  • 4
  • 54
  • 166
1

This version is deterministic for the cases given by @repeat using if_/3 and (=)/3. It shows how purity and efficiency can coexist in one and the same Prolog program.

next(E, Xs, Ys) :-
   xs_e_(Xs, E, Ys).

xs_e_([], _E, []).
xs_e_([X|Xs], E, Ys) :-
   if_(X = E, xs_e_xys(Xs, E, Ys), xs_e_(Xs, E, Ys)).

xs_e_xys([], _E, []).
xs_e_xys([X|Xs], E, [X|Ys]) :-
   xs_e_(Xs, E, Ys).
%xs_e_xys([X|Xs], E, [X|Ys]) :- % alternate interpretation
%   xs_e_([X|Xs], E, Ys).
Community
  • 1
  • 1
false
  • 10,264
  • 13
  • 101
  • 209