Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Operators

patch-prolog supports the standard prefix and infix operators of ISO Prolog. Postfix is not supported — see Postfix is unsupported, by design below.

op/3 (user-defined operators) is also not supported. The operator table below is the complete fixed set the engine recognizes.

Canonical form is always available

Every operator term is sugar for a compound. Anything you can write with an operator, you can write in functor notation:

Operator formCanonical form
2 + 3+(2, 3)
- a-(a)
\+ Goal\+(Goal)
H = [X|T]=(H, '.'(X, T))
X is 6 /\ 3is(X, /\(6, 3))

The arithmetic evaluator, unification, and clause resolution see the compound form — operator syntax is purely a reader-level convenience. If you ever hit a parse-precedence surprise, the canonical form will always parse unambiguously.

Prefix operators

OpTypePrecMeaning
-fy200Arithmetic negation. Folds for literal numbers: -3 reads as the integer -3, not the compound -(3).
+fy200Identity / explicit positive sign. Folds for literal numbers: +3 reads as 3. For non-literals, builds +(X).
\fy200Bitwise complement (evaluable in is/2). No folding — \3 reads as the compound \(3).
\+fy900Negation as failure (control construct).

! (cut) is a 0-arity atom, not a prefix operator — it does not take an argument.

The clause and directive markers :- and ?- are recognized by the parser but are not user-redefinable operators:

  • Head :- Body. — clause separator (infix at the top level of a program).
  • :- Directive. — directive prefix (e.g. :- dynamic(foo/1).).
  • ?- Goal. — query prefix (optional, accepted by the query reader).

Infix operators

Listed from loosest binding to tightest. Associativity uses the standard fixity codes (xfx non-associative, xfy right-associative, yfx left-associative).

OpTypePrecMeaning
;xfy1100Disjunction (also the if-then-else outer in (C -> T ; E)).
->xfy1050If-then. Only meaningful inside a parenthesized goal expression.
,xfy1000Conjunction.
=xfx700Unification.
\=xfx700Not-unifiable.
==xfx700Term identity (no unification).
\==xfx700Term non-identity.
isxfx700Arithmetic evaluation.
<xfx700Arithmetic less-than.
>xfx700Arithmetic greater-than.
=<xfx700Arithmetic less-or-equal. (Note: =<, not <=.)
>=xfx700Arithmetic greater-or-equal.
=:=xfx700Arithmetic equality.
=\=xfx700Arithmetic inequality.
@<xfx700Standard term ordering: less.
@>xfx700Standard term ordering: greater.
@=<xfx700Standard term ordering: less-or-equal.
@>=xfx700Standard term ordering: greater-or-equal.
=..xfx700Univ: term ↔ list decomposition.
+yfx500Addition.
-yfx500Subtraction.
/\yfx500Bitwise AND.
\/yfx500Bitwise OR.
xoryfx500Bitwise XOR.
*yfx400Multiplication.
/yfx400Float division (ISO 9.1.4 — always returns a float, even for integer operands).
//yfx400Integer division (truncates toward zero).
modyfx400ISO modulo (sign follows divisor).
remyfx400ISO remainder (sign follows dividend).
divyfx400Floor division (rounds toward −∞; differs from // when signs disagree).
<<yfx400Shift left (integer).
>>yfx400Shift right (integer).
**xfx200Float power (always returns a float).
^xfy200Integer power for Int ^ Int with non-negative exponent; float otherwise.
:xfy200Module qualifier (parser-only; no module system, but the term parses and round-trips).

Postfix is unsupported, by design

patch-prolog recognizes no postfix operators and none are planned.

Three reasons:

  1. Postfix is pure syntactic sugar — zero expressive power. A term written with a hypothetical postfix yf operator (X yf) is exactly the compound yf(X). The form unification and resolution see is identical to what functor notation already gives you.
  2. Standard Prolog ships no built-in postfix operators. ISO 13211-1 defines the postfix types (xf, yf) so a program could declare one via op/3, but the standard operator table itself contains zero postfix entries.
  3. op/3 is not supported. Without op/3 there is no path to a user-defined operator of any fixity, so the choice is moot anyway.

Teaching materials sometimes present postfix alongside prefix and infix for symmetry. Treat that as a description of the language family; this engine is a deliberate subset.

Known quirks

  • Literal folding. -3 and +3 read as the integer literals -3 and 3, not the compounds -(3) and +(3). To force the compound form (e.g. when pattern-matching with functor/3), use a non-numeric operand: - a, + X. \3 is not folded — it parses as \(3).
  • ! is an atom, not an operator. ! X is a syntax error; if you want cut followed by X, write !, X.
  • -> outside parens. The if-then operator is only meaningful inside a parenthesized goal expression. ( Cond -> Then ; Else ) is the idiom; bare Cond -> Then at clause-body level may not parse the way you expect.
  • / is always float. Per ISO 9.1.4, 10 / 3 evaluates to 3.3333..., not 3. Use // (truncating) or div (floor) for integer division.
  • =< vs <=. The Prolog convention is =<. Writing <= is a parse error.

See also

  • Language Guide — how these operators are used (terms, arithmetic, control, unification).
  • Builtin & Stdlib Reference — the predicates the comparison, arithmetic, and term-order operators name.
  • ISO/IEC 13211-1:1995, §6.3.4 (operator notation) and §8.7 (arithmetic).