General Core

DRAFT TECHNICAL CORRIGENDUM 2

Remark: This is only the draft of technical corrigendum 2! The actual technical corrigendum 2 is available free of charge from ISO/IEC as

ISO/IEC 13211-1:1995/Cor.2:2012.

This document is prepared in fulfillment of WG 17 resolutions A1, A2, A5, A6, A7, A8 in Edinburgh, 2010. References in brackets refer to the corresponding sections.

Additional corrections:A 1. Resolved that the missing error corresponding to a call to open/3,4 in which the stream variable is instantiated be called uninstantiation_error and that a corrigendum to this effect be submitted. [C1] A 2. Resolved that the predicates in the following list, compare/3, sort/2, keysort/2, ground/1, call/2-8, false/0, callable/1, subsumes_term/2, acyclic_term/1, term_variables/2, and retractall/1, unaccountably omitted from part 1 but present in most implementations be added as corrigenda. [C3, C4, C5, C6, C8, C9] A 6. Resolved that the evaluable functors on the following list be added by means of a corrigendum: (+)/1, max/2, min/2, acos/1, asin/1, tan/1, pi/0, xor/2 (as functor only), atan2/2, (^)/2, and (div)/2. [C14, C15, C16, C17] A 7. Resolved to change 6.3.4.3 of part 1 to allow the bar character | as an operator, but only if its precedence is greater than or equal to 1001. [C2] A 8. Resolved to change 6.3.4.3 to forbid the creation of operators called '{}' or '[]'. [C2]

- Error condition for retract/1. [C7]
- Error conditions of number_chars/2 et al.. [C10]
- Error conditions for evaluating an expression. [C11]
- Typo in call/1 example. [C12]
- Template and modes, and error conditions of catch/3. [C13]

- Incorrect example for write_canonical/1 [C18]

C1

`variable`

from the enumerated
set `ValidType`

.k) There shall be an Uninstantiation Error when an argument or one of its components is not a variable, and a variable or a component as variable is required. It has the form`uninstantiation_error(Culprit)`

where`Culprit`

is the argument or one of its components which caused the error.

5 When a built-in predicate has a single mode and template,

an argument whose mode is`-`

is always associated with an error

condition:a type errorwhen the argument is not a variable.

a type error

an uninstantiation error

- f) Stream is not a variable

—`type_error(variable, Stream).`

- f) Stream is not a variable

—`uninstantiation_error(Stream).`

C2

A bar (6.4) shall be equivalent to the atom`'|'`

when`'|'`

is an operator.

`op =`

`bar ;`

Abstract: `|`

Priority: nnSpecifier: ssCondition: `'|'`

is an operator

There shall not be an operator`'{}'`

or`'[]'`

.

An operator`'|'`

shall be only an infix operator with priority greater than or equal to 1001.

Bar is also a solo character (6.5.3), and a token (6.4) but not an atom.

3 The third argument of`op/3`

(8.14.3) may be any atom

except ',' so the priority of the comma operator cannot be

changed.

3 The third argument of`op/3`

(8.14.3) may be any atom except`','`

,`'[]'`

, and`'{}'`

so the priority of the comma operator cannot be changed, and so empty lists and curly bracket pairs cannot be declared as operators.

bar (* 6.4 *) = [ layout text sequence (* 6.4.1 *) ] , bar token (* 6.4.8 *) ;

bar token (* 6.4.8 *) = bar char (* 6.5.3 *) ;

`solo char`

:| bar char (* 6.5.3 *)

bar char (* 6.5.3 *) = "|" ;

l)`Op_specifier`

is a specifier such that`Operator`

would have an invalid set of specifiers (see 6.3.4.3).

—`permission_error(create, operator, Operator).`

l)`Operator`

is an atom,`Priority`

is a priority, and`Op_specifier`

is a specifier such that`Operator`

would have an invalid set of priorities and specifiers (see 6.3.4.3).

—`permission_error(create, operator, Operator).`

m)`Operator`

is a list,`Priority`

is a priority, and`Op_specifier`

is a specifier such that an element`Op`

of the list`Operator`

would have an invalid set of priorities and specifiers (see 6.3.4.3).

—`permission_error(create, operator, Op).`

op(500, xfy, {}). permission_error(create, operator, {}). op(500, xfy, [{}]). permission_error(create, operator, {}). op(1000, xfy, '|'). permission_error(create, operator, '|'). op(1000, xfy, ['|']). permission_error(create, operator, '|'). op(1150, fx, '|'). permission_error(create, operator, '|'). op(1105,xfy,'|'). Succeeds, making | a right associative infix operator with priority 1105. op(0,xfy,'|'). Succeeds, making | no longer an infix operator.

