【问题标题】:Prolog rule within a rule规则中的 Prolog 规则
【发布时间】:2017-04-16 21:37:35
【问题描述】:

我有一个简单的序言程序,它试图根据信任规则和知道规则来确定谁信任谁。在这里

know(joe,jack).
know(joe,sue).
know(joe,betty).
know(sue,betty).
know(jack,betty).
know(bill,betty).

knows(X,Y):- know(X,Y);know(Y,X).

trust(jack,joe).
trust(bill,joe).
trust(betty,jack).

knows 规则是对称且可传递的,trusts 规则由

定义
Person X trusts Y if and only if
-X inherently trusts Y, or
-X knows two DIFFERENT people who trust Y.

信任不是对称的,也不是传递的。

我不确定如何在规则中执行规则,变量似乎让我很困惑,因为试图只使用 2 个变量作为参数,但在规则中使用 4。任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 首先,只有一个小提示:要表示两个术语不同,您可以使用谓词dif/2。请参阅prolog-dif 了解更多信息。完全没有问题,只有您在规则正文中使用的一些变量出现在头部。事实上,这是一个比较典型的案例。关键是要以声明的方式考虑它,即使用您需要的任何其他变量来描述必须为参数保留的约束。
  • @mat 我已经创建了这条规则,但由于某种原因它导致了无限循环。信任(X,Y):-差异(A,B),知道(X,A),信任(A,Y),知道(X,B),信任(B,Y)。知道为什么会这样吗?

标签: parameters prolog rules


【解决方案1】:

您的问题以某种方式表明您认为您必须在谓词的头部包含出现在谓词主体中的所有变量。这不是必需的。假设我想找出问题定义中某人知道的人数:

?- bagof(X, knows(betty, X), Xs), length(Xs, N).

您可能真的只是想知道 Betty 认识 4 个人,但无论如何,顶层都会写出 Betty 认识的人的列表。所以你把它放在一个谓词中:

knows_count(X, N) :-
    bagof(Y, knows(X, Y), Ys),
    length(Ys, N).

所以现在你只看到你需要看到的:

?- knows_count(betty, N).
N = 4.

?- knows_count(X, N).
X = betty, N = 4 ;
X = bill,  N = 1 ;
X = jack,  N = 2 ;
X = joe,   N = 3 ;
X = sue,   N = 2.

您现在已经“隐藏”了knows_count/2 正文中的人员列表。

要定义trusts/2 的第二种情况,您可以这样做:

trusts(X, Y) :-
    knows(X, A), trust(A, Y), ... % and so on

正如@mat 所指出的,现在您所要做的就是确保谓词正文中“X 认识”的所有人都不是同一个人。请参阅 link in the comment by @mat 或在 Stackoverflow 中搜索 [prolog] dif

【讨论】:

  • 我试过这样做,但没有任何进展。无论我做什么,我都会以无限循环告终,因为 Prolog 不够聪明,无法自行循环。我试图了解您的第一个示例问题与信任问题的关系,但我也无法弄清楚。
  • @Johnny 最重要的是:您需要trusts/2 的一个子句,它不是递归的,并且仅根据trust/2 的事实定义;另一个子句将根据knows/2 和事实trust/2 来定义,我猜。那,并使用dif/2 确保必须不同的变量是不同的。
  • @Johnny 我注意到我在上面的小代码 sn-p 中实际上犯了一个严重的错误(现在已编辑!):我使用trusts/2 而不是trust/2,所以实际上谓词是递归的已定义,即使您在问题中明确表示“信任”不是传递关系....抱歉浪费您的时间:-(
  • 抱歉,来晚了,但我想我明白了,我只是想确保这是有道理的。 Trusts(X,Y):- dif(A,B),knows(X,A),trusts(A,Y),knows(X,B),trusts(B,Y)。
  • 这就是你要我做的,但是这会导致无限循环,因为我相信它会循环回到起始变量并且无法断定它应该停在那里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多