scryer-prolog
scryer-prolog copied to clipboard
write/1 does escape " characters unexpectedly - compared with src/examples/bimetatrans/Readme.md
Edit: Mistyped / submitted too early. Now it is complete!
The readme for the ruleml converter states that
?- parse_ruleml([people('Alex',male),people('Alex',female),people('Siri',female)], [], XML),
write(XML).
should yield
"<Assert mapClosure="universal"><Atom><Rel>people</Rel><Ind>Alex</Ind><Data iso:type="symbol">male</Data></Atom><Atom><Rel>people</Rel><Ind>Alex</Ind><Data iso:type="symbol">female</Data></Atom><Atom><Rel>people</Rel><Ind>Siri</Ind><Data iso:type="symbol">female</Data></Atom></Assert>" XML = "<Assert mapClosure= ...".
however if I execute this in a debug/release build of the current master, I obtain escaped " sequences within the XML.
I think the behavior of write/1
is crucial here, this is not an issue with bimetatrans.pl
, maybe the documentation is wrong or the implementation of write/1
changed.
How to reproduce:
./target/release/scryer-prolog src/examples/bimetatrans/bimetatrans.pl --goal "parse_ruleml([people('Alex',male),people('Alex',female),people('Siri',female)], [], XML), write(XML), write('\n'), halt(0)"
Easier way to see what is not working as it should according to the readme:
?- write("foo\"bar").
"foo\"bar" true.
The readme assumes this should write "foo"bar".
If the implementation is correct, what is the correct way to print out the string in a variable without any escapes?
I tried
?- use_module(library(lists)).
?- findall(., (X="b\"ar", member(M,X), write(M)), []).
b"ar false.
but this seems not the right way / unelegant to me.
Sorry, I previously submitted an incomplete issue and now edited it.
You are using double quotes and that means that you have here lists of chars. What you probably want is one of the following:
?- write('foo\"bar'). % use an atom instead
foo"bar true.
?- use_module(library(format)).
true.
?- format("~s",["foo\"bar"]).
foo"bar true.
Note that write/1
is really an overloaded built-in. The functionality to write out characters literally was originally provided with putatom/1
in the 1978-version of DEC10. But in later versions this was removed.
And, indeed, in the case of an atom the escaping is not necessary:
?- write('foo"bar').
foo"bar true.
What does "not necessary" mean. Thats nonsense.
Wouldn't it be a better and less confusing explanation that write/1
must behave as putatom/1
, and everything else would be a bug,
since it has quoted(false)
?
At least this is what the ISO core standard tells me:
- ISO/IEC 13211-1:1995(E), Page 100
So basically write/1
will behave, concerning atoms as if (in DEC-10 Dialect):
[...]
write(X) :- atom(X), name(X,L), putlist(L).
[...]
putlist([X|Y]) :- put(X), putlist(Y).
putlist([]).
Edit 24.08.2022
I don't find a putatom/1
in DEC-10 Manual from year 1982 here:
Department of Artificial Intelligence. University of Edinburgh DECsystem-10 PROLOG USER'S MANUAL - 10 November 1982 https://userweb.fct.unl.pt/~lmp/publications/online-papers/DECsystem-10%20PROLOG%20USER%27S%20MANUAL.pdf
Where do you have an evidence, for the year 1978?
Closable.
@peschue: To write each character literally, you can also use put_char/1
:
?- maplist(put_char, "b\"ar"). b"ar true.
Using format/2
is much more efficient:
?- format("~s", ["b\"ar"]). b"ar true.