C3

## 8.2.4 subsumes_term/2

This built-in predicate provides a test for syntactic one-sided unification.## 8.2.4.1 Description

`subsumes_term(General, Specific)`

is true iff there is a substitutionθsuch that

- a)
`General`

θand`Specific`

θare identical, and- b)
`Specific`

θand`Specific`

are identical.

Procedurally,`subsumes_term(General, Specific)`

simply succeeds or fails accordingly. There is no side effect or unification.## 8.2.4.2 Template and modes

`subsumes_term(@term, @term)`

## 8.2.4.3 Errors

None.## 8.2.4.4 Examples

subsumes_term(a, a). Succeeds. subsumes_term(f(X,Y), f(Z,Z)). Succeeds. subsumes_term(f(Z,Z), f(X,Y)). Fails. subsumes_term(g(X), g(f(X))). Fails. subsumes_term(X, f(X)). Fails. subsumes_term(X, Y), subsumes_term(Y, f(X)). Succeeds.

- NOTES
- 1 The final two examples show that
`subsumes_term/2`

is not transitive. A transitive definition corresponding to the term-lattice partial order is`term_instance/2`

(3.95). term_instance(Term, Instance) :- copy_term(Term, Copy), subsumes_term(Copy, Instance). term_instance(g(X), g(f(X))). Succeeds.- 2 Many existing processors implement a built-in predicate
`subsumes/2`

which unifies the arguments. This often leads to erroneous programs. The following definition is mentioned only for backwards compatibility. subsumes(General, Specific) :- subsumes_term(General, Specific), General = Specific.

C4

## 8.3.9 callable/1

## 8.3.9.1 Description

`callable(Term)`

is true iff`Term`

is a callable term (3.24).

- NOTE — Not every callable term can be converted to the body of a clause, for example
`(1,2)`

.## 8.3.9.2 Template and modes

`callable(@term)`

## 8.3.9.3 Errors

None.## 8.3.9.4 Examples

callable(a). Succeeds. callable(3). Fails. callable(X). Fails. callable((1,2)). Succeeds.## 8.3.10 ground/1

## 8.3.10.1 Description

`ground(Term)`

is true iff`Term`

is a ground term (3.82).## 8.3.10.2 Template and modes

`ground(@term)`

## 8.3.10.3 Errors

None.## 8.3.10.4 Examples

ground(3). Succeeds. ground(a(1, _)). Fails.## 8.3.11 acyclic_term/1

## 8.3.11.1 Description

`acyclic_term(Term)`

is true iff`Term`

is acyclic, that is, it is a variable or a term instantiated (3.96) with respect to the substitution of a set of equations not subject to occurs check (7.3.3).## 8.3.11.2 Template and modes

`acyclic_term(@term)`

## 8.3.11.3 Errors

None.## 8.3.11.4 Examples

acyclic_term(a(1, _)). Succeeds. X = f(X), acyclic_term(X). Undefined. [STO 7.3.3, does not succeed in many implementations, but fails, produces an error, or loops]

C5

`pair`

to the set `ValidType`

.`order`

to the set `ValidDomain`

.These built-in predicates compare and sort terms based on the ordering of terms (7.2).

## 8.4.2 compare/3 – three-way comparison

## 8.4.2.1 Description

`compare(Order, X, Y)`

is true iff`Order`

unifies with`R`

which is one of the following atoms:`'='`

iff`X`

and`Y`

are identical terms (3.87),`'<'`

iff`X`

term_precedes`Y`

(7.2), and`'>'`

iff`Y`

term_precedes`X`

.

Procedurally,`compare(Order, X, Y)`

is executed as follows:

- a) If
`X`

and`Y`

are identical, then let`R`

be the atom`'='`

and proceeds to 8.4.2.1 d.- b) Else if
`X`

term_precedes`Y`

(7.3), then let`R`

be the atom`'<'`

and proceeds to 8.4.2.1 d.- c) Else let
`R`

be the atom`'>'`

.- d) If
`R`

unifies with`Order`

, then the goal succeeds.- e) Else the goal fails.
## 8.4.2.2 Template and modes

`compare(-atom, ?term, ?term)`

`compare(+atom, @term, @term)`

## 8.4.2.3 Errors

- a)
`Order`

is neither a variable nor an atom

—`type_error(atom, Order).`

- b)
`Order`

is an atom but not`<`

,`=`

, or`>`

—`domain_error(order, Order).`

## 8.4.2.4 Examples

