Reputation: 3
I am trying to delete elements from a list which satisfy a given constraint. The user inputs a budget and items having price greater than the budget are deleted. I am getting a type error when consulting the file.
:- use_module(library(lists)).
main(_) :-
write('Enter budget'),
nl,
read(Budget),
write(Buget),
numlist(1,168,MasterList),
BudgetList is [],
apply_budget(MasterList, Budget, BudgetList),
write(BudgetList).
apply_budget([],_,_).
apply_budget([H | T], B, R) :-
price(H, Pr),
(Pr > B ->
apply_budget(T, B, R);
append(R, [H], L),
R is L,
apply_budget(T, B, R)
).
Upvotes: 0
Views: 3510
Reputation: 117064
You've written this entirely as if this were an imperative language. You simply can't delete elements from a list in Prolog. In Prolog everything is immutable. If you've got a list then the list cannot be changed. You can only create new things. So if you want to delete elements from a list you would create a new list without the elements you want to delete.
Here's how you should write your apply_budget
predicates:
apply_budget([],_,[]).
apply_budget([H|Ts],B,Rs) :- price(H, P), P > B, !, apply_budget(Ts,B,Rs).
apply_budget([H|Ts],B,[H|Rs]) :- apply_budget(Ts,B,Rs).
The first is the case when the have an empty list in then you don't care about the budget and an empty list should come out.
The second is the case when the value H
is greater than B
so we throw away H
and recurse. The !
(cut) is there to prevent back-tracking so that the third predicate isn't tried if we have failure.
The third is the case when H
is less than or equal to B
. In this case we keep H
by building (not deleting) it on to the output as [H|Rs]
.
The cut could have been removed by writing the code this way:
apply_budget([],_,[]).
apply_budget([H|Ts],B,Rs) :- price(H, P), P > B, apply_budget(Ts,B,Rs).
apply_budget([H|Ts],B,[H|Rs]) :- price(H, P), P =< B, apply_budget(Ts,B,Rs).
I think that becomes less manageable, but you can decide which you like better.
Upvotes: 1