Declaratieve Talen/Oplossing winkelen
een mogelijke oplossing voor de basisopgave
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). leveranciers([delhaize,carrefour,champion]). bestorder(Bestelling, Plaatsing) :- findall(P, bestelling(Bestelling, P), Ps), list_to_set(Ps,Pset), filter_2(Pset,Max2Ps), minimum_kost(Max2Ps, Bestelling, Plaatsing). %zoek de plaatsing met de laagste kost uit een lijst van plaatsingen minimum_kost([P],_, MinP) :- MinP = P. minimum_kost([P|Ps],Bestelling, MinP) :- minimum_kost(Ps, Bestelling, MinPSub), kost(Bestelling, P, KostP), kost(Bestelling, MinPSub, SubKost), (KostP < SubKost -> MinP = P ; MinP = MinPSub ). %filter plaatsingen met meer dan 2 winkels filter_2([P],Ps) :- (max_2_winkels(P) -> Ps = [P] ; Ps = [] ). filter_2([P|Prest],Ps) :- filter_2(Prest,Precur), (max_2_winkels(P) -> Ps = [P|Precur] ; Ps = [Precur] ). %bestaat de plaatsing uit maximaal 2 winkels? max_2_winkels([_/_]). max_2_winkels([_/Winkel|Rest]) :- max_2_winkels(Rest, [Winkel]). max_2_winkels([_/Winkel],Winkels) :- list_to_set([Winkel|Winkels],X), length(X,Aantal), Aantal =< 2. max_2_winkels([_/Winkel|Rest],Winkels) :- list_to_set([Winkel|Winkels],VerschillendeWinkels), length(VerschillendeWinkels,Aantal), Aantal =< 2, max_2_winkels(Rest,[Winkel|Winkels]). %kost van een bestelling/plaatsing kost([Product/Aantal], [Product/Winkel],TotaalKost) :- prijs(Winkel, Product, StukKost), TotaalKost is StukKost * Aantal. kost([Product/Aantal|RestBest],[Product/Winkel|RestPlaatsing], TotaalKost) :- kost(RestBest,RestPlaatsing, Subkost), prijs(Winkel, Product, StukKost), Kost is StukKost * Aantal, TotaalKost is Kost + Subkost. %een mogelijke bestelling bestelling([Product/_],Plaatsing) :- leveranciers(Product, Leveranciers), select(Leveranciers, Leverancier), Plaatsing = [Product/Leverancier]. bestelling([X|Xs],Plaatsing) :- bestelling(Xs,P1), bestelling([X],[P2]), Plaatsing = [P2|P1]. %alle leveranciers van een product leveranciers(Product, Leveranciers) :- findall(X,prijs(X,Product,_),Leveranciers). %selecteer een element uit een lijst select([L],X) :- X = L. select([L|Lijst],X) :- X = L; select(Lijst,X).