【发布时间】:2015-10-02 14:24:24
【问题描述】:
我正在关注要求定义对称关系的 Prolog 教程。
假设你在知识库中有以下事实:
colleague(john,bob).
您还希望 colleague(bob,john) 是真实的,对于所有同事的事实也是如此。
教程说要使用以下规则...
colleague(X,Y) :- colleague(Y,X).
但是当我使用以下查询时这样做会出现问题...
| ? - colleague(john,X).
X = bob ? ;
X = bob ? ;
X = bob ? ;
X = bob ? ;
...
| ? - colleague(bob,X).
X = john ? ;
X = john ? ;
X = john ? ;
X = john ? ;
...
我想我明白为什么会发生这种情况 - 规则是无限递归的?但我在修复它时遇到了问题。这就是我想要的……
| ? - colleague(john,X).
X = bob ? ;
no
| ? - colleague(bob,X).
X = john ? ;
no
我在这里查看了非常相似问题的其他答案,但无法对其进行排序。我尝试在规则的末尾使用 cut ,这似乎表现更好,但由于知识库中包含的事实仍然重复一次:
colleague(X,Y) :- colleague(Y,X), !.
_
| ? - colleague(john,X).
X = bob ? ;
X = bob ? ;
no
| ? - colleague(bob,X).
X = john ? ;
no
任何想法我做错了什么?
【问题讨论】:
-
请参阅closely related question。添加
!/0只会完全破坏这种关系,所以我强烈建议避免这种情况。作为一个简单的检查,请始终尝试最一般的查询(在您的情况下:?- colleague(X, Y).),看看它是否仍然意味着您最初的意思。您会发现彻底使用!/0可以确保它不会。 -
我还没有完全理解削减的用法,因为我们这周在课堂上才刚刚接触到它,所以我有点不确定它的用法。感谢您指出这一点!
-
使用
!/0附带一个简单的规则:简而言之,不要。使用它们时,您很有可能会完全破坏程序语义。作为一个初学者,使用!/0真的没有什么收获,只会浪费很多时间。