Comments on TC1 and unresolved issed of Draft Technical Corrigendum 1 ("ST77 Annex A").

Ulrich Neumerkel 2010-09-04 (Version history)
Document status: Being written.

This document comments on one problem of TC1 (ISO/IEC 1321101:1995/Corr.1:2007) and unresolved issues listed in Annex A of Draft Technical Corrigendum 1 "ST77". It is being written in the course of preparting a Draft Technical Corrigendum 2.

TC1 reads:


Add additional errors:
i) The value of an argument Culprit is not a member of the set $I$
type_error(integer, Culprit)
j) The value of an argument Culprit is not a member of the set $F$
type_error(float, Culprit)
9.1.7 example no. 35 shows these errors are required.
Taken literally, error condition j applies to the goal X is 1+1. since 1 is not a member of the set $F$. Solution in DTC2.

Unclear how to resolve this cleanly, since there are much more problems present. E.g. X is 1//0+_. and X is _+1//0 must never be an evaluation_error(zero_divisor) and always have to be an instantiation error due to 7.9.2 b, and not 7.9.2 a! This seems rather an accident. Systems B, CIAO, CX, ECLiPSe, GNU, IF, SICStus 3, SWI, YAP, XSB all produce an error related to the zero_divisor for at least one of both expressions.

DTC1 reads: Quoted characters

The text does not define what character is denoted by a 'double quote char' or 'back quote char' which is a 'single quoted character'. Similar omissions exist for 'double quoted character' and 'back quoted character'.
Comment: All 4 mentioned nonterminals are defined. No need for action. For example, the first nonterminal in mentioned subclause reads: Quoted characters

single quoted character (* *)
   = non quote char (* *)
   | single quote char (* 6.5.5 *),
     single quote char (* 6.5.5 *)
   | double quote char (* 6.5.5 *)
   | back quote char (* 6.5.5 *) ;
Here, 'double quote char' and 'back quote char' are used, and the place of their definition is give as comment. Both are found in subclause 6.5.5.


It shall be implementation defined for each extended
character whether it is a graphic char, or an
alphanumeric char, or a solo char,

This classification is incomplete in the following sense:

- It is not enough to classify an extended character as an «alphanumeric char», one has to also tell if it is a «small letter char», «capital letter char» (e.g. NOTE 2 of 6.5 speaks of «extended small letter char»).

Comment: The codex covers these cases already. No need for action.

The codex reads:

6.5 Processor character set

The processor character set PCS is an implementation
defined character set. The members of PCS shall include
each character defined by char (6.5).

PCS may include additional members, known as extended
characters. It shall be implementation defined for each
extended character whether it is a graphic char, or an
alphanumeric char, or a solo char, or a layout char, or a
meta char.
This enumeration ensures that a PCS may include extended characters that belong to one of the mentioned nonterminals. For example, an extended character may be an alphanumeric char. This, however, does not imply that the extended character will be added directly to the syntax production of alphanumeric char! NOTE 2 gives already such an example:
Examples of extended small letter char (6.5.2) are small letters with grave or acute accent and Japanese Kanji characters.
This footnote helps a reader to understand that the extension will be added on the syntax production of small letter char (* 6.5.2 *) and not alphanumeric char (* 6.5.2 *).

- The notion of «solo char» is unfortunate: it contains characters that form a «name token» alone (! and ;), and punctuation characters, which cannot be part of an unquoted «name token». Classifying an extended character as a «solo char» does not make this character usable as a token alone, because there is no syntactic rule for this (! and ; are included explicitly in «name token»).

Along the lines of the Quintus/SICStus Prolog syntax, perhaps the category of «solo char» should be changed to mean only «cut char» and «semicolon char», and a new category «punctuation char» is introduced to contain all other characters presently classified as solo. And there should be a non-terminal «solo token», replacing «semicolon token» and «cut token» in «name token», which is defined as:

    solo token = solo char ;
The standard should let the user classify an extended character by placing it in exactly one of the following character categories: graphic char small letter char capital letter char solo char layout char

