Ann: SWI-Prolog 8.1.22

Dear SWI-Prolog user,

SWI-Prolog 8.1.22 is available for download. This release comes with
three major changes. The impact on compatibility should be minimal, but
some regression is not unlikely. Highlights:

  • COMPATIBILITY: The addition of rational numbers required several
    constants in SWI-Prolog.h to be changed. Foreign code is source
    code compatible, BUT NOT BINARY. C code expecting to cover all
    data types should process rational numbers. Binary serialization
    of terms (library(fastrw) and PL_record_external()) is NOT

    The policy is to maintain compatibility at this level, so the above
    is a sad exception.

  • Rational numbers (P/Q) as first class citizens. Support is largely
    compatible with ECLiPSe thanks to the involvement of Joachim Schimpf.
    Implementation of X^Rational by Rick Workman, as well as many of the
    tests. Highlights:

    • Rational numbers satisfy atomic/1 and number/1
    • Integer is a sub-type of rational. The canonical form of
      P/1 is simply P.
    • The syntax is e.g. 1r3.
    • The flag prefer_rationals make all arithmetic that have a precise
      result as a rational number return a rational number instead of a
    • The flag rational_syntax can be used to add 1/3 as preferred syntax.
  • Further implementation of ECLiPSe proposed support for IEEE-754
    floating point arithmetic, allowing arithmetic to produce float
    infinitity, NaN (not a number) and +/- 0.0 as opposed to an
    exception. Default is the ISO Prolog behavior.

  • Support for controlled autoloading, i.e., define specific predicates
    to be autoloaded from specific files. This can also be considered a
    lazy equivalent to use_module/1,2. See autoloaded/1,2 and the
    Prolog flag autoload. Most of the library now uses autoload/2
    rather than use_module/1 or relying on general autoloading from the

    This may have some impact on stability. Libraries can only be auto
    loaded if they have no impact on the global system such as defining
    hooks or setting flags.

    Not all extension packages fully support the new auto loading and
    thus disabling autoloading only works with the core system and some
    packages. Notably the HTTP infrastructure does not yet run without

Finally, some bugs are fixed. Matt Lilley fixed some of the SAML support
for the changes to certificate handling in SSL. A possible memory
corruption in tabling. is fixed. There is a start handling restraints
with tabling: consider results that cannot be computed due to resource
limitations as undefined.

Enjoy --- Jan

SWI-Prolog Changelog since version 8.1.21

  • TEST: Split the core test dir to support concurrent testing better

  • ADDED: Proper exponentiation (** and ^) for X^rat. Implemented by
    Rick Workman.

  • DOC: Make library(simplex) documentation depend on GMP.

  • BUILD: Fixed compilation without GMP

  • ENHANCED: simplify Rat is Expr if Rat is instantiated to a rational

  • MODIFIED: is/2 to unify the first argument instead of using arithmetic
    equality if the left argument is instantiated.

  • FIXED: retractall/1: if decompiling a clause head raises a stack
    overflow the clause is not retracted and retractall/1 succeeded.
    Now retractall raises a resource error exception. Note that it may
    have completed part of its job.

  • ADDED: connect_ugraph/3. Also added docs or complement/2 and

  • ENHANCED: Trapping recursive autoloading, debug/3 and print_message/2.
    Not really ideal yet, but at least a plain system error is avoided
    and some context is provided.

  • FIXED: tty control on not really terminals for Unix-like systems.
    Breaks single stroke interaction in e.g., swipl-win. Jan Burse.

  • AUTOLOAD: Support HTML to text conversion (lynx subdir of library).

  • MODIFIED: Make use_foreign_library/1,2 available as built-in

  • ADDED: Handle require/1 in library(prolog_xref).

  • ENHANCED: Make require/1 cooperate properly with autoloading.
    Non-built-in predicates that are requested using require/1 are
    mapped to autoload/2 calls. As a result, require/1 cooperates with
    all modes of the autoload flags and prevents local (re-)definition
    of required predicates.

  • ENHANCED: library(ansi_term): keep working of library(time) is not

  • MODIFIED: Moved exists_source/1 to built-in to simplify writing
    conditional code.

  • ADDED: Autoload flag values user and user_or_explicit.

  • FIXED: Avoid the toplevel from counting on module inheritance.

  • CLEANUP: Avoid excessive library dependencies in library(shlib).

  • CLEANUP: Enable autoloading for many of the libraries that are almost
    always loading. Reducing the number of file s loaded at startup from
    33 to 12.

  • DEVEL: Avoid library(pure_input) and library(lists) dependency in
    startup file used to run from the build directory. Reduces startup
    time and avoids unnecessary dependencies.

  • ADDED: autoload/1,2, providing a controlled way to perform autoloading
    of both libraries and application files. Controlled by the flag
    autoload, which provides an additional value explicit, disabling
    uncontrolled autoloading while keeping controlled autoloading.
    Some re-organization of the autoload code.

  • MODIFIED: Renamed autoload/0,1 from library(prolog_autoload) to
    autoload_all/0,1 to avoid a conflict with the new autoload/1,2
    directive. As this library is normally used through saved-state
    creation the impact should be minimal.

  • CLEANUP: Removed isDefinedProcedureSource() hack. No longer needed
    since Keri Harris supported reloading as a proper transaction.

  • ENHANCED: print_term/2: integrate parts with Pengines term//2 to
    convert a term into HTML. Used to avoid unnecessary spacing around

  • BUILD: Renamed CMake target prolog_products to core as this is
    a too common step in the development cycle.

  • FIXED: Properly initialise the rational tripwire in a new thread.

  • ADDED: nexttoward/2 function.

  • ADDED: ECLiPSe compatible IEEE 754 floating point arithmetic. This
    commits provides four flags to make floating point arithmetic return
    special values (Inf, NaN, -0.0) rather than raising an exception
    and supports setting the float rounding mode. Not all arithmetic
    has been updated to fully suppor these flags.

  • ADDED: Extend (tabling) tripwire system to deal with very large
    rational numbers.

  • MODIFIED: rdiv/2 function to throw a type error if an argument is
    a float.

  • DOC: rational numbers are always decimal.

  • ADDED: abolish_private_tables/0 and abolish_shared_tables/0.

  • TEST: Rational tests by Rick Workman.

  • FIXED: rational/3 (possible crash)

  • MODIFIED: Sync rational syntax with ECLiPSe, always accepting
    1r3 and 1/3 if rational_syntax is set to natural.

  • FIXED: PL_term_type() return PL_RATIONAL. This renumbers the PL_*
    types in SWI-Prolog.h! We accept this as a lot of the header has
    changed anyway for supporting rational numbers. Rick Workman.

  • FIXED: MPQ handling for in skipArgs().

  • DOC: Updated docs for the (/)/2 (division) function.

  • DOC: PL_is_rational().

  • CONFIG: Add rational settings to customize/

  • FIXED: in_temporary_module/3: avoid possible races.

  • FIXED: Avoid race if two threads try to create a temporary module
    with the same name.

  • ENHANCED: Reduce the risk that the random/1 function start at the same
    value in multiple threads if we do not use the GMP random functions.

  • MODIFIED: Changed rational defaults to be conservative, i.e., set
    prefer_rationals to false and rational_syntax to compatibility.
    Documentation invites people to evaluate the defaults we would like to
    see in the future, prefer_rationals = true and rational_syntax =

  • FIXED: Pushing rational arguments when using optimized arithmetic.

  • DOC: statistics/2, thread_cputime

  • FIXED: Q/P with MPZ numbers still yielded a float if prefer_rationals
    is true.

  • ADDED: PL_get_float() to succeed on MPZ and MPQ numbers (already
    did integers).

  • FIXED: is/2 on instantiated rational, e.g. 1/3 is 1/3.

  • FIXED: Saving rationals to QLF files (thus also saved states)

  • FIXED: Compilation of MPZ/MPQ integers in the head

  • ADDED: Support rationals in library(prolog_colour).

  • ADDED: Prolog flag rational_syntax with values natural,
    compatibility and none

  • ADDED: rational_syntax flag as module-sensitive flag with values
    natural, compatibility and none.

  • MODIFIED: Renamed rational flag to prefer_rationals.

  • PORT: Allow building the system without GMP.

  • FIXED: Make rational branch compile without gmp

  • DOC: Rational number support.

  • ADDED: list_rationals/0,1

  • DOC: The Prolog flag rational

  • ADDED: ECLiPSe compatible functions numerator/1 and denominator/1.

  • MODIFIED: ^ now does rational arithmetic.

  • TEST: Generalize tests to deal with rational numbers.

  • ADDED: Prolog flag rational.

  • MODIFIED: PL_get_nchars() and PL_get_wchars() to support rationals.
    This changes the flag values for the these functions (CVT_* and BUF_*),
    making binary extensions incompatible. Source code remains compatible.

  • MODIFIED: Added rational numbers as first class atomic citizens rather
    than a term numerator/denominator. Reserve a bit to distinguish
    mpz and mpq on the stack

  • FIXED: Use-after-free error when dealing with updated answers for
    answer subsumptive tabling.

  • FIXED: Unification from trie nodes. Could leave the argument stack
    in a modified state.

  • FIXED: Memory leak when unifying a trie term fails due to an exception.

  • FIXED: Possible crash in tabling after an exception during tabling.

  • ADDED: Declare not_exists/1 from tabling as safe.

  • ADDED: Tabling meta predicates to xref.

  • XSB: Pass on tabling restraint options in the compatibility library.

  • DOC: More work on the documentation for restraints.

  • FIXED: delays_residual_program/2 if conditions is not ground.

  • ADDED: Partial support for tabling restraints. Currrently deals with
    max_answers(Count) and provides the tabling options and Prolog flags
    to deal with radial restraints.

  • MODIFIED: format_types/2 now throws an exception if the format
    is invalid.

  • ADDED: list_format_errors/0,1, by default called from check/0.

  • FIXED: list_redefined/0: suppress messages for table aux predicates.

Package archive

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.

Package clib

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.

  • ADDED: support autoload for library(time).

Package clpqr

Package cql

  • PORT: Allow compiling without rational number support.

  • FIXED: Missing argument in format/2 call.

Package http

  • FIXED: append argument order in auth_expansion authentication did
    not expand the request because the appnd in auth_expansion failed
    (wrong argument order)

  • FIXED: library(http_open): Include the path/1 in the parsed URL
    so that http_cookie can correctly use it to identify cookies with
    specific paths to be included in requests. Failure to include path/1
    means that http_cookie will default to / which is not correct

  • FIXED: Communicated HTTP status code if this was set using the CGI
    Status: code command.

  • TEST: Make test robust against rationals.

  • FIXED: Excess argument in debug/3 call.

Package jpl

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.

  • COMPAT: Updated PL_* and CVT_* constants due to renumbering to
    include rationals.

Package libedit

  • CLEANUP: Make libedit use the new autoloader to reduce its footprint,
    notably if it is not used.

Package ltx2htm

  • ENHANCED: handle LaTeX ``word’’ and `word’.

Package paxos

  • FIXED: Fixed format template in debug/3 message

Package pengines

  • ADDED: Support rational numbers in term --> HTML conversion.

  • FIXED: term//2 from library(http/term_html) to use priority 999 for
    list elements.

Package pldoc

  • FIXED: Help index generation for division functions (/ and //).

  • ADDED: Determinism mode undefined to deal with the well founded
    semantics status.

  • FIXED: PlDoc rendering for source code: too many arguments for

Package protobufs

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package

Package semweb

  • MODIFIED: Turtle parser: if input is a text stream assume that the
    encoding is correct. This avoids a permission error if the stream
    (for example) originates from open_stream/2.

Package sgml

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.

  • FIXED: library(c14n2): Preserve namespaces belonging to attributes
    in the element when canonicalizing.

Package ssl

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.

  • FIXED: Update library(saml) to use new crypto API

  • FIXED: library(xmldsig) updated to use the new certificate API and
    use the nominated canonicalization method

  • FIXED: library(saml) needs to be updated to use the new certificate
    API - in particular, two certificates cannot be compared using
    unification anymore

Package xpce

  • FIXED: Browsing in right panel of profiler.

  • AUTOLOAD: Get basics of PceEmacs and graphical debugger working with
    disabled autoloading.

  • AUTOLOAD: Working on autoload-safe operation for xpce and PceEmacs.

  • FIXED: Graphical debugger: avoid duplicate option key expose
    (crashes new print_term/2).

  • FIXED: force float arithmetic as xpce cannot handle rationals (yet).

  • ADDED: PceEmacs to support rationals

Package yaml

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.

Package zlib

  • AUTOLOAD: Add explicit autoload/2 statements to all libraries provided
    by this package.


Are the new flags documented somewhere. I checked current_prolog_flag/2 documentation,
but they are not yet listed. But it seems that flags are already there, like for example:

SWI-Prolog (threaded, 64 bits, version 8.1.22)

?- current_prolog_flag(float_rounding, X).
X = nearest.

Interestingly concerning ECLiPSe Prolog, they seem to only exist on paper.
I get for example with -L iso command line:

ECLiPSe Version 7.0 #52 (x86_64_nt)

[eclipse 1]: current_prolog_flag(float_rounding, X).
No (0.00s cpu)

Using get_flag/2 in non-iso mode doesn’t help either.
So I even don’t know how to compare with ECLiPSe Prolog.

Yes, but the float_rounding flag escaped documentation. Docs are in the git version.

ECLiPSe has bounded reals (breal) that provides an elegant alternative to playing with the float rounding flag. I think ECLiPSe doesn’t implement mapping evaluation_error to NaN either (yet).
@ridgeworks needs these and following this proposal makes sense to me. Joachim Schimpf knows a lot more about floats than I do :slight_smile:

SWISH now runs 8.1.22 with some additional patches wrt. comparison to NaN and two work-in-progress notebooks dealing with rationals and floats SWISH Prolog tutorials

Very good progress on the arithmetic side; certainly more than I expected a couple of weeks ago.

As noted this is still a work in progress. I’ve now got over 300 unit test cases (assertions) with a little over 50 failing. Nothing catastrophic; mainly sign issues on IEEE special values and probably much fewer root causes than failures. I’ll put a more detailed report on the IEEE 754 discussion over the next couple of days.

For those interested in trying the nan value for the float_undefined flag, be aware that it’s behavior may appear quite illogical. It’s a number which is not a number. So nan =\= nan is true; all the other arithmetic comparisons which have a nan argument are false. But nan == nan (identity) at the term level.

Also for all number(X), X =:= min(X,nan) and X =:= max(X,nan).

The purpose of a nan continuation value is to avoid testing the result of each subexpression in a larger expression; just check the final result. But it should probably be treated as an application level error at that point and discarded. It probably isn’t the answer you want.

I am a bit surprised. After all, the resulting X is tainted. Checking the ECLiPSe proposal we find this, so I think we should go for a X instead of NaN.

min(NaN,Any) Any see below
max(NaN,Any) Any see below

IEEE 754 (2008) specifies minNum() and maxNum() in this way, i.e. preferring the non-NaN argument. [KAH] says there are good reasons to do so, but that they are disputed.

Also from C11:

F.10.9.2 The fmax functions
1 If just one argument is a NaN, the fmax functions return the other argument (if both
arguments are NaNs, the functions return a NaN).

F.10.9.3 The fmin functions
1 The fmin functions are analogous to the fmax functions (see F.10.9.2).

I agree it does seem weird, but there’s nothing normal about NaN’s.

I’m seeing some warnings/errors that I didn’t see before:

Warning: /usr/lib/swi-prolog/library/
Warning:    Variable not introduced in all branches: Arg

ERROR: /usr/lib/swi-prolog/library/ Syntax error: Operator expected
ERROR: /usr/lib/swi-prolog/library/ Syntax error: Operator expected
% Disabled autoloading (loaded 75 files)

The “Disabled autoloading” seems to be because of one instance of :- set_prolog_flag(autoload, false). … it would be nice if this warning had some source information with it. The error message is also related.
I haven’t tracked down why prolog_codewalk is being loaded … is there a way to trace the "load_module"s and similar directives?

Compiling gets stuck generating

[....regular cmake stuff here...]
Cleaning... 0 files.
PGO: Compiling instrumented version
[1706/1707] Generating ../home/library/
<---- stuck here, even after 20 minutes --->

I am using the following to compile (from archlinux PKGBUILD bash script):

#...some vars and other PKGBUILD stuff before this...
 mkdir -p build
  cd build
  cmake ../swipl-$pkgver \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_C_FLAGS="$CFLAGS -fPIC -ffile-prefix-map=$PWD= -w" \
    -DLIBEDIT_LIBRARIES=/usr/lib/ \
    -DLIBEDIT_INCLUDE_DIR=/usr/include \
    -G Ninja

Is there a problem with the ?

EDIT: this was working fine for 8.1.21; the compilation above was done using a clean source tree.

EDIT2: Seems the problem happens only when the cmake build directory is at the same as the swipl-8.1.22 directory.

This is indeed the case. The code was also wrong. In general though, this message is by default disabled as it produces far too many false positives. It has nothing to do with autoloading AFAIK.

This has to do with loading order and missing (). Pushed fixes for both.

See source_file_property/2, property load_context(Module, Location, Options).

Thanks. The Macports build bot also complains about this issue. I haven’t seen it in any test nor for building the system on various servers or the Ubuntu PPA build. Macports insists in building in the source tree though (not making a build dir). Seems the level of the build directory is involved in this. No clue how this relates to the changes in this version, but if this reproduces it should be possible to find out.

AFAIK, the only change I made was upgrading from 8.1.21 to 8.1.22. So, the message might have nothing to do with autoloading, but it probably has something to do with 8.1.21->8.1.22.

As for the “% Disabled autoloading (loaded 75 files)” message – is it possible to add something to indicate what caused that message? Is it triggered by set_prolog_flag(autoload,false) or by something else?

Sure. The library changed :slight_smile:

This message is only triggered by disabling autoloading completely.

Pushed a fix for that.

Thanks! I think you are still the most responsive maintainer in the open source world :slight_smile:


I’ve just upgraded from 7.6.4 and it appears I need to update a lot of my predicates that rely on unification of float terms

fraction(A rdiv B, A, B).

?- fraction(2r3, A, B). 

Is there an easy replacement to unify with 2r3 ?

Sorry if the question doesn’t make sense. I am not fluent in either English or Prolog!

The notation 2r3 has been added recently, then your code should continue to work unchanged, I think…

?- X rdiv Y = 2r3.

?- X rdiv Y = 2 rdiv 3.
X = 2,
Y = 3.

It isn’t, unfortunately, as you’re kind of found in your first example. And I’m not sure how to unify with the new notation.

?- set_prolog_flag(prefer_rationals, true).

?- A is 2/3.
A = 2r3.

?- A is 2/3, A = N rdiv D.

?- rational(2r3).

?- rational(2 rdiv 3).

As of V8, rational numbers are primary citizens and thus a rational is atomic, a number and a super-type of integers. There is rational/3 to break it into pieces, so

 ?- A is 2/3, A = N rdiv D.


 ?- A is 2/3, rational(A, N, D).

That does require updates to your code. With some luck some clever replacements may do the trick. Possibly goal_expansion/2 can also do the trick. As is, rational/3 does not work in mode rational(-,+,+). If adding that mode solves a real problem we can add that.

P.s. better upgrade to 8.4 or 8.5 in one go :slight_smile:

1 Like