purchase(Product) :- product_available(Product), sufficient_payment(Product, Change), dispense_product(Product), return_change(Change), !. purchase(Product) :- product_available(Product), product_cost(Product, Cost), print(Product, ' costs ', Cost, ' cents'), !. purchase(Product) :- print(Product, ' is not available'),!. insert_coin(Coin) :- value(Coin,Worth), Worth > 0, coin_accept(Worth), !. insert_coin(Coin) :- print('coin reject'), !. coin_return :- deposit(X), change(X), clear_deposit, print(X, ' cents returned'), !. coin_return :- print('No coins deposited'). product_available(Product) :- quantity(Product, Qty), Qty > 0, !. sufficient_payment(Product, Change) :- product_cost(Product, Cost), deposit(Amount), Amount >= Cost, Change is Amount - Cost, !. sufficient_payment(Product, _) :- product_cost(Product, Cost), deposit(Amount), Deficit is Cost - Amount, print('Deposit additional ', Deficit, ' cents'), fail, !. dispense_product(Product) :- print(Product, ' dispensed'), quantity(Product,Qty), retract(quantity(Product, Qty)), Newqty is Qty - 1, assert(quantity(Product,Newqty)), !. return_change(Change) :- Change > 0, change(Change), print(Change, ' cents change returned'), clear_deposit, !. return_change(0) :- print('No change'). change(Change) :- change_half_dollar(Change,X). change_half_dollar(Change, X) :- Change >= 50, X is Change - 50, print('dispense half_dollar'), print('rem: ',X),!, change_half_dollar(X, Y). change_half_dollar(X, Y) :- change_quarter(X,Y). change_quarter(Change, X) :- Change >= 25, X is Change - 25, print('dispense quarter'), print('rem: ',X),!, change_quarter(X, Y). change_quarter(X, Y) :- change_dime(X,Y). change_dime(Change, X) :- Change >= 10, X is Change - 10, print('dispense dime'), print('rem: ',X), !, change_dime(X, Y). change_dime(X,Y) :- change_nickel(X, Y). change_nickel(Change, X) :- Change >= 5, X is Change - 5, print('dispense nickel'), print('rem: ',X),!, change_nickel(X, Y). change_nickel(X,Y) :- print('change OK'), !. clear_deposit :- retract(deposit(X)). coin_accept(X) :- deposit(Y), Z is Y + X, retract(deposit(Y)), assert(deposit(Z)), print('Total deposit ', Z, ' cents'), !. coin_accept(X) :- assert(deposit(X)), print('Total deposit ', X, ' cents'), !. value(nickel, 5). value(dime, 10). value(quarter, 25). value(half-dollar, 50). value(slug, 0). quantity(pretzels, 5). quantity(chips, 5). quantity(cookies, 5). quantity(doughnuts, 5). product_cost(pretzels, 50). product_cost(chips, 45). product_cost(cookies, 55). product_cost(doughnuts, 60).