如何在GNU prolog中读取列表?

如何在GNU prolog中读取列表?,prolog,Prolog,因此,我有一项任务,我要在3个不同的人之间安排合适的会面时间。在我定义谓词的prolog文件中,有一行给出了我要比较的三个人的名字,如下所示: people([ann,bob,carla]). 我们应该从定义事实的数据文件中匹配这些名称,其中事实具有以下格式: free(ann,slot(time(7,0,am),time(9,0,am))). 我的问题是,我如何通读“人”,这样我就可以互相匹配名字了 我的教科书并没有很好地解释序言,当我说“人”实际上是什么时,我对“人”到底是什么感到困惑,

因此,我有一项任务,我要在3个不同的人之间安排合适的会面时间。在我定义谓词的prolog文件中,有一行给出了我要比较的三个人的名字,如下所示:

people([ann,bob,carla]).
我们应该从定义事实的数据文件中匹配这些名称,其中事实具有以下格式:

free(ann,slot(time(7,0,am),time(9,0,am))).
我的问题是,我如何通读“人”,这样我就可以互相匹配名字了

我的教科书并没有很好地解释序言,当我说“人”实际上是什么时,我对“人”到底是什么感到困惑,我的意思是“人”是一个列表吗?阵列?因此,我甚至很难找到一个解决方案,如何通读每个名字,以便比较它们。

人们[ann,bob,carla]。这是事实。谓词people/1包含人名列表。在prolog中,可以使用不同的方法从列表中获取元素

最肮脏的版本就是用固定数量的元素来写列表:

?- people([P1,P2,P3]).
P1 = ann,
P2 = bob,
P3 = carla ;
false.
您不应该这样做,因为它只适用于3个人,每次有人离开/进入时,您都必须修改代码

通常情况下,您在序言列表中只得到第一个元素的头部和列表尾部的其余部分:

通过重做,您可以遍历整个列表,直到列表只剩下一个元素。为此,您需要一个帮助谓词,我将其命名为person。person将列表作为第一个元素,将变量或名称作为第二个元素进行测试。它使用列表中的一个元素统一变量:

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.
?- people(L), member(P,L), free(P,S).
它的工作原理如下:您有一个列表,想象您只看到其中的第一个元素。这里有两个选择:首先,您可以将head元素作为输出,因此第二个属性应该与head元素完全相同:person[H | uh],H。 或者第二个:忽略head元素,并尝试在列表的其余部分中查找某个内容,只需使用较小的列表再次调用谓词:person[|T],P:-personT,P。 当变量以下划线开头时,您对其内容不感兴趣

还值得了解的是:最有可能的内置帮助器谓词(如member/2)会返回列表中的任何成员:

?- people(L), member(P,L).
我会给你洛杉矶的任何人

要访问所选人员的单个时间段,只需从列表中请求谓词free with the person:

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.
?- people(L), member(P,L), free(P,S).
如果要查找列表中所有人员都必须参与的时间段,则需要定义一个助手谓词。我给它起了个名字

-人,自由,S,黑斯梅尔,S的输出会给你一个每个人都有时间的时隙。在调用Hastinme/2之前,您猜测一个时隙S。Hastinme/2将查看是否所有人都有时间在S上:如果没有人空列表[],您可以接受任何时隙\。如果列表中至少有一个人H:通过调用尾部列表的谓词,询问H是否在时间段S上有时间,并尝试列表中的其他人是否也有此时间段S空闲。 如果prolog选择了一个并非所有人都有时间的时隙,它将返回到选择时隙的位置,并将查找不同的值,然后重试。如果没有这样的时隙,它将返回false。 此外,Hastinme/2还可以单独用于查找时隙,但同时将其用作生成器和测试有点令人困惑。

人们[ann,bob,carla]。这是事实。谓词people/1包含人名列表。在prolog中,可以使用不同的方法从列表中获取元素

最肮脏的版本就是用固定数量的元素来写列表:

?- people([P1,P2,P3]).
P1 = ann,
P2 = bob,
P3 = carla ;
false.
您不应该这样做,因为它只适用于3个人,每次有人离开/进入时,您都必须修改代码

通常情况下,您在序言列表中只得到第一个元素的头部和列表尾部的其余部分:

通过重做,您可以遍历整个列表,直到列表只剩下一个元素。为此,您需要一个帮助谓词,我将其命名为person。person将列表作为第一个元素,将变量或名称作为第二个元素进行测试。它使用列表中的一个元素统一变量:

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.
?- people(L), member(P,L), free(P,S).
它的工作原理如下:您有一个列表,想象您只看到其中的第一个元素。这里有两个选择:首先,您可以将head元素作为输出,因此第二个属性应该与head元素完全相同:person[H | uh],H。 或者第二个:忽略head元素,并尝试在列表的其余部分中查找某个内容,只需使用较小的列表再次调用谓词:person[|T],P:-personT,P。 当变量以下划线开头时,您对其内容不感兴趣

还值得了解的是:最有可能的内置帮助器谓词(如member/2)会返回列表中的任何成员:

?- people(L), member(P,L).
我会给你洛杉矶的任何人

访问ch的单个时隙的步骤 oosen person您只需从列表中与您的person一起请求谓词free:

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.
?- people(L), member(P,L), free(P,S).
如果要查找列表中所有人员都必须参与的时间段,则需要定义一个助手谓词。我给它起了个名字

-人,自由,S,黑斯梅尔,S的输出会给你一个每个人都有时间的时隙。在调用Hastinme/2之前,您猜测一个时隙S。Hastinme/2将查看是否所有人都有时间在S上:如果没有人空列表[],您可以接受任何时隙\。如果列表中至少有一个人H:通过调用尾部列表的谓词,询问H是否在时间段S上有时间,并尝试列表中的其他人是否也有此时间段S空闲。 如果prolog选择了一个并非所有人都有时间的时隙,它将返回到选择时隙的位置,并将查找不同的值,然后重试。如果没有这样的时隙,它将返回false。
Hastinme/2也可以用来自己查找时隙,但同时将其用作生成器和测试有点令人困惑。

findall如何?Try member/2。findall如何?Try member/2。