I'm working on a Prolog program. It produces the correct output (a list) but the list has an uninstantiated variable at the end. I am doing something wrong, and am unsure how to get rid of it.
This is the code:
plaatsingen([],_).
plaatsingen([Prod/Hoev|Rest],[Order|Plaatsing]) :-
prijs(Lev,Prod,Prijs),
Kost is Prijs*Hoev,
Order = Lev/Prod/Kost,
plaatsingen(Rest,Plaatsing).
prijs(delhaize, zeep, 8).
prijs(delhaize, prei, 10).
prijs(delhaize, zout, 6).
prijs(carrefour, prei, 9).
prijs(carrefour, soep, 19).
prijs(champion, zeep, 7).
prijs(champion, prei, 11).
prijs(champion, pinda, 6).
This is the input and output:
41 ?- plaatsingen([zeep/10, prei/14],P).
P = [delhaize/zeep/80, delhaize/prei/140|_G4160] .
If you want to get rid of it, you need to get a handle on it:
plaatsingen([],G,G).
plaatsingen([Prod/Hoev|Rest],[Order|Plaatsing],G) :-
prijs(Lev,Prod,Prijs),
Kost is Prijs*Hoev,
Order = Lev/Prod/Kost,
plaatsingen(Rest,Plaatsing,G).
G
is such a handle. Now you get back in it the uninstantiated tail, explicitly, and can set it to anything:
plaatsingen(In, Out, Z), Z=[].
sets the end of list to the empty list. Or you can pre-set it, with
plaatsingen(In, Out, [end, of, list]).
or leave it as a free logvar, which is the mechanism of difference lists.
when facing a list processing problem, try to see if a Prolog builtin can help:
plaatsingen(I, Orders) :-
maplist(plaatsingen_c, I, Orders).
plaatsingen_c(Prod/Hoev, Lev/Prod/Kost) :-
prijs(Lev,Prod,Prijs),
Kost is Prijs*Hoev.
yields
3 ?- plaatsingen([zeep/10, prei/14],P).
P = [delhaize/zeep/80, delhaize/prei/140] ;
P = [delhaize/zeep/80, carrefour/prei/126]
...
easier, isn't it ? For more complex processing, see 'all solutions' and aggregation