从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 的变量里。
result
[1, 2, 3, 4, 5]
补充说明:这只是一个例子,我不想重写我现在的 Prolog 程序。
4 个回答
2
目前在写这段话时,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]}
4
既然你不想“重写我现在的Prolog程序”,那么一个自然的做法就是从Python中调用SWI-Prolog,并传递合适的命令行参数。
你可以看看这个讨论,如何在Python中调用外部命令,这是2008年9月的内容。使用subprocess
模块可以让外部命令的输出直接传给Python程序,并在那儿作为流来读取。
这样一来,问题就变成了选择SWI-Prolog的命令行参数。你可以通过在类Unix系统上使用shell脚本,或者在Windows上使用“DOS”批处理文件来间接调用SWI-Prolog,但我就不再详细说这种间接调用了。
特别要注意SWI-Prolog手册中第2.4.2节的讨论(上面有链接),关于-g
和-t
选项。例如:
swipl --quiet -t rD( [1,2,3,4,5,4], X ),halt
这可能正是你想要的。--quiet
选项可以抑制欢迎信息,这样你在解析Python接收到的输出时会更简单。