Reputation: 161
I am writing a prolog code which has rooms and courses. A room can have multiple things such as a projector and smartboard and some of the courses needs these items.
%knowledge base
needs(101,projector).
needs(102,smart_board).
needs(241,smart_board).
needs(241,projector).
has(z23,projector).
has(z23,smart_board).
has(z06,projector).
has(z11,smart_board).
capacity(z06,50).
capacity(z11,70).
capacity(z23,90).
capacity(101,80).
capacity(102,70).
capacity(241,60).
capacity(341,40).
capacity(343,50).
%rules
assignRoom(C,R):- % C is a course, R is a Room
%course C can bi assigned to room R if:
((has(R,X),needs(C,X));%it needs 1 item and class has it or
(has(R,X),needs(C,X),has(R,Y),needs(C,Y)),X\=Y,%it needs 2 distinct items and class have both.
capacity(C, A), capacity(R, B), A=<B). %and the room can hold the number of students assigned to this course.
This code works for courses which needs one item only. But it doesn't work for courses which needs multiple items such as 241 because it holds for both conditions. How can I make the first condition checked if there is only one needs relation of the course.
Query for 102(correct):
?- assignRoom(102,X).
X = z23 ;
X = z11 ;
Query for 241(should be only z23):
?- assignRoom(241,X).
X = z23 ;
X = z23 ;
X = z11 ;
X = z23 ;
X = z23 ;
Upvotes: 1
Views: 76
Reputation: 3753
You could use forall/2
predicate.
forall(:Cond, :Action)
For all alternative bindings of Cond, Action can be proven.
You can deal with all requirements in one statement.
assignRoom(C,R):-
capacity(C, A), capacity(R, B), A=<B,
forall(needs(C, X), has(R, X)).
?- assignRoom(241, X).
X = z23 ;
false.
?- assignRoom(102, X).
X = z11 ;
X = z23 ;
false.
Upvotes: 1