从python调用prolog谓词



我有一些.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].

我想以某种方式从python脚本中调用rD,并在结果变量中得到答案

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

ps:这只是一个例子,我不想重写我当前的Prolog程序。

这并不是说我有直接的经验,但有一个名为PySWIP的项目在Python和SWI-Prolog之间提供了一座桥梁。谷歌代码项目页面上的wiki包含安装说明和一些使用示例。

编辑(2019年7月5日)

PySWIP现在似乎是在Github上维护的,有自己的安装说明。TLDR:安装SWI-Prolog和pip install pyswip应该可以完成这项工作,无论是Python 2还是Python 3。

由于您不想"重写我当前的Prolog程序",我认为自然的方法是从Python对SWI-Prolog进行外部调用,并传递适当的命令行参数。

看看这个SO讨论,如何在Python中调用外部命令,从2008年9月开始。使用subprocess模块可以将来自外部命令的stdout通过管道传输到Python进程,并在那里作为流读取。

这减少了为SWI-Prolog选择命令行参数的问题。可以通过类Unix系统上的shell脚本或Windows上的"DOS"批处理/cmd文件间接调用SWI-Prolog,但我将省略对这种间接调用的进一步提及。

请特别参阅SWI Prolog手册(链接至上文)第2.4.2节中关于-g-t选项的讨论。例如:

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

很可能会做你想做的事。--quiet选项抑制横幅/欢迎消息,您可能希望简化解析Python接收到的输出。

Python3的更新,在撰写本文时PyPI中的PySwip仅适用于遗留Python,但github上的源代码与Python3兼容。你可以克隆这个,运行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]}
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

最新更新