Вызов предиката пролога из питона - PullRequest
4 голосов

У меня есть файл .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: это всего лишь пример, и я не хочу переписывать мою текущую программу Prolog.

Ответы [ 4 ]

3 голосов
/ 24 мая 2011

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

EDIT (5 июля 2019 г.)

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

2 голосов
/ 25 мая 2011

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

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

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

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

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

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

1 голос
/ 20 мая 2018

Обновление для Python3, PySwip в PyPI на момент написания, предназначено только для устаревшего Python, но исходный код на github совместим с Python3.Вы можете git clone this, запустить 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]}
0 голосов
/ 29 января 2013
from subprocess import Popen, PIPE, STDOUT

p = Popen('/usr/local/sicstus4.2.3/bin/sicstus', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
cmd = open('/path/to/your/test.pl').read()
res = p.communicate(cmd)
for line in res:
    print line
...