我已成功将PHP与Prolog连接,并设法查询驻留在knowledge_base.pl
文件中的所需知识库,并设法通过php exec
函数回显结果。
我在回复每次执行查询后返回的true
/ false
值时遇到了问题(see previous question)所以我想出了一个我无法实现的解决方案。< / p>
假设我有一个简单的knowledge_base.pl
文件,其中包含以下事实和规则:
girl(erin).
boy(john).
likes(erin, reading).
likes(john, reading).
hangs_out_with(erin, X) :-
likes(X, reading),
boy(X),
writeln('Someone s got a new friend!!').
让我们说我想看看erin
是否是女孩,如果是,请写下它是真的,否则写下它是假的。我将此添加到我的knowledge_base.pl
文件中:
girl(erin) :-
girl(erin)
-> write('it is true')
; write('it is not true').
当我输入查询时:?- girl(erin).
我收到out of local stack
错误。我搜索了网络,发现这是由于无限递归。
有人可以给我一个如何写的提示
girl(X) :-
( girl(X)
-> write('it is true')
; write('it is not true')).
在Prolog中?提前谢谢。
作为新用户,我不允许发布图片。
SWI-Prolog的输出:
1 ?-hangs_out_with(erin,kosta).
false.
2 ?-hangs_out_with(erin,john).
Someone s got a new friend!!
true.
命令提示符的输出:
C:\(directory)>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
C:\(directory)>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,john),halt.
Someone s got a new friend!!
第一个查询失败,第二个查询失败。正如您所看到的,prolog在查询执行后输出true / false但是当我在命令提示符中执行相同的查询时,true / false值不会被回显!!
答案 0 :(得分:2)
我想你应该问
is_girl(X) :-
girl(X) -> write('t is true') ; write('it is not true').
修改
你是说这种事吗?
is_type(Type, X) :-
call(Type, X) -> writeln(yes); writeln(no).
答案 1 :(得分:1)
所以你通过在命令shell中执行Prolog查询并捕获和分析其输出来“将PHP连接到Prolog”。 http://www.swi-prolog.org/man/quickstart.html说
“2.1.1.1在Unix上启动SWI-Prolog
默认情况下,SWI-Prolog安装为'swipl'。 SWI-Prolog本身及其实用程序的命令行参数使用标准的Unix手册页进行记录。“
请参阅有关“-q”开关的手册页。这也许是安静的“-q”吗? “-f”是什么意思(好吧,那可能是“文件”)?但解决方案是相同的 - 只需为新谓词使用不同的名称。
请注意,在您第一次尝试时,
C:>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
halt
未执行,正是因为hangs_out_with(erin,kosta)
失败了。逗号表示连词(“和”)。
您需要做的就是创建一个新的谓词来报告目标是真还是假,并且始终成功:
report_hangs_out_with(A,B):-
hangs_out_with(A,B)- > writeln(['YES',A,B]) ; writeln('NO').
并改为使用 :
C:>swipl -q -f knowledge_database.pl -g report_hangs_out_with(erin,kosta),halt.
此外,Prolog回应“true”或“false”是其交互式会话的一部分。但是你用halt
终止了它!
编辑 :
1 ?-hangs_out_with(erin,kosta).
false.
因此,当您在交互式Prolog shell中运行该查询时,它会报告失败。 halt/0
退出Prolog shell。当您使用通过命令行开关指定的目标运行它时,显然它不会报告失败的成功。就用户而言,这就是自然界的事实(例如编译器编写者)。用我向你展示的内容很容易解决。而且你自己也说它有效。对于可能失败或成功的每个谓词,定义另一个 报告谓词,就像我向您展示的那样。
这是一个示例脚本(在Windows中,但这是无关紧要的)。这应该清除你的疑虑:
C:\Program Files\pl\bin>plcon -q -g (writeln('****'),halt).
**** // didn't say Yes, right??
C:\Program Files\pl\bin>plcon -q
1 ?- writeln('****'),halt.
**** // didn't say Yes here either
C:\Program Files\pl\bin>plcon -q
1 ?- writeln('****').
****
Yes // does say Yes as part of interaction
2 ?- halt.
C:\Program Files\pl\bin>
这就是它的样子。处理它。 :)或者写Jan并请他改变它。 :)
答案 2 :(得分:1)
girl(erin) :-
girl(erin)
-> write('it is true')
; write('it is not true').
这有两个原因是错误的。 Prolog试图以最左边的文字解析身体。 所以它基本上是一个循环“是erin女孩?是的,如果erin是女孩。是erin女孩吗?......”
第二个原因是你混合了两种不同的东西。尽量将您的知识表示部分与您使用它的方式分开。 在Prolog中你只需说:
girl(erin)
然后查询
?- girl(erin)
Prolog只会说“是”。如果要打印它,可能最简单的方法是添加谓词。
check_and_print(X): - X,写(X),写(“是真”)。
您可能需要调用(X)而不是 X ,具体取决于您使用的实现。
我不确定命令提示符,我怀疑结果会以不同的方式返回。