Ann: SWI-Prolog 8.3.4

Dear SWI-Prolog user,

I’m happy to announce SWI-Prolog 8.3.4. As opposed to recent releases
that mostly brought fixes, this one mainly brings new functionality.

  • Added transactions. See transaction/1, etc. Although not completely
    set in stone, the current implementation seems fairly stable and I
    do no expect serious changes to the API. This may have some impact
    on portability due to required changes in thread synchronization for the
    update generation management. Tested on Linux (amd64), Windows (32 and
    64 bits), MacOS (gcc and clang) and Raspberry Pi (Rasbian, Pi3, arm32).

    Note that transactions are also available for the single threaded version.

  • Added library(hashtable). The implementation seems quite robust. The API
    may be changed or extended based on feedback. Somehow the docs do
    not show up in the search. See here

In addition there are the usual small fixes and documentation updates,
notably contributed by Adrian Wong and David Tonhofer. Roy Ratcliffe
provided hooks to make file:// references work. See library(iri_scheme/file).

Enjoy --- Jan

SWI-Prolog Changelog since version 8.3.3

  • FIXED: Actually allow hashtables to have non-ground keys by using
    variant_hash/2 instead of term_hash/2.

  • DOC: Explain working directory issues for loading likes.pl.

  • FIXED: Issue#637 (following Discourse message): functional notation
    expansion in ^-meta arguments (bagof/3, setof/3, etc.).

  • ADDED: library(hashtable): mutable and backtrackable hash table
    in Prolog.

  • ADDED: library(error), type pair to denote a Key-Value pair.

  • ADDED: Generate events on a transaction rollback. This also fixes
    consistency for private incremental tables under transactions.

  • PORT: 32-bit platform without 64-bit atomic operations.

  • FIXED: Single threaded build.

  • ADDED: Support file IRI scheme

  • DOC: Clarify transaction/3 and clause ordering inside transactions.

  • FIXED: Generation synchronization wrt transaction constraints.

  • FIXED: Generation management of assert/retract

  • FIXED: Possibly crash while enumerating table answers (missing stack
    space check and expansion).

  • FIXED: An asserted term may be visible in arbitrary generations for
    a short time.

  • FIXED: Clauses asserted in a transaction could become briefly visible
    outside.

  • FIXED: Avoid inconsistent L_PREDICATE and L_GENERATION locking
    (deadlock).

  • FIXED: Assert+retract inside a transaction may cause a clause to
    become visible again.

  • ENHANCED: transaction_updates/2: distinguish asserta and assertz.

  • TEST: Test transaction constraints.

  • FIXED: Added option/2 dependency for library(thread).

  • ADDED: transaction/3

  • FIXED: Added missing predicate_options/3 declarations for
    concurrent_forall/3 and concurrent_and/3.

  • FIXED: Proper commit generation

  • ADDED: transaction_updates/1 to get access to pending updates in
    a transaction.

  • FIXED: retract/1 in nested transaction for clauses added by an outer
    transaction.

  • DOC: Mostly changes to atom_codes/2 et al.

  • ENHANCED: Avoid remembering clauses that are asserted and retracted
    in the same transaction.

  • ADDED: current_transaction/1 to test whether a goal is running inside
    a transaction.

  • FIXED: transaction nesting

  • ENHANCED: Make reconsult predicate updates truly atomic.

  • FIXED: Use L_GENERATION lock for removeClausesPredicate() to make
    this truly atomic.

  • FIXED: propagate I/O exceptions or signalled exceptions
    from discarding an unbuffered stream temporary buffer.
    Report

  • ADDED: Transaction isolation support. See transaction/1 and
    snapshot/1. Experimental. Use ?- help(transactions). for help.

  • CLEANUP: Generation management

  • FIXED: Single threaded build.

  • ENHANCED: concurrent_and/2,3: limit size of answer queue. Jan Burse.

  • DOC: Reviewed chapter on “exceptions”

Package clib

  • FIXED: A destroyed engine under a time limited goal destroys the main
    thread’s timers.

Package jpl

  • TEST: Install jpltest-${JPL_VERSION}.jar as jpltest.jar. If we
    install jpltest.jar itself, it is just a link. We do not want to
    install links if we can avoid it for portability.

Package plunit

  • ADDED: current_test/5 to reason about known tests.
2 Likes

