综合解决多个事实 [英] Aggregate solution over multiple facts

查看:108
本文介绍了综合解决多个事实的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试创建一个计算特定事实的两个日期之间的时间段的谓词( timePeriod / 2 )。我自己设法做到这一点,但在同一列表中存在其他答案时(即使用例子更容易解释),面临问题。

Trying to create a predicate (timePeriod/2) that calculates the time period between two dates for a specific fact. I've managed to do this by myself, but face issues when 'other answers' exist in the same list (i.e. easier to explain with examples).

我有以下知识库事实;

I have the following knowledge-base facts;

 popStar('Jackson',1987,1991).
 popStar('Jackson',1992,1996).
 popStar('Michaels',1996,2000).
 popStar('Newcastle',2000,2007).
 popStar('Bowie',2008,2010).

以下函数计算具体事实的日期之间的时间(如下所示)。

And the following function, calculates the time between dates for a specific fact (as per below).

谓词(timePeriod / 2) -

 timePeriod(PS,X) :-
    bagof((Name,Start,End),popStar(Name,Start,End),PSs),X is End-Start+1)

以Bowie为例;它返回 X = 3 (这是正确的)。

Using Bowie as an example; it returns X=3 (which is correct).

但是,当列表中有重复时,有多个答案可用,谓词只显示false。以事实杰克逊为例,我想能够计算出两个事实的两个时间段;与此同时。

However, when there is repetition in the list, with more than one answer available, the predicate just states 'false'. Using the facts 'Jackson' as an example, I want to be able to calculate both of the time periods for both facts; at the same time.

因此,如果谓词适用于Jackson的两个事实,谓词 timePeriod 将会声明 X = 10

So, if the predicate would work for both of the Jackson facts, the predicate timePeriod would state X=10.

真的很感激任何人可以建议什么改变,以使其正常工作。

Would really appreciate if anyone could suggest what to change in order for this to work correctly.

谢谢。

推荐答案

你可能不太明白 foreach / 3 。我不认为我完全理解 foreach / 3 。我确信这是,就像:

You probably don't quite understand what foreach/3 does. I don't think I fully understand foreach/3 either. I know for sure that it is not the same as say:

for each x in xs:
    do foo(x)

另一件事:Prolog中的tuples不是你可能会期望,来自像Python或Haskell这样的语言。这是:(a,b,c)实际上是这样的:','(a,','(b,c))。更好的是使用平面术语,通用形式将是 triple(a,b,c)。对于一对,成语是 First-Second

Another thing: "tuples" in Prolog are not what you might expect, coming from a language like Python or Haskell. This: (a,b,c) is actually this: ','(a,','(b,c)). Much better is to use a flat term, the generic form would be triple(a,b,c). For a pair, the idiom is First-Second.

所以,你可以简化你对 bagof / 3 到:

So, you can simplify your call to bagof/3 to this:

?- 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].

一旦你有一个上面的列表,你需要总结差异,这可能是:

Once you have a list as above, you need to sum the differences, which would be maybe something like:

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.

这篇关于综合解决多个事实的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