gpt4 book ai didi

Prolog - 规则是正确的,但没有按照预期的方式输出?

转载 作者:行者123 更新时间:2023-12-04 02:40:18 24 4
gpt4 key购买 nike

线索

四位客人(芥末上校、普拉姆教授、斯嘉丽小姐、格林女士)参加了在博迪先生家举行的晚宴。突然,灯灭了!当他们回来时,博迪先生已经死在 table 中间了。每个人都是嫌疑人。经过进一步检查,发现以下事实:

  • Boddy 先生与 Green 女士有染。
  • Plum 教授与 Green 女士结婚。
  • 先生博迪非常富有。
  • 芥末上校非常贪婪。
  • 斯嘉丽小姐还与博迪先生有染。

谋杀的动机可能有两种:

  • 仇恨:如果另一个人与他/她的配偶有外遇,某人就会讨厌另一个人。
  • 贪婪:如果贪婪而不富有,并且受害者有钱,有人愿意杀人。

A 部分:将上述事实和规则写入您的 Prolog 程序中。为人员使用以下名称:colMustard、profPlum、missScarlet、msGreen、mrBoddy。小心你如何编码(或不编码)像婚姻这样的对称关系 - 你不想要无限循环! married(X,Y) :- married(Y,X) % 无限循环

?-suspect(Killer,mrBoddy)
Killer = suspect_name_1
Killer = suspect_name_2
etc.

B 部分:写一个谓词 suspect/2,确定嫌疑人可能是谁,即谁有动机。

?-suspect(Killer,mrBoddy)
Killer = unique_suspect.

C 部分:向您的数据库添加一个事实,这将导致存在一个唯一的嫌疑人。在您的源评论中清楚地指出这一行,以便可以将其删除/添加评分。

?-suspect(Killer,mrBoddy)
Killer = unique_suspect.

每当我输入

suspect(Killer,mrBoddy).

我明白了

suspect(Killer,mrBoddy).
Killer = profPlum

我不见了

Killer = colMustard.

这是我的来源。

%8) Clue

%facts

affair(mrBoddy,msGreen).
affair(missScarlett, mrBoddy).
affair(X,Y) :- affair(X,Y), affair(Y,X).

married(profPlum, msGreen).
married(X,Y) :- married(X,Y), married(Y,X).

rich(mrBoddy).
greedy(colMustard).

%rules

hate(X,Y) :- married(X,Spouse), affair(Y,Spouse).
greed(X,Y) :- greedy(X), not(rich(X)), rich(Y).


%suspect

suspect(X,Y):- hate(X,Y).
suspect(X,Y):- greed(X,Y).

最佳答案

你的程序有两种问题。一个是在程序层面:您观察到 Prolog 循环;另一个是逻辑层——Prolog 的人称之为声明层。由于第一个烦人的事情就是这个无限循环,让我们先缩小它的范围。实际上我们得到:

?- suspect(Killer,mrBoddy).
Killer = profPlum ;
ERROR: Out of local stack

您现在有几个选项可以缩小这个问题的范围。或者,选择另一个答案并调用跟踪器。虽然跟踪器可能会向您显示真正的罪魁祸首,但它很可能会在其中穿插许多不相关的步骤。太多了,你的头脑会溢出来。

另一种选择是通过将目标 false 添加到您的程序中来手动修改您的程序。我将尽可能多地添加 false 目标,同时仍然会出现循环。最大的优势是,通过这种方式,您将在源代码中看到真正的罪魁祸首(或者更准确地说,可能是许多此类罪魁祸首之一)。1 尝试了一下之后,这就是我得到的 :

?- suspect(Killer,mrBoddy), false.married(profPlum, msGreen) :- false.married(X,Y) :- married(X,Y), false, married(Y,X).hate(X,Y) :- married(X,Spouse), false, affair(Y,Spouse).suspect(X,Y):- hate(X,Y), false.suspect(X,Y):- false, greed(X,Y).

All remaining parts of your program were irrelevant, that is, they are no longer used. So essentially the rule

married(X,Y) :- married(X,Y), married(Y,X).

是罪魁祸首。

现在,对于它的声明部分。无论如何,这条规则是什么意思?为了理解它,我将 :- 解释为一种暗示。所以只要右边写的是真的,我们就可以得出左边写的结论。在这种情况下:

Provided X is married to Y and Y is married to X
we can conclude that
X is married to Y.

无论如何,这个结论得出了我们假设为真的结论。所以它没有定义任何新的逻辑。您只需删除规则即可获得相同的结果——以声明的方式。所以 married(profPlum, msGreen) 成立但 married(msGreen, profPlum) 不成立。换句话说,正如您声称的那样,您的规则不正确。

要解决这个问题,删除规则,将所有事实重命名为 husband_wife/2 并添加定义

married(M,F) :- husband_wife(M,F).
married(F,M) :- husband_wife(M,F).

所以这里实际更深层次的问题是一个逻辑错误。除此之外,Prolog 的证明机制非常简单,将其变成一个循环。但这只不过是原始逻辑问题的一个受欢迎的借口。2


脚注:
1 此方法仅适用于纯粹的单调片段。 not/1(\+)/1 等非单调结构不得出现在片段中。
2 @larsmans 对这个例子很感兴趣。

关于Prolog - 规则是正确的,但没有按照预期的方式输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20060840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com