In addition to these, the notion of «char» covers the categories «decimal digit char», «underline char», «punctuation char» and «meta char» - It may not
make sense to allow the user to classify extended characters into one of these categories. Perhaps it may be useful to have a category «other char», initially empty; any extended character classified as such would only be allowed in (double, back) quoted tokens.

A wide character extension to SICStus Prolog allows the user to plug in arbitrary character sets and define, through C hook functions, the character-type mapping. This is a function taking a character code, and returning a constant denoting one of the above character categories. This extension is part of the SICStus Prolog 3.8 release.

I hope the term «implementation defined» in the Prolog standard does allow such delegation of definitions to the user through hook functions.

Comment: Need for correction, change below.

The nonterminal solo char is defined in 6.4.3 but it is never used within the grammar.

solo char (* 6.5.3 *)
    = cut char (* 6.5.3 *)
    | open char (* 6.5.3 *)
    | close char (* 6.5.3 *)
    | comma char (* 6.5.3 *)
    | semicolon char (* 6.5.3 *)
    | open list char (* 6.5.3 *)
    | close list char (* 6.5.3 *)
    | open curly char (* 6.5.3 *)
    | close curly char (* 6.5.3 *)
    | head tail separator char (* 6.5.3 *)
    | end line comment char (* 6.5.3 *) ;
This nonterminal therefore only serves to collect characters with similar properties that are stated in 6.5.3. For this reason, adding an extended character to the production of solo char would have no effect on the set of valid Prolog text.

However, the production of solo char makes many extensions rather cumbersome. Consider that an implementation wants to add the not sign (¬) of ISO 8859-1 as a solo char. In the current classification, the not sign can only be added within cut char or within semicolon char. Clearly, this is an unsatisfactory situation.

A new nonterminal graphic solo char which subsumes cut char and semiclon char will also permit to add further extensions. Thus:

6.4.2 Names. In definition of name token: Replace

   | semicolon token (* 6.4.2 *)
   | cut token (* 6.4.2 *) ;
   | graphic solo token (* 6.4.3 *) ;

6.4.2 Names. At the end. Replace

semicolon token (* 6.4.2 *)
   = semicolon char (* 6.5.3  *) ;

cut token (* 6.4.2 *)
   = cut char (* 6.5.3 *) ;
graphic solo token (* 6.4.2 *)
   = graphic solo char (* 6.5.3 *)

6.5.3 Solo characters. In definition of solo char: Replace

   = cut char (* 6.5.3 *)
   = graphic solo char (* 6.5.3 *)
Delete line
   | semicolon char (* 6.5.3 *)
Replace definitions
cut char (* 6.5.3 *) = "!" ;
semicolon char (* 6.5.3 *) = ";" ;
graphic solo char = "!" | ";" ;

6.5 and

The distinction between PCS (Processor character set) and C (the set of characters) is quite confusing at first reading. It does make sense, for example, in SICStus Prolog there is a member of PCS with character_code 0, which is not a character (not a member of C) - as there cannot be a one-char atom representing a 'character' with code 0.

Giving an example of this kind would help the uninitiated reader. Also replacing the name «character» by a qualified form, e.g. «Prolog character» would help. This is because currently the «processor character set» has members which are «character»s, and other members which are not - how would you call the letter 'things''? For example in the previous paragraph, referring to the 'character' with code 0 was quite cumbersome, because formally the thing with code 0 is not a character.

7.2.2, 7.2.3 and 7.2.5

The use of the built-in predicates '<'/2 and '=='/2 in defining the term order is not very elegant. Perhaps using the mathematical relation <, and the notion of «identical terms» would be preferable.


A reference to the definition of «predicate indicator sequence» and «predicate indicator list» in 7.1.6 would be quite helpful here. Also perhaps these notions should be included in chapter 3.
Comment: No need for action.


Perhaps it would make sense to explicitly mention that an implementation may add other conversion steps, as an extension. The goal_expansion mechanism of SICStus Prolog is an example of such extensions.
Comment: So far, a precise definition has never been achieved. And I suspect most implementations are not that consistent with themselves. Too complex for a corrigendum.

