Prolog 中的列表和序列

17 Mar 2025 | 4 分钟阅读

在 Prolog 中,列表构建器使用方括号[...]。 列表通过符号 [A | B] 来引用,其中 A 是第一个元素,其尾部是 B。 以下示例显示了三个定义,其中列表的第一个元素由 'car' 引用,列表的尾部由 'cdr' 引用,列表构造函数由 'cons' 引用。

其中,

  • A 是 [A | B] 的头部 (car)。
  • B 是 [A | B] 的尾部 (car)。
  • 将 A 放在头部并将 B 放在尾部,构造列表 [A | S]。

然而,上述显式定义是不必要的。 Prolog 团队 [A|B] 指的是 A 是列表的头部,B 是它的尾部。 如果列表可以与 prolog 团队 '[A|B]' 统一,A 将绑定到列表的第一个元素,B 将绑定到列表的尾部。

在本节中,许多谓词是为许多 Prolog 解释器内置的。

谓词 'member/2' 的定义描述如下

这些子句可以这样理解

  • A 是列表成员,其第一个元素是 A。
  • 如果 A 是 S 的成员,则 A 是列表成员,其尾部是 S。

我们可以用多种方式使用这个程序。 我们还可以如下测试成员资格

我们还可以如下生成列表成员

这里,使用以下推导树来显示此最后一个目标如何生成所有答案。

Lists and Sequence in Prolog

每个左分支对应于与 'member' 的第一个子句的匹配。 每个右分支对应于与第二个子句的匹配。 在最右边的分支上,子目标 'member(A, [])' 将不匹配任何 'member' 子句头。

成员有许多其他用途。 此示例查询如下所示

在上面的查询中,我们打算搜索以查找与指定元素配对的元素。 在列表中,我们可以用另一种方式找到元素,并且这些元素将满足某些约束

成员定义写成如下

"不在乎" 变量用 '_'(下划线)表示。 "不在乎" 变量也称为匿名变量。 一般来说,匿名变量的名称以以下划线开头。

以下 'takeout' 的定义与 'member' 相关,如下所示

用英语来说,我们可以这样解释这些子句

  • 如果从 [A | S] 中取出 A,结果将是 S。
  • 如果从 [A | S] 的尾部取出了 A,结果将是 [A | S]。

例如:

在 'takeout' 的定义中,使用任何匿名变量是不合适的。 结果定义为 'takeout(3, [1, 2, 3], [1, 2])',如以下子句树所示。

Lists and Sequence in Prolog

我们将得到以下目标

上面的例子解释了 'takeout(A, C, X)' 也可以解释为“将 A 插入 X 以生成 C”。 我们也可以定义

以下定义显示了两个 Prolog 列表的连接或附加

各种可能的目标如下