0

Ok. That's my problem. I need to implement a predicate that sums up all the prices of the products in the list. But, for now, I'm not getting any further with it. What am I doing wrong? Thanks in advance.

domains
    state =  reduced ; normal

database
    producte (string, integer, state)
predicates
    nondeterm calculate(integer)

clauses 
   % ---> producte( description , price , state )
    producte("Enciam",2,normal). 
    producte("Llet",1,reduced). 
    producte("Formatge",5,normal). 
    calculate(Import):-
        producte(_,Import,_).
    calculate(Import):-
        producte(_,Import,_),
        calculate(Import2),
        Import=Import2+Import,!.

Goal
    calculate(I). 
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
mkll
  • 41
  • 9
  • What are you trying to do? In PROLOG, you need to specify things which are true. The line "producte("Enciam",2,normal)." says that it is true that Enciam, with price 2 and status normal, is a producte. The line "calculate(Import):-producte(_,Import,_)." says that Import satisfies calculate if there is some producte with price Import. That doesn't make a lot of sense. If you'd like an example of computing the sum of things in a list, I will be happy to provide one... – Patrick87 Jan 05 '12 at 17:43
  • Thank you so much. But if it must be with "facts/databases"? – mkll Jan 05 '12 at 17:53

2 Answers2

1

Disclaimer: I'm a bit daft when it comes to prolog. Also, I don't have access to a prolog interpreter right now.

The canonical example, sum of a list:

sum([], 0).
sum([Head | Tail], Total) :- sum(Tail, Temp), Total is Head + Temp.

making a list with findall/3:

findall(Val, producte(_, Val, _), Vals).

Vals has your list you want to sum.

Update: per your comment, I'm a bit out of my depth without access to an interpreter.

calculate(I) :- sum(Vals, I), findall(Val, producte(_, Val, _), Vals).

What I think this does:

uses your single goal I, which receives the result of summing your Vals list, which is generated by findall. But it's been so long since I've used prolog that I may not even have the syntax right for doing what I want. However, a small variation should accomplish what you want with a single goal.

ccoakley
  • 3,235
  • 15
  • 12
  • I'm grateful for the help. I just can pass one parameter at the "goal": I(as the total price to receive). – mkll Jan 05 '12 at 17:57
  • @mkll - If my update doesn't help, hopefully Mog's answer will suffice (looks good to me). I can't do trial-and-error programming to fix my answer without access to an interpreter. – ccoakley Jan 05 '12 at 18:12
0

The findall part :

calculate(Price) :-
    List = [ Price || producte(_, Price, _) ],
    sum_list(List, 0, Sum).

The sum_list part :

sum_list([], Acc, Acc).
sum_list([Head|Tail], Acc, Sum) :-
    NewAcc is Acc + Head,
    sum_list(Tail, NewAcc, Sum).

I guess something along these lines should work according to visual-prolog doc but I kinda don't wanna install visual-prolog to test it...

m09
  • 7,490
  • 3
  • 31
  • 58
  • I'm lost in that problem of mine. Do you think to implement that predicate we need to pass 2 parameters? calculate(List, Sum) A list and an integer. – mkll Jan 05 '12 at 18:06