compare(Order, 3, 5). Succeeds, unifying Order with (<). compare(Order, d, d). Succeeds, unifying Order with (=). compare(Order, Order, <). Succeeds, unifying Order with (<). compare(<, <, <). Fails. compare(1+2, 3, 3.0). type_error(atom, 1+2). compare(>=, 3, 3.0). domain_error(order, >=).## 8.4.3 sort/2

## 8.4.3.1 Description

`sort(List, Sorted)`

is true iff`Sorted`

unifies with the sorted list of`List`

(7.1.6.5).

Procedurally,`sort(List, Sorted)`

is executed as follows:

- a) Let
`SL`

be the sorted list of list`List`

(7.1.6.5).- b) If
`SL`

unifies with`Sorted`

, then the goal succeeds.- c) Else the goal fails.

- NOTE — The following definition defines the logical and procedural behaviour of
`sort/2`

when no error conditions are satisfied and assumes that`member/2`

is defined as in 8.10.3.4. sort([], []). sort(List, Sorted) :- setof(X, member(X,List), Sorted). /* 8.10.3, 8.10.3.4 */## 8.4.3.2 Template and modes

`sort(@list, -list)`

`sort(+list, +list)`

## 8.4.3.3 Errors

- a)
`List`

is a partial list

—`instantiation_error.`

- b)
`List`

is neither a partial list nor a list

—`type_error(list, List).`

- c)
`Sorted`

is neither a partial list nor a list

—`type_error(list, Sorted).`

## 8.4.3.4 Examples

sort([1, 1], Sorted). Succeeds, unifying Sorted with [1]. sort([1+Y, z, a, V, 1, 2, V, 1, 7.0, 8.0, 1+Y, 1+2, 8.0, -a, -X, a], Sorted). Succeeds, unifying Sorted with [V, 7.0, 8.0, 1, 2, a, z, -X, -a, 1+Y, 1+2] sort([X, 1], [1, 1]). Succeeds, unifying X with 1. sort([1, 1], [1, 1]). Fails. sort([V], V). Undefined. [STO 7.3.3, corresponds to the goal [V] = V. In many implementations this goal succeeds and violates the mode sort(@list, -list).] sort([f(U),U,U,f(V),f(U),V],L). Succeeds, unifying L with [U,V,f(U),f(V)] or [V,U,f(V),f(U)]. [The solution is implementation dependent.]## 8.4.4 keysort/2

## 8.4.4.1 Description

`keysort(Pairs, Sorted)`

is true iff`Pairs`

is a list of compound terms with principal functor`(-)/2`

and`Sorted`

unifies with a permutation`KVs`

of`Pairs`

such that the`Key`

entries of the elements`Key-Value`

of`KVs`

are in weakly increasing term order (7.2). Elements with an identical`Key`

appear in the same relative sequence as in`Pairs`

.

Procedurally,`keysort(Pairs, Sorted)`

is executed as follows:

- a) Let
`Ts`

be the sorted list (7.1.6.5) containing as elements terms`t(Key, P, Value)`

for each element`Key-Value`

of`Pairs`

with`P`

such that`Key-Value`

is the`P`

-th element in`Pairs`

.- b) Let
`KVs`

be the list with elements`Key-Value`

occurring in the same sequence as elements`t(Key, _, Value)`

in`Ts`

.- c) If
`KVs`

unifies with`Sorted`

, then the goal succeeds.- d) Else the goal fails.

- NOTE — The following definition defines the logical and procedural behaviour of
`keysort/2`

when no error conditions are satisfied. The auxiliary predicate`numbered_from/2`

is not needed in many existing processors because`Ps`

happens to be a sorted list of variables. keysort(Pairs, Sorted) :- pairs_ts_ps(Pairs, Ts, Ps), numbered_from(Ps,1), sort(Ts, STs), /* 8.4.3 */ pairs_ts_ps(Sorted, STs, _). pairs_ts_ps([], [], []). pairs_ts_ps([Key-Value|Pairs], [t(Key,P,Value)|Ts], [P|Ps]) :- pairs_ts_ps(Pairs, Ts, Ps). numbered_from([], _). numbered_from([I0|Is], I0) :- I1 is I0 + 1, numbered_from(Is, I1).## 8.4.4.2 Template and modes

`keysort(@list, -list)`

`keysort(+list, +list)`

## 8.4.4.3 Errors

- a)
`Pairs`

is a partial list

—`instantiation_error.`

- b)
`Pairs`

is neither a partial list nor a list

—`type_error(list, Pairs).`

- c)
`Sorted`

is neither a partial list nor a list

—`type_error(list, Sorted).`

- d) An element of a list prefix of
`Pairs`

is a variable

—`instantiation_error.`

- e) An element
`E`

of a list prefix of`Pairs`

is neither a variable nor a compound term with principal functor`(-)/2`

