Первое, на что нужно обратить внимание, это то, что ваш «список списков» по сути является древовидной структурой, и вы в основном выполняете обход дерева слева направо в глубину.
Итак, вам нужен "публичный" предикат, который может искать в дереве элемент и возвращать его глубину. Возврат должен возвращать все такие совпадения:
tree_walk( X , Tree , Depth ) :-
tree_walk( X , Tree , 0 , Depth ) % seed the accumulator with an initial depth
.
Тогда вам нужен предикат работника:
tree_walk( X , [ X | _ ] , D , D ) % success! if the desired item is found
. %
tree_walk( X , [ Y | Ys ] , T , D ) :- % otherwise...
T1 is T+1 , % - increment the depth
tree_walk( X , Y , T1 , D ) % - and recurse down on the head of the list
. %
tree_walk( X , [ _ | Ys ] , T , D ) :- % if that failed, then
tree_walk( X , Ys , T , D ) % - recursively search the tail of the list
. %
Вот и все, что нужно.
ПРИМЕЧАНИЯ
Чтобы перейти к поиску в ширину, я думаю, все, что вам нужно сделать, - это изменить порядок последних двух предложений предиката работника.
, если X
не связан или один из элементов в «списке списков» не связан, вы, вероятно, столкнетесь ... с интересными проблемами. Что касается производственного кода, вы бы хотели установить защитные устройства для правильной работы с этими крайними случаями.
Ура!