如何在不同的事实中进行数字求和

  • 本文关键字:数字 求和 事实 prolog
  • 更新时间 :
  • 英文 :


假设我有一个英雄和几个怪物的游戏。如果你打败它们,每个怪物都会得到一定数量的分数。

total_score(Hero, Score):-
    defeated(Hero, Monster),
    score(Monster, Points),
    Score is Points.
monster(bat).
monster(skeleton).
monster(boss).
score(bat, 100).
score(skeleton, 100).
score(boss, 1000).
defeated(bob, bat).
defeated(bob, skeleton).
defeated(bob, boss).

如果我做未来的请求:

?- total_score(bob, Y).

我希望答案是:

Y : 1200.

但我得到的却是:

Y : 100,
Y : 100,
Y : 1000.

我应该对total_score进行哪些更改才能使其正常工作?我明白为什么我会有这个结果,但我真的不知道该怎么做才能总结事实。

好吧,我设法找到了解决方案,问题是我知道我可以使用findall和sum_list,但我不知道如何将不同的关系结合在一起。经过一番研究,我终于设法找到了解决方案......所以我做了:

total_score(Hero, Score):-
    findall(Points, (defeated(Hero, Monster), score(Monster, Points)), ListOfPoints),
    sum_list(ListOfPoints, Score).

聚合目标给出的所有答案的标准方法是使用 findall/3 。我们可以通过修改total_score/2来实现您想要的目标:

total_score(Hero, Score):-
    findall(Points,
            ( defeated(Hero, Monster),
              score(Monster, Points)),
            Points),
    sum_list(Points, Score).

findall/3的SWI-Prolog文档概述了谓词的使用:findall(+Template, :Goal, -Bag),即,我们找到所有实例化Template给定Goal的解决方案,这些值被收集在Bag中。正如你从我提供的例子中看到的,目标可以是复合(即合取或析取)。

但是,SWI-Prolog还提供了(默认的,即不需要显式导入的)库(聚合),我们避免使用它调用sum_list/2,因此:

total_score(Hero, Score):-
    aggregate_all( sum(Points),
                   ( defeated(Hero, Monster),
                     score(Monster, Points)),
                   Score).

最新更新