Reputation: 13
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
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
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