如何对不同事实中的数字求和?

时间:2016-03-09 00:38:37

标签: 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进行哪些更改才能使其正常工作?我理解为什么我有这个结果,但我真的不知道如何做一个事实的总结。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

汇总目标给出的所有答案的标准方法是使用import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # generate some data with noise xData = np.linspace(0.01, 100., 50) aOrg = 0.08 Norg = 10.5 yData = Norg * xData ** (-aOrg) + np.random.normal(0, 0.5, len(xData)) # get logarithmic data lx = np.log(xData) ly = np.log(yData) def f(x, N, a): return N * x ** (-a) def f_log(x, lN, a): return a * x + lN # optimize using the appropriate bounds popt, pcov = curve_fit(f, xData, yData, bounds=(0, [30., 20.])) popt_log, pcov_log = curve_fit(f_log, lx, ly, bounds=([0, -10], [30., 20.])) xnew = np.linspace(0.01, 100., 5000) # plot the data plt.plot(xData, yData, 'bo') plt.plot(xnew, f(xnew, *popt), 'r') plt.plot(xnew, f(xnew, np.exp(popt_log[0]), -popt_log[1]), 'k') plt.show() 。我们可以通过修改findall/3来实现您期望的目标:

total_score/2

SWI-Prolog documentation for findall/3草拟了谓词的使用:total_score(Hero, Score):- findall(Points, ( defeated(Hero, Monster), score(Monster, Points)), Points), sum_list(Points, Score). 。即,我们找到了findall(+Template, :Goal, -Bag)实例Template的所有解决方案,这些值都在Goal中收集。从我提供的例子中可以看出,目标可以是一个复合(即结合或分离)。

但是,SWI-Prolog还提供(默认,即不需要显式输入)library(aggregate),我们可以避免调用Bag,因此:

sum_list/2