2011-05-23 123 views
3

我有一些.pl文件,我想调用python脚本中声明的谓词。我怎样才能做到这一点?从python调用prolog谓词

例如,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 pr ogram。

回答

2

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

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

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

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

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

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

+0

是的,它是一种变种。但不是真的可用 – 2011-05-25 15:41:13

+0

@ garm0nboz1a:如果有特定的步骤需要澄清,我很乐意尝试。该方法将SWI-Prolog程序视为“黑盒子”。因此,尽管现有的.pl编码“不知道”Python调用者,但这样的调用者必须承担解析Prolog顶级查询结果并对其做适当处理的负担,例如,分配给一个变量。你的例子并不清楚Python代码是否需要“识别”result的数据类型,或者只是将所有的值视为字符串。所以你的问题有很多未知的方面(我)。 – hardmath 2011-05-26 14:12:24

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