7.7.12 a)

Where is the definition and purpose of the «callable term representing the built-in predicate BP». Also the «MGU» produced here is never used.

Table 17

Why is the cut-parent of true shown to be equal to N-2?
Comment: Leave that unresolved. c)

It might benefit the user if the Culprit in the error term here could be more precise than the whole argument of call/1. Maybe call((...,1)) raising type_error(callable, 1) should be allowed by the standard.
Comment: Very hairy - if, this would change a lot of other things. example no. 6

This example should not output '3'.
Comment: B, IF, GNU, SICStus, SWI do not produce an output. But ECLiPSe, YAP, Ciao, CX, XSB, Qu do.

Possible fix:

   type_error(callable, (write(3),3)).
Included into DTC2

Table 25, Table 26

The cut-parent of the first subgoal of the execution state with index CP is shown as CP - this should be different. o)

The introduction of a local cut in front of the Else part is artificial.
Comment: leave this unresolved.

7.8.10 c)

This says that a throw without an applicable catch causes a system error. This error condition is different from other errors, because in this situation it does not make sense to apply the rules concerning the effect of an error: 7.12.1 says that the current goal should be replaced by the goal throw(error(system_error,Imp_def)). Perhaps it should be left implementation defined what should happen with uncaught exceptions.
Comment: Most processors will take precautions to avoid this situation anyway. E.g., the top level loop will usually give an appropriate message. But otherwise, the system error is the ideal error in that situation.
j) There may be a System Error at any stage of
execution. The conditions in which there shall be a
system error, and the action taken by a processor after
a system error are implementation dependent. It has the
form system_error.
So currently the effect is implementation depended. Changing it it implementation defined as suggested in the Annex, would increase the requirements to an implementation.
It does not seem right to replace CP by the cut-parent of each execution state. g)

The text
is used without definition.
Leave it unresolved.

7.10.4 NOTE

Replace The current operators do not affect output when there is a write option numbervars(true).

This seems to be garbled.

Comment: True, but minor.

7.10.5 Writing a term

No method is provided for writing a curly bracketed term (6.3.6) with curly brackets.
Comment: True. But how should this be resolved easily?

7.10.5 d)

Some implementations, e.g. SICStus, write «.» as «'.'» when quoted(true) is in force, to avoid confusion with end token. It might be good if the standard allowed this.
Many implementations write . quoted when quoted(true). However this is somewhat misleading as people now believe that . is something similar to comma (,) or bar (|). But then, a(.,.,[.|.]). is valid and adding a space after a . renders it invalid. Even (.)/2 is valid.

Maybe consider the following exception: If '.'/2 is used in functional notation, the quotes are not necessary at all, since adding a space after . would void its role as functor. However, in all other cases it appears "intuitive" to add an additional blank - which would change the meaning completely.

7.12.2 NOTE 4 (b)

See the remark to 7.8.10 c)
No action. See above.


Replace A list of the error conditions and associated error terms for the built-in predicate

Is the order of this list relevant? It should not be. If two or more error conditions apply, any of them could be raised by a standard-conforming processor. Perhaps this issue is worth clarifying.

Immediately following this subclause is the following note:

2 The effect of an error condition being satisfied is defined in subclause 7.12.

And in subclause 7.12, paragraph 4 we read

When more than one error condition is satisfied, the error
that is reported by the Prolog processor is implementation
So there is already a labyrinth of cross references.



The error conditions and examples for a bootstrapped built-in predicate are included in the appropriate clauses of the general built-in predicate.

This is quite cumbersome, especially that error conditions use the argument names which appear only later, and only as part of the Prolog definitions. I would suggest to list the heads of the bootstrapped predicates earlier, so that the argument naming becomes more visible.

An example of this: mentions the name «Code» which only appears buried in Prolog code on the next page in

True, but minor. Will try to change that for new definitions. c)

