Prolog list has uninstantiated tail, need to get r

2019-07-16 10:33发布

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] .

标签: list prolog
2条回答
Bombasti
2楼-- · 2019-07-16 11:05

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

查看更多
太酷不给撩
3楼-- · 2019-07-16 11:07

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.

查看更多
登录 后发表回答