尝试创建一个谓词(timePeriod/2
),用于计算特定事实的两个日期之间的时间段。我自己设法做到了这一点,但是当“其他答案”存在于同一列表中时面临问题(即更容易用示例解释)。
我有以下知识基础事实;
popStar('Jackson',1987,1991).
popStar('Jackson',1992,1996).
popStar('Michaels',1996,2000).
popStar('Newcastle',2000,2007).
popStar('Bowie',2008,2010).
以下函数计算特定事实的日期之间的时间(如下所示)。
谓词(timePeriod / 2) -
timePeriod(PS,X) :-
bagof((Name,Start,End),popStar(Name,Start,End),PSs),X is End-Start+1)
以鲍伊为例;它返回X=3
(这是正确的)。
但是,当列表中有重复时,如果有多个答案可用,则谓词只会声明“false”。以事实'杰克逊'为例,我希望能够计算两个事实的两个时间段;同时。
因此,如果谓词适用于两个杰克逊事实,则谓词timePeriod
将表示X=10
。
如果有人可以建议改变什么来使其正常工作,我们将非常感激。
感谢。
答案 0 :(得分:2)
您可能不太了解foreach/3
的作用。我不认为我完全理解foreach/3
。我肯定知道不和说:
for each x in xs:
do foo(x)
另一件事:Prolog中的“元组”并不是你所期望的,来自像Python或Haskell这样的语言。这个:(a,b,c)
实际上就是这样:','(a,','(b,c))
。更好的是使用平面术语,通用形式将是triple(a,b,c)
。对于一对,成语是First-Second
。
因此,您可以简化对此bagof/3
的调用:
?- bagof(From-To, pop_star(Name, Start, End), Ts).
Name = 'Bowie',
Ts = [2008-2010] ;
Name = 'Jackson',
Ts = [1987-1991, 1992-1996] ;
Name = 'Michaels',
Ts = [1996-2000] ;
Name = 'Newcastle',
Ts = [2000-2007].
如果你有一个上面的列表,你需要总结差异,这可能是这样的:
periods_total(Ps, T) :-
maplist(period_length, Ps, Ls),
sum_list(Ls, T).
period_length(From-To, Length) :-
Length is To - From + 1.
然后你可以像这样查询:
?- bagof(From-To, pop_star('Jackson', From, To), Ps), periods_total(Ps, T).
Ps = [1987-1991, 1992-1996],
T = 10.
?- bagof(From-To, pop_star(Name, From, To), Ps), periods_total(Ps, T).
Name = 'Bowie',
Ps = [2008-2010],
T = 3 ;
Name = 'Jackson',
Ps = [1987-1991, 1992-1996],
T = 10 ;
Name = 'Michaels',
Ps = [1996-2000],
T = 5 ;
Name = 'Newcastle',
Ps = [2000-2007],
T = 8.
答案 1 :(得分:0)
SWI-Prolog有一个很好的library来处理聚合:它基于标准的所有解决方案'像findall / 3,setof / 3,bagof / 3这样的谓词,所以你应该首先掌握这些的基本原理(正如鲍里斯在他的回答中所解释的那样)。使用该库,单个查询可以解决您的问题:
<table><tr>
<th>
<p align="center">22/02/16<br />to<br />27/02/16</p>
</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font color="red" size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font color="red" size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<p> </font></tr>
<tr>
<th>
<p align="center">29/02/16<br />to<br />05/03/16</p>
</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font color="red" size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font color="red" size="6">xx</font></th>
<th>x<br />x<br />x</th>
<p> </font></tr>
<tr>
<th>
<p align="center">07/03/16<br />to<br />12/03/16</p>
</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<p> </font></tr>
<tr>
<th>
<p align="center">14/03/16<br />to<br />14/03/16</p>
</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<th>x<br />x<br />x</th>
<th><font size="6">xx</font></th>
<th>x<br />x<br />x</th>
<p> </font></tr></table>