如何从prolog列表中创建一个仿函数?

时间:2017-01-07 22:59:20

标签: prolog

我是Prolog的新手,我试着了解一些基本的东西。 通常,我要做的是返回给定列表的仿函数。 这个例子是接力赛,规则如下:

%race(_team,_first_runner,_second_runner)
race(reds,yael,dan).
race(reds,dan,oren).
race(reds,oren,guy).
race(reds,guy,daphna).
race(reds,daphna,tali).
race(blue,yoni,avi).
race(blue,avi,naama).
race(blue,naama,tahel).
race(blue,tahel,tohar).
race(blue,tohar,asaf).

%time(_team,_runner,_time)
time(reds,yael,12).
time(reds,dan,15).
time(reds,oren,12).
time(reds,guy,13).
time(blue,yoni,12).
time(blue,avi,13).
time(blue,naama,15).
time(blue,tahel,8).
time(blue,tohar,10).
time(blue,asaf,20).

想要的谓词应该返回根据每个组的总时间排名的队伍(假设我们有total_time(_race,_total_time)返回给定团队的总时间。)

 total_time(team,_total_time):-
 findall(T,time(_team,,T), Times), 
 listsum(_total_time, Times).


 listsum(0, []).
 listsum(Result, [Head|Tail]):-
 listsum(SumOfTail, Tail),
 Result is Head + SumOfTail.

例如:

    total_time(reds,T).
    Returns:T=77

    total_time(blue,T).
    Return: T=78

很明显红队在最短的时间内完成了比赛,所以他们是获胜者(第一名)和蓝队 - 在第二名。

看起来应该是这样的:

    rank_teams(_list_o_ranks):- /*The logic that ranks the team and returns
 the result in a data structure of rank(place,team)*/


Input: [reds,blue...]
Output: [rank(1,red),rank(2,blue),…]

我在这里有2个难点,首先是将团队列表转换为这种形式:

rank(Team, Place):-
rank(Team,Place).

第二个是确定团队名额(根据最短时间排在第一位的时间对团队进行排名)。

感谢帮助人员!

1 个答案:

答案 0 :(得分:1)

这还远远不足以提供完整的,经过测试的答案。但这里有一些提示。

如果您描述了total_time/2谓词,则可以使用以下内容找到正确的顺序:

ordered_teams(OrderedTeams) :-
    setof(Time-Team, total_time(Team, Time), OrderedTeams).

使用您的示例数据调用此函数后,您将拥有OrderedTeams = [77-reds, 78-blue]。该列表按时间按setof/3自动排序。

仍然要对此列表中的元素进行编号。这是一个草图:

orderedteams_ranked(OrderedTeams, RankedTeams) :-
    orderedteams_ranked(OrderedTeams, 1, RankedTeams).

orderedteams_ranked([], _Rank, []).
orderedteams_ranked([_Time-Team|Os], Rank, [rank(Rank, Team)|Rs]) :-
    Rank1 is Rank + 1,
    orderedteams_ranked(Os, Rank1, Rs).

同样,这未经过测试。