2
score(Movies,Total) :-
    findall(Money,(member(Movie,Movies),takings(Movie,Money)),Profit),
    sum_list(Profit,Total)

I want to convert this rule using recursion but I am not sure how. Help! Link to the previous question that answers this one : Sum up data from facts

Guy Coder
  • 24,501
  • 8
  • 71
  • 136

2 Answers2

3
% base case
score([],0).
% recursive case
score([Movie|Movies],Total) :-
    takings(Movie,Profit),
    score(Movies,Total0),
    Total is Total0 + Profit.

Example run

?- score([robots,hulk,bad_boys_ii],Y).
Y = 749200000.

Explanation of code

List in Prolog are recursively constructed and deconstructed using the | operator. As 0 is the initial value for counting integers, [ ], known as the empty list, is the initial value for a closed list. To recursively build to the front of a closed list one uses the current list and the | operator. When using | in Prolog it is common to refer to the item being added as the Head, (H) and the current closed list being added to as the Tail, (T), and this why you often see the notation [H|T] when talking about list in Prolog.

So to construct the list [1,2,3] would be [] then add 1, [1].

?- L = [1|[]].
L = [1].

To add 2 would be [1] then add 2, [2,1].

?- L = [2|[1]].
L = [2, 1].

To deconstruct the list [1,2,3] would use variables so [H|T] will become H being 1 with T being [2,3].

?- [H|T] = [1,2,3].
H = 1,
T = [2, 3].

When you get to the end of the list it is just [] with out a head.

?- [H|T] = [1].
H = 1,
T = [].

So in the code [Movie|Movies] takes input list of movies and unifies the head of the list Movie with the first movie and passes the tail of the list Movies recursively to the predicate. Only when the list is empty will the clause score([],0) match and unify the 0 with Total0 in score(Movies,Total0).

I know this can have a lot more detail in explanations, but these explanations are all over the place in Prolog examples.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • Thanks a lot you saved me. – Zisis Kostakakis Mar 07 '20 at 22:13
  • @ZisisKostakakis It was odd that you were closer to solving it your first time using findall instead of recursion. Many people have a hard time understanding findall/3 at first until they see a few examples, and good findall examples are not easy to find. – Guy Coder Mar 07 '20 at 22:14
  • @ZisisKostakakis Don't forget to up-vote the answer you like and click the check mark next to answers that give you the correct answer. – Guy Coder Mar 07 '20 at 22:15
  • I found it easier to use findall that I self-taught than using [H|T] where I hardly understand – Zisis Kostakakis Mar 07 '20 at 22:17
  • i will agree with you that the instructor is not the best at explaining as English is not his/her main language. – Zisis Kostakakis Mar 07 '20 at 22:19
0

This way :)

recursive_score([H], CurrentMoney):-
    takings(H, Value),
    CurrentMoney is Value.
recursive_score([H|T], Money):-
    takings(H, Value),
    recursive_score(T, CurrentMoney),
    Money is CurrentMoney + Value.
yusuf_sabri
  • 129
  • 6
  • If you new at Prolog, you can examine [my prolog homework](https://github.com/yusufbayrakdar/Pokemon_Prolog), it will teach you basics of Prolog – yusuf_sabri Mar 07 '20 at 22:24
  • While the OP did not specify what should happen with an empty list, would it not be better to return 0, than `false` with an empty list? – Guy Coder Mar 07 '20 at 22:26
  • Stop being angry, I was trying to help :( it is true there is no explanation but he/she can search and it is let he/she learn better. – yusuf_sabri Mar 07 '20 at 22:34