Ann: SWI-Prolog 8.4.3 (stable)

Dear SWI-Prolog user,

There is finally an update for the SWI-Prolog stable series: 8.4.3. Many
things happened in the development branch, including patches that
introduced many changes and (thus) complicate backporting. Roughly,
the 8.4.3 release picks most patches from the development version that
have no or very low compatibility impact. Some big changes are notably


  • All the work on allowing to shutdown and re-create Prolog in the
    same process (PL_cleanup()). Besides allowing to restart, this
    work improved memory management a lot. It is considered too
    involved to include in the stable version.
  • Most of the work by @dmchurch preparing for a better WASM version,
    notably on signal handling.
  • Conditional breakpoints by @oskardrums (because it involves an
    interface change).
  • Low level coverage data collection
  • This version also stays at pcre version 1.

Still, there are some highlights

  • Many updates, notably to the tools, for det/1, => rules, $/0
    and $/1.
  • Fixes to dif/2
  • Fixed many Windows portability issues
  • Fixed several memory leaks (still, use the development version
    is this is critical to you).
  • Improved UDP socket support.
  • PPA now have debug symbols.

Although all tests pass, regression as a result of backporting many
patches is not unlikely. Please test and report so they can be fixed
and we can release 8.4.4.

Two patches have already been applied to git and the Ubuntu jammy

  • Revert the last patch on show_coverage/1,2 that relies on the new
    data collection. This implies show_coverage/1,2 is broken on all
    versions except for the jammy PPA.

  • Include the latest patches for the SSL package. Some portability
    patches were omitted, one breaking the tests in the package build
    environment on Ubuntu jammy.

    Enjoy — Jan

