Quantum Prolog on the Web

References to ISO/IEC 13211-1:1995 (core) including Cor.1:2007, Cor.2:2012, and Cor:3:2017 are highlighted. How to get the document.
20: * ISO: missing flag double_quotes
:- set_prolog_flag(double_quotes, chars).
f("abc").

?- f(L)
Error: Class$obf_1002: invalid flag in set_prolog_flag/2 directive, unexpected
See 7.12.2.5. The default value is implementation defined. Recent Prolog systems (Ichiban, Scryer, Tau, Trealla) all chose chars whereas old systems have codes or atom as default but they process chars correctly in above example.
19: * ISO: list syntax incorrect
?- L=[[]], L = []
{"L" : "[]"}, unexpected.
18: * Answer not an answer substitution
?- T = A+B, A = B
{"T" : "+(A$1, B$1)", "B" : "A$1"}
If B = A is chosen ("B" : "A$1"), then all occurences of B must be replaced by A. This is not a conformity issues, since the top level loop is out of scope of 13211-1, see 1 NOTE f.
17: * ISO: false/0 does not exist
The language reference states that Cor.2 has been taken into account, yet
?- false
Error: 'existence_error'('/'('false', 0)), unexpected.
16: * acyclic_term/1 improvable
?- -X=X, fail, acyclic_term(X)
No (more) solutions
?- -X=X, acyclic_term(X)
InternalError: too much recursion
The idea of acyclic_term/1 is to have a clean means to check interfaces. Thus a failure would help much more. Note that also other Prologs that do not implement rational tree unification nevertheless fail here, like B and GNU. Thus in case of failure, a better error message could be produced by the user. In any case, this is not a conformity issue, since -X=X is already undefined. A standard is a precondition for a usable Prolog system not a guarantee.
15: * Better error preferable
?- [-X,-Y,X] = [X,Y,Y]
InternalError: too much recursion
?- catch([-X,-Y,X] = [X,Y,Y],Pat,true)
InternalError: too much recursion
This is not incorrect, since this unification is STO and thus the outcome is undefined, 8.2.1.1 a. But still it is preferable to produce a recoverable error like resource_error(internal_stack) 7.12.2 h. If possible, even unification_stack which points towards the actual culprit.
14: * ISO: unify_with_occurs_check/2 incorrect
?- unify_with_occurs_check([-X,-Y,X],[X,Y,Y])
InternalError: too much recursion, unexpected.
Looks like a definition
unify_with_occurs_check(T,T) :- acyclic_term(T).
which only works with rational tree unification.
13: * ISO: subsumes_term/2 incorrect
?- subsumes_term([-X,-Y,X],[X,Y,Y])
InternalError: too much recursion, unexpected.
Since Quantum does not support rational tree unification, it needs to use unify_with_occurs_check/2 to implement subsumes_term/2. Like:
subsumes_term(General, Specific) :-
   \+ \+ (
      term_variables(Specific, SVs1),
      unify_with_occurs_check(General, Specific),
      term_variables(SVs1, SVs2),
      SVs1 == SVs2
   ).
