# Ann: SWI-Prolog 9.3.22

**URL:** <https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-22/8926>\
**Category:** Releases\
**Created:** [April 2, 2025, 7:34pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-22/8926 "2025-04-02T19:34:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 2, 2025, 7:34pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-22/8926/1 "2025-04-02T19:34:43Z")

</div>

Dear SWI-Prolog user,

I’m happy to announce SWI-Prolog 9.3.22. The Changelog is long.  
Highlights:

- Support configurations that install the .qlf (Quick Load Files)  
next to the sources for all libraries. This is enabled using  
`cmake -DINSTALL_QLF=ON`. This is not yet default in this  
release. If you build from source, please try this. It reduces  
library load times a lot. If, for some reason, you want to try  
using the source for some run, use `swipl -Dsource ...`

- Support installing the libraries as **only**.qlf files. This  
is enabled using `cmake -DINSTALL_PROLOG_SRC=OFF`. It seriously  
reduces the size of the installation, but debugging and inspecting  
the Prolog source for some predicate is of course a lot harder.  
Currently used by SWI-Tinker. SWI-Tinker allows viewing the  
library sources as they are downloaded on demand. This will not  
become default, possibly except for the `npm` package?

- A lot of cleanup and fixes to support the two above features.  
One of them is a change to the library INDEX.pl files to provide  
information on meta-predicates, public predicates and operators  
provided by the library modules. Old INDEX.pl file are still  
read to minimise impact for people using this on private libraries.

- Many changes for the WASM version. Added various options to the  
JavaScript API. Moved bind/4 from library(dom) to library(wasm)  
and added bind\_async/4 and wait/3 as wait(+Element, +EventType, -Event). Extended  
library(dom) to fully implement the same library as found in  
Tau-Prolog.

- Various fixes to the debugger, mostly fixing regression due to  
the introduction of _yield_ based debugging.

- Modified edit/1 internals. This affects code using the  
edit:edit\_source/1 hook to call a user-defined editor.

- Fixed various issues with term//2, rendering Prolog terms as nested  
`<span>` elements.

# SWI-Prolog Changelog since version 9.3.21

- FIXED: Using tabling when configured for debugging with autoloading  
disabled.

- WASM: Enhanced error message when evaluating `:=/2`

- FIXED: Clear `FR_SKIPPED` after skip/up in yield-based debugger.

- FIXED: continue in trace mode after hitting a spy point. This was  
broken when using Prolog defined tracing in recent rewrites.

- FIXED: Retrieving source info for `Head --> "terminal", ...`

- DEBUG: Attempt to improve visible trace points in the debugger.

- FIXED: xref\_public\_list/3 on absolute .pl file on qlf-only release.

- FIXED: file\_autoload\_directives/3: Handle absence of sources Use  
public xref\_public\_list/3 rather than a private predicate from  
boot/autoload.pl that is designed for source only.

- FIXED: library(dom) get\_by\_id/2: getElementById() returns `null`  
on failure

- WASM: library(dom): Tau-Prolog compatible handling of set\_style/3 and  
get\_style/3 Several DOM style strings are translated to Prolog terms.

- ADDED: library(dom): remove\_class/2.

- WASM: Move bind/4 from library(dom) to library(wasm) Also added wait/3.

- DOC: Added library(wasm) and library(dom) to documentation server.

- DOC: library(wasm)

- ADDED: WASM: Prolog.promise\_event()

- WASM: bind/4 can now handling JavaScript objects without using the  
database

- WASM: Updated `bind.html` demo.

- ADDED: Complete the Tau-Prolog compatibility library(dom).

- ADDED: WASM: Allow for nested `#(Value)`

- WASM: Prolog.bind(): added options.

- BUILD: Install pldoc/hooks.pl instead of the .qlf file This is an  
include file that is used by the web server to customise PlDoc.

- FIXED: library(prolog\_colour): handle non-ground directives. E.g. `:- use_module(mymodule, [op(_,_,_)])`.

- MODIFIED: prolog:xref\_update\_syntax/2 This hook is now called both with  
the raw and expanded terms. Directives are called as (:- Directive)  
rather than the plain term.

- FIXED: library(prolog\_xref): missing multifile declaration.

- FIXED: library(prolog\_colour): style mismatch for multifile heads.

- ADDED: Support access to public predicates for library indexes

- ADDED: xref\_public\_list/2: get information from library INDEX.pl  
Using the INDEX.pl file provides a fast and simple way to get the  
library exports and meta-predicate information. Still need to deal  
with public predicates.

- MODIFIED: INDEX.pl files. Thes files used to contain

- FIXED: edit/1 using edit(file(File)).

- FIXED: edit/1: find e.g. library(lists) if only qlf files are  
installed.

- DOC: #1358 prolog\_stack\_frame\_property/2

- ADDED: prolog\_colourise\_term/4: option current\_variable(Name)  
This causes the marking to mark the named variable with the class  
`current_variable`.

- WASM: Prolog.consult(): added `engine:true` option. This allows  
loading files to proceed asynchronously.

- ADDED: xref\_source/2: stream(In) option This allows processing  
arbitrary data.

- WASM: Do not install the package build tools.

- ADDED: `qlf` app `swipl qlf info -e file.qlf` Show exports of the  
.qlf file.

- ENHANCED: library(prolog\_xref) without sources Get exports from  
.qlf files.

- MODIFIED: edit/1: use dicts for representing (partial) locations.  
As a result, hooks info the editing infrastructure need to be updated.

- ENHANCED: edit/1 - Feedback on locations - Code simplification and  
modernizing

- CLEANUP: edit/1 - Avoid deprecated us of absolute\_file\_name/3. -  
Avoid proposing .qlf files.

- ADDED: prolog\_file\_directives/3 This predicate used to be part of  
library(prolog\_xref). It is now public from library(prolog\_source).

- DOC: Update CMAKE.md to include instructions on Python installation  
Added a list of the options useful for installing Janus

- DOC: install with symlinks

- WASM: Use lz4 compression for data file.

- WASM: Demo server to serve library sources.

- WASM: Support library(chr). The package was compiled, but only  
partially installed and thus non-functional.

- WASM: Enable adding packages in the node version This was disabled  
due to issues with Emscripten opendir(), but these seem resolved.

- WASM: Support INSTALL\_QLF and INSTALL\_PROLOG\_SRC CMake flags

- WASM: Remove several libraries that cannot be supported

- BUILD: Allow qlf builds without PlDoc and xpce

- DOC: WASM function Prolog.query() Documented `nodebug` and `string`  
options.

- WASM: Prolog.query(): add option `{string:"atom"}`

- ENHANCED: Generalise user interaction on answer Allow reusing the  
toplevel answer user interaction by using an alternative input.

- ENHANCED: `qlf` app to report .qlf files without sources. Used to  
report these as out of data.

- FIXED: We must insert I\_CONTEXT in multifile predicates Multifile  
predicates are typically installed in modules using `target:head :- body`, where body is executed in the containing module. This is  
achieved using an I\_CONTEXT VM instruction. Before, when the predicate  
contains one such clause, it set `P_MFCONTEXT` and inserted a  
I\_CONTEXT for each subsequent clause. When using .qlf files though,  
the files may be loaded in different order than when creating the  
.qlf files, leading to clauses without an I\_CONTEXT instruction to  
follow clauses with this.

- ENHANCED: library(prolog\_xref): cleaner exception handling.

- ENHANCED: Allow cross-referencer to deal with .qlf files

- BUILD: Added CMake option `-DINSTALL_PROLOG_SRC=OFF` This can be  
used together with `-DINSTALL_QLF` to ship the Prolog libraries as  
.qlf files without including the sources.

- FIXED: Handle autoload/1,2 declarations in aggregate .qlf files

- FIXED: load\_files/2: resolve to files loaded from .qlf Some qlf  
files may load multiple source files. When looking for a file in  
e.g. use\_module/1,2, first try the file system, but on failure ee  
whether we loaded a .qlf file that registered the required file.

- FIXED: Use canonical .pl files for all admin purposes. Despite the  
fact that code is loaded from .qlf files, use the .pl file from which  
the .qlf file is compiled for admin purposes.

- ADDED: ‘$qlf\_module’(+File, -Dict) This predicate extracts properties  
for a module without loading it. This is required to make autoload/1,2  
work if we remove the source files.

- MODIFIED: absolute\_file\_name/3: distinguish file types `prolog` and  
`source` These used to be synonyms. Now `prolog` includes `.qlf`  
and `source` does not.

- INSTALL: Install .qlf files if these have been build.

- ADDED: library(prolog\_qlfmake) This library allows for compiling the  
entire library to .QLF files.

- ADDED: Prolog flag `source`. This flag can be used to ignore the  
.qlf files in the library and load the .pl (source) files instead.

- ADDED: library(prolog\_qlfmake) This library allows for compiling the  
entire library to .QLF files.

- FIXED: Do not keep an erased clause when doing an incremental  
compilation

- ENHANCED: qcompile/1: preserve predicate properties When compiling  
clauses for another module as commonly done as a return of  
term\_expansion/2, preserve the multifile and dynamic properties,  
such that the module can be loaded as qlf and later loading of the  
module into which the clauses are added does not wipe the predicate.

- FIXED: Debugging the fail port of Prolog defined built-in predicates.

- FIXED: If engines are enabled without threads, call the main engine  
`main`.

## Package http

- FIXED: term//1: possible exception on compound\_name\_arity/3.  
This happened when spacing around operators need to be computed and  
the left or right hand of the operator is a blob.

- FIXED: Running out of file descriptors if device for log files  
is full. This patch is a serious cleanup of error handling in the  
HTTP log library.

- ADDED: Provide cross-referencing hooks for `:- html_meta(+Decls)`

- FIXED: #168 http\_daemon/0,1: exit with status 0 The startup was  
translating all exceptions into halt(1). That is wrong after halt  
is implemented as throw(unwind(halt)).

- FIXED: library(http/jquery): support Qlf compilation ensure\_jquery/1  
cannot use conditional compilation. We must use a runtime conditional  
instead.

- CLEANUP: Avoid demo dependency on xpce.

- FIXED: term//2: make operators a trigger.

- FIXED: term//2: portray(true) implies numbervars(true).

## Package pldoc

- ADDED: PlDoc to LaTeX converter: file\_synopsis(Text) option Allows for  
overwriting the default synopsis. Used to document some not-installed  
libraries.

- ADDED: Support “=” mode. This is a proposal in the PIP meetings to  
deal with “Output” arguments.

## Package xpce

- ENHANCED: PceEmacs: reload styles if new style facts are added.  
This is necessary if Prolog files that hold highlight declarations  
are loaded after creating the editor.

- BUILD: Build xpce library index before running qlf\_make/0

- ENHANCED: PceEmacs: deal with possibly not-installed sources.

- FIXED: Add dependencies to make qlf compile work qlf\_make/0 now  
reorders based on file dependencies. This means we can add the  
dependencies here and avoid hacks.

- FIXED: Load library(emacs\_extend) explicitly in mode files This is  
required to ensure that the term expansion is applied when generating  
the .qlf files.

- CLEANUP: Remove pce\_boot search path. Now using hard paths to resolve  
references between the various boot files.

- BUILD: Better support building .qlf files without an X11 display

- CLEANUP: Removed forgotten HTTP implementation

- CLEANUP: Delete duplicate libraries Deleted

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 3, 2025, 8:21am UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-22/8926/4 "2025-04-03T08:21:49Z")

