Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Compare lists and return if true.

Status
Not open for further replies.

Pshycoone

Programmer
Oct 26, 2011
2
SE
Hey everyone, pretty new to Prolog and just started programming in it,hence the "newbie"-questions.

I decided to make a small software that, this is basic I know - but I have trouble getting started with it, anyways here's the example;

I'm a carpenter, wanting to build different things for my house so I have a few "recipes" for different stuff and their required ingredients. At home I also have a few ingredients, maybe not enough though.

My ingredients at home;
at_home([ingredient(nails,2), ingredient(wood,10)]).

and the "recipes";
recipe(wooden_roof,[ingredient(nails, 4), ingredient(hammer,1), ingredient(wood, 5)]).

recipe(stairs, [ingredient(nails, 2), ingredient(hammer,1), ingredient(wood, 2)]).

Now I want to be able to write ;
build(X) and then the software should return all the things I can build.

And the second part of the example is that I want a function (I've some programming in C# so I'm a bit damaged from that, lol)
called "buy" where it returns what I need to buy in order to be able to build everything, i.e;
buy(X,L)
And then it returns the ingredients needed to be bought.

Is there anyone who can help me with that? I really need a kick in the butt to get started.
Or do ya have any recommended tutorials?
 
This is what I have tried so far;

buy(X,L) :- recipe(X,Ls), compare3(L,Ls).

compare3([], []).
compare3(K, [L|Ls]):- compareAtHome(L, at_home(Ks),K), compare3(L, Ls).



compareAtHome(ingredient(F1,S1),[ingredient(F2,S2)|Ks], L):- (F1==F2 -> to_buy(S1,S2, K), add(ingredient(F1,K),L,L1), compareAtHome(ingredient(F1,S1), [Ks]);compareAtHome(ingredient(F1,S1),[Ks])).

to_buy(X,Y,Z):- K is X-Y, K >= 0, Z is K.


add(X,[],[X]).
add(X,[A|L],[A|L1]):- add(X,L,L1).
 
Ok, I give you a solution in the manner you used, but there is a probleme, when an ingredient is not needed, the TT is set to 0, I'll give you a tip where when an ingredient is not needed it is not in the result list.
Code:
buy(X,L) :-
	recipe(X,Ls),
	compare3(L, Ls).

compare3([], []).

compare3([K | Ks], [L|Ls]):-
	compareAtHome(K, L),
	compare3(Ks, Ls).

% compareAtHome(ingredient(F,TT),ingredient(F,S))
% @arg1 : ingredent to buy (maybe)
% @arg2 : ingredient needed
compareAtHome(ingredient(F,TT),ingredient(F,S)):-
	at_home(Lst),
	(   member(ingredient(F, Nb), Lst) ->
	    % the ingredient is present at home,
	    % we check if we have enough (required S)
	   (   Nb >= S -> % not needed we set the number to 0
	               TT = 0
	   ;   TT is S - Nb
	   )
	;   % the ingredient is not at home
	    % we need to buy all
	    TT = S).
Now, if you don't want to have 0 is the list, you must walk through the list with compare3(LstNeeded, CurrentLstToBuy, FinalLstToBuy).
Code:
% the list is finished, we unify the 2 lists Current and Final
compare3([], LstToBuy, LstToBuy).

% here we study the current ingredient
compare3([ingredient(F, S) | T], CurrentLstToBuy, FinalLstToBuy) :-
........ what have we to do ????
   compare3(T, NewCurrentLstToBuy, FinalLstToBuy).
Hope this help !
 
What do you mean by "walk through the list with compare3(LstNeeded, CurrentLstToBuy, FinalLstToBuy)." could you show an example or write it in the code?
 
Walk through the list : example sum of a list with accumulator.
Code:
% list is finished
sum([], Acc, Acc).

% one step
sum([H|T], CurAcc, FinalAcc) :-
   Acc1 is CurAcc + H,
   % next step
   sum(T, Acc1, FinalAcc).
 
yea so i put "compare3([H|T], CurAcc, FinalAcc) :- Acc1 is CurAcc + H, sum(T, Acc1, FinalAcc)." after "compare3([], LstToBuy, LstToBuy)." but i still don't get it to work, what am i doing wrong?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top