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:
