首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用swi-prolog编写递归

用swi-prolog编写递归
EN

Stack Overflow用户
提问于 2012-09-16 07:59:33
回答 3查看 2.5K关注 0票数 1

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

在每次执行查询(true)之后,我在回显Prolog返回的false/see previous question值时遇到了一个问题,所以我想出了一个解决方案,我在实现这个解决方案时遇到了问题。

让我们假设我有一个简单的knowledge_base.pl文件,其中包含以下事实和规则:

代码语言:javascript
复制
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文件中:

代码语言:javascript
复制
girl(erin) :-
        girl(erin)
     -> write('it is true')
     ;  write('it is not true'). 

当我输入查询:?- girl(erin).时,我会得到一个out of local stack错误。我搜索了Web,发现这是无限递归的结果。

谁能给我一个如何写作的提示?

代码语言:javascript
复制
girl(X) :-
    (    girl(X)
      -> write('it is true')
      ;  write('it is not true')).  

在Prolog?提前谢谢。

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

SWI-Prolog的输出:

代码语言:javascript
复制
1 ?-hangs_out_with(erin,kosta).
false.

2 ?-hangs_out_with(erin,john).
Someone s got a new friend!!
true.

命令提示符的输出:

代码语言:javascript
复制
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,但当我在命令提示符中执行相同的查询时,真假值不会被回显!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-17 10:13:10

因此,您可以通过在命令shell中执行Prolog查询并捕获和分析其输出来“将PHP连接到Prolog”。http://www.swi-prolog.org/man/quickstart.html

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

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

注意你的第一次尝试,

代码语言:javascript
复制
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)失败了。逗号表示连词(“和”)。

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

代码语言:javascript
复制
report_hangs_out_with(A,B):-
  hangs_out_with(A,B)- > writeln(['YES',A,B]) ; writeln('NO').

然后用它来代替:

代码语言:javascript
复制
C:>swipl -q -f knowledge_database.pl -g report_hangs_out_with(erin,kosta),halt.

另外,Prolog回显"true“或"false”是其交互会话的一部分。但是你用halt来终止它!

编辑:您发布的

代码语言:javascript
复制
1 ?-hangs_out_with(erin,kosta).
false.

因此,当您在交互式Prolog shell中运行该查询时,它会报告故障。halt/0退出Prolog外壳。当您使用通过命令行开关指定的目标运行它时,显然它不会报告失败的成功。就我们用户而言,这是自然的事实。编译器编写者)。我给你看的东西很容易寻址。你自己说它也能工作,也是。对于每个可能失败或成功的谓词,定义另一个谓词,reporting 谓词,就像我已经向您展示的那样。

这里有一个样本记录(在Windows中,但这是不相关的)。这应该能消除你的疑虑:

代码语言:javascript
复制
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>      

事情就是这样的。处理好它。)或者写信给简,让他改变它。:)

票数 1
EN

Stack Overflow用户

发布于 2012-09-16 08:04:34

我觉得你应该问问

代码语言:javascript
复制
is_girl(X) :-
    girl(X) -> write('t is true') ; write('it is not true'). 

编辑

你是说这种事吗?

代码语言:javascript
复制
is_type(Type, X) :-
    call(Type, X) -> writeln(yes); writeln(no).
票数 2
EN

Stack Overflow用户

发布于 2012-09-21 12:02:04

代码语言:javascript
复制
girl(erin) :-
        girl(erin)
     -> write('it is true')
     ;  write('it is not true'). 

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

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

代码语言:javascript
复制
girl(erin)

然后查询

代码语言:javascript
复制
?- girl(erin)

普罗洛只会说“是”。如果您想打印它,可能最简单的方法是添加一个谓词。

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

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12445305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档