我想在Prolog中为同一个原子设两个名字:
player(thomas).
player(william).
teamOfPlayer(thomas, redSocks).
teamOfPlayer(william, redSocks).
tom :- thomas.
will :- william.
teamOfPlayer(will, X).
我希望能够使用“william”原子并使用“will”原子来引用William。
我知道我可以使用仿函数来定义昵称:
nick(tom, thomas).
nick(will, william).
然后,
nick(tom,X), teamOfPlayer(X, Y).
但我想避免所有这些冗长。
答案 0 :(得分:1)
实现特定的设施可用于此目的 - 以及更多。事实上,鉴于身份是逻辑的“核心”,重写规则以适应不同的识别策略并不是一个罕见的问题。
在SWI-Prolog中,您可以使用expansion hooks,更具体地说goal_expansion / 2。
在你的模块中,添加到文件结尾附近(虽然只是一个约定)
:- multifile user:goal_expansion/2.
user:goal_expansion(will, william).
user:goal_expansion(tom, thomas).
答案 1 :(得分:0)
您可以定义某事物是否是其他东西
player(tom) :- !.
player(thomas) :- player(tom), !.
现在Prolog可以看到,如果某个玩家被命名为thomas
或tom
,则会达到目标,因此他们会被视为同一个人。
您的第一个解决方案是可取的,因为nick(tom,X), teamOfPlayer(X, Y).
不太具体,因此您可以更加可扩展且更易于维护,因为您不会更改现有代码,您只需添加新事实即可知识库。
通过定义两个规则,您可以为Prolog提供两种回答X的方法。
%is X a member of team Y?
isPartOfTeam(X,Y) :- teamOfPlayer(X,Y).
isPartOfTeam(X,Y) :- nick(X, Z), teamOfPlayer(Z, Y).
通过定义这些一般规则,可以通过直接在事件teamOfPlayer(X,Y)
中找到团队,或者通过尝试为X的特定实例定义的每个昵称来解决X < / em>的。这就是Prolog的力量所在。你可以为1个人拥有10000个昵称,而Prolog将通过一个称为回溯到选择点的过程,通过上面定义的这两个简单规则来检查它们。