从python调用prolog谓词

时间:2011-05-23 21:49:01

标签: python prolog ffi swi-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程序。

4 个答案:

答案 0 :(得分:3)

并非我对它有直接的体验,但有一个名为PySWIP的项目提供了Python和SWI-Prolog之间的桥梁。 Google Code的项目页面上托管的wiki包含installation instructions和一些usage examples

答案 1 :(得分:2)

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

从2008年9月开始查看此SO讨论How to call external command in Python。使用subprocess模块允许来自外部命令的stdout通过管道传输到Python进程并在那里读取为流

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

特别参见第二节中的讨论。 2.4 -g-t选项的SWI-Prolog手册(上面已链接)。例如:

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

可能会做你想要的。 --quiet选项会禁止标题/欢迎消息,您可能希望简化解析Python接收的输出。

答案 2 :(得分:1)

Python3的更新,撰写本文时PyPI中的PySwip仅适用于旧版Python,但source code on 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]}

答案 3 :(得分:0)

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