people([ann,bob,carla]). 是事实。谓词people/1 包含人名的列表。在 prolog 中,您有不同的方式从列表中获取元素。
最“脏”的版本就是用固定数量的元素来写列表:
?- people([P1,P2,P3]).
P1 = ann,
P2 = bob,
P3 = carla ;
false.
您不应该这样做,因为它仅适用于 3 人一组,并且您必须在每次有人离开/进入时更改您的代码。
通常你会通过一个序言列表,你只得到第一个元素 Head 和列表的其余部分 Tail:
?- people([Head|Tail]).
Head = ann,
Tail = [bob, carla] ;
false.
通过重做,您可以遍历整个列表,直到列表只剩下一个元素。为此,您需要一个帮助谓词,我将其命名为person。 person 将 List 作为第一个元素,将变量(或测试名称)作为第二个元素。它将变量与列表中的一个元素统一起来:
person([H|_], H).
person([_|T], P):-
person(T, P).
?- people(L), person(L,P).
L = [ann, bob, carla],
P = ann ;
L = [ann, bob, carla],
P = bob ;
L = [ann, bob, carla],
P = carla ;
false.
它的工作原理如下:您有一个列表,并想象您只看到其中的第一个元素。您在这里有两个选择:第一个您可以只将 head 元素作为输出,所以第二个属性应该与 head 元素完全相同:person([H|_], H).
或者 second:您忽略 head 元素并尝试通过使用较小的列表再次调用谓词来在列表的其余部分中找到一些东西:person([_|T], P):- person(T, P).
当变量以下划线 _ 开头时,您对其内容不感兴趣。
还值得了解:有(很可能)内置辅助谓词,例如 member/2,可以返回列表中的任何成员:
?- people(L), member(P,L).
会给你L的任何人。
要访问选定人员的单个时间段,您只需使用列表中的人员请求谓词free:
?- people(L), member(P,L), free(P,S).
如果您想找到列表中的所有人都必须参与的时间段,您需要定义一个辅助谓词。我把它命名为hastime
hastime([],_).
hastime([H|L], S):-
free(H,S),
hastime(L,S).
?- people(L), free(_,S), hastime(L,S). 的输出将为您提供一个时间段 S,每个人都有时间。在调用hastime/2 之前,您猜测时隙S。 hastime/2 将查看是否所有人都有时间在S:如果没有人(空列表[]),您可以接受任何时间段(_)。如果您的列表中至少有一个人H:询问H 是否有时间在时间段S 上,并通过调用谓词来尝试列表中的其他人是否也有这个时间段S 空闲尾列表。
如果 prolog 选择了一个并非所有人都有时间的时隙,它将回到它选择时隙 S 的位置,并会寻找不同的值并重试。如果没有这样的时间段,它将返回false.
hastime/2 也可以用来自己查找时间段,但是将其用作“生成器”并同时进行测试有点混乱。