user1212639
user1212639

Reputation: 13

How to find what depth a member is in a list in prolog?

The built-in predicate member(x, List) checks if a member exists in a list, but when there are lists within lists it only checks the first depth. I'm trying to find out exactly what depth a member is in. For example:

?- memberDepth(a, [b, c, [d], [[e, f, [], [g], a], j], [k]], Depth).
Depth = 3 .

So basically, it finds the depth of the first instance of 'a' in the list. If the member doesn't exist, it'll return Depth = 0. It would also be useful if I could find the depth of all instances of the member in order, for example:

?- memberDepthAll(a, [b, c, [a], [[e], a], [[a]]], Depth).
Depth = 2 ;
Depth = 2 ;
Depth = 3 ;
Depth = 0 ;
false.

I'm very new to prolog so any help would be appreciated.

Upvotes: 1

Views: 1604

Answers (2)

Scott Hunter
Scott Hunter

Reputation: 49803

Note that, if at any point the second argument isn't a list, none of the rules will match. Also, you could use member to check at the top level, but since we have to break down the list to go deeper, I check each element individually, which avoids duplicating work or needed an auxiliary predicate.

% First, check the first element of the list
memberDepth(X,[X|_],0).
% Next search inside the first element of the list (hence the +1)
memberDepth(X,[H|_],D1) :- memberDepth(X,H,D), D1 is D+1.
% FInally, search the rest of the list
memberDepth(X,[_|T],D) :- memberDepth(X,T,D).

Upvotes: 2

Eran Egozi
Eran Egozi

Reputation: 773

You should handle it by checking each element of the list whether it's an atom.
If so, check if it's equal to 'a', else, it's probably a list, call "memberDepth" recursively.
More about atom here

memberDepth(X,[L|Ls],Depth) :-
    atom(L),!,                     % true iff L is an atom
    ...
memberDepth(X,[L|Ls],Depth) :-
    ...

Upvotes: 0

Related Questions