Just yesterday ran into a problem where I had a module with DCG that exported option//1. The code in the module worked, and the other modules imported it correctly but when gtrace/0 was started, gtrace/0 gave a series of error messages and would not work correctly. Since the code was still being developed I just commented out the export and left a TODO for now. I don’t think it is a related problem but something of note as option/3 might be a popular predicate to create and not realize it already exist.

How is current_test/5 used? I looked for a test case or more details but only found the GitHub commit.

That is up to your imagination :slight_smile: The use case was to get access to fixme and similar options for a test to emit more precise messages. You could also use it to list or search tests, etc.

Should in theory be unrelated. If reproducible I can have a look.

Will put that on my TODO list.

It was reproducible then and I am pretty sure I could reproduce it now so will make a reprex.

I’m seeing an error under 8.3.4 with autoloading disabled, presumably due to the changes with dicts inside bagof.

in foo.pl:

:- module(foo, [test_get_bag/2]).

test_get_bag(Dict, Bag) :-
    bagof(Key-Value, (Value = Dict.Key), Bag).

When loading:

?- set_prolog_flag(autoload, false).
?- [foo].
?- ERROR: /home/james/tmp/foo.pl:3:
ERROR:    diff3/6: Unknown procedure: '$expand':oset_diff/3
ERROR: Exported procedure foo:test_get_bag/2 is not defined
true.

Getting an error trying current_test/5:

13 ?- run_tests.
% PL-Unit: utils ....... done
[...]
% 26 tests passed
true.

14 ?- current_test(U,T,L,B,O).
ERROR: Unknown procedure: current_test/5 (DWIM could not correct goal)
15 ?- current_prolog_flag(version,Ver).
Ver = 80304.

Thanks. Pushed a fix.

1 Like

Seems your autoload index is not up to date. This sometimes happens when doing an upgrade using git pull and ninja. Probably some missing dependency. Run

?- make.

with sufficient rights to write the library index and it should tell you it updates the library index. Need to fix this …

Reproducible error.

:- module(check,
    [
        option//1    % Interferes with gtrace when exported
    ]).

option(String) -->
    [Code],
    {string_codes(String,[Code]) }.

Code runs correctly.

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.4)

?- working_directory(_,'C:/Users/Eric/Documents/Notes/Discourse SWI-Prolog OSU OSL/OSU OSL Prolog').
true.

?- [option_gtrace_bug].
true.

?- string_codes("a",Codes),phrase(option(String),Codes).
Codes = [97],
String = "a".

When gtrace is used results in stream of errors.

?- gtrace.
ERROR: [Thread pce] c:/program files/swipl/xpce/prolog/lib/trace/util.pl:126: Initialization goal raised exception:
ERROR: [Thread pce] Type error: `text' expected, found `tail(_482)' (a compound)
ERROR: [Thread pce] In:
ERROR: [Thread pce]   [40] string_codes(tail(_532),[file_errors(fail)])
ERROR: [Thread pce]   [39] check:option(tail(_586),[file_errors(fail)],[]) at c:/users/eric/documents/notes/discourse swi-prolog osu osl/osu osl prolog/option_gtrace_bug.pl:7
ERROR: [Thread pce]   [38] read_util:read_file_to_terms(config('Tracer.cnf'),_634,[file_errors(fail)]) at c:/program files/swipl/library/readutil.pl:291
ERROR: [Thread pce]   [37] prolog_trace_utils:load_trace_settings at c:/program files/swipl/xpce/prolog/lib/trace/util.pl:118
ERROR: [Thread pce]   [36] '$run_init_goal'('<garbage_collected>') at c:/program files/swipl/boot/init.pl:712
ERROR: [Thread pce]   [35] catch(system:'$run_init_goal'(...),error(type_error(text,...),context(...,_774)),system:'$initialization_error'(...,...,...)) at c:/program files/swipl/boot/init.pl:480
ERROR: [Thread pce]   [34] catch_with_backtrace(system:'$run_init_goal'(...),error(type_error(text,...),context(...,_850)),system:'$initialization_error'(...,...,...)) at c:/program files/swipl/boot/init.pl:530
Warning: c:/program files/swipl/xpce/prolog/lib/trace/viewterm.pl:41:
Warning:    prolog_term_view:option/3 is already imported from module check
% The graphical front-end will be used for subsequent tracing
true.