—`type_error(pair, E).`

- f) An element
`E`

of a list prefix of`Sorted`

is neither a variable nor a compound term with principal functor`(-)/2`

—`type_error(pair, E).`

## 8.4.4.4 Examples

keysort([1-1, 1-1], Sorted). Succeeds unifing Sorted with [1-1, 1-1]. keysort([2-99, 1-a, 3-f(_), 1-z, 1-a, 2-44], Sorted). Succeeds unifying Sorted with [1-a, 1-z, 1-a, 2-99, 2-44, 3-f(_)]. keysort([X-1,1-1],[2-1,1-1]). Succeeds unifying X with 2. Pairs = [1-2|Pairs], keysort(Pairs, Sorted). Undefined. [STO 7.3.3. type_error(list, [1-2,1-2,...]) or loops in many implementations.] keysort([V-V], V). Undefined. [STO 7.3.3, corresponds to the goal [V-V] = V. In many implementations this goal succeeds and violates the mode keysort(@list, -list).]

C6

## 7.1.1.5 Witness variable list of a term

The witness variable list of a term`T`

is a list of variables and a witness of the variable set (7.1.1.2) of`T`

. The variables appear according to their first occurrence in left-to-right traversal of`T`

.

- NOTES
- 1 For example,
`[X, Y]`

is the witness variable list of each of the terms`f(X,Y)`

,`X+Y+X+Y`

,`X+Y+X`

, and`X*Y+X*Y`

.- 2 The concept of a witness variable list of a term is required when defining
`term_variables/2`

(8.5.5).## 8.5.5 term_variables/2

## 8.5.5.1 Description

`term_variables(Term, Vars)`

is true iff`Vars`

unifies with the witness variable list of`Term`

(7.1.1.5).

Procedurally,`term_variables(Term, Vars)`

is executed as follows:

- a) Let
`TVars`

be the witness variable list of`Term`

(7.1.1.5).- b) If
`Vars`

unifies with`TVars`

, then the goal succeeds.- c) Else the goal fails.

- NOTE — The order of variables in
`Vars`

ensures that, for every term`T`

, the following goals are true: term_variables(T, Vs1), term_variables(T, Vs2), Vs1 == Vs2. term_variables(T, Vs1), term_variables(Vs1, Vs2), Vs1 == Vs2.## 8.5.5.2 Template and modes

`term_variables(@term, -list)`

`term_variables(?term, ?list)`

## 8.5.5.3 Errors

- a)
`Vars`

is neither a partial list nor a list

—`type_error(list, Vars).`

## 8.5.5.4 Examples

term_variables(t, Vars). Succeeds, unifying Vars with []. term_variables(A+B*C/B-D, Vars). Succeeds, unifying Vars with [A, B, C, D]. term_variables(t, [_, _|a]). type_error(list, [_, _|a]). S=B+T, T=A*B, term_variables(S, Vars). Succeeds, unifying Vars with [B, A], T with A*B, and S with B+A*B. T=A*B, S=B+T, term_variables(S, Vars). Same answer as above example. term_variables(A+B+B, [B|Vars]). Succeeds, unifying A with B and Vars with [B]. term_variables(X+Vars, Vars), Vars = [_, _]. Undefined. [STO 7.3.3, corresponds to the goal [X, Vars] = Vars.]

C7

—`permission_error(access, static_procedure, Pred).`

—`permission_error(modify, static_procedure, Pred).`

C8

## 8.9.5 retractall/1

## 8.9.5.1 Description

`retractall(Head)`

is true.

Procedurally,`retractall(Head)`

is executed as follows:

- a) Searches sequentially through each dynamic user-defined procedure in the database and removes all clauses whose head unifies with
`Head`

, and the goal succeeds.

- NOTES
- 1 The dynamic predicate remains known to the system as a dynamic predicate even when all of its clauses are removed.
- 2 Many existing processors define
`retractall/1`

as follows. retractall(Head) :- retract((Head :- _)), fail. retractall(_).## 8.9.5.2 Template and modes

`retractall(@callable_term)`

## 8.9.5.3 Errors

- a)
`Head`

is a variable

—`instantiation_error.`

- b)
`Head`

is neither a variable nor a callable term

—`type_error(callable, Head).`

- c) The predicate indicator
`Pred`

of`Head`

is that of a static procedure

—`permission_error(modify, static_procedure, Pred).`

## 8.9.5.4 Examples

The examples defined in this subclause assume the database has been created from the following Prolog text::- dynamic(insect/1). insect(ant). insect(bee). retractall(insect(bee)). Succeeds, retracting the clause 'insect(bee)'. retractall(insect(_)). Succeeds, retracting all the clauses of predicate insect/1. retractall(insect(spider)). Succeeds. retractall(mammal(_)). Succeeds. retractall(3). type_error(callable, 3). retractall(retractall(_)). permission_error(modify, static_procedure, retractall/1).

C9

## 8.15.4 call/2..8

These built-in predicates provide support for higher-order programming.

- NOTE — A built-in predicate
`apply/2`

was implemented in some processors. Most uses can be directly replaced by`call/2..8`

.## 8.15.4.1 Description

`call(Closure, Arg1, ...)`

is true iff`call(Goal)`

is true where`Goal`

is constructed by appending`Arg1`

, ... additional arguments to the arguments (if any) of`Closure`

.

Procedurally, a goal of predicate`call/N`

with`N`

≥ 2. is executed as follows:

- a) Let
`call(p(X`

be the goal to be executed,_{1},...,X_{M}), Y_{2}, ..., Y_{N})`M`

≥ 0,- b) Execute
`call(p(X`

instead._{1}, ..., X_{M}, Y_{2}, ..., Y_{N}))## 8.15.4.2 Template and modes

`call(+callable_term, ?term, ...)`

## 8.15.4.3 Errors

- a)
`Closure`

is a variable

—`instantiation_error.`

- b)
`Closure`

is neither a variable nor a callable term

—`type_error(callable, Closure).`

- c) The number of arguments in the resulting goal exceeds the implementation defined maximum arity (7.11.2.3)

—`representation_error(max_arity).`

- d)
`call/N`

is called with`N`

≥ 9 and it shall be implementation dependent whether this error condition is satisfied

—`existence_error(procedure,call/N).`

- e)
`Goal`

cannot be converted to a goal

—`type_error(callable, Goal).`

- 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.## 8.15.4.4 Examples

call(integer, 3). Succeeds. call(functor(F,c), 0). Succeeds, unifying F with c. call(call(call(atom_concat, pro), log), Atom). Succeeds, unifying Atom with prolog. call(;, X = 1, Y = 2). Succeeds, unifying X with 1. On re-execution, succeeds, unifying Y with 2. call(;, (true->fail), X=1). Fails. The following examples assume that maplist/2 is defined with the following clauses: maplist(_Cont, []). maplist(Cont, [E|Es]) :- call(Cont, E), maplist(Cont, Es). maplist(>(3), [1, 2]). Succeeds. maplist(>(3), [1, 2, 3]). Fails. maplist(=(X), Xs). Succeeds, unifying Xs with []. On re-execution, succeeds, unifying Xs with [X]. On re-execution, succeeds, unifying Xs with [X, X]. On re-execution, succeeds, unifying Xs with [X, X, X]. Ad infinitum.## 8.15.5 false/0

## 8.15.5.1 Description

`false`

is false.## 8.15.5.2 Template and modes

`false`

## 8.15.5.3 Errors

None.## 8.15.5.4 Examples

false. Fails.

C10

## 7.1.6.9 List prefix of a term

`LP`

is a list prefix of a term`P`

if:

- a)
`LP`

is an empty list, or- b)
`P`

is a compound term whose principal functor is the list constructor and the heads of`LP`

and`P`

are identical, and the tail of`LP`

is a list prefix of the tail of`P`

.

- NOTE — For example,
`[]`

,`[1]`

, and`[1,2]`

are all list prefixes of`[1,2,3]`

,`[1,2|X]`

, and`[1,2|nonlist]`

.

- a)
`Atom`

is a variable and`List`

is a partial list.

—`instantiation_error.`

- c)
`List`

is neither a partial list nor a list

—`type_error(list, List).`

- d)
`Atom`

is a variable and an element of a list prefix of`List`

is a variable.

—`instantiation_error.`

- e) An element
`E`

of a list prefix of`List`

is neither a variable nor a one-char atom

—`type_error(character, E).`

- a)
`Atom`

is a variable and`List`

is a partial list.

—`instantiation_error.`

- c)
`List`

is neither a partial list nor a list

—`type_error(list, List).`

- d)
`Atom`

is a variable and an element of a list prefix of`List`

is a variable.

—`instantiation_error.`

- e) An element
`E`

of a list prefix of`List`

is neither a variable nor an integer

—`type_error(integer, E).`

- f) An element of a list prefix of
`List`

is neither a variable nor a character code

—`representation_error(character_code).`

- a)
`Number`

is a variable and`List`

is a partial list.

—`instantiation_error.`

- c)
`List`

is neither a partial list nor a list

—`type_error(list, List).`

- d)
`Number`

is a variable and an element of a list prefix of`List`

is a variable.

—`instantiation_error.`

- f) An element
`E`

