ISO/IEC JTC1 SC22 WG17 post-N289
Draft for further corrigenda.

This document is an attempt to look at all issues that might be part of the next corrigendum. (The numbering of items changes, when new items are inserted, so please always refer to the content in addition to the number)
  1. (m)
    3.146 read-option: A compound term with uninstanti-
    * arguments which amplifies the results produced
    by the built-in predicate read-term/3 (8.14.1) and the
    bootstrapped * built-in predicates based on it (see 7.10.3).
    Does this mean that every read-option even as an extension has to have uninstantiated arguments? How many such arguments? Augments?
  2. 5.5 Extensions: replace "in the part of" by this.
  3. 5.5.10 Change 2nd sentence
    A processor may support the value of an expression being a value of an additional type instead of an exceptional value.
    A processor may support the value of an expression being some value including a value of an additional type instead of an exceptional value or error.
    Illustrative example from IF, SWI, YAP:
    ?- X is (1 rdiv 2) - (1 rdiv 2), integer(X).
    X = 0.
    This could be controversial and definitely needs an explicit resolution!
  4. 5.5.10 Note, replace is/2 by (is)/2.
  5. Negative Numbers. There is some perceived ambiguity that maybe needs clarification:
    A term which is the name - followed directly by a numeric
    constant denotes the corresponding negative constant.
    What means "directly" and what is a "numeric constant". 6.1.2 c and d defined them - they have no sign. A numeric constant is either an integer constant (* 6.4.4 *) or a float number token (* 6.4.5 *). There is even a separate Note in 6.4.5 to insist that a float number token is unsigned.

    Compatibility: integer(- /**/ 1).: Succeeds in B, Ciao, IF, Minerva, SICStus, YAP, XSB, GNU (new!). Fails in ECLiPSe, GNU, SWI.


    N92 1st CD 1992-03
    The prefix operator - with a numeric constant as operand
    denotes the corresponding negative constant.
    N110 revised CD 1993-03
    N128 DIS 13211-1 1994-03
    A term which is the name - followed directly by a numeric
    constant denotes the corresponding negative constant.
    ISO/IEC 13211-1 1995-06-01
    A term which is the name - followed directly by a numeric
    constant denotes the corresponding negative constant.
    On the other hand the EBNF-rules in for negative numbers are very clear:
    term = name, integer ;
    term = name, float number ;
    The nonterminals integer and float number are defined in 6.4 Tokens. Thus, both permit an optional layout text sequence.
    integer (* 6.4 *)
       = [ layout text sequence (* 6.4.1 *) ] ,
         integer token (* 6.4.4 *) ;
    float number (* 6.4 *)
       = [ layout text sequence (* 6.4.1 *) ] ,
         float number token (* 6.4.5 *) ;
    Would it have been intended to disallow spaces between - and the numeric constant, then the rules in would have been:
    term = name, integer token ;
    term = name, float number token;
    Further, the Prolog text - 1. cannot be misread as a compound term (-)/1, because in Operators as functors, the minus sign is explicitly excluded.
              term = op, term ;
    Abstract: f(a)   f   a
    Priority: n      n   n
    Specifier:       fy
    Condition:If a is a numeric constant, f is not -
    Condition:The first token of a is not open ct
              lterm = op, term ;
    Abstract: f(a)    f   a
    Priority: n       n   n-1
    Specifier:        fx
    Condition:If a is a numeric constant, f is not -
    Condition:The first token of a is not open ct
  6. Note 2: (,)/2 by (',')/2
  7. 6.4.2 up to 6.5.3 add graphic solo: (probably no longer needed, provided graphic characters in the extended character set are never solos).
    1. 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 *) ;
      (@@@ Also update 6.1.2 b 3)
    2. 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 *)
    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 = "!" | ";" ;
      or by
      graphic solo char = cut char | semicolon char ;
    This change is only needed if there is a need for more graphic solo chars in extended character sets.
  8. Small Prolog text: Related to outputting .. Testfiles, they should all compile!
  9. 6.5.4 2 times dependent replace by defined. But: horizontal tab char is not strictly needed. See A control escape sequence... Similarily replace
    followed by an implementation dependent new line character (6.5,
  10. 7.1.2 Note 3: A processor may provide as an extension more than one integer type. Each integer type shall have a distinct set of the operations described in 9.1.3. Where is equality between different integer types defined?
  11. Predicate indicator list: The empty list is not allowed. Shouldn't it be allowed? Otherwise, shouldn't a domain_error(non_empty_list, []) be defined?
  12. 7.4.3, last paragraph: replace "directive indicating" by "indicating".
  13. 7.7.12 d: replace "(see 8) This" by "(see 8). This"
  14. 7.8 Control constructs, second par:
    The format and notation of the definition of each control
    construct is consistent with that used for built-in predicates
    (8.1) except that a mode goal indicates that the argument
    is a goal rather than a term.
    It is not clear, why goal is called a mode. It is type and mode at the same time, in addition it indicates arguments where cuts cut to the outside. It indicates arguments that are converted to a goal. (Maybe its only a mode and no type, because there are no type errors associated?)

    This is the case for,,,, but not for and

  15. 7.8.7 (if-then) delete entire control construct. Demand error instead. 7.8.9 (if-then-else) is enough. (Warning: Potentially controversial) Discussion
  16. (catch/3 Examples), last example: Remove is in
       ['throw(X)' is causes a goal
  17. 7.9.2 Errors. Several explanations why E is -(-(_)). should result in an instantiation error. Subclause a vs. b. This leads to ambiguities in 5.5.10 extensions. Consider a new evaluable functor zero/1 such that 0 is zero(_). The argument shall be ignored. Due to subclause b this would be an instantiation error. but zero(-_) would be no instantiation error.

    Even worse:

    X is 1/0+_.
    X is _+1/0.
    These examples should never produce a zero_divisor, since subclause b is always "faster" than subclause a. But all systems produce that error.

  18. eof_action(Action):
    error — There shall be a Permission Error
    (7.12.2 e) signifying that no more input exists in
    this stream.
    GNU and B is fine, SICStus: wrong error, SWI, YAP: ignored.
  19. Note 2: remove second "it".
  20. 7.10.5 d
    the sequence of characters forming the atom followed by a layout character could not be input as a valid atom.
    Alternatively, a dot at the end (without a layout char and without a %) is an end token only.

    Alternatively, replace in 6.4.2 Names:

    A graphic token shall not be the single character . (dot)
    when . is followed by a layout char or single line
    A graphic token shall not be the single character . (dot)
    when . is followed by a layout char or single line
    comment or when . is the last character
    6.4.8 other tokens. Replace
    An end char shall be followed by a layout character or a
    An end char shall be followed by a layout character or a
    % or it shall be the last character
  21. Flag: bounded, last paragraph.
    If the value of this flag is false, inte-
    ger arithmetic is always performed correctly (ex-
    cept when there is a system_error),
    This should probably be a resource error. Integers, as defined as type (7.1) in (7.1.2) are accompanied with Note 1 which suggest a resource error "because of exhaustion of resource".
  22. Flag: min_integer, note
    NOTE - The possible values are required to be -M or -(M+1) where M is the value of the flag max_integer.
    In 13211-1 1.1 Notes it is defined that "Notes in this part of ISO/IEC 13211 have no effect on the language, Prolog text or Prolog processors that are defined as conforming to this part of ISO/IEC 13211". Reasons are only cross references and warnings for differences to existing implementations. This note has however a very strong effect on an implementation. For this reason it should be accompanied with a cross reference towards 7.1.2.
  23. 7.12.2 g: There shall be a Evaluation Error
  24. Decide for N-th or Nth.
  25. g&h, g&h, i, f&g, f&g, g, h, h. The usage of target stream ( is quite inconsistent and appears unmotivated. Reason why not: TS is used when the stream can be S_or_a or the implicit one. Most errors only apply when S_or_a is explicitly present.
  26. 8.12.X.4, 8.13.X.4 all implicitly assume a text resp. binary stream. Maybe add a remark. But not clear where.
  27. both f and g apply for an atom that is not associated to an open stream. C.f. 3.5 alias. Currently: SICStus, XSB.
    put_char(my_file, C).
       If a stream is associated with my_file
    put_char(st_o, 'ty').
       If a stream is associated with st_o
       type_error(character, ty).
    put_code(my_file, C).
       If a stream is associated with my_file
    put_code(st_o, 'ty').
       If a stream is associated with st_o
       type_error(integer, ty).
    put_byte(my_file, C).
       If a stream is associated with my_file
    f) Operator is neither a partial list nor a list nor an atom
    type_error(list, Operator).
    Should be atom_or_list or atom_or_atom_list. has type atom_or_atom_list. There is also a type character_list. atom_or_list is simpler, but then it is nowhere used. (This would affect also 7.12.2 b!). Alternatively it might be preferable to issue type_error(atom,Xs) to "advertise" that one does not need a list.
  31. type_error(list, Operator). The actual type should be changed to atom_or_atom_list.
  32. @@@ The "declarative" description demands
    a character sequence of Number which could be output (7.10.5 b, 7.10.5 c).
    But the procedural description:
    b) Else parses the list of the characters of the name of the one-char atoms according to the syntax rules for numbers and negative numbers (, to give a value N,
    So the declarative description is not true for "01", while the procedural description succeeds. There are many other examples of that kind.

    Maybe add a new subclause:

    Additionally is true, if Number unifies with N obtained by b.
  33. 9.2.3 Errors, Note. Replace defined in clause 7.12 by subclause.
  34. NOTE. Replace "an infix predefined operator" by "a predefined infix operator".
    The following items were detected after WDCor.3
  35. Implementation definedness of error/2. Currently, any throwing of error/2 depends on the implementation definded second argument. In other words, signalling an error is not portable.
  36. missing bar in token rule
    Source: SO

    Nature of defect: the non-terminal token (* 6.4 *) could include bar for reasons of consistency.

    Solution: Add bar to token (* 6.4 *). However, this leads to ambiguity, since ht sep (* 6.4 *) describes the very same text as bar (* 6.4 *) So further clarification would be required.

  37. Body to term conversion incorrect. Description of clause/2 inconsistent
    Source: SO

    Nature of defect: The declarative and procedural descriptions of clause/2 in are inconsistent. The error is in the procedural description that does not take into account the sharing of variables between the head and body of a rule.
    Similarly, 7.6.4 body to term conversion is incorrect.


    :- dynamic(a/1).
    :- dynamic(c/0).
    a(X) :- b(X).
    c :- a(X), b(X).
    ?- clause(a(A), b(B)), A == B.
    ?- clause(c, ( a(A), b(B) )), A == B.
    The declarative description demands correctly that both queries should succeed. However, the current procedural description demands that A and B are independent copies of the same variable, thus A == B fails.

    Solution: Reword 7.6.4 and

  38. Problem with variable identity and clause/2, 7.6.3 and 7.6.4 must probably be reformulated completely.
  39. (After discussion with Jan Burse, note that several of my comments were deleted) The following terms are invalid or ambiguous Prolog text but should be valid and unambiguous.
    - (1).
    Invalid due to the condition for prefix operators. The condition refers to abstract syntax, but in abstract syntax 1, (1), ((1)) are all the same.
    - -1.
    Maybe invalid. Might be excluded by that same rule, depending on what a numeric constant (no definition anywhere), is. Is it only non-negative numbers or not? E.g. 6.1.2 talks about integer constants only. That is, no negative integers are defined as abstract terms. On the other hand, there are rules to produce negative numbers!
    - 1^3.
    Ambiguous. It might mean (-1)^3 and - (1^3) since the validity of the minus prefix operators only depends on the abstract syntax. And (1^3) is definitely not a numeric constant.


    Modify c and d to include negative numbers. @@@

    A term which is the name - followed directly by a numeric
    constant denotes the corresponding negative constant.

    term =op, term ;
    Abstract: f(a)fa
    Priority: nnn
    Condition:If a is a numeric constant
    the first token of a is integer
    or float number
    , f is not -
    Condition:The first token of a is not open ct
    Same for last syntax production for fx operators.

    Add Note 3

    3 The condition "If the first token of a is integer or float number, f is not -" defines the use of - in the term - 1 meaning -1, - (1) meaning -(1), - -1 meaning -(-1), and - 1^2 meaning ^(-1,2).
  40. the syntax of float numbers is defined without giving a precise meaning to values that are not exactly representable. The rounding process is left undefined. (indirectly reported 2016-12-06 by Harry Stoteles Jan Burse on comp.lang.prolog)
    System\Query writeq(
    X is 244124086793065425827
    IF V5.1B 2.4412408679306543e+020 -32768.0
    SWI 6.3.18-3 2.4412408679306543e+20 -32768.0
    YAP 6.3.4 2.4412408679306543e+20 -32768.0
    B 7.8#5 2.44124e+20 0.0
    GNU 1.4.5 2.4412408679306543e+20 ovl.
    SICStus 4.3.5 2.4412408679306543E+20 0.0
    Minerva 2.4 2.4412408679306543E20 ovl.
    XSB 3.7 244124086793065431040.0000 ovl.
    Ciao 1.15 2.441240867930654e20 32768.0
    IV 1.4.2 2.4412408679306543e+020 0.0
    Jekejeke 2.4412408679306543E20 0.0
    ECLiPSe 6.2#21 2.4412408679306543e+20 0.0
  41. Directives op/3 and set_prolog_flag/3 must effectively precede the text they apply to. Some correction to this end is needed. Source: SO.
  42. Missing floatI→F conversion for sin/1, cos/1 etc al (Per Mildner, 2017-08-10).
  43. 8.15.1 Note: s/infix operator/prefix operator/ (Jan Burse, 2018-06-02)
  44. d (2018-07-08)
    char_code(Ch, c) may be both a Type Error ( c) and a Representation Error ( d). However, 7.12.2 f only permits a Representation Error
    when an implementation defined limit has been breached.
    But a character can never be a character code.
    d) Code is neither a variable nor an integer but not a character code
  45. 7.7.2 (Markus Triska, 2018-07-10)
    ... is based on aan execution stack
  46. 3.200 variable: add NOTE about the notion logic variable. (Markus Triska, 2018-09-19).
  47. 6.1.1, facet Priority, add at end: A variable has a zero priority. or
    An atomic term, a variable, and a
    compound term expressed in functional notation have a
    zero priority.
  48. l, "instantiates" collides with query read_term(T, [variables([])]) and input T. (Paulo Moura, 2021-08-21)
  49. read_term/3 never produces end_of_file.
    i) If C_next represents an end token (6.4.8) or an optional layout text sequence (6.4.1) at the end @@@, then proceeds to k,


    k) Parses C_Seq as a read-term (6.2.2) T. or parses C_Seq as an optional layout text sequence (6.4.1) and @@@T = end_of_file,

  50. 8.7 Arithmetic comparison, four incorrect axioms.
    lssIF(n, y) = geqFI(y, n) grtFI(y, n)
    leqIF(n, y) = gtrFI(y, n) geqFI(y, n)
    gtrIF(n, y) = leqFI(y, n) lssFI(y, n)
    geqIF(n, y) = lssFI(y, n) leqFI(y, n)
    (Yutaka Ichibangase, 2022-03-13)
  51. 9.1.7 Examples, The simple arithmetic functors.
    '/'(7, 35).
       Evaluates to the value 0 a value approximately equal to 0.2.
  52., (twice)
    2.7818 2.71828
  53., and more. The notion of solution is misleading here, it would be preferable to call these uses answers. Description

    ';'('->'(If, Then), Else) is true iff (1a) If is true,
    and (1b) Then is true for the first solution answer of If, or (2)
    If is false and Else is true.

    Solution is not problematic, as long as there are no redundant solutions. Like in Examples
       Succeeds, unifying Name with elk.
       On re-execution, succeeds,
       unifying Name with insect.
       [The order of solutions is
          implementation dependent]
  54., power. In LIA-2, the value for zero raised to the power of zero is invalid(1). So far however, this has been defined as one. (Daniel Diaz, 2023-07-07)
  55. Flag: integer_rounding_function. Fix value to toward_zero, since down is now realized with (div)/2.
  56. 7.5.2 Static and dynamic procedures. (:-)/2 and (:-)/1 are neither control constructs nor built-in. Still, issue a permission error for:
    6 ?- (:-B).
    6 ?- (A:-B).
    3 ?- call((A:-B)).
    4 ?- (A:-B).
    1 ?- asserta(((a:-b):-true)).
         permission_error(modify,static_procedure,(:-)/2). % proposed
    2 ?- asserta(((:-b):-true)).
         permission_error(modify,static_procedure,(:-)/1). % proposed
    There is a slight inconsistence, as modification is not permitted which somewhat implies its existence, but then there is an existence error upon calling it. And does this also apply to directives? (2023-07-09)

    Scryer,Trealla OK SICStus OK 1,2 - context_error 3,4,5 IF OK 1,2 IV OK 1,2 ex YAP OK 2 call((:-X=1)). X = 1. ECLiPSe i.e. for 6

    GNU,Minerva,SWI,Ichiban,B succ 1,2

  57. 9.1.7 Examples. The last five examples are only for bounded integers. For unbounded integers all five examples fail. (2023-08-12)
  58. Errors (of set_prolog_flag/2). Missing instantiation error.
    e) Flag is a valid flag and Value is inappropriate for Flag and
    there is no appropriate instance of Value
    domain_error(flag_value, Flag+Value).

    g) Value is inappropriate for Flag but an instance of Value is appropriate
    Value has a component which is a variable and an instantiated component is required

  59. could use pair_list in place of list which then would also extend with a definition for pair_list. (2023-09-10)
ISO/IEC 10967-1:1994, Floats discussion, Symbols


Uppsala 1996, Schliersee 1997, Chiswick 1999, Sitges 2005, Seattle 2006, builtins, Oporto 2007, Udine 2008, Pasadena 2009, Edinburgh 2010, Lexington 2011, Budapest 2012, Istambul 2013, Vienna 2014, Dresden 2015, WebEx 2017, 2018, Zoom 2019, JITSI 2020, Zoom 2021, 2022, 2023.
Version control
Validated HTML