4
votes

Prolog systems aiming at conformity do not have to support compound terms with arbitrarily large arities. The Prolog flag max_arity reflects this.

According to 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.

So Prolog systems may or may not impose an upper limit on max_arity ... but what about the lower limit? Is, say, 5 okay?

NO! ISO/IEC 13211-1:1995/Cor.2:2012, Technical Corrigendum 2, defines call/2..8 as:

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. Implement only the seven built-in predicates call/2 up to call/8.
  2. Implement call/2..N up to any N that is within 8..max_arity (7.11.2.3). Produce existence errors for larger arities below max_arity.
  3. Implement call/9 and above only for certain execution modes.

All of these ways only imply Max_arity >= 8—but nothing more.

So my question has (at least) two sides:

  1. Prolog User:
    "What is the maximum arity I may use if I want to avoid vendor lock-in?"

  2. Prolog Implementor:
    "What is the smallest Max_arity I must support if I aim1 at ISO-Prolog conformity?"

Right now, I'm quite sure the answer is this:

Yes, Max_arity = 8 is okay.

But is it in fact so? Are there clues I am missing?


Footnotes:
1) I do.

3

3 Answers

2
votes

There is a gap somehow. max_arity only covers the compound size. But there is no flag for predicate size. The two things might vary as SWI-Prolog shows. But SWI-Prolog names the limit wrongly max_arity, although its not its max_arity flag:

/* 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.

The predicate size limit might be more relevant to call/n than the compound size. The ISO core standard definition is a little unsatisfactory.

But its not thoroughly checked, but a fix on SWI-Prologs side is underway:

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

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

Edit 25.02.2021:
The glitch in the error message is only explained when you look at the C-Code of SWI-Prolog, which has a C Constant MAXARITY with the meaning of predicate size. This Constant and the Error Message possibly predates the ISO core standard, which introduced another constant.

3
votes

Ad 2: Standard conformity is a precondition for a working system. It is by no means a guarantee that a system is fit for any purpose including the one you are (reasonably) interested in. Given that, I'd say 1 is the minimum, as zero cannot be the arity of a compound term. Of course, any attempt to produce a list would produce a representation error. It could be worse, see Purpose of this.

The usage of built-ins with higher arity (5 or 8) is not precluded in such a processor. After all, a conforming processor needs just to prepare Prolog text for execution (5.1.a) and correctly execute Prolog goals (5.1.b). Nowhere is it stated that such goals are represented as compound terms.

But of course that is what we expect, as we expect to be able to program our own top level loop which is itself out of scope of ISO/IEC 13211-1.

Ad 1: As for future portability, 255 appears to be the minimum. But IF has 127. Minerva 125. Of course unbounded would be the best choice, with up to 7 for fast and compact representation.

Are there clues I am missing?

The relation of compound terms to predicates is often overseen in this context. A system may support predicates with only a smaller arity than max_arity — the appropriate error to issue here would be a resource_error. Compare this situation to a system with current_prolog_flag(max_arity, unbounded) and the goal functor(F,f,N) with N exceeding the processor's address space (in current implementations). While such a goal would never succeed in current implementations, it still issues a resource_error and not a representation_error.

0
votes

The ISO Prolog standard predicate with the larger number of arguments is sub_atom/5. We can use this predicate to justify at least call/6 and thus a maximum arity of at least 6:

| ?- call(sub_atom, A, B, C, D, E).

Of course, with call/6, nothing prevents the programmer to call e.g.

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