如何将变量 X 分配给 Prolog 中的一件事

How can I assign variable X to only one thing in Prolog

我正在编写包含房间和课程的序言代码。一个房间可以有多个东西,例如投影仪和智能板,一些课程需要这些东西。

%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.

此代码适用于只需要一项的课程。但它不适用于需要多个项目的课程,例如 241,因为它适用于这两种情况。如果课程只有一个需求关系,如何检查第一个条件。

查询 102(正确):

?- assignRoom(102,X).
X = z23 ;
X = z11 ;

查询 241(应该只有 z23):

?- assignRoom(241,X).
X = z23 ;
X = z23 ;
X = z11 ;
X = z23 ;
X = z23 ;

您可以使用 forall/2 谓词。

forall(:Cond, :Action) For all alternative bindings of Cond, Action can be proven.

您可以在一条语句中处理所有需求。

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.