Вызов предиката пролога из python

У меня есть файл .pl, и я хочу вызвать объявленный в нем предикат из скрипта python. Как я могу это сделать?

Например, test.pl

rD( [], Ans, Ans ).
rD( [X|Xs], Ans, Acc ) :-
    member( X, Acc ),
    rD( Xs, Ans, Acc ), !.
rD( [X|Xs], Ans, Acc ) :-
    \+member( X, Acc ),
    append( Acc, [X], AccNew ),
    rD( Xs, Ans, AccNew ), !.

Работает как

?- rD( [1,2,3,4,5,4], X ).
X = [1, 2, 3, 4, 5].

Я хочу как-то вызвать rD из скрипта python и получить ответ в переменной результата

result
[1, 2, 3, 4, 5]

PS: это всего лишь пример, и я не хочу переписывать свою текущую программу на Прологе.


person ДМИТРИЙ МАЛИКОВ    schedule 23.05.2011    source источник


Ответы (3)


Не то чтобы у меня был непосредственный опыт работы с ним, но есть проект под названием PySWIP, который предоставляет мост между Python и SWI-Prolog. вики, размещенная на страницах проектов Google Code, содержит инструкции по установке и некоторые примеры использования.

ИЗМЕНИТЬ (5 июля 2019 г.)

PySWIP теперь поддерживается на Github со своим собственным инструкции по установке. TLDR: установка SWI-Prolog и pip install pyswip должна выполнить эту работу как для Python 2, так и для Python 3.

person Giulio Piancastelli    schedule 23.05.2011

Поскольку вы не хотите «переписывать мою текущую программу на Прологе», я думаю, что естественный подход состоит в том, чтобы сделать внешний вызов из Python в SWI-Prolog, передав соответствующие аргументы командной строки.

Взгляните на это обсуждение SO, Как вызвать внешнюю команду в Python, от сентября 2008 г. Использование модуля subprocess позволяет стандартный вывод из внешней команды для передачи в процесс Python и чтения там в виде потока.

Это сводит проблему к выбору аргументы командной строки для SWI-Prolog. Можно вызвать SWI-Prolog косвенно, через сценарий оболочки в Unix-подобных системах или пакетный/командный файл «DOS» в Windows, но я опускаю дальнейшее упоминание о таком косвенном вызове.

См. особенно обсуждение в гл. 2.4.2 руководства SWI-Prolog (ссылка выше) опций -g и -t. Например:

swipl --quiet -t rD( [1,2,3,4,5,4], X ),halt

вероятно, сделает то, что вы хотите. Параметр --quiet подавляет баннер/приветствие, которые вы, вероятно, захотите упростить для анализа вывода, полученного Python.

person hardmath    schedule 25.05.2011
comment
Да, это своего рода вариант. Но не совсем юзабельный - person ДМИТРИЙ МАЛИКОВ; 25.05.2011
comment
@ garm0nboz1a: Если есть конкретные шаги, требующие разъяснения, я буду рад попробовать. При таком подходе программа SWI-Prolog рассматривается как черный ящик. Таким образом, хотя существующий код .pl ничего не знает о вызывающем объекте Python, такой вызывающий объект должен взять на себя бремя синтаксического анализа результата запроса верхнего уровня Prolog и выполнения с ним соответствующих действий, например. присвоение переменной. В вашем примере не ясно, требуется ли код Python для распознавания типа данных result или просто для обработки всех значений как строк. Таким образом, в вашем вопросе есть много неисследованных (мной) аспектов. - person hardmath; 26.05.2011

Обновление для Python3, PySwip в PyPI на момент написания статьи предназначено только для устаревшего Python, но исходный код на github совместим с Python3. Вы можете клонировать это git, запустить python3 setup.py install, и он даст вам версию Python3.

Чтобы обратиться к существующей базе знаний, хранящейся как Knowledge_base.pl:

from pyswip import Prolog
prolog = Prolog()
prolog.consult("knowledge_base.pl")
for res in prolog.query("rD( [1,2,3,4,5,4], X )."):
    print(res)

# output:
# {'X': [1, 2, 3, 4, 5]}
person Paul Brown    schedule 19.05.2018
comment
Кажется, его снова можно установить для Python 3 из pypi. - person Martin; 05.07.2019