在序言中定义 is_a 谓词?

发布于 2024-08-18 05:02:40 字数 563 浏览 9 评论 0原文

我试图在 Prolog 中定义继承检查谓词 is_a/2,但到目前为止我的所有试验都失败了。

只要 Y 是 X 的超类,is_a(X, Y) 谓词就应该返回 true。例如:

object(bare).
object(mammal).
object(animal).
object(bird).
is_a(bare, mammal).
is_a(mammal, animal).
is_a(bird, animal).
is_a(X, Y):- <definition goes here>.

定义应该使得以下查询将返回 true:

?- is_a(bare, animal).
true.

我尝试将其定义为 明显方式,但我陷入了无限循环:

is_a(X, Y):- X\==Y, object(X), object(Y), object(Z), is_a(X, Z), is_a(Z, Y).

有什么建议吗?

I'm trying to define the inheritance-check predicate is_a/2 in Prolog, but so far all my trials failed.

The is_a(X, Y) predicate should return true whenever Y is a superclass of X. For example:

object(bare).
object(mammal).
object(animal).
object(bird).
is_a(bare, mammal).
is_a(mammal, animal).
is_a(bird, animal).
is_a(X, Y):- <definition goes here>.

The definition should go such that the following query will return true:

?- is_a(bare, animal).
true.

I tried to define it the obvious way, but I got stuck in infinite loops:

is_a(X, Y):- X\==Y, object(X), object(Y), object(Z), is_a(X, Z), is_a(Z, Y).

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

锦上情书 2024-08-25 05:02:41

避免无限循环的一种方法是添加一个谓词,它显示“直接”继承(无传递性),即 direct/2。然后你可以写这样的东西:

object(bare).
object(mammal).
object(animal).
object(bird).

direct(bare, mammal).
direct(mammal, animal).
direct(bird, animal).

isa(X, Y) :- object(X), object(Y), direct(X, Y).
isa(X, Y) :- object(X), object(Y), object(Z), direct(X, Z), isa(Z, Y).

然后你会得到:

?- findall(X, isa(X, animal), L).
   L = [mammal,bird,bare] ? ;
   no

我不确定这是否正是你所要求的。

One way to avoid the infinite loop, is to add a predicate, which shows "direct" inheritance (no transitive), namely direct/2. Then you could write something like this:

object(bare).
object(mammal).
object(animal).
object(bird).

direct(bare, mammal).
direct(mammal, animal).
direct(bird, animal).

isa(X, Y) :- object(X), object(Y), direct(X, Y).
isa(X, Y) :- object(X), object(Y), object(Z), direct(X, Z), isa(Z, Y).

Then you get:

?- findall(X, isa(X, animal), L).
   L = [mammal,bird,bare] ? ;
   no

I'm not sure this is exactly what you ask for though.

荆棘i 2024-08-25 05:02:41

is_a(X, X).
is_a(X, Y) :- X \== Y, is_a_1(X, Z), is_a(Z, Y).
is_a_1(bear, mammal).
is_a_1(mammal, animal).
is_a_1(bird, animal).

编辑: 与 electrologos3 的答案相同的想法,他更努力地保持它像你的原始代码一样。

Something like

is_a(X, X).
is_a(X, Y) :- X \== Y, is_a_1(X, Z), is_a(Z, Y).
is_a_1(bear, mammal).
is_a_1(mammal, animal).
is_a_1(bird, animal).

Edit: Same idea as electrologos3's answer, who tried harder to keep it like your original code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文