SWI-Prolog Changelog since version 8.4.2

  • FIXED: Issue#114: Windows getenv/2 may return additional garbage
    (typically an extra \u0000 character at the end of variables of
    1023 bytes or longer because the 0-byte is not added. Paul Singleton.

  • FIXED: Several issues to consistently deal with buffer sizes in

  • FIXED: Sfprintf(): handling of ENC_WCHAR() encoding.

  • ENHANCED: Sfprintf(): allow Unicode characters for %c

  • ENHANCED: PL_record_external() deal with records > 2Gb on 64 bit

  • FIXED: write_term/2 and friends handling of embrace of operants that
    are operators for partial writes.

  • FIXED: no space is required between a space and (.

  • FIXED: write_term/2 and friends: do not embrace writing a single atom
    if this is an operator and the priority(Priority) option is given.

  • DOC: Create links for S*() function references

  • DOC: Started documenting SWI-Stream.h

  • FIXED: Sgets() handling of non-0-terminated output from Sfgets().

  • DOC: ord_intersection/2 is semidet.

  • DIST: Fixed rmd160 generation for scripts/update-macports

  • FIXED: write_term/2 with numbervars and variable_names (#866)

  • FIXED: Issue#993: possible deadlock when loading a module. Reported by
    Sean Leather.

  • FIXED: eliminated a spurious choice-point in sub_atom/5 Reported in
    Careful with sub_atom/5 and feature request last_sub_atom/5

  • DOC: enhance documentation for det/, $/1 and $/0, describing the
    exceptions and how trap/1 can be used to make the debugger act quickly.

  • FIXED: explain/1: hide references from prolog_xref:called/5

  • FIXED: Have breakpoints cleared in the UI when the clause that holds
    them is removed during a reload of the file.

  • FIXED: breakpoint_property/2: fixed character_range property

  • ENHANCED: Issue#17: reverse/2 to be deterministic if second argument
    is a proper list. Ulrich Neumerkel.

  • TEST: Added STO restriction as this test involves rational trees.

  • FIXED: Issue#122: dif/2: or-node simplification.

  • FIXED: Possible deadlock enumerating predicates from a source file.

  • FIXED: Avoid Unicode quote in library(aggregate) comment

  • FIXED: LaTeX conflict preventing building the PDF docs

  • FIXED: Possible race condition importing into a module. Can lead to
    termination on a system error.

  • FIXED: Make source layout handling aware that debug/3 and assertion/1
    may be removed by the optimizer.

  • ADDED: Sopen_iri_or_file() API to allow foreign code to access the

  • ENHANCED: require/1 to simply import if the target module is already
    loaded. Reduces startup time.

  • FIXED: fd_degree/2 and fd_set/2 for constant integer arguments.

  • DOC: added cross-references from absolute_file_name/3 to

  • ADDED: library(sandbox): allow declaring prolog flags as safe.

  • ADDED: open/4 option newline(Mode).

  • DOC: Updated clause/2.

  • FIXED: Memory leak reading Unicode queries at the toplevel.
    Peter Ludemann.

  • ADDED: library(sandbox): support predicate_property/2

  • DOC: PL_atom_wchars(): wrong types

  • ADDED: library(sandbox): functor/4.

  • FIXED: Possible wrong Windows drive letter normalisation.

  • PORT: msys2, detect libdb-6.0.dll from libdb.a

  • PORT: Msys2/clang64

  • PORT: MSYS2/clang64 the dll name appears several times in the “.a”
    file, select the first appearance

  • FIXED: swipl-ld didn’t pass -I for SWI-Prolog.h any more.

  • PORT: Sopenmem() to use SIO_NL_POSIX. All internal strings use
    POSIX \n to delimit lines. @mgodan1.

  • FIXED: copy_term/4 to handle cyclic terms for the first argument.
    Also proper recovery in case of a memory overflow.

  • DOC: open/3,4 pipe(Command) limitations.

  • PORT: open/3,4 on Windows: use clib popen() instead of the broken
    emulation in src/os/windows/popen.c

  • FIXED: Clause position management for h => X = ..., rest_body:
    the unification is not inlined.

  • FIXED: swipl-ld: access to uninitialized memory

  • FIXED: current_predicate/1 bug in updating module reference count
    that may cause temporary modules not to be destroyed. Notably affects

  • DOC: Add transpose/2 to the clpfd docs.

  • FIXED: bulk mode for transactions was not actually passed.

  • FIXED: retract in nested transaction of a clause asserted in the
    outer transaction to properly reclaim the clause.

  • FIXED: fast_term_serialized/2: memory leak.

  • FIXED: Avoid transaction rollback to be recorded (memory leak).

  • FIXED: Avoid leaking a trie node on concurrent insert of the same

  • ENHANCED: if we created a supervisor that is equal to the existing,
    discard the new one. This may happen if multiple threads create
    a supervisor. Leaks memory as we cannot safely discard a running

  • FIXED: consistent use of tree pool allocation.

  • FIXED: Initial atom table was allocated twice. Also set the initial
    size for this table to be big enough to load the initial state,
    avoiding two rehash operations.

  • FIXED: Reclaim argument admin for destroyed predicates.

  • FIXED: Typo on, harming operation without xpce.
    Johan Romme.

  • ADDED: Make encoding accessible by name using PL_atom_to_encoding()
    and PL_encoding_to_atom()

  • DOC: tabling po(Compare) argument.

  • DOC: refer to pack debug_adapter in the GNU Emacs Interface page

  • FIXED: dif/2 not firing after unifying with other attributed variables.

  • FIXED: call_residue_vars/2: possible spurious reported variables
    because the trail entry was removed but the variable was not reclaimed
    due to a frozen stack.

  • ADDED: on_signal/3 now takes value ‘ignore’ This allows for requesting
    the SIG_IGN disposition, and also unifies the SIGPIPE behavior with
    the other initially-prepared signals. Technically, this could be
    considered a backwards-incompatible change. However, for this to
    actually affect someone’s working code, they would have to

    1. Redefine the system predicate ignore/1,
    2. Call on_signal(Sig, _, ignore), AND
    3. Expect ignore(Signal) to do something besides ignoring Signal;

    and in that case I think we can all agree they’ve brought this trouble
    upon themselves. :slight_smile:

    Also adds SIGPIPE’s default disposition to the docs.

  • MODIFIED: fixing SIG_PROLOG_OFFSET at 32, per docs This also introduces
    a set of macros to interact with the pending signal mask which should
    hopefully ease refactoring if and when we change which signals swipl
    supports, like adding support for system signals over 31.

  • MODIFIED: switching core libswipl code to C11 This allows for a
    standards-compatible implementation of the LD macros that is guaranteed
    to compile down to a simple reference even at -O0. I’ve also added
    some code that, at least in my testing, makes print LD work again
    in GDB and any debugger that uses it as a backend.

  • PORT: adding O_SIGNALS define in config.h This provides a single define
    to check if Prolog’s signal-handling is enabled, rather than checking
    each of HAVE_SIGNAL etc. This also makes the existence and use of
    GD->signals.sig_alert consistent on whether SIG_ALERT is defined.

  • PORT: Do not depend on SIGINT if signal support is disabled.

  • PORT: Get optional symbols via weak linking This unifies the tcmalloc
    and ptmalloc linking code and also allows systems without dlsym(),
    like WASM, to expose the malloc-implementation predicates, so long
    as the linker is capable of resolving weak symbols.

  • PORT: Issue#939: TLD_alloc() undefined error on Win32. @mgodan.

  • FIXED: Gui tracer for inlined unification with SSU clauses, e.g.
    p(X), X = aap(N) => writeln(N).

  • FIXED: Allow tracing test predicates that are inlined into the VM.

  • FIXED: Make gui tracer handle inlined head unifications.

  • FIXED: rule/3 for => rules that have the unification moved into the
    head and listing/1 for such SSU clauses.

  • FIXED: Preproc/build errors Adding a couple GCC builtins to the config
    tests, using them to force short-circuiting of _LD_WITH_FALLBACK even
    in low-optimization modes (e.g. Clang in DEBUG configuration).

    Also adding a few missing-but-used defines to config.h.cmake
    and fixing an unbalanced #ifdef pair that got added in f3b79d6.

  • FIXED: Consider /0 a breakable instruction. This fixes the debugger for clauses holding /0.

  • FIXED: Avoid instantiation error on =…/2 when analysing clause
    positions with incomplete information.

  • SANDBOX: SWISH issue#147: Allow for copy_term/4.

  • FIXED: Allow retry from the body of => rules.

  • ENHANCED: Avoid tracing inside spy/1, nospy/1 and related debug
    control predicates.

  • FIXED: Issue#935: package manager: download location of git archives

  • DOC: Remove obsolete reference of break/1 trace port

  • FIXED: Issue#963: possible undefined to_list/2 in message
    handling. Caused by wrong backport.

Package clib

  • FIXED: process_create/3: allow env([]).

  • FIXED: process_create/3: Windows: make environment(List) inherit the
    environment as documented.

  • FIXED: process_create/3: double env/environment option raised an
    assertion failure. Now raises a permission error.

  • TEST: Disable CGI test for Windows because environment variables set
    using Prolog setenv/2 are not visible in the CRT runtime function
    getenv(). This either requires updating the CGI module to use the
    Win32 environment API or start a new process for reading the CGI input.

  • TEST: Cross-platform null in stream_input

  • ENHANCED: Close sockets that are reclaimed because their blob is
    being garbage collected.

  • TEST: Basic tests for udp_send/4 and udp_receive/4.

  • ADDED: udp_send/4: as(Type) option.

  • ADDED: udp_receive/4 as(term) to parse the message into a Prolog

  • ADDED: udp_receive/4 and udb_send/4: encoding(Enc) option to affect
    the encoding.

  • CLEANUP: Use new PL_atom_to_encoding() to avoid code duplication.

  • TEST: Disable test killing non-existing process on MacOS. Can deliver
    SIGTERM to Prolog itself when executed concurrently.

  • TEST: test_af_unix works without signals

  • FIXED: memory_file_to_atom/3: do not trap an assertion if the encoding
    is not supported but raise a domain error instead.

  • FIXED: tcp_connect/3 and other predicates that rely on
    nbio_get_sockaddr() to initialize the unused part of the address.

Package clpqr

  • FIXED: Missed module rename for attribute_goals//1. Reported by
    Paul Bredbury.

  • MODIFIED: renamed internal modules with names that may easily conflict
    to clpqr_ followed by the old name. As as result the attributes
    on variables have also be renamed. Should not affect code unless
    applications use explicitly qualified calls or directly manipulate
    the attributes.

  • ENHANCED: Faster dump/3 implementation.

Package cpp

  • ADDED: PlFunctor class conversion and comparison to functor_t

  • TEST: Add Unicode/wchar tests

  • TEST: PL_atom_wchars print

  • TEST: Added foreign language interface regression tests

Package http

  • ADDED: Hook html_write:html_header_hook/1 to emit additional HTTP
    headers for HTML pages.

  • ADDED: http_open/3: option raw_encoding(+Encoding) to prevent deconding
    certain (transfer) encodings.

  • ADDED: http_open/3: option raw_headers(-Strings) to get access to
    the unparsed HTTP header as a list of strings.

  • ADDED: http_post_data/3: support string(String) and string(Type,
    String) simlar to atom(String) and atom(Type, String). Avoids creating
    a potentially large garbage atom.

  • ENHANCED: Reduce overhead of session GC

  • PORT: Make CGI tests succeed on Windows. @mgodan1

  • UPDATED: Bundled jquery from jquery-1.11.3 to 3.6.0.

  • REVERT: It is not a good idea to handle file input not as binary.

  • FIXED: HTTP multipart message handling: set encoding for uploading a
    file and ensure that switching to octet restores the binary mode.
    After report by Mike Elston.

  • TEST: Avoid non-termination if there is an error.

  • TEST: Resolve timing issues in

  • FIXED: http_stop_server/2 to avoid leaking socket handles for
    connections accepted during shutdown.

  • FIXED: Ping and pong frames may contain non-utf8 “Application Data”

Package libedit

  • MODIFIED: Don’t do any signal-handling if O_SIGNALS is disabled

Package mqi

  • FIXED: Residual constraints on variables are now returned in a special
    binding variable called ‘$residuals’ MQI Prolog change only, no
    changes to the language clients (e.g. the swiplserver Python library)
    are required.


    with server.create_thread() as client:

                result = client.query("member(X, [A, B, C]),

put_attr(X, my_module, x).")
[{‘$residuals’: [{‘args’: [‘A’, ‘my_module’, ‘x’],
‘functor’: ‘put_attr’}], ‘X’: ‘A’, ‘A’: ‘A’, ‘B’:
', ‘C’: '’},
{‘$residuals’: [{‘args’: [‘B’, ‘my_module’, ‘x’],
‘functor’: ‘put_attr’}], ‘X’: ‘B’, ‘A’: ‘', ‘B’:
‘B’, ‘C’: '
{‘$residuals’: [{‘args’: [‘C’, ‘my_module’, ‘x’],
‘functor’: ‘put_attr’}], ‘X’: ‘C’, ‘A’: ‘', ‘B’:
’, ‘C’: ‘C’}] == result

  • FIXED: If exceptions happen during serialization to JSON, MQI will
    now send an exception message instead of hanging

  • FIXED: On a multi-user system, running the MQI test suite fails if
    you’re the second user to do that. Reported by

  • FIXED: Goals are now expanded when used in MQI as they are on the
    top level. Found by @Losbarthos

Package pengines

  • FIXED: term//2: operator atoms for other operators must always be

  • ENHANCED: Pengines waiting for a new event now wait the first second
    without idling. After than they call thread_idle/2 to minimise
    their footprint. This avoids garbage collections for short waits
    while going into a deeper sleep mode for a long wait.

  • ENHANCED: term//2 for rendering terms as HTML has many new options
    and provides HTML that is easier to deal with using JavaScript and CSS.

Package pldoc

  • DOC: Support the S*() functions for IOSTREAMS.

  • MODIFIED: when creating a link from a URL, do not include a punctuation
    character before a space. So, Bla
    correctly links to the html page.

Package semweb

  • PORT: msys2/clang64, Release, avoid unused warning

Package sgml

  • FIXED: Avoid illegal access to local variable (harmless)

  • CLEANUP: Use PATH_MAX consistently

  • TEST: Make tests independent from newline conventions.

  • TEST: Make independent from newline conventions.

  • ENHANCED: Avoid leaking the DTDs in the main thread on exit.

Package xpce

  • FIXED: PceEmacs Prolog/spy and Prolog/trace menu items to deal with
    SSU (=>) rules and fix DCG (–>) rules.

  • ADDED: PceEmacs: Prolog mode command Set breakpoint condition.

  • CLEANUP: Consistently use PATH_MAX


  • ADDED: file->open: allow using resource iris

  • ENHANCED: file->size to use information from the stream when the
    file is open.

  • ADDED: Allow opening res:// resources.

  • ADDED: PceEmacs to recognise Emacs -*- Var: Value; ... -*-
    syntax. For now only processes tab-width: Width;

  • FIXED: PceEmasc Consult selection command resulted in an error
    message wrt. format/3 and url/1 terms.

  • CLEANUP: MinGW-11 complains on cl_hash() in gitwrite.c. Code seems
    fine to me, but a simple memset() does the same trick and keeps the
    compiler silent.

  • FIXED: GIF: Write last byte outside mask image if width is divisible
    by 8.

  • FIXED: Buffer overflow by one byte. Avoid using alloca().

  • FIXED: Read outside object.

  • PORT: Avoid non-portable %I64d.

  • TEST: Make test file conform to policies and include into the test set.

  • FIXED: edit or create the Prolog preferences file from the swipl-win

  • FIXED: Occasional lack of display update, notably in the graphical
    debugger. This fix is a work-around that disables an early abort of the
    repaint cycle if a new event arrives. It is not clear why this fixes
    the redraw issue. This needs to be investigated further. Applications
    that wish the old behaviour can use send(@display_manager, test_queue, @on).

  • FIXED: Delay geometry request for windows with a given geometry to
    happen after processing the MapNotify event (X11 only). This seems to
    avoid a 5 sec delay that sometimes happens in the XtGeometryRequest()


Trying to build on MacOSX , I get this some way through cmake --build:

[ 88%] Generating lib/explain.tex
cd /Users/itz/src/homebrew-personal/swipl-8.4.3/build/man && ../src/swipl -f none --no-packs -x /Users/itz/src/homebrew-personal/swipl-8.4.3/build/man/pldoc2tex -- --source=/Users/itz/src/homebrew-personal/swipl-8.4.3/man --out=lib/explain.tex --subsection --summaries "library(explain)"
gmake[2]: *** No rule to make target 'man/archive', needed by 'man/lib/prologpack.tex'.  Stop.
gmake[2]: Leaving directory '/Users/itz/src/homebrew-personal/swipl-8.4.3/build'
gmake[1]: *** [CMakeFiles/Makefile2:2879: man/CMakeFiles/core.doc.html.dir/all] Error 2
gmake[1]: Leaving directory '/Users/itz/src/homebrew-personal/swipl-8.4.3/build'
gmake: *** [Makefile:159: all] Error 2

Please ignore the homebrew reference in the path; this is just preparation for the real packaging job.
I leave the directory exactly as it is after this error, in case you have questions that can be answered by inspecting it.

Make sure to have all dependencies installed. A full build requires libarchive as dependency. It is more than just nice to have for the final system as well as this library is used to install packs (pack_install/1).

That worked, thanks. However it is slightly complicated by the fact that Homebrew libarchive package is “keg only” i.e. not symlinked into /usr/local/{include,lib}. One has to pass explicit CPPFLAGS and LDFLAGS to the cmake config step. Maybe this could be mentioned on the swipl build page. I think it’s a wiki so when I have time I’ll try to update it myself.


  • the ninja based build sure gives my Mac a workout, and it is a high level Mac. A MacBook Air user who tries to follow the instructions literally may get burns on their lap. :stuck_out_tongue:
  • the reason Homebrew doesn’t export libarchive is that supposedly MacOS (plus Xcode) supposedly provides its own copy, but if so clearly swipl build system can’t find it wihtout help, either.


Have a look at cmake/port/Darwin.cmake which already holds several hacks for Macports and Homebrew. Maybe you can create a PR for that? Better to do it automatically than to put it in a readme nobody reads :slight_smile:

My M1 Macbook air does the job completely silent in a little over 30 seconds :slight_smile: My old Intel based one takes quite a bit longer and has some moments it makes a lot of noise :slight_smile:

That is very interesting, indeed. But is the intention that cmake includes this file automatically? Because that doesn’t seem to happen.


But it should :slight_smile: The Homebrew support is not that well maintained :frowning:

I’ve seen this occasionally in the past on my Ubuntu system … I manually created the directory (mkdir -p man/archive_ and re-ran cmake and ninja, everything was fine.

… except you still do not have library(archive) and thus pack_install/1 doesn’t work (except for git based packages if you have git on your PATH).

I don’t know what changed, but now it works as expected.

My homebrew package is at the web address below [1]. Compared to the official one, it includes X11 support (via quartz), and, most important for me, exports the swi pkgconfig file, so I can install stuff like [2].

[1] homebrew-personal/swi-prolog-fixed.rb at a9d22763353bf8fe0f28637d9b798fa561293678 · nobrowser/homebrew-personal · GitHub

[2] Kiran Gopinathan / SWIPL-OCaml · GitLab



If you can get the official package updated, many Mac users will be grateful!