user3321266
user3321266

Reputation: 13

Identify whether an object comes before another object in a list

I have this clause that says an object is directly before another object in the list. I'm looking for guidance on how to generalize this to be an object that is any location before the object in the list (not necessarily to the left of it immediately). Then I want to be able to also check for after as well.

% Checks that `X` comes before `Y`
% in the list `Ds`
before(X,Y,Ds) :-
    remainder(X,Ds,Rs),
    member(Y,Rs).

% Finds a member of a list and
% unifies the third parameter such
% that it is the remaining elements in
% the list after the found member
remainder(X,[X|Ds],Ds).
remainder(X,[_|Ds],Rs) :- remainder(X,Ds,Rs).

Upvotes: 1

Views: 69

Answers (3)

repeat
repeat

Reputation: 18726

That's the right hunch: member/2 can be put to use for that.

You were probably thinking about writing something like this:

before(A,Z,[A|Xs]) :-   member(Z,Xs).
before(A,Z,[_|Xs]) :- before(A,Z,Xs).

Sample query using SICStus Prolog 4.5.1:

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

And here's another query, this one even a bit more general:

| ?- before(A,Z,[1,2,3,4]).
A = 1, Z = 2 ? ;
A = 1, Z = 3 ? ;
A = 1, Z = 4 ? ;
A = 2, Z = 3 ? ;
A = 2, Z = 4 ? ;
A = 3, Z = 4 ? ;
no

Upvotes: 1

false
false

Reputation: 10102

before(X,Y, Ds) :-
   phrase(( ..., [X], ..., [Y], ... ), Ds).

... --> [] | [_], ... .

Upvotes: 1

CapelliC
CapelliC

Reputation: 60004

if you are not doing this for learning, you can use append/2:

before(X,Y,Ds) :-
  append([_,[X],_,[Y],_],Ds).

?- before(2,X,[1,2,3]).
X = 3 ;
false.

Upvotes: 0

Related Questions