1

我已经成功地将 PHP 与 Prolog 连接起来,并设法查询驻留在文件中的所需知识库,knowledge_base.pl并设法通过php exec函数回显结果。

true我在回显 Prolog 在每次查询执行后返回的/false值时遇到了问题(请参阅上一个问题),因此我想出了一个难以实施的解决方案。

假设我有一个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')).  

在序言中?提前致谢。

作为新用户,我不允许发布图片。

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!!

第一个查询失败,第二个查询成功。如您所见,查询执行后的序言输出真/假,但是当我在命令提示符下执行相同的查询时,真/假值不会得到回显!

4

3 回答 3

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).
于 2012-09-16T08:04:34.630 回答
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 回显“真”或“假”是其交互式会话的一部分。但是你用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 并让他改变它。:)

于 2012-09-17T10:13:10.237 回答
1
girl(erin) :-
        girl(erin)
     -> write('it is true')
     ;  write('it is not true'). 

这是错误的,原因有两个。Prolog 尝试解析采用最左边文字的主体。所以它基本上是一个循环“是艾琳女孩吗?是的,如果艾琳是女孩。艾琳女孩吗?......”

第二个原因是你混合了两种不同的东西。尝试将您的知识表示部分与您使用它的方式分开。在 Prolog 中,您只需说:

girl(erin)

然后查询

?- girl(erin)

Prolog 只会说“是”。如果要打印它,可能最简单的方法是添加谓词。

check_and_print(X) :- X, write(X), write(“是真的”)。

可能您需要call(X)而不是X,具体取决于您使用的实现。

我不确定命令提示符,我怀疑结果以不同的方式返回。

于 2012-09-21T12:02:04.890 回答