Например:
?- position([[b,c,f],[a,d,g],[h,e]],c,P)
P=1
?- position([[b,c,f],[a,d,g],[h,e]],g,P)
P=2
?- position([[b,c,f],[a,d,g],[h,e]],b,P)
P=0
Я смотрел на предикат nth0/3, но я не уверен, что это правильный способ сделать это. Любые указатели будут высоко оценены.
Я пытаюсь найти положение каждого элемента в его вложенном списке.
position(LL,E,N):-
nth1(N,LL,L),
member(E,L).
?- position([[b,c,f],[a,d,g],[h,e]],c,P).
P = 1 ;
false.
?- position([[b,c,f],[a,d,g],[h,e]],g,P).
P = 2 ;
false.
Предполагая, что вам разрешено использовать member/2
и nth1/3
, см. их реализацию ниже.
Предикат просто проходит через все элементы L
списка ввода LL
через nth1/3
(и отслеживает позицию N
) и проверяет, является ли искомый элемент E
членом списка L
.
Этот предикат работает для простых вложенных списков, где искомый элемент является прямым членом подсписка. Это не будет работать для дальнейших вложенных подлостов, например: position([[b,c,f],[[a],[d,g]],[h,e]],g,P)
Если вам не разрешено использовать встроенные предикаты:
my_nth1(1,[X|_],X).
my_nth1(Idx,[_|List],X) :-
my_nth1(Idx1,List,X),
Idx is Idx1+1.
my_member(X, [X|_]).
my_member(X, [_|T]):-
my_member(X, T).
Вы могли бы даже не использовать предикат члена, просто написав
position(LL,E,N):-
mynth1(N,LL,L),
mynth1(_,L,E).
Если вас интересует не номер подсписка, а номер элемента в подсписке:
position(LL,E,N):-
member(L,LL),
nth0(N,L,E).
?- position([[b,c,f],[a,d,g],[h,e]],c,P).
P = 1 ;
false.
?- position([[b,c,f],[a,d,g],[h,e]],g,P).
P = 2 ;
false.
@Joe исправил проблему. Мне было интересно, почему вы хотите использовать nth0/3, если вам явно нужен nth1/3 xD
Вот мой подход:
1. Предикат первой позиции является базовым случаем (условие остановки, если элемент не найден, продолжайте проверять, пока список не станет пустым).
2. Второй предикат берет список Элемент для проверки и задает конечную позицию в P. Используя метод if-else. Если Элемент является членом H (что означает H=[b,c,f]), то дайте нам позицию Элемента, используя nth0. В противном случае проверьте оставшуюся T (хвост: [[a,d,g],[h,e]]) таким же образом.
position([],_,_).
position([H|T],Element,P):-
( member(Element,H)->
nth0(P,H,Element);
position(T,Element,P)).
Пример:
?-position([[b,c,f],[a,d,g],[h,e]],c,P).
P = 1
false
?-position([[b,c,f],[a,d,g],[h,e]],e,P).
P = 1
?-position([[b,c,f],[a,d,g],[h,e]],g,P).
P = 2
?-position([[b,c,f],[a,d,g],[h,e]],b,P).
P = 0
false
Спасибо за это. Разве пример с 'e' не должен возвращать P = 1? Так как это его позиция в списке? Я могу ошибаться.
@Joe дает 1.
Мне очень жаль, я не был достаточно ясен в своем вопросе. Я надеялся найти положение элемента во вложенных списках (т.е. b = 0, c = 1, f = 2). Ваше решение отлично подходит для поиска списка, в котором оно находится. Извините за путаницу, я отредактировал вопрос, чтобы сделать его более ясным.