【问题标题】:Why does my predicate not work, when a similar predicate does?为什么我的谓词不起作用,而类似的谓词却起作用?
【发布时间】:2020-03-24 05:09:26
【问题描述】:

我有以下事实:

loves(andy, julia).
loves(andrew, maria).
loves(bob, sofia).
loved(juila).
loved(maria).
loved(sofia).

我想要两个谓词:

do_love(X, Y) :- ...
is_loved(X, Y) :- ...

返回 Y 作为人名,X 作为事实本身。对于loved 事实,我写道:

is_loved(X, Y) :- X = loved(Y), X.

正如预期的那样,返回:

is_loved(X,Y).
X = loved(juila),
Y = juila ;
X = loved(maria),
Y = maria ;
X = loved(sofia),
Y = sofia.

但是,当我以类似的方式为loves 事实编写谓词时:

do_love(X, Y) :- X = loves(X, Y), X.

它为查询返回 false:

do_love(X,Y).
false.

我是 prolog 的新手,真的不明白为什么会这样。 为什么is_loved 的查询有效,而do_love 的查询无效?

【问题讨论】:

  • 问问自己,X = loved(Y) 在 Prolog 中做了什么?它不同于 C# 或 Java。
  • 想想X = loves(X, Y)是什么意思——你试图将它统一为X = loves(loves(X, Y), Y),然后是X = loves(loves(loves(loves(X, Y), Y), Y), Y)等等。它永远不会满足。
  • 您使用的是哪个 Prolog 系统?如果您使用的是 SWI,请尝试在 Prolog 文件前添加 :- set_prolog_flag(occurs_check, error).,重新加载并再次运行查询。

标签: prolog


【解决方案1】:

问题是你试图用两个不同的值来统一X

  • X = loves(...)
  • loves(X, ...)

(我使用... 截断,因为这些部分与我所说的无关)。

换句话说,您的do_love 谓词是说“X 必须与loves 谓词统一”并且“X 必须与loves 谓词中的第一个参数统一”。使用您设置的数据集,没有一个值可以同时满足这两个要求。

根据您要执行的操作,这可能是您想要的:

do_love(X, Y) :- loves(X, Y).

旁注 1: 谓词不会像在其他语言中的函数那样“返回”值。您不需要谓词中的 , X 来使它们起作用。

旁注 2:= 是“统一”运算符,而不是像其他语言那样的“赋值”。请参阅this page 了解更多信息。

【讨论】:

  • 感谢有关统一的链接,示例使其用法更加清晰,但是,我仍然不确定如何从这里开始。您建议的谓词,查询loves(X,Y),将评估为例如X = 安迪,Y = 朱莉娅。但我想要的是 X =loves(andy,julia), Y = julia (因此我尝试使用等于/统一运算符)。
  • 在这种情况下,您只需要使用一个单独的变量。 X = loves(Z, Y) 之类的东西,或者如果您不关心它的值,请使用下划线,例如 X = loves(_, Y)
  • 谢谢,感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 2012-04-06
  • 1970-01-01
相关资源
最近更新 更多