1

I created a simple database on SWI Prolog. My task is to count how long each of departments will work depending on production plan. I am almost finished, but I don't know how to sum my results. As for now I am getting something like this

department amount

b 20

a 5

c 50

c 30

how I can transform it to this?

b 20

a 5

c 80

My code https://gist.github.com/senioroman4uk/d19fe00848889a84434b

false
  • 10,264
  • 13
  • 101
  • 209

2 Answers2

1

The code provided won't interpret the count predicate on account of a bad format. You should rewrite it as count:- instead of count():-. As far as I know, all zero-ary predicates need to be defined like this.

Second, your count predicate does not collect the results in a list upon which you could operate. Here's how you can change it to collect all department-amount pairs in a list with findall:

count_sum(DepAmounts):-
    findall((Department,Sum),
            (   productionPlan(FinishedProduct, Amount),
                resultOf(FinishedProduct, Operation),
                executedIn(Operation, Department, Time),
                Sum is Amount * Time
            ),
            DepAmounts
    ).

Then, over that list, you can use something like SWI-Prolog's aggregate:

 ?- count_sum(L), aggregate(sum(A),L,member((D,A),L),X).

Which will yield, by backtracing, departments in D and the sum of the amounts in X:

D = a,
X = 15 ;
D = b,
X = 20 ;
D = c,
X = 80.

BTW, if I were you I'd replace all double-quoted strings for department names and operations and etc. for atoms, for simplicity.

vmg
  • 4,176
  • 2
  • 20
  • 33
0

you should consider library(aggregate): for instance, calling data/2 the interesting DB subset, you get

?- aggregate(set(K-A),aggregate(sum(V),data(K,V),A),L).
L = [a-5, b-20, c-80]
CapelliC
  • 59,646
  • 5
  • 47
  • 90