如何在给定数据库的情况下获取列表

时间:2019-03-22 03:53:15

标签: prolog

我正在学习序言,目前仍坚持此练习。我正在尝试获取输出以下内容的安大略省队的列表:

从下面的数据库中。

city(ottawa,ontario).
city(guelph,ontario).
city(kingston,ontario).
city(gatineau,quebec).
city(montreal,quebec). 
team(ravens,ottawa).
team(ggs,ottawa).
team(gryphons,guelph).
team(queens,kingston).
team(torrents,gatineau).
team(stingers,montreal).

这是我到目前为止所拥有的。

setof(X, city(X,ontario), L). %This returns L = [guelph,kingston,ottawa]

我将如何进行下一步以获得

L = [ggs, gryphons, queens, ravens].

2 个答案:

答案 0 :(得分:0)

city(ottawa,ontario).
city(guelph,ontario).
city(kingston,ontario).
city(gatineau,quebec).
city(montreal,quebec). 

team(ravens,ottawa).
team(ggs,ottawa).
team(gryphons,guelph).
team(queens,kingston).
team(torrents,gatineau).
team(stingers,montreal).

city_team(_city_,_team_) :-
city(_city_,_province_) ,
team(_team_,_city_) .

演示

?- setof(_team_,city_team(_,_team_),_teams_) , T = _teams_  .
T = [torrents] ? ;
T = [gryphons] ? ;
T = [queens] ? ;
T = [stingers] ? ;
T = [ggs,ravens]

答案 1 :(得分:0)

ISO Prolog标准指定了三个用于收集目标解决方案的元谓词:SQLitebagof/3setof/3(还有一个事实上的标准findall/3元-谓语)。这些元谓词具有不同的语义,尤其是关于它们如何处理目标参数(第二个参数)上不在模板参数(第一个参数)中的变量。由于它们都将目标作为论证之一,因此它们都被描述为元谓词。让我们使用您的findall/4谓词来说明它们的语义。

首先,我们尝试city/2

bagof/3

请注意,解决方案是按状态聚合进行的,该状态是在目标中而不是模板中出现的变量。让我们现在尝试使用| ?- bagof(City, city(City, State), Solutions). Solutions = [ottawa,guelph,kingston] State = ontario ? ; Solutions = [gatineau,montreal] State = quebec yes

setof/3

注意到第一个解决方案的不同之处?它们是 ordered | ?- setof(City, city(City, State), Solutions). Solutions = [guelph,kingston,ottawa] State = ontario ? ; Solutions = [gatineau,montreal] State = quebec yes 谓词按标准顺序(使用术语比较)对解决方案进行排序,并消除重复项。

但是,元谓词setof/3不会汇总模板中未发生的目标变量绑定的解决方案:

findall/3

因此,您可以使用它来回答您的问题。以下查询返回所有团队:

| ?- findall(City, city(City, State), Solutions).

Solutions = [ottawa,guelph,kingston,gatineau,montreal]

yes

要只获取安大略省的球队,我们可以使用:

| ?- findall(Team, team(Team, City), Teams).

Teams = [ravens,ggs,gryphons,queens,torrents,stingers]

yes

我们还可以使用| ?- findall(Team, (team(Team, City), city(City,ontario)), Teams). Teams = [ravens,ggs,gryphons,queens] yes 获取列表的顺序:

setof/3

| ?- setof(Team, City^(team(Team, City), city(City,ontario)), Teams). Teams = [ggs,gryphons,queens,ravens] yes 构造指令City^(也可以与setof/3一起使用)不要通过绑定bagof/3变量来聚合解决方案。

关于这些谓词,尤其是关于可变术语City运算符的文章可以写得更多,但是这个答案越来越长。但是,最后一句话是:为了清楚起见和最佳性能,请避免在这些元谓词中使用复杂的目标参数。通常很容易定义一个辅助谓词。例如:

^/2

使用此谓词:

state_team(State, Team) :-
    team(Team, City),
    city(City, State).