Получение первого / второго элемента кортежа в Прологе

Я не нашел, как я могу получить первый / второй элемент кортежа в Прологе, я пробовал arg, но он работает только с предикатами. Мой список выглядит так:

Pairs = [
  (pos(1, 2), pos(1, 3)),  
  (pos(1, 2), pos(2, 1)),  
  (pos(1, 2), pos(2, 3)),  
  (pos(1, 2), pos(3, 1)),  
  (pos(1, 2), pos(3, 2)),  
  (pos(1, 3), pos(2, 1)),  
  (pos(1, 3), pos(2, 3)),  
  (pos(..., ...), pos(..., ...)),  
  (..., ...)|...].

1 ответ

Решение

Вам не нужен специальный предикат для этого, просто объединение, например:

?- (A, B) = (pos(1, 2), pos(4, 3)).
A = pos(1, 2),
B = pos(4, 3).

?- (pos(X1, Y1), pos(X2, Y2)) = (pos(1, 2), pos(4, 3)).
X1 = 1,
Y1 = 2,
X2 = 4,
Y2 = 3.

Объединение может происходить в теле правила или непосредственно в главе правила. Рассмотрим следующий пример "посещения" всех пар:

visit_pairs([]).               % same as: %  visit_pairs([]).
visit_pairs([(A, B) | Xs]) :-  %   -->    %  visit_pairs([X|Xs]) :-
    writeln(first_pair(A)),    %          %      (A, B) = X,
    writeln(second_pair(B)),   %          %      writeln(first_pair(A)),
    visit_pairs(Xs).           %          %      writeln(second_pair(B)),
                               %          %      visit_pairs(Xs).

visit_pairs будет работать только со списками кортежей, и каждый элемент списка должен объединяться с (A, B),

?- visit_pairs([(pos(1, 2), pos(1, 3)),  (pos(1, 2), pos(2, 1)),  (pos(1, 2), pos(2, 3)),  (pos(1, 2), pos(3, 1)),  (pos(1, 2), pos(3, 2)),  (pos(1, 3), pos(2, 1)),  (pos(1, 3), pos(2, 3))]).
first_pair(pos(1,2))
second_pair(pos(1,3))
first_pair(pos(1,2))
second_pair(pos(2,1))
first_pair(pos(1,2))
second_pair(pos(2,3))
first_pair(pos(1,2))
second_pair(pos(3,1))
first_pair(pos(1,2))
second_pair(pos(3,2))
first_pair(pos(1,3))
second_pair(pos(2,1))
first_pair(pos(1,3))
second_pair(pos(2,3))
true.

Другим способом может быть использование nth0/3 получить доступ к одному конкретному элементу по индексу, а затем снова использовать унификацию для распаковки кортежа:

?- Pairs = [(pos(1, 2), pos(1, 3)),  ...], nth0(0, Pairs, Elem), (A, B) = Elem.
Elem =  (pos(1, 2), pos(1, 3)),
A = pos(1, 2),
B = pos(1, 3).

но это выглядит довольно нетипично.

Другие вопросы по тегам