(Implementation with rational tree unification may replace unify_with_occurs_check/2 by just (=)/2. So they are a bit faster here.)
12: * ISO misunderstandings
On HN, tannhaeuser (the only user referring to Quantum Prolog) wrote:
Also, ISO/IEC 13211-1:1995/Cor.2:2012(E) feels kindof rushed (eg specifying false/0 thereby trivially breaking existing Prolog code such as ILP packages for no reason, insufficient description for subsumes_term/2, introducing call/N and the concept of closures without sufficient precedent, etc.)
Ad false/0
false/0 is a built-in in Quintus at least since version 1.0 of 1985, in SICStus since its introduction 1987 and also in many other systems. Its first public use was 1986-08-08 in the Prolog Digest Volume 4, Issue 41. In YAP (which put great effort for SICStus compatibility) it was originally not a built-in but since YAP defaulted to failure for undefined predicates, it behaved as if it has been a built-in. So nobody who expected SICStus compatibility complained. It should be obvious that this is a vulnerabilty that can easily be exploited. The non-conforming default was reported to YAP 6.2.0 2010-11-29 as #208 (more than fifteen years after the publication of the standard) and fixed until 2011-01-06. Also before that date and while preparing Cor.2, false/0 was listed as a YAP bip in the list of current built-in predicates which was used for preparing Cor.2.
Ad insufficient description for subsumes_term/2
It is unclear what is insufficient in its description. This definition was the first complete definition which is particularly independent of STO-ness which was a killer in all implementations and caused lots of confusion and paralysis. Just look at SICStus' #23 which was confused even after the publication of Cor.2. (Even the current first description in the manual is incorrect.) It was proposed as subsume/2 (N59 pp9-11) for inclusion in N60:18.4 of 1990-05, and rejected. No wonder, the current definition did simply not exist and STO-ness was not well defined at that time. Also remember that many did not understand that matching is not exactly what we think it is. This was brought to the attention of a broader audience only by an article published about that time see this for more. To summarize, the only thing that may feel kind of rushed is the new name which was necessary given all these confusing variations present.
Ad call/2..8
Unclear what sufficient precedent would be. call/1 was already in the standard which was the much harder part, as all the issues with cut and the like had to be resolved. For quite some time a transparent_call/1 was there as well. call/2..8 not only fit nicely into type systems (in fact, that's where Richard O'Keefe got his inspiration to call/2...). First proposed in 1984. In Quintus 1.5, 1986-04, call/2..5 and apply/2 were in the library call.pl listed in the System-Dependent Features Manual version 6, III The Quintus Prolog Library, p83. Its adoption was certainly accelerated by the preparations of Cor.2. So maybe this was perceived as a rush, a quarter century later.
11: * Web-Interface: "No (more) solutions" unintuitive
When looking at the answer substitutions one gets one answer after the other, nicely displayed at once, like:
?- X=1;X=2;X=3
{"X" : 1}
{"X" : 2}
{"X" : 3}
But then, if one asks for a further answer, all answers disappear and one is left with
?- X=1;X=2;X=3
No (more) solutions
alone, so all the answers are gone. It would help a lot if all answers would still be visible. Thus:
?- X=1;X=2;X=3
{"X" : 1}
{"X" : 2}
{"X" : 3}
No (more) solutions
10: * ISO: DCG
Please note the current draft is here.
9: * ISO: Documentation status
See 5.4. It helps a lot if that part is separate and kept to just the required minimum. Currently, the documentation often reiterates parts of the standard, and sometimes changes it.
8: * ISO: unrecognized escape sequences
?- atom_chars('\b\r\f\t\n\v',Chars)
Error: Class$obf_1002: unrecognized character in escape sequence, unexpected.
Expected list of chars. Also, the documentation mentions only some of them. Unclear why this is documented at all, just implementing the standard suffices.
7: * ISO: Odd format of errors
t.
?- phrase([],L)
Error: 'existence_error'('/'('phrase', 2)), unexpected.
There is no write option that enforces single quotes for these atoms. Expected in canonical form: existence_error(/(phrase,2)) Also, where is the DCG support?
6: * Web-interface:
Consider to use valid terms as queries, that is just add a dot at the end of a query. In this manner the entire text is valid Prolog text.
5: * maplist/2 ... not conforming
There is currently a draft for the Prolog prologue which defines maplist/2..8 differently. Why not call your parallel version pmaplist/2...?
4: * ISO: Documentation: '?-'/2 invalid
Correct is (?-)/2 only. See e.g. 7.1.6.6 Note.
3: * ISO: Too permissive syntax
t.
?- var(a:-b)
No (more) solutions, unexpected.
Expected: syntax error see #75. There is a single other system that permits this, and that is SWI, which is not conforming.
2: * ISO: Built-ins can be redefined
?- catch(asserta(write(67)), Pat, true)
{}, unexpected.
Expected: Pat = error(permission_error(modify,static_procedure,_Impdef)

Similarly

write(67).
?- write(X)
{"X" : 67}, unexpected.
In the Web interface there is a subset of ISO Prolog, but still, the names of such built-ins must be reserved, otherwise the program cannot run on any other conforming processor.
1: * ISO: Wrong errors format, cannot be caught
?- catch(functor(V,V,V),Pat, true)
{"Pat" : "instantiation_error"}, unexpected.
?- catch(functor(V,V,V),error(E,_), true)
Error: Usage: functor(-nonvar, +atomic, +integer)
        functor(+nonvar, ?atomic, ?integer), unexpected.
Expected: E = instantiation_error see 7.12.1.

You can put your own more verbose messages into the second argument of error/2.

Web-Interface