[trace]  ?- string_codes("a",Codes),phrase(option(String),Codes).
Warning: c:/program files/swipl/library/prolog_colour.pl:52:
Warning:    prolog_colour:option/3 is already imported from module check
ERROR: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:50:
ERROR:    Unhandled exception: No permission to redefine imported_procedure `delete_breakpoint/1'
Warning: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:50:
Warning:    Goal (directive) failed: emacs_prolog_mode:require([guitracer/0,tdebug/0,auto_call/1,delete_breakpoint/1,manpce/1,prolog_ide/1,rational/1,spypce/1,tracepce/1,atomic_list_concat/2,breakpoint_property/2,call_cleanup/2,is_dict/2,memberchk/2,module_property/2,set_stream/2,source_file_property/2,string_codes/2,term_string/2,term_to_atom/2,absolute_file_name/3,atomic_list_concat/3,between/3,compound_name_arity/3,default/3,file_autoload_directives/3,file_name_extension/3,get_dict/3,nb_setarg/3,pi_head/2,rational/3,send_list/3,setup_call_cleanup/3,stream_position_data/3,strip_module/3,xref_prolog_flag/4,get_dict/5,sub_string/5])
ERROR: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:89:
ERROR:    Unhandled exception: No permission to redefine imported_procedure `comment_modes/2'
Warning: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:89:
Warning:    Goal (directive) failed: emacs_prolog_mode:autoload(library(pldoc/doc_process),[comment_modes/2])
Warning: c:/program files/swipl/library/prolog_xref.pl:78:
Warning:    prolog_xref:option/3 is already imported from module check
ERROR: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:50:
ERROR:    Unhandled exception: No permission to redefine imported_procedure `delete_breakpoint/1'
Warning: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:50:
Warning:    Goal (directive) failed: emacs_prolog_mode:require([guitracer/0,tdebug/0,auto_call/1,delete_breakpoint/1,manpce/1,prolog_ide/1,rational/1,spypce/1,tracepce/1,atomic_list_concat/2,breakpoint_property/2,call_cleanup/2,is_dict/2,memberchk/2,module_property/2,set_stream/2,source_file_property/2,string_codes/2,term_string/2,term_to_atom/2,absolute_file_name/3,atomic_list_concat/3,between/3,compound_name_arity/3,default/3,file_autoload_directives/3,file_name_extension/3,get_dict/3,nb_setarg/3,pi_head/2,rational/3,send_list/3,setup_call_cleanup/3,stream_position_data/3,strip_module/3,xref_prolog_flag/4,get_dict/5,sub_string/5])
ERROR: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:89:
ERROR:    Unhandled exception: No permission to redefine imported_procedure `comment_modes/2'
Warning: c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:89:
Warning:    Goal (directive) failed: emacs_prolog_mode:autoload(library(pldoc/doc_process),[comment_modes/2])
ERROR: [Thread pce] Unhandled exception: Type error: `text' expected, found `subterm_positions(_382)' (a compound)
ERROR: [Thread pce] In:
ERROR: [Thread pce]   [43] string_codes(subterm_positions(_432),[subterm_positions(_442)])
ERROR: [Thread pce]   [42] check:option(subterm_positions(_480),[subterm_positions(_490)],_476) at c:/users/eric/documents/notes/discourse swi-prolog osu osl/osu osl prolog/option_gtrace_bug.pl:7
ERROR: [Thread pce]   [41] prolog_colour:prolog_colourise_term(<stream>(000000000396F1C0),@7102168/emacs_buffer,emacs_prolog_mode:colour_item(...),[subterm_positions(_550)]) at c:/program files/swipl/library/prolog_colour.pl:499
ERROR: [Thread pce]   [40] '<meta-call>'(emacs_prolog_mode:(...,...)) <foreign>
ERROR: [Thread pce]   [39] setup_call_catcher_cleanup(emacs_prolog_mode:pce_open(...,read,<stream>(000000000396F1C0)),emacs_prolog_mode:(...,...),_624,emacs_prolog_mode:close(<stream>(000000000396F1C0))) at c:/program files/swipl/boot/init.pl:562
ERROR: [Thread pce]   [37] Get-method on @7286464/emacs_prolog_mode: emacs_prolog_mode<-colourise_clause(163) --> _698 at c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:1985
ERROR: [Thread pce]   [36] <meta call>
ERROR: [Thread pce]   [35] pce_principal:get(@7286464/emacs_prolog_mode,colourise_clause(163),_764) <foreign>
ERROR: [Thread pce]   [34] Get-method on @7286464/emacs_prolog_mode: emacs_prolog_mode<-check_clause(163,@off/bool) --> _808 at c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:1459
ERROR: [Thread pce]   [33] <meta call>
ERROR: [Thread pce]   [32] pce_principal:get(@7286464/emacs_prolog_mode,check_clause(163,@off/bool),_880) <foreign>
ERROR: [Thread pce]   [31] ignore(emacs_prolog_mode:get(...,...,_932)) at c:/program files/swipl/boot/init.pl:463
ERROR: [Thread pce]   [30] emacs_prolog_mode:check_clauses(@7286464/emacs_prolog_mode,163,163) at c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:1695
ERROR: [Thread pce]   [29] Send-method on @7286464/emacs_prolog_mode: emacs_prolog_mode->mark_variable(@on/bool) at c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:1655
ERROR: [Thread pce]   [28] <meta call>
ERROR: [Thread pce]   [27] pce_principal:send(@7286464/emacs_prolog_mode,mark_variable(@on/bool)) <foreign>
ERROR: [Thread pce]   [26] Send-method on @7286464/emacs_prolog_mode: emacs_prolog_mode->new_caret_position(163) at c:/program files/swipl/xpce/prolog/lib/emacs/prolog_mode.pl:1631
ERROR: [Thread pce]   [25] <meta call>
ERROR: [Thread pce]   [24] pce_principal:send(@7286464/emacs_prolog_mode,new_caret_position(?(...,caret))) <foreign>
ERROR: [Thread pce]   [22] <meta call>
ERROR: [Thread pce] 
ERROR: [Thread pce] Note: some frames are missing due to last-call optimization.
ERROR: [Thread pce] Re-run your program in debug mode (:- debug.) to get more detail.

