3

I have a problem with Prolog. If it was another language with an imperative paradigm would be easier for me, but that's not the point. There are several items, some of which have requirements to be obtained. For example, if I have item b means I already have item a.

to_get(b):-
     need(a).

to_get(a3):-
     need(a2),
     need(a1).

So, I have a list with items. I have to check which items are there, and then check if each item's requirements is there as well. If it's not there, then I have to create a new list and add it there. And return this new list.

L1 = [b, a1, a3]

b needs a, but a isn't in L1, so that means it is in a new list, L2

L2 = [a, a2]

I hope it's not such a dumb question, I'm just new to prolog. Thanks

1 Answers1

4

You probably assume that there is a relation to describe dependencies between items. Below uses closure0/3 and non_member/2.

item_needs(b, a).
item_needs(a3, a2).
item_needs(a3, a1).

items_missing(Items, Needed) :-
   member(Item, Items),
   closure0(item_needs, Item, Needed),
   non_member(Needed, Items).    

?- items_missing([b,a1,a3],Missing).
   Missing = a
;  Missing = a2
;  false.

To get this into a list, use setof/3:

?- setof(M,items_missing([b,a1,a3],M),Ms).
   Ms = [a, a2].

And more generally:

items_missingitems(Items, Ms) :-
   ( ground(Items) -> true
   ; throw(error(instantiation_error,_)) ),    % safety check
   ( length(Items,_) -> true
   ; throw(error(type_error(list,Items),_)) ), % one more
   setof(M, items_missing(Items,M), Ms).
false
  • 10,264
  • 13
  • 101
  • 209
  • Undefined procedure: nonmeber/2 ERROR: However, there are definitions for: ERROR: nonmember/2 I'm getting this error now. – Javier González Nov 15 '14 at 17:11
  • @false Do you indent this to fail in case of no missing items? E.g., `?- items_missingitems([a], X)`. The empty list may be more natural in this case. – Wouter Beek Nov 16 '14 at 12:56
  • @WouterBeek: This is the olde negation question: Both ways have their point. – false Nov 16 '14 at 13:36