Maybe replace 2) and 3) with 2) (H:-B) unifies with (Head:-Body).
The sharing of variables is not very clear, true. Worth it? examples no. 5, 10 and 12

Mention that the order of solutions is undefined.
This is already done for 5 and 12. So you mean 10 only.

5 examples no. 22, 23 and 24 (last

Replacing «Xs» by «Ys» might make these examples easier to understand.

get_code/1 should be defined in terms of get_code/2, just as it is done for get_char:
   get_code(Code) :-
       get_code(S, Code).
Comment: Minor. Remainder of debates about bootstrapped definitions. d) and j)

Error condition j) makes little sense, given error condition d).
It is not evident that every one-char atom can be printed. Even more so, since says that C is an implementation defined subset of PCS. So if it is a subset, it is possible that there are elements of PCS that are not in C and thus the error would apply in this case. Seems to be primarily of relevance for Japanese character sets. example no. 4

The example is not fortunate, as the error permission_error(output, text_stream, user_output) would be also a valid outcome (see also the remark to 8.1.3).

I suggest to add an error condition, so that
   current_op(_, 0, _)
raises the error type_error(atom, 0).
Reasonable, but minor. A domain error is currently raised. Worth it/

Maybe an error condition has to be added so that if atom_codes is called, e.g. as atom_codes(X, [foo]), it should raise a type_error(integer, foo).

8.16.4 -- 8.16.8

The error conditions of atom_codes and number_codes seem not to be in sync, and similarly for ..._chars. Example:
   | ?- catch(atom_codes(f, [foo]), error(E,_),
   | ?- catch(number_codes(1, [foo]),
   error(E,_), true).
        E = type_error(integer,foo) ?

Explain the need for the last sentence before the NOTE: The approximate-addition function should satisfy ... last but one line

Replace round_R->Z(x) = entier(x+1/2)» Is it not the case that the IEEE FP standard allows other forms of rounding, e.g. rounding an integer+0.5 to the nearest *even* integer? If so, could this be allowed in standard Prolog?
Only resolvable in a larger scope - when systems will agree to drafter together an implementation specific extensions for IEEE.

9.1.7 examples no. 5 10 15 20 28 34 45 50 55

These should raise the type_error(evaluable, foo/0) error, according to 7.9.2 c).
Comment: Seems to be more critical. Maybe:
Replace all occurences of type_error(number, foo) by type_error(evaluable, foo/0). That is, for examples no. 5, 10, 15, 20, 28, 34, 45, 50, and 55.

9.1.7 examples no. 25 and 26

   '/'(7, -3)
   '//'(7, -3)
And replace
   '/'(-7, 3)
   '//'(-7, 3)
Perhaps it is worth adding extending the text 'Evaluates to an implementation dependent value which is either -2 or -3'.
Its implementation defined due to integer_rounding_function.
Evaluates to an implementation defined value
Evaluates to an implementation defined value
which is either -2 or -3 depending on the flag
integer_rounding_function (


Annex B
Editorial notes

Unusual characters

Check the following characters are correctly printed. Square root symbol: √ Greater than or equal symbol: ≥


These faults were noted after preparing for publication the text of ISO/IEC 13211-1:1995 Prolog: Part 1 - General Core, and subsequent lists of errors noted by Roger Scowen, Peter Szeredi, Pierre Deransart, and Ali Ed-Dbali.

Roger Scowen (editor) 9 Birchwood Grove, Hampton, Middlesex United Kingdom TW12 3DU Telephone: +44 (0) 20 8979 7429 E-Mail: October - November 2005

Document history

2006 April 15: Two further corrections are noted (3.125, 3.148). The structure is amended to be based on ISO/IEC 1539-1:2004/Cor.1:2005 (E). Posted to Jonathan Hodgson for distribution and balloting within SC22.

December 1: Posted to Jonathan Hodgson for distribution to, and discussion within JTC 1 SC 22 WG17.

2005 October 26: Copied from c:\rs0\prolog\da58.tex, and stored in c:\rs5\standard\st77.doc. Examples and sources are removed.


Validated HTML