简体   繁体   中英

PROLOG Sum of a list created from facts

I want to create a list from the facts. And the list should contains only one of the arity in the facts.

For example :

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

Sample :

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

EDIT :

Using the suggestion by Vaughn Cato in the comment, the code become this :

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

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

The list is created, but how to sum up the list A ?

If sum of list for input from query,

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

But if want to sum the existing list, how to define the predicate?

To sum a list of numbers such as that produced by your definition of lists/1 , most Prolog systems (eg, GNU , SWI ) implement sum_list/2 which takes a list of numbers as the first argument and binds their sum in the second:

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

You can also solve it with aggregate_all/3. It eliminates need to build list in memory if you just need a sum.

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

In this example I use a generic call with defined Template:

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

If you will always use it with the first arg of abc/3 this version will be enough:

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

As suggested by Vaughn Cato, it's help me a lot by using findall(X,abc(X, _ , _ ),A). to create the list I wanted to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM