Semantics & ISO Conformance
patch-prolog implements an ISO subset. This page is the precise statement of how it behaves where the standard leaves room for choices, the few deliberate divergences, and the safety guarantees layered on top. The Language Guide teaches these with examples; this is the reference, with ISO section numbers.
Unification (ISO 8.3.2)
=/2does not perform the occurs check —X = f(X)succeeds, creating a cyclic term, which is the ISO default. Solution display handles cycles safely.unify_with_occurs_check/2is the safe variant: it fails onX = f(X)-style cycles instead of building them.
Float equality
- Unification treats floats by bit pattern, so
NaNunifies withNaN. - This differs from arithmetic comparison, where any comparison involving
NaNis false (=:=,<, etc.).
Arithmetic
moduses ISO floored semantics — the result takes the sign of the divisor (-7 mod 3is2), not the truncated remainder. (remtakes the sign of the dividend.)- Integer overflow is a runtime error (
evaluation_error(int_overflow)), never a silent wraparound. - A
NaNor infinite float result from any operation is a runtime error. - Division by zero (integer or float) is a runtime error.
Standard order of terms (ISO 8.4.2)
Variables < Numbers < Atoms < Compounds
- A float sorts just before an integer of equal value (
1.0 @< 1). NaNsorts after all other floats (a deterministic total order).
Built-in error behavior
number_chars/2andnumber_codes/2raise a syntax error on a non-numeric string (not silent failure), and rejectNaN/infinity.T =.. [F]withFunbound raises an instantiation error (ISO 8.5.3); an empty list is an error, not a failure.functor/3with a negative arity is an error.atom_chars/2is for atoms only;number_chars/2handles numbers.- When
is/2(or an arithmetic comparison) meets a non-evaluable functor, thetype_error(evaluable, Culprit)culprit is a predicate indicatorName/Arity(ISO 8.6) — so a bare atomfooreportsfoo/0, exactly like the compound casefoo(1)reportsfoo/1. (The original v1 interpreter reported the bare atom for the arity-0 case.)
Exceptions
catch/3andthrow/1(ISO 7.8.9, 7.8.10) use the ISO error taxonomy:error(Formal, Context), whereFormalis one ofinstantiation_error,type_error/2,existence_error/2,domain_error/2,evaluation_error/1,permission_error/3,representation_error/1,resource_error/1, orsyntax_error.throw/1of an unbound variable raisesinstantiation_error.catch/3is opaque to cut: a!inside the goal cannot escape the catch frame.
Cut (ISO 7.8.4)
! is transparent through ,, ;, and ->: a cut inside a
disjunction branch cuts the whole clause, including the other branch and
the predicate’s remaining clauses. With m(1). m(2). m(3).:
t(X) :- (m(X), X > 1, ! ; X = fallback).
?- t(X). yields exactly X = 2. Cut remains opaque inside \+/1,
once/1, the condition of ->, and catch/3.
If you used the original patch-prolog interpreter, note this is a change: it treated the cut as local to the disjunction branch (and also produced
X = fallback). patch-prolog follows ISO here, matching SWI and GNU Prolog.
Dynamic and undefined predicates (ISO 7.7.3)
:- dynamic(F/A).declares a predicate whose clauses may be absent. An undefined dynamic predicate fails silently; an undefined non-dynamic predicate raisesexistence_error(procedure, F/A).- A direct call to a predicate defined nowhere is still a well-formed
program: it compiles and raises that (catchable)
existence_errorif reached. Because patch-prolog is a whole-program compiler, such a call can never succeed, soplgc build/run/checkwarn about it andplglshows a squiggle.--deny-undefinedpromotes the warning to a hard error — opt-in strictness above the ISO-compliant default, not a divergence from it. See Compiler Usage.
Safety guarantees (beyond ISO)
- A runaway computation hits a step limit and stops with
resource_error(steps). This error is deliberately uncatchable, so a buggy clause cannot trap its own timeout. This is a safety guarantee, not an ISO requirement.
Not implemented
These are deliberate omissions of the subset:
assert/1,retract/1— the knowledge base is immutable (compiled at build time);:- dynamiconly enables silent-fail, not runtime mutation.op/3— the operator table is fixed; see Operators.- Module system.
- Definite clause grammars (DCG).