2012-05-15 46 views
0

我想从事实创建一个列表。而且这个清单应该只包含事实中的一个。PROLOG从事实创建的列表的总和

例如:

%facts 
abc(a, b, c). 
abc(d, e, f). 
abc(g, h, i). 

样品:

?-lists(A). 
    A = [a, d, g]; 
    No. 

编辑:

使用在注释Vaughn Cato建议,代码变成这样:

%facts 
abc(a, b, c). 
abc(d, e, f). 
abc(g, h, i). 

lists(A) :- 
    findall(findall(X, abc(X, _, _), A). 

该列表已创建,但如何总结列表A

如果总和名单从输入的查询,

sumlist([], 0). 
sumlist([X|Y], Sum) :- 
    sumlist(Y, Sum1), 
    Sum is X + Sum1. 

但是,如果要总结现有列表,如何界定谓词?

+1

findall(X,abc(X,_,_),A)。 –

+0

谢谢,@VaughnCato。 – Chin

+0

如何??列表(A),sumlist(A,Sum)'?当然你也可以使用@sharky提出的内置谓词。 –

回答

0

正如Vaughn Cato所建议的那样,通过使用findall(X,abc(X, _ , _),A).来创建我想要的列表,可以帮助我很多。

0

综上所述号码的列表,诸如由您的lists/1定义产生,大多数的Prolog系统(例如,GNUSWI)实施sum_list/2这需要号码的列表作为第一个参数,并结合其在所述第二总和:

?- sum_list([1,2,3],Sum). 
Sum = 6. 
+0

'sum_list/2'是一个预定义的谓词吗?我目前正在使用WIN-Prolog,并且使用您的示例进行了测试,看起来好像没有定义。 – Chin

+0

哎呀!你是对的,在WIN-Prolog中没有'sum_list/2'的库实现。但是,您添加到问题的定义看起来很好。 – sharky

+0

谢谢@sharky。 – Chin

0

你也可以用aggregate_all/3来解决它。它不需要在内存中建立列表,如果你只需要一笔钱。

sum_facts(Template, Arg, Sum) :- 
    aggregate_all(sum(X), (call(Template), arg(Arg, Template, X)), Sum). 

在这个例子中我用定义的模板通用通话:

sum_facts(abc(_, _, _), 1, Sum). 

如果你将永远与ABC/3的第一个参数使用这个版本就足够了:

sum_facts(Template, Arg, Sum) :- 
    aggregate_all(sum(X), abc(X, _, _), Sum). 
+0

感谢您的回答。我在Prolog中很新。我需要时间来理解你的规则。我认为,在内存中建立'list'可以帮助我。无论如何,我会感谢你的回答。 – Chin