我对这个特定程序的逻辑感到困惑

时间:2016-04-06 09:27:46

标签: prolog

问题:

  杰克正在看安妮,安妮正在看着乔治   杰克已婚,乔治不是。

  已婚人士是否正在看未婚人士?

我正在研究this link中找到的解决方案:

unmarried(X) :- not(married(X)).
unmarried("George").
unmarried("Anne").

married("Jack").
married("Anne").

looking_at("Jack", "Anne").
looking_at("Anne", "George").

check(X, Y):-
    looking_at(X,Y),
    married(X),
    unmarried(Y).

完成这么多工作后,有几个问题立即显现出来。对于第一部分,我很困惑为什么安妮被定义为已婚(&#34;安妮&#34;)和未婚(&#34;安妮&#34;),但我很快把它放在一边假设< / em>这可能意味着将Anne定义为已婚或未婚

  

快速查看SO也没有任何帮助,因为我发现只有一些远程   相关问题;
This特别问题是最接近的问题。

现在回到我在这里的问题......

未婚(X): - 不(已婚(X))。处理操作,如果将Anne作为 check(_,_)

that解决方案的程序员已使用单个检查(_,_)处理它,具体如下: 检查(安妮,乔治)将推断:

  • 安妮看着乔治
  • 安妮结婚
  • 乔治未婚
  

That compiler产生以下结果:
  的 - &GT; Jack-&GT; Anne-&GT;安
  的乔治 - &GT; Anne-&GT;乔治 - &GT;乔治

此时,我不知道编译器为什么会产生这些结果。据我所知,this也没有提供解决方案。在我使用的旧版桌面版prolog中,检查(Anne,George)。应该产生 YES ,因为所有条件都是正确的(嗯我从未尝试过在线swi-prolog tbh;它有什么不同吗?

支票(杰克,安妮)是:

  • 杰克看着安妮
  • 杰克结婚
  • 安妮未婚
  

我不知道这是如何解决这个问题的。有人可以发布更好的解决方案或详细解释这是如何工作的吗?

要求:

我需要一个问题的解决方案,我在这个问题的开头发布了。如果你可以从我发布的现有条件中解决它,那很酷。但是,我也愿意接受其他想法和解决方案。

2 个答案:

答案 0 :(得分:2)

首先让我们来看看这个谜题本身。问题是“已婚人士是否在看未婚人士?”显然是一个是/否的问题。考虑到婚姻状况,我们有不完整的知识(安妮)。我们所知道的婚姻状况的人并没有互相凝视,所以我们必须考虑安妮才能找到答案。如果我们假设:

  • 安妮结婚然后回答是肯定的,因为她正在看未婚的乔治。

  • 安妮没有结婚,答案是肯定的,因为已婚的杰克正在看着她。

所以无论哪种方式都有一个已婚人士在看未婚人士,因此这个难题的答案是肯定的。

关于给定的解决方案:我认为作者试图通过事实married("Anne")unmarried("Anne").模拟“安妮已经结婚未婚”但事实似乎是表示安妮已经结婚并且同时未婚。规则unmarried(X) :- not(married(X)).结合已婚/ 1和未婚/ 1的事实也会产生解决方案“安妮”两次。因此,check / 2也会产生两次Anne-looking-at-George解决方案:

    ?- check(X,Y).
X = "Jack",
Y = "Anne" ? ;
X = "Anne",
Y = "George" ? ;
X = "Anne",
Y = "George"

我可以看到作者尝试使用他的解决方案的地方但是并没有真正表达出涉及的假设以及这两种独特解决方案是如何连接的。

我的尝试如下:我会保留原始版本中的四个事实,并为Anne添加另一个:

married(jack).

unmarried(george).

looking_at(jack,anne).
looking_at(anne,george).

unknown(anne).

然后我可以假设我不知道婚姻状况的人:

person_assumption(A,married) :- unknown(A).
person_assumption(A,unmarried) :- unknown(A).

现在,答案的相关案例是:(1)已知已婚人士正在查看已知的未婚人士;(2)P1是

  • 在P1结婚的情况下看着已知的未婚人士

  • 在假设P1未婚的情况下由已知的已婚人士观看

谓词problematicgaze / 1正在对这些观察进行建模:

problematicgaze((P1-P2)) :-                                   % case (1)
    married(P1),
    unmarried(P2),
    looking_at(P1,P2).
problematicgaze((if_married(P1)-P2,P3-if_unmarried(P1))) :-   % case (2)
    assumedproblematic(if_married(P1),P2),
    assumedproblematic(P3,if_unmarried(P1)).


assumedproblematic(if_married(P1),P2) :-
    person_assumption(P1,married),
    unmarried(P2),
    looking_at(P1,P2).
assumedproblematic(P1,if_unmarried(P2)) :-
    person_assumption(P2,unmarried),
    married(P1),
    looking_at(P1,P2).

这分解为:我得到一个解决方案,答案是或谓词失败,答案是。所以我问在给定的情况下是否存在问题:

   ?- problematicgaze(G).
G = (if_married(anne)-george,jack-if_unmarried(anne)) ? ;
no

正如预期的那样,来自problematicgaze / 1的第一条规则没有答案,而是来自第二条规则。无论对安妮采取何种假设,已婚人士都在看未婚者。除此之外,没有找到解决方案。

答案 1 :(得分:0)

您已关联的解决方案不正确。在评论中指出,我不确定这是如何给出答案的:

?- check(X, Y).
X = "Jack",
Y = "Anne" ;
X = "Anne",
Y = "George" ;
X = "Anne",
Y = "George".

如果有人知道该程序是要使用的,请解释一下。我担心我只是遗漏了一些东西。

以下是真正解决方案的一次尝试。首先,我们完全按照给出的理由留下基本事实:

looking_at(jack, anne).
looking_at(anne, george).

married(jack).
unmarried(george).

我现在将定义一个谓词solution/2,它具有解决方案和任何可能的解释它的绑定。如果我理解,有三种可能的解决方案:&#34;是&#34;,&#34;否&#34;和&#34;未确定&#34;。在&#34;是&#34;的情况下回答:

solve(yes, married_unmarried(A, B)) :-
    married(A),
    looking_at(A, B),
    unmarried(B).

&#34; no&#34;案例有点不同。应该说:

  

对于看A的所有A,A未婚或B结婚。

使用SWI-Prolog和forall/2,您可以写:

solve(no, false) :-
    forall(looking_at(A, B),
           ( unmarried(A) ; married(B) )).

这相当于:

solve(no, false) :-
    \+ ( looking_at(A, B),
           \+ ( unmarried(A) ; married(B) ).

未确定的案例更有趣,但我们可以尝试欺骗:

solve(undetermined, B) :-
    \+ solve(yes, B),
    \+ solve(no, B).
  

我们既不能证明某人在寻找,也不能证明没有人在寻找。