在swi-prolog中编写递归

在swi-prolog中编写递归,prolog,Prolog,我已成功地将PHP与Prolog连接,并设法查询驻留在knowledge_base.pl文件中的所需知识库,并设法通过PHP exec函数返回结果 我在回显Prolog在每次查询执行()后返回的true/false值时遇到了一个问题,因此我提出了一个实现起来有困难的解决方案 假设我有一个简单的knowledge\u base.pl文件,其中包含以下事实和规则: girl(erin). boy(john). likes(erin, reading). likes(john, reading).

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

我在回显Prolog在每次查询执行()后返回的
true
/
false
值时遇到了一个问题,因此我提出了一个实现起来有困难的解决方案

假设我有一个简单的
knowledge\u 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\u base.pl
文件中:

girl(erin) :-
        girl(erin)
     -> write('it is true')
     ;  write('it is not true'). 
当我输入查询:
?-girl(erin)。
我从本地堆栈中得到一个
错误。我在网上搜索,发现这是由于无限递归造成的

有人能给我一个如何写作的提示吗

girl(X) :-
    (    girl(X)
      -> write('it is true')
      ;  write('it is not true')).  
在序言中?提前谢谢

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

SWI Prolog的输出:

命令提示符的输出:


第一个查询失败,第二个查询成功。如您所见,执行查询后,prolog会输出true/false,但当我在命令提示符中执行相同的查询时,true/false值不会得到响应

我想你应该问一下

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).

我想你应该问一下

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).
因此,通过在命令shell中执行Prolog查询并捕获和分析其输出,“将PHP连接到Prolog”。说

“2.1.1.1在Unix上启动SWI Prolog

默认情况下,SWI Prolog安装为“swipl”。SWI Prolog本身及其实用程序的命令行参数使用标准Unix手册页记录。”

因此,请参阅有关“-q”开关的手册页。是不是“q”代表安静?“-f”是什么意思(好的,那可能是“file”)?但解决方案是相同的——只需为新谓词使用不同的名称即可

注意,在您的第一次尝试中

C:>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
halt
没有执行,正是因为
挂起(erin,kosta)
失败了。逗号表示连词(“and”)

您需要做的就是创建一个新的谓词,报告目标是真是假,并始终成功:

report_hangs_out_with(A,B):-
  hangs_out_with(A,B)- > writeln(['YES',A,B]) ; writeln('NO').
并改用它:

此外,Prolog回响“true”或“false”是其交互式会话的一部分。但您可以用
停止
来终止它


编辑:您发布了:

1 ?-hangs_out_with(erin,kosta).
false.
因此,当您在交互式Prolog shell中运行该查询时,它会报告失败
halt/0
退出Prolog shell。当您使用通过命令行开关指定的目标运行它时,显然它不会报告失败的成功。就我们用户而言,这是自然的事实(a.o.t.编译器编写者)。我给你看的东西很容易解决。你自己也说它也有效。对于每个可能失败或成功的谓词,定义另一个,报告谓词,正如我向您展示的那样

这是一份成绩单样本(在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>      
就是这样。处理它。:)或者写信给简,让他改变它。:)

因此,通过在命令shell中执行Prolog查询并捕获和分析其输出,“将PHP连接到Prolog”。说

“2.1.1.1在Unix上启动SWI Prolog

默认情况下,SWI Prolog安装为“swipl”。SWI Prolog本身及其实用程序的命令行参数使用标准Unix手册页记录。”

因此,请参阅有关“-q”开关的手册页。是不是“q”代表安静?“-f”是什么意思(好的,那可能是“file”)?但解决方案是相同的——只需为新谓词使用不同的名称即可

注意,在您的第一次尝试中

C:>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
halt
没有执行,正是因为
挂起(erin,kosta)
失败了。逗号表示连词(“and”)

您需要做的就是创建一个新的谓词,报告目标是真是假,并始终成功:

report_hangs_out_with(A,B):-
  hangs_out_with(A,B)- > writeln(['YES',A,B]) ; writeln('NO').
并改用它:

此外,Prolog回响“true”或“false”是其交互式会话的一部分。但您可以用
停止
来终止它


编辑:您发布了:

1 ?-hangs_out_with(erin,kosta).
false.
因此,当您在交互式Prolog shell中运行该查询时,它会报告失败
halt/0
退出Prolog shell。当您使用通过命令行开关指定的目标运行它时,显然它不会报告失败的成功。就我们用户而言,这是自然的事实(a.o.t.编译器编写者)。我给你看的东西很容易解决。你自己也说它也有效。对于每个可能失败或成功的谓词,定义另一个,报告谓词,正如我向您展示的那样

这是一份成绩单样本(在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>      
就是这样。处理它。:)或者写信给简,让他改变它。:)

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

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

girl(erin)
然后查询

?- girl(erin)
序言只会说“是”。如果要打印它,最简单的方法可能是添加谓词

检查并打印(X):-X,写入(X),写入(“为真”)

可能您需要调用(X)而不是X,这取决于您正在使用的实现

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