Передача результатов предиката пролога - PullRequest
3 голосов
/ 19 марта 2012

Как можно оценить результат предиката пролога для передачи в качестве аргумента? Я пытаюсь написать код для обращения пар элементов в списке:

swap([A,B,C,D,E,F],R).

Я хочу получить результат:

[B,A,D,C,F,E]

но я получаю такой результат:

append(append(append([],[B,A],[D,C],[F,E])))

Вот мой код:

swap(L,R) :- swapA(L,[],R).
swapA([],A,A).
swapA([H,H2|T],A,R) :-  swapA(T, append(A,[H2,H]), R).

Спасибо.

Ответы [ 2 ]

8 голосов
/ 19 марта 2012

Несколько вещей:

  • переменная начинается с заглавной буквы, если вы хотите отличить атом от переменной, оберните ее между ': ['A','B','C','D','E','F']
  • вам не нужно добавлять, чтобы успешно реализовать этот предикат.Сложность намного хуже при использовании append.
  • , потому что вам не нужно добавлять, вам не нужно 3 аргумента, достаточно 2

Вот предложение:

swapA([], []).
swapA([X, Y|T], [Y, X|R]) :- swapA(T, R).

И рассмотрите возможность добавления другого базового случая, если вы хотите, чтобы ваш предикат удерживался, когда в вашем списке нечетное количество элементов:

swapA([X], [X]).
2 голосов
/ 19 марта 2012

Вы не можете вызывать предикат Prolog как функцию. Это ничего не возвращает. Когда вы передаете append(A,[H2,H]) для свопинга, он интерпретирует его как данные, а не как код.

Предложение Prolog создает связь между N логическими переменными. Это означает, что в теории нет понятия «вход» и «выход» в предикатах Пролога, вы можете сделать запрос с любой комбинацией экземпляров и неинстанцированных переменных, и язык найдет для вас значимые отношения:

1 ?- append([a],[b,c],[a,b,c]).
true.

2 ?- append([a],[b,c],Z).
Z = [a, b, c].

3 ?- append([a],Y,[a,b,c]).
Y = [b, c].

4 ?- append(X,[b,c],[a,b,c]).
X = [a] ;
false.

5 ?- append([a],Y,Z).
Z = [a|Y].

6 ?- append(X,[b,c],Z).
X = [],
Z = [b, c] ;
X = [_G383],
Z = [_G383, b, c] ;
X = [_G383, _G389],
Z = [_G383, _G389, b, c] . % etc

7 ?- append(X,Y,[a,b,c]).
X = [],
Y = [a, b, c] ;
X = [a],
Y = [b, c] ;
X = [a, b],
Y = [c] ;
X = [a, b, c],
Y = [] ;
false.

8 ?- append(X,Y,Z).
X = [],
Y = Z ;
X = [_G362],
Z = [_G362|Y] ;
X = [_G362, _G368],
Z = [_G362, _G368|Y] . % etc

9 ?- 

На практике не каждый предикат может быть вызван с каждой комбинацией из-за ограничений в выражении отношения таким образом, что это не приведет к бесконечному циклу. Другой причиной могут быть дополнительные логические особенности, такие как арифметика. Когда вы видите предикат, задокументированный как:

pred(+Foo, -Bar, ?Baz)

Это означает, что он ожидает создания экземпляра Foo (то есть объединенного с другим не-var), Bar - свободной переменной и Baz может быть любым. Один и тот же предикат может иметь несколько способов его вызова.

Это причина, по которой вы не можете рассматривать отношение Пролог как функцию в целом. Если вы передаете соединение в качестве аргумента, предложения, скорее всего, будут рассматривать его как соединение, если только оно не является специально , предназначенным для обработки его как кода. Одним из примеров является call/1, который выполняет свой аргумент как код. is, =:=, < и другие арифметические операторы также выполняют некоторую интерпретацию, если вы передаете что-то вроде cos(X).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...