</div>

> [@anon95304481](#):
>
> ```prolog
> set_attr(Elem, #id, #writeme),
> 
> ```

Thanks. That is a bug. Fixed (and updated SWI-Tinker). There has been little testing on these predicates. I didn’t find a test suite. I ported one of the Tau examples, which you can see at [Tau Prolog - Example: My little doge](https://wasm.swi-prolog.org/wasm/doge/doge.html). The porting work was limited to changing how Prolog is loaded and get it running. That spotted a couple of discrepancies between what I implemented based on the documentation and what actually happened. There may be more issues ☹

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 4, 2025, 9:59am UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-22/8926/6 "2025-04-04T09:59:58Z")

</div>

> [@anon95304481](#):
>
> ```prolog
> ERROR: /swipl/library/dom.pl:47:
> ERROR: Unhandled exception: No permission to run goal `load_file(wasm)'
> 
> ```

Thanks. Fixed. I pushed a number of changes that move the Tau-compatible library(dom) to use the “dialect” mechanism, so if you want to use the Tau DOM access, you now need

```prolog
:- expects_dialect(tau).
:- use_module(library(dom)).

```

or

```prolog
:- use_module(library(dialect/tau/dom)).

```

The first offers more options for emulating Tau-Prolog (but nothing is implemented). The latter just loads Tau’s dom library.

Just `library(dom)` now gets SWI-Prolog’s DOM library. What that does is still a bit open. For now it provides a html//1 that does not generate HTML text, but it produces a list of JavaScript HTMLElement objects. It allows for `Var=Spec` at any point to bind `Var` to the element created by `Spec`. The library also provides `append_html(+Elem, +Spec)` to extend the content of any element that understands `appendChild()`. Finally, the new library contains the browser event binding predicates. We’ll see how it develops.

> [@anon95304481](#):
>
> Also the ESC 8 for links doesn’t work on Windows 11, the link is  
> not shown.

The URL embedding was used for all terminals for absolute URLs. Made dependent on the `hyperlink_term` flag. That flag is `false` by default. Tinker implements these hyperlinks and explicitly enables this flag. If you want to use it, you must explicitly enable it in your `init.pl`. It works on most modern Linux terminal emulators, so you can open links to external resources and files using Ctrl-click,

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [April 4, 2025, 1:40pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-22/8926/8 "2025-04-04T13:40:48Z")

</div>

See also [hyperlnk \_term flag and SWI-Prolog banner? [Windows 11] · Issue #1361 · SWI-Prolog/swipl-devel · GitHub](https://github.com/SWI-Prolog/swipl-devel/issues/1361)

Ideally, clear bugs go into github issues and anything else here. But, of course it is not always clear to users what a real bug is. This surely classifies.
