Ann: SWI-Prolog 9.3.13

Dear SWI-Prolog user,

SWI-Prolog 9.3.13 is ready for download. This versions comes with
a lot of changes. Highlights:

  • Stability:
    • Fix to select_dict/3, which could crash. Code is also
      simpler and faster.
    • Several issues with memory leaks when using the foreign
      API for accessing strings outside Prolog.
  • New stuff:
    • Introduced exceptions of the shape unwind(Why) that
      re-throw after being caught and (thus) bubble up to the
      very top. Used for abort/0 (instead of '$aborted' with
      the same semantics, thread_exit/1 and halt/0,1 when possible.
      During shut down, threads are terminated using unwind(halt(Status))
      rather than '$aborted' This is also in use by Janus to
      propagate the Python exceptions SystemExit and KeyboardInterrupt
    • catch/3 now evaluates constraints while unifying Ball. This
      allows for creating exception filters using a combination of
      unification and evaluating a predicate.
    • Added a Prolog flag halt_grace_time to specify how long halt/0,1
      waits for threads to be terminated gracefully (default 1 sec). Fixed
      xpce issue in not propagating abort/unwind exceptions.
    • dict_same_keys/2 (similar to same_functor/2 for dicts),
      mapdict/2,3,4
    • parse_time/3 to support more formats and better integration
      into HTTP http_timestamp/2.
    • Added PL_print_message(). Added SIO_TRYLOCK to PL_get_stream()
    • Added janus.heartbeat() to allow Python processing signals
      while a call to Prolog is in progress.
  • Development:
    • Fix breakpoint on arg(+Int, +Term, -Var). Break had no
      support for the VM instruction that implements this, causing
      a crash.
    • GUI Tracer: term viewer (showing variables after double click
      in the bindings pane) may be “pinned”. If pinned, the next
      variable opens in a new window, so you can keep the pinned
      for reference.
    • PceEmacs: properly wrap the ``%! pred(Arg, …) lines if
      they get too long. Added C-x52 and M-, key bindings for
      better GNU Emacs compatibility.

Typically, all this should have few implications for 99% of the
applications. The introduction of unwind(Term) exceptions is quite
involved and (thus), some regression is not unlikely.

Enjoy --- Jan

SWI-Prolog Changelog since version 9.3.12

  • ADDED: library(dicts): mapdict/2,3,4

  • ADDED: dict_same_keys/2 Similar to same_functor/2. This is a building
    block for a future mapdict/3 predicate.

  • FIXED: select_dict/3: possible crash. Could crash if the first
    argument dict did not have unbound keys. The new implementation is
    also faster, building the new dict opportunistically rather than in
    a second scan.

  • FIXED: Build failure on systems without sem_timedwait()

  • FIXED: Avoid message when assertion/1 is interrupted by abort

  • ADDED: Prolog flag halt_grace_time: graceful timeout limit

  • CLEANUP: Getting Prolog flags from C

  • ADDED: PL_print_message() for calling print_message/2 from C

  • FIXED: print_term/2: indentation of right argument of infix term.

  • FIXED: Allow breakpoints in arg(C,T,F) I.e., arg/3 calls with a known
    argument and the 3th index being a first var. These map to the
    B_ARG_CF VM instruction.

  • FIXED: Possible memory leak in various C API functions using
    BUF_MALLOC These functions could “stack” intermediate results,
    overflowing the string stack when used excessively inside a single
    foreign predicate or outside calls from Prolog (i.e., using “main”
    in foreign code).

  • ADDED: PL_get_stream(): SIO_TRYLOCK flag to allow failure if the
    stream is locked.

  • ADDED: catch/3: support constraints on the Ball.

  • FIXED: Bail out with fatal error if we cannot allocate a foreign
    frame for an exception.

  • FIXED: Generate a fatal error if there is no local stack emergency
    space

  • FIXED: Partial unification while searching for a matching catch/3.
    As the partial unification is not undone, we may fail to find the
    right catch frame.

  • FIXED: Memory leak in PL_get_wchars() when using BUF_MALLOC.

  • FIXED: Avoid error message when calling halt/0,1 from -g goals.
    Reported by Jos de Roo

  • MODIFIED: cancel threads using unwind(halt(Status)) Older versions used
    '$aborted'

  • MODIFIED: PL_halt() return status and new flag. If the flag
    PL_HALT_WITH_EXCEPTION is used, PL_halt() tries to raise an
    exception and returns false. If the halt was cancelled, the return
    is now true (was false). Otherwise, the function does not return.

  • ENHANCED: halt/1: use the unwind(halt(Status)) if possible.

  • CLEANUP: Removed '$aborted'

  • DOC: Status of unwind(…) exceptions.

  • MODIFIED: Re-implement thread_exit/1 based on
    unwind(thread_exit(Term)).

  • ADDED: Allow unwind(halt(Status)) to halt from an exception.

  • MODIFIED: Introduced unwind(Term) exceptions.

  • ADDED: parse_time/3: support RFC1036 and ASCTIME formats These formats
    are old HTTP timestamp formats.

  • DOC: Added documentation for PL_for_dict()

  • FIXED: Windows format_time/3 implementation for time stamps > 32 bits.
    While the Windows time_t is 64 bits, it doesn’t seem to localtime()
    seems broken handling large time offsets.

  • MODIFIED: parse_time/2,3: interpret missing timezone as local time.
    This patch fixes parsing YYYY-MM, which used to be a day too early.

  • ADDED: date_time_stamp/2: allow leaving components unbound from
    the right.

  • DOC: #1323 Wrong claim on default for prefer_rationals flag.

Package clib

  • COMPAT: Support both old and new abort exception

Package cpp

  • TEST: Fixed file tests for Windows where Prolog and OS paths differ,

  • FIX: add missing PlStringBuffers in calls to PL_chars(), PL_nchars(),
    PL_wchars()

  • DOC: adding warning to PlTermv

Package http

  • COMPAT: Support both old and new abort exception

  • FIXED: http_reply_file/3: be more tolerant about if-modified-since
    Recent systems provided file times in sub-second, while HTTP typically
    looses this.

  • FIXED: Steadfastness of http_timestamp/2

  • ADDED: http_parse_header_value/3: support expires For compatibility,
    this is not converted by default.

  • ADDED: http_timestamp/2: support mode (-,+), i.e., parsing

Package libedit

  • FIXED: Avoid deadlock when trying to save history from a background
    thread.

Package mqi

  • COMPAT: Support both old and new abort exception

Package pengines

  • COMPAT: Support both old and new abort exception

Package semweb

  • FIXED: Make RDF GC thread stop gracefully.

  • COMPAT: Support both old and new abort exception

Package ssl

  • COMPAT: Support both old and new abort exception

Package swipy

  • DOC: Python signal handling

  • ADDED: janus.heartbeat() to make Python process interrupts while
    Prolog runs.

  • ADDED: propagate keyboard interrupt.

  • ENHANCED: Cooperate with Python sys:exit() Calls from Prolog to
    Python, where Python raises a SystemExit() exception are mapped to
    Prolog unwind(halt(Status)) exceptions or, for older versions into
    abort/0, recording the exit status requested. Consisently, when
    control comes back from Prolog to Python, the unwind(halt(Status))
    raises SystemExit(Status) or, abort with recorded exit status raises
    this Python exception.

Package tipc

  • COMPAT: Support both old and new abort exception

Package xpce

  • COMPAT: PceEmacs: implemented C-x 5 2 and M-,

  • FIXED: Pass on unwind() exceptions from e.g. timer events calling
    Prolog.

  • ADDED: GUI tracer term viewer: allow pinning.

  • ADDED: PceEmacs Prolog mode: auto-fill the mode line properly.

  • COMPAT: Support both old and new abort exception

1 Like

After update of select_dict/3, it doesn’t seem to handle attributed variables on unification. For example, the following simply fails:

  A = _{ key: VA },
  B = _{ key: vb },
  put_attr(VA, user, some),
  select_dict(A, B, Rest).
1 Like

Found another regression. If halt is given as a goal in command line the output is not flushed.
For example:

swipl -g "format('text~n',[])"

prints

text
?-

while

swipl -g "format('text~n',[])" -g "halt"

prints nothing.

UPD: however, swipl -g "format('text1~n',[])" -g "format('text2~n',[])" -g "halt" prints

text1
text2

This doesn’t reproduce for me:

$ swipl --version
SWI-Prolog version 9.3.13 for x86_64-darwin
$ swipl -g "format('text~n',[])" -g "halt"
text

So it might be platform-specific?

Ok, strange, now it does work for me, but…

~ > swipl --version
SWI-Prolog version 9.3.13 for x86_64-darwin
~ > swipl -g "format('text~n',[])" -g halt
text
~ > swipl -g "format('text',[])" -g halt
~ > swipl -g "writeq('text')" -g halt
~ > swipl -g "writeq('text')" -g flush_output -g halt
text~ >

it has something to do with flush.

Found this trying to compile swipl-info, which fails on version check. The question is what is the desired behavior of streams on halt? Should they flush?

1 Like

Yes. And it seems they don’t :frowning:

Right. Couldn’t be implemented opportunistically as the unification steps may push delayed goals :frowning: Again back to a two stage implementation, but a bit simpler and faster than the original and without re-introducing the bug that causes this :slight_smile:

Fixed as well. That was a lot simpler.

Thanks for the feedback!

1 Like