Как узнать, на какой глубине член в списке в прологе? - PullRequest
1 голос
/ 16 февраля 2012

Встроенный элемент предиката (x, List) проверяет, существует ли член в списке, но когда в списках есть списки, он проверяет только первую глубину. Я пытаюсь выяснить, на какой глубине находится член. Например:

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

Таким образом, в основном, он находит глубину первого экземпляра 'a' в списке. Если элемент не существует, он вернет Depth = 0. Было бы также полезно, если бы я мог найти глубину всех экземпляров элемента по порядку, например:

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

Я очень новичок в прологе, поэтому любая помощь будет признательна.

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Обратите внимание, что если в любой момент второй аргумент не является списком, ни одно из правил не будет совпадать.Кроме того, вы можете использовать member для проверки на верхнем уровне, но поскольку нам нужно разбить список, чтобы углубиться, я проверяю каждый элемент отдельно, что позволяет избежать дублирования работы или необходим вспомогательный предикат.

% 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).
0 голосов
/ 16 февраля 2012

Вы должны обработать это, проверив каждый элемент списка, является ли он атомом.
Если это так, проверьте, равен ли он 'a', иначе, возможно, это список, рекурсивно вызовите "memberDepth".
Подробнее об атоме здесь

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