This is half a question and half me sharing what I already found out. In short: when exchanging Prolog terms (in text form) with a different Prolog system or other software that reads Prolog terms, how do I make SWI-Prolog write terms so that the other side has the best chance of understanding them?
The obvious answer is write_canonical/1, which quotes atoms where necessary and uses plain f(A, B, C)
syntax for all compound terms… well, almost all. SWI-Prolog’s write_canonical/1 actually still uses special syntax for lists ([x]
instead of '[|]'(x,[])
or '.'(x,[])
) and braces ({x}
instead of {}(x)
). This is fine when exchanging terms with SWI-Prolog and most other Prolog systems, but can be a problem with other parsers. (Guess who’s working with a Prolog term parser that doesn’t even understand list syntax…)
To disable the special syntax for lists and braces as well, we have to use write_term/2 and set the appropriate options. First, we need quoted(true)
, ignore_ops(true)
, and character_escapes_unicode(false)
to get the behavior of write_canonical/1. Then we can use dotlists(true)
to write lists as .(H,T)
and brace_terms(true)
to write braces as {}(X)
.
Another problem still remains though, namely Unicode characters in atoms. SWI-Prolog has full Unicode support in source code, so Unicode letters and symbols like α
and ∅
can be used in unquoted atoms the same way as ASCII letters/symbols. Not all Prolog systems support Unicode this well though - for example, SICStus only supports Latin-1 characters unquoted, so ä
is a valid atom in SICStus, but α
is not and has to be written as 'α'
. This causes problems when sending Unicode atoms from SWI-Prolog to SICStus: all SWI term writing predicates will write an atom like α
unquoted, which SICStus isn’t able to read.
Is there any way to change this behavior and force Unicode characters in atoms to be quoted or escaped? I found the option character_escapes
, but that apparently only affects characters that SWI wouldn’t accept as unquoted atoms (e. g. \uFEFF
). Characters like α
are still not quoted even with character_escapes(true)
(which seems to be the default setting anyway).
TLDR: The best I can do is:
write_term(Term, [
quoted(true),
ignore_ops(true),
character_escapes_unicode(false),
dotlists(true),
brace_terms(true)
]).
Somewhat related: