【问题标题】:How to read from a list in GNU prolog?如何从 GNU prolog 中的列表中读取?
【发布时间】:2020-11-18 21:16:57
【问题描述】:

所以我有一个任务,我要在 3 个不同的人之间制作兼容的会议时间。在我定义谓词的 prolog 文件中,有一行给出了我应该比较的三个人的名字,内容如下:

people([ann,bob,carla]).

我们应该从定义事实的数据文件中匹配这些名称,其中事实具有以下格式:

free(ann,slot(time(7,0,am),time(9,0,am))).

我的问题是,我如何阅读“人”,以便将姓名相互匹配?

我的教科书并没有很好地解释序言,我对“人”实际上是什么感到困惑(当我说它实际上是什么时,我的意思是“人”是一个列表?一个数组?)所以我甚至在寻找如何阅读每个名称以便我可以比较它们的解决方案时也遇到了麻烦。

【问题讨论】:

  • findall 怎么样?
  • 试试member/2

标签: prolog


【解决方案1】:

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.

通过重做,您可以遍历整个列表,直到列表只剩下一个元素。为此,您需要一个帮助谓词,我将其命名为personperson 将 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 之前,您猜测时隙Shastime/2 将查看是否所有人都有时间在S:如果没有人(空列表[]),您可以接受任何时间段(_)。如果您的列表中至少有一个人H:询问H 是否有时间在时间​​段S 上,并通过调用谓词来尝试列表中的其他人是否也有这个时间段S 空闲尾列表。
如果 prolog 选择了一个并非所有人都有时间的时隙,它将回到它选择时隙 S 的位置,并会寻找不同的值并重试。如果没有这样的时间段,它将返回false.
hastime/2 也可以用来自己查找时间段,但是将其用作“生成器”并同时进行测试有点混乱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多