我怎么能在Prolog中为同一个原子命名?

时间:2018-03-14 22:54:05

标签: prolog

我想在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).

但我想避免所有这些冗长。

2 个答案:

答案 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可以看到,如果某个玩家被命名为thomastom,则会达到目标,因此他们会被视为同一个人。

您的第一个解决方案是可取的,因为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将通过一个称为回溯到选择点的过程,通过上面定义的这两个简单规则来检查它们。