of a list prefix of`List`

is neither a variable nor a one-char atom

—`type_error(character, E).`

- a)
`Number`

is a variable and`List`

is a partial list.

—`instantiation_error.`

- c)
`List`

is neither a partial list nor a list

—`type_error(list, List).`

- d)
`Number`

is a variable and an element of a list prefix of`List`

is a variable.

—`instantiation_error.`

- f) An element
`E`

of a list prefix of`List`

is neither a variable nor an integer

—`type_error(integer, E).`

- g) An element of a list prefix of
`List`

is neither a variable nor a character code

—`representation_error(character_code).`

C11

- 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).`

- i)
`E`

is a compound term with no corresponding operator in step 7.9.1 c but there is an operator corresponding to the same principal functor with different types such that

- a) the
i-th argument of the corresponding operator has type`Type`

, and- b) the value
`Culprit`

of thei-th argument of`E`

has a different type

—`type_error(Type, Culprit).`

C12

b(X) :- Y = (write(X), X), call(Y).

b(3). Outputs '3', then type_error(callable, 3).

b(3). type_error(callable, (write(3),3)).

C13

## 7.8.9.2 Template and modes

`catch(+callable_term, ?term, ?term)`

## 7.8.9.3 Errors

- a)
`G`

is a variable

—`instantiation_error.`

- b)
`G`

is neither a variable nor a callable term

—`type_error(callable, G)`

## 7.8.9.2 Template and modes

`catch(goal, ?term, goal)`

## 7.8.9.3 Errors

None.

C14

Priority Specifier Operator(s) 400 `yfx`

`div`

200 `fy`

`+`

Evaluable functor Operation `(div)/2`

intfloordiv_{I}`(+)/1`

pos,_{I}pos_{F}

`'div'`

to enumeration in Note. Add to Note:'+', '-' are prefix predefined operators.

intfloordiv:_{I}I×I→I∪ {int_overflow, zero_divisor}

pos_{I}: I → I

intfloordiv(_{I}x,y)= ⌊ x/y⌋if y≠ 0 ∧ ⌊x/y⌋ ∈I= int_overflowif y≠ 0 ∧ ⌊x/y⌋ ∉I= zero_divisorif y= 0

pos_{I}(x) = x

pos_{F}: F → F

pos_{F}(x) = x

C15

## 9.3.8 max/2 – maximum

## 9.3.8.1 Description

`max(X, Y)`

evaluates the expressions`X`

and`Y`

with values`VX`

and`VY`

and has the value of the maximum of`VX`

and`VY`

. If`VX`

and`VY`

have the same type then the valueRsatisfiesR∈ {`VX`

,`VY`

}.

If`VX`

and`VY`

have different types then let`VI`

and`VF`

be the values of type integer and float. The valueRshall satisfyR∈ {`VI`

,`float(VI)`

,`VF`

,undefined}

and the value shall be implementation dependent.

- NOTE — The possible values of
`float(VI)`

include the exceptional valuefloat_overflow∉F(9.1.6).## 9.3.8.2 Template and modes

max(float-exp, float-exp) = float max(float-exp, int-exp) = number max(int-exp, float-exp) = number max(int-exp, int-exp) = integer## 9.3.8.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

- b)
`Y`

is a variable

—`instantiation_error.`

- c)
`VX`

and`VY`

have different type and it shall be implementation dependent whether this error condition is satisfied

—`evaluation_error(undefined).`

- d)
`VX`

and`VY`

have different type and one of them is an integer`VI`

withfloat(_{I→F}`VI`

) =float_overflow(9.1.6) and it shall be implementation dependent whether this error condition is satisfied

—`evaluation_error(float_overflow).`

## 9.3.8.4 Examples

max(2, 3). Evaluates to 3. max(2.0, 3). Evaluates to 3, 3.0, or evaluation_error(undefined). [The result is implementation dependent.] max(2, 3.0). Evaluates to 3.0 or evaluation_error(undefined). [The result is implementation dependent.] max(0, 0.0). Evaluates to 0, 0.0, or evaluation_error(undefined). [The result is implementation dependent.]## 9.3.9 min/2 – minimum

## 9.3.9.1 Description

`min(X, Y)`

evaluates the expressions`X`

and`Y`

with values`VX`

and`VY`

and has the value of the minimum of`VX`

and`VY`

. If`VX`

and`VY`

have the same type then the valueRsatisfiesR∈ {`VX`

,`VY`

}.

If`VX`

and`VY`

have different types then let`VI`

and`VF`

be the values of type integer and float. The valueRshall satisfyR∈ {`VI`

,`float(VI)`

,`VF`

,undefined}

and the value shall be implementation dependent.

- NOTE — The possible values of
`float(VI)`

include the exceptional valuefloat_overflow∉F(9.1.6).## 9.3.9.2 Template and modes

min(float-exp, float-exp) = float min(float-exp, int-exp) = number min(int-exp, float-exp) = number min(int-exp, int-exp) = integer## 9.3.9.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

- b)
`Y`

is a variable

—`instantiation_error.`

- c)
`VX`

and`VY`

have different type and it shall be implementation dependent whether this error condition is satisfied

—`evaluation_error(undefined).`

- d)
`VX`

and`VY`

have different type and one of them is an integer`VI`

withfloat(_{I→F}`VI`

) =float_overflow(9.1.6) and it shall be implementation dependent whether this error condition is satisfied

—`evaluation_error(float_overflow).`

## 9.3.9.4 Examples

min(2, 3). Evaluates to 2. min(2, 3.0). Evaluates to 2, 2.0, or evaluation_error(undefined). [The result is implementation dependent.] min(2.0, 3). Evaluates to 2.0 or evaluation_error(undefined). [The result is implementation dependent.] min(0, 0.0). Evaluates to 0, 0.0, or evaluation_error(undefined). [The result is implementation dependent.]## 9.3.10 (^)/2 – integer power

## 9.3.10.1 Description

`^(X, Y)`

evaluates the expressions`X`

and`Y`

with values`VX`

and`VY`

and has the value of`VX`

raised to the power of`VY`

. If`VX`

and`VY`

are both zero then the value shall be one.## 9.3.10.2 Template and modes

^(int-exp, int-exp) = integer ^(float-exp, int-exp) = float ^(int-exp, float-exp) = float ^(float-exp, float-exp) = float

- NOTE — '^' is an infix predefined operator (see 6.3.4.4).
## 9.3.10.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

- b)
`Y`

is a variable

—`instantiation_error.`

- c)
`VX`

is negative and`VY`

is neither an integer nor a float with an integer value.

—`evaluation_error(undefined).`

- d)
`VX`

is zero and`VY`

is negative

—`evaluation_error(undefined).`

- e)
`VX`

and`VY`

are integers and`VX`

is not equal to 1 and`VY`

is less than -1.

—`type_error(float, VX).`

- f)
`VX`

or`VY`

is a float and the magnitude of`VX`

raised to the power of`VY`

is too large

—`evaluation_error(float_overflow).`

- g)
`VX`

or`VY`

is a float and the magnitude of`VX`

raised to the power of`VY`

is too small and not zero

—`evaluation_error(underflow).`

## 9.3.10.4 Examples

^(0,0). Evaluates to 1. 3^1.0. Evaluates to 3.0. 3^3. 27. 3^27. Evaluates to 7625597484987. 3^3^3. Evaluates to 7625597484987. 2^(-1). evaluation_error(undefined). 1^(-1). Evaluates to 1. 0^0. Evaluates to 1. 2^ -1.5. Evaluates to a value approximately equal to 0.353553.## 9.3.11 asin/1 – arc sine

## 9.3.11.1 Description

`asin(X)`

evaluates the expression`X`

with value`VX`

and has the principal value of the arc sine of`VX`

(measured in radians), that is, the valueRsatisfies

-π/2 ≤R≤ π/2## 9.3.11.2 Template and modes

asin(float-exp) = float asin(int-exp) = float## 9.3.11.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

- b)
`VX`

is greater than 1 or less than -1

—`evaluation_error(undefined).`

## 9.3.11.4 Examples

asin(0.5). Evaluates to a value approximately equal to 0.523599. 2*asin(1). Evaluates to a value approximately equal to 3.14159. asin(2). evaluation_error(undefined).## 9.3.12 acos/1 – arc cosine

## 9.3.12.1 Description

`acos(X)`

evaluates the expression`X`

with value`VX`

and has the principal value of the arc cosine of`VX`

(measured in radians), that is, the valueRsatisfies

0 ≤R≤ π## 9.3.12.2 Template and modes

acos(float-exp) = float acos(int-exp) = float## 9.3.12.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

- b)
`VX`

is greater than 1 or less than -1

—`evaluation_error(undefined).`

## 9.3.12.4 Examples

acos(-1). Evaluates to a value approximately equal to 3.14159. acos(0.5). Evaluates to a value approximately equal to 1.047197. acos(1.5). evaluation_error(undefined).## 9.3.13 atan2/2 – arc tangent

## 9.3.13.1 Description

`atan2(Y, X)`

evaluates the expressions`Y`

and`X`

with values`VY`

and`VX`

and has the principal value of the arc tangent of`VY/VX`

(measured in radians), using the signs of both arguments to determine the quadrant of the valueR, that is, the valueRsatisfies

-π ≤R≤ π## 9.3.13.2 Template and modes

atan2(int-exp, int-exp) = float atan2(float-exp, int-exp) = float atan2(int-exp, float-exp) = float atan2(float-exp, float-exp) = float## 9.3.13.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

- b)
`Y`

is a variable

—`instantiation_error.`

- c)
`X`

is equal to zero and`Y`

is equal to zero

—`evaluation_error(undefined).`

## 9.3.13.4 Examples

atan2(1,0). Evaluates to a value approximately equal to 1.570796. atan2(0,-1). Evaluates to a value approximately equal to 3.14159. atan2(0,0). evaluation_error(undefined).## 9.3.14 tan/1 – tangent

## 9.3.14.1 Description

`tan(X)`

evaluates the expression`X`

with value`VX`

and has the value of the tangent of`VX`

(measured in radians).## 9.3.14.2 Template and modes

tan(float-exp) = float tan(int-exp) = float## 9.3.14.3 Errors

- a)
`X`

is a variable

—`instantiation_error.`

## 9.3.14.4 Examples

tan(0.5). Evaluates to a value approximately equal to 0.5463.

C16

- 1 An error occurs if T is an atom or variable.

- 1 An error occurs if T is a variable or if there is no operation
Fin step 7.9.1 c).

## 9.3.15 pi/0 – pi

## 9.3.15.1 Description

`pi`

has the value of π which is the ratio of a circle's circumference to its diameter.## 9.3.15.2 Template and modes

pi = float## 9.3.15.3 Errors

None.## 9.3.15.4 Examples

pi Evaluates to a value approximately equal to 3.14159.

C17

## 9.4.6 xor/2 – bitwise exclusive or

## 9.4.6.1 Description

`xor(B1, B2)`

evaluates the expressions`B1`

and`B2`

with values`VB1`

and`VB2`

and has the value such that each bit is set iff exactly one of the corresponding bits in`VB1`

and`VB2`

is set.

The value shall be implementation defined if`VB1`

or`VB2`

is negative.## 9.4.6.2 Template and modes

xor(int-exp, int-exp) = integer## 9.4.6.3 Errors

- a)
`B1`

is a variable

—`instantiation_error.`

- b)
`B2`

is a variable

—`instantiation_error.`

- c)
`B1`

is not a variable and`VB1`

is not an integer

—`type_error(integer, VB1).`

- d)
`B2`

is not a variable and`VB2`

is not an integer

—`type_error(integer, VB2).`

## 9.4.6.4 Examples

xor(10, 12). Evaluates to the value 6. xor(125, 255). Evaluates to the value 130. xor(-10, 12). Evaluates to an implementation defined value.

(informative)

Issues still to be resolved

C18

`write_canonical/1`

does not correspond to
7.10.5 Writing a term. The functor `('.')/2`

is written in
functional notation as `.(H,T)`

and not
as `'.'(H,T)`

(three times). The constant `[]`

is written with a space between the opening and closing bracket. It
should be written without the space, because 7.10.5 d demands that it
is output "as the sequence of characters defined by the syntax for the
atom (6.1.2b, 6.4.2)". 7.10.5 f demands for `'.'`

(H,T)
that the atom of the principal functor is output. That means
that `'.'`

is now written according to 7.10.5 d. Since a
single unquoted `'.'`

is misread as the
nonterminal `end`

it must be quoted. In many situations,
it could be disambiguated by using round brackets. However, only
quoting is allowed in 7.10.5 d.write_canonical([1,2,3]). Succeeds, outputting the characters .(1,.(2,.(3,[ ]))) to the current output stream.

write_canonical([1,2,3]). Succeeds, outputting the characters '.'(1,'.'(2,'.'(3,[]))) to the current output stream.

(informative)

Editorial notes

- All error subclauses (X.Y.Z.3) starting with C1: Mdash: —
- C3 8.2.4.1: Theta: θ
- C5 8.4.2: Ndash: –
- C14 9.1.3:
- Times: ×
- Rightwards arrow: →
- Union: ∪
- Floor: ⌊ ⌋
- Inequality: ≠
- Logical and: ∧
- Element of, not in: ∈, ∉

- C15 9.3.11.1, 9.3.12.1, 9.3.13.1, C16:
- Pi: π
- Less or equal: ≤

Ulrich Neumerkel (editor)

Institut für Computersprachen E185/1

TU Wien

Argentinierstr. 8

A-1040 Wien

Austria

Telephone: +43 1 58801 18513

E-Mail: Ulrich.Neumerkel@tuwien.ac.at

August - December 2010

Validated HTML