# Ann: SWI-Prolog 9.3.14

**URL:** <https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-14/8571>\
**Category:** Releases\
**Created:** [October 31, 2024, 1:54pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-14/8571 "2024-10-31T13:54:34Z")\
**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:** [October 31, 2024, 1:54pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-14/8571/1 "2024-10-31T13:54:34Z")

</div>

Dear SWI-Prolog user,

SWI-Prolog 9.3.14 is ready for download. This release fixes some  
regression issues resulting from the rather large changes in 9.3.13,  
and some portability issues. It has some usability improvements.  
Following Jan Burse’s comments, library(nb\_set) has been reimplemented  
using _close hash tables_. This does not make much difference for  
performance, but the memory usage is about 30% lower.

```
Enjoy --- Jan

```

# SWI-Prolog Changelog since version 9.3.13

- DOC: Update library(shlib) documentation.

- ENHANCED: Re-implement library(nb\_set) using closed hash tables.  
This provides better performance at lower memory usage. It comes  
with a few modifications:

- BUILD: Make sure to clear `DISPLAY` when running xpce steps  
(one more)

- BUILD: Make sure to clear `DISPLAY` when running xpce steps While  
the build works without a DISPLAY variable, an invalid variable causes  
the build to fail.

- TEST: Disable collation\_key/2 test for MacOS Macos Sequoia (15)  
wcsxfrm() returns garbage.

- FIXED: Avoid corruption in setjmp()/longjmp() Clang demands using  
a volatile variable for protecting the throw environment’s parent.  
This is probably correct, although it seems weird to place this  
variable in a register.

- ENHANCED: Add Prolog navigator to `theme/dark.pl`

- FIXED: build order for dependencies in packs. Based on #1326, but  
fixing build\_order/2 rather than reversing afterwards.

- FIXED: expand\_term/2 to succeed twice when expanding a toplevel  
list. Results in duplicate clauses when compiling `[f(1), f(2)].`.  
Reported by Uwe Neumerkel.

- FIXED: pack management: find available versions from wildcard URL.  
Patch by Nicos Angelopoulos

- PORT: Added FreeBSD signal names to the name/number map. Contributed  
by Dewayne Geraghty

- ENHANCED: file\_autoload\_directives/3: deal with library(main) hooks.

- FIXED: Flush pending output on halt/1.

- FIXED: select\_dict/3: deal with attributed variables.

- CLEANUP: Split `select_dict/3` and `:</2` code. Although there is some  
shared functionality, the merge complicates things more than it solves.

## Package mqi

- TEST: Specify encoding in test\_prologserver.py

- TEST: Specify encoding in test\_prologserver.py Fixes a problem for  
MSYS2. I hope my ad hoc fix is harmless.

## (test\_prologserver.TestPrologMQI.test\_variable\_attributes)

Traceback (most recent call last): File  
“c:/msys64/home/c7201178/swipl-devel/packages/mqi/python/test\_prologserver.py”,  
line 95, in setUp  
self.initialProcessCount = self.process\_count(“swipl”)  
^^^^^^^^^^^^^^^^^^^^^^^^^^^  
File  
“c:/msys64/home/c7201178/swipl-devel/packages/mqi/python/test\_prologserver.py”,  
line 123, in process\_count output =  
subprocess.check\_output(call).decode()  
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UnicodeDecodeError:  
‘utf-8’ codec can’t decode byte 0xff in position 237: invalid start  
byte ````

## Package plunit

- FIXED: Report generator state on failing forall(Generator) test.  
This was completely broken. Format has been changed to print the  
generator goal rather than just the variables.

## Package xpce

- ENHANCED: #38 Support themes in navigator.

- FIXED: #38 Avoid loading the GUI tracer when trace/util.pl is loaded.  
The navigator loads this, but should not load the GUI debugger itself.

- FIXED: Class tabbed\_window: avoid sending -\>resize\_window when freed.

---

<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:** [November 1, 2024, 10:39am UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-14/8571/3 "2024-11-01T10:39:05Z")

</div>

The new implementation depends a bit more on arithmetic. Using `-O`, the performance difference on this test is about 3%. I think that is a reasonable price for a 30% space reduction. There is probably room for some more optimization. For example, we need a good “empty” entry. As a plain variable is also valid, this is hard. Ideally you’d have a module-local atom or something like that. As is, I use a term and same\_term/2.

But … I tried implementing distinct/1,2 and reduced/1,3 using tries. That takes the time for your test down from 1.5 sec to 0.3 seconds. Most of the time is now in generating the data 🙂

The price is that tries cannot handle attributed variables nor cyclic terms. This is often fine, but I wonder whether it is acceptable?

**edit** Added cycle and attvar test and if found create a new term for variant testing with these extracted. That slows down from 0.3 to 0.45 sec, but it is fully compatible and still provides a good speed improvement. Sooner or later tries will handle attributed variables for implementing constraint support in tabling.

---

<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:** [November 1, 2024, 1:57pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-14/8571/5 "2024-11-01T13:57:01Z")

</div>

> [@anon95304481](#):
>
> I just was wondering how space is measured?

term\_size/2 gets you the size in _cells_

---

<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:** [November 2, 2024, 4:03pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-9-3-14/8571/7 "2024-11-02T16:03:04Z")

</div>

> [@anon95304481](#):
>
> ```prolog
> statistics(stack, A),
> 
> ```

This is the _allocated_ size for all Prolog stacks in all threads. Better use `globalused` (after garbage\_collect/0). In this case though, calling term\_size/2 on the nb\_set term is the easiest way to figure out how big it is.