Thanks. Pushed a fix. The theory is that the libraries do not inherit from the user module, so you cannot make them disfunctional by defining conflicting predicates, operators, etc. This however was broken for the autoload/2 handling.

I am sure it will work but will test tomorrow with daily build.

EDIT

Tested with daily build. Bug fixed. Works as expected.

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.4-11-g1db629e24)

?- working_directory(_,'C:/Users/Eric/Documents/Notes/Discourse SWI-Prolog OSU OSL/OSU OSL Prolog').
true.

?- [option_gtrace_bug].
true.

?- string_codes("a",Codes),phrase(option(String),Codes).
Codes = [97],
String = "a".

?- gtrace.
% The graphical front-end will be used for subsequent tracing
true.

[trace]  ?- string_codes("a",Codes),phrase(option(String),Codes).

<gtrace starts up without errors>

Had a little fight with CMake, but it seems this is fixed now. This makes incremental builds a bit safer. CMake actually does a pretty good job at that. I only do a build from scratch to check it still works and for the release builds.

This is exactly what I had done, and I also had forgotten to do:

git submodule update --init   

Hopefully a pull, submodule update and ninja now does the job. Optionally a ninja install, but you can also run the not installed version. See scripts/swipl-activate.

Yes, that is what I was using already. I have two versions installed:

  • The locally compiled version (usually release with debug info), from git pull: this is activated with swipl-activate with a symlink in my home/bin.
  • I also have my distro version (installed by the package manager) in /usr/bin (usually the latest swipl-devel) which I use for production.

So when I want production I use /usr/bin/swipl <....> and when I am developing I use swipl <...>.

1 Like

Thanks. I have updated the daily build machine to use the build Docker. Using PGO , this should be about 20% faster, all dependencies should be up-to-date again and using the same process as for the releases it is a better signal for issues.

Predicates from library(hashtable) are not found when searching on the website search box for ht_new or ht_put; strangely enough ht_size works if you press <enter>.

EDIT: the documentation also does not work on the console:

3 ?- h(ht_size).
Warning: No help for ht_size.
Warning: Use ?- apropos(query). to search for candidates.
true.

I know :frowning: I think it is related to the predicate index not always being up-to-date after incremental build (which is used for updating the server)…

That is correct. help/1 only deals with libraries that are included in the manual. I did not yet include the hashtable library in there yet, considering it a bit too immature.

1 Like