scryer-prolog icon indicating copy to clipboard operation
scryer-prolog copied to clipboard

write/1 does escape " characters unexpectedly - compared with src/examples/bimetatrans/Readme.md

Open peschue opened this issue 2 years ago • 4 comments

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.

peschue avatar Aug 07 '22 11:08 peschue

Sorry, I previously submitted an incomplete issue and now edited it.

peschue avatar Aug 07 '22 11:08 peschue

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.

UWN avatar Aug 08 '22 05:08 UWN

And, indeed, in the case of an atom the escaping is not necessary:

?- write('foo"bar').
foo"bar   true.

UWN avatar Aug 08 '22 05:08 UWN

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:

Unbenannt - 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?

Jean-Luc-Picard-2021 avatar Aug 24 '22 17:08 Jean-Luc-Picard-2021

Closable.

UWN avatar Mar 09 '23 07:03 UWN

@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.

triska avatar Nov 29 '23 23:11 triska