ISO Prolog 程序中复合项的最小“max_arity”

The smallest `max_arity` of compound terms in ISO Prolog programs

旨在 一致性的 Prolog 系统 而不是 必须支持具有 任意大 参数的复合项。 Prolog 标志 max_arity 反映了这一点。

根据 ISO/IEC 13211-1:1995:

7.11.2.3 Flag: max_arity

Possible values: The default value only

Default value: implementation defined

Changeable: No

Description: The maximum arity allowed for any compound term, or unbounded when the processor has no limit for the number of arguments for a compound term.

所以 Prolog 系统 可能会也可能不会 max_arity 施加 上限 ......但是 下限?比如说,5 可以吗?

没有! ISO/IEC 13211-1:1995/Cor.2:2012,技术勘误 2,将 call/2..8 定义为:

8.15.4 call/2..8
...
NOTE — A standard-conforming processor may implement call/N in one of the following ways because error condition d is implementation dependent (3.91).

  1. 仅实现 call/2 到 call/8 的七个内置谓词。
  2. 实现 call/2..N 直到 8..max_arity 内的任何 N (7.11.2.3)。为 max_arity.
  3. 以下的较大参数生成存在性错误
  4. 仅针对某些执行模式实施 call/9 及更高版本。

所有这些方式暗示Max_arity >= 8——但仅此而已。

所以我的问题(至少)有两个方面:

  1. Prolog 用户
    “如果我想避免供应商锁定,我 可以使用 的最大数量是多少?”

  2. Prolog 实现者
    “如果我的目标是1 符合 ISO-Prolog,我必须支持 的最小 Max_arity 是多少?”

现在,我相当确定答案是这样的:

Yes, Max_arity = 8 is okay.

但事实真的如此吗?有没有我遗漏的线索?


脚注:
1) 我愿意。

参数数量较多的 ISO Prolog 标准谓词是 sub_atom/5。我们可以使用此谓词来证明至少 call/6 的合理性,从而证明至少 6:

的最大数量
| ?- call(sub_atom, A, B, C, D, E).

当然,对于call/6,没有什么能阻止程序员调用例如

| ?- call(foo(A,B,C), D, E, F, G, H)

广告 2:符合标准是工作系统的先决条件。这绝不保证系统适合任何目的,包括您(合理)感兴趣的目的。鉴于此,我会说 1 是最小值,因为零不能是复合术语的元数。当然,任何生成列表的尝试都会产生表示错误。情况可能更糟,请参阅 this.

的目的

不排除在此类处理器中使用具有更高数量(5 或 8)的内置函数。毕竟,合格的处理器只需要为执行准备 Prolog 文本 (5.1.a) 并正确执行 Prolog 目标 (5.1.b)。没有任何地方表示此类目标表示为复合术语。

但这当然是我们所期望的,因为我们希望能够编写我们自己的顶级循环,它本身超出了 ISO/IEC 13211-1 的范围。

广告1:至于未来的可移植性,255似乎是最低限度。但是IF有127。Minerva 125。当然unbounded会是最好的选择,为了快速和紧凑的表示,最多7个。

Are there clues I am missing?

在这种情况下,复合术语与谓词的关系经常受到监督。系统可能只支持比 max_arity 更小的谓词——这里发出的适当错误是 resource_error。将这种情况与具有 current_prolog_flag(max_arity, unbounded) 且目标 functor(F,f,N)N 超过处理器地址 space 的系统进行比较(在当前实现中)。虽然这样的目标在当前的实现中永远不会成功,但它仍然会发出 resource_error 而不是 representation_error.

不知何故有差距。 max_arity 仅涵盖复合尺寸。但是谓词大小没有标志。正如 SWI-Prolog 所示,这两件事可能会有所不同。但是 SWI-Prolog 错误地命名了限制 max_arity,尽管它不是它的 max_arity 标志:

/* SWI-Prolog 8.3.19 */

?- functor(_,f,10000).
true.

?- functor(F,f,10000), assertz(F).
ERROR: Cannot represent due to `max_arity' (limit is 1024, request = 10000)

?- current_prolog_flag(max_arity, X).
X = unbounded.

谓词大小限制可能与 call/n 相关,而不是复合大小。 ISO核心标准定义有点差强人意

但尚未彻底检查,但正在进行 SWI-Prologs 方面的修复:

?- functor(F,f,10000), assertz(test:-F).
F = f(_ ...)

?- functor(F,f,10000), call(F,a).
%%% crash

编辑 25.02.2021:
只有在查看 SWI-Prolog 的 C 代码时才能解释错误消息中的故障,它有一个 C 常量 MAXARITY,表示谓词大小。此常量和错误消息可能早于引入另一个常量的 ISO 核心标准。