SWI-Prolog / swipl-devel

SWI-Prolog Main development repository
http://www.swi-prolog.org
Other
988 stars 176 forks source link

given prefix mode “fy” for atom "[]" ignored #1300

Closed Jean-Luc-Picard-2021 closed 4 months ago

Jean-Luc-Picard-2021 commented 4 months ago

Mostlikely the error is here, that it ignores the given prefix mode “fy”, and switches to block syntax a postfix mode:

5.3.3 Block operators ?- op(100, yf, []). https://www.swi-prolog.org/pldoc/man?section=ext-blockop

The example doesn’t need backtracking for parsing, only the atom [] needs to be correctly recognized as a prefix operator, and a postfix list [...] for indexing syntax should not be confused

as a prefix operator. You can also try a lower priority, it only changes the error messages in SWI-Prolog but the strange behaviour of SWI-Prolog persists:

/* SWI-Prolog 9.3.8 */
:- op( 600, fy, !). 
:- op( 100, fy, []).

?- X = -[Y].
ERROR: Syntax error: Unbalanced operator

So the error message went from “Operator priority clash” to “Unbalanced operator”. On the other hand there is no change in Ciao Prolog, it still passes the test case:

/* Ciao Prolog 1.23.0 */
?- op( 600, fy, !). 
yes 

?- op( 100, fy, []).
yes

?- X = -[Y].
X= -[Y] ?
Jean-Luc-Picard-2021 commented 4 months ago

Even if the mode “fy” is correctly honored, it might nevertheless be a challenge. Since for example this here works also. note the space inside the empty list atom:

/* Ciao Prolog 1.23.0 */
?- op( 100, fy, []).
yes

?- X = [ ] p.
X = []p ?

Took me a while to figure out how to do it. But its rather straight forward to do. You find it in the source code of Novacore.

Jean-Luc-Picard-2021 commented 4 months ago

Its not yet working 100%. Means I cannot yet run my Segerberg Models in SWi-Prolog. The combo TPTP modal logic and TPTP first order logic does still not yet work. Take this definition:

/* Segerberg Models */
:- op( 600, fy, !).     % universal quantifier:  ![X]:
:- op( 600, fy, ?).     % existential quantifier:  ?[X]:
:- op( 600, fy, []).    % necessity
:- op( 600, fy, <>).    % possibility

Then both should work, but it doesn't in SWI-Prolog nightly build:

/* SWI-Prolog 9.3.8-20-gf9350f083 */
?- X = ! [Y]:p(Y).
ERROR: Syntax error: Operator expected
ERROR: X = ! [Y]
ERROR: ** here **
ERROR: :p(Y) . 

?- X = [] p.
X = []p.

Do I have the wrong version? The combo works in Ciao Prolog:

image

image

Jean-Luc-Picard-2021 commented 4 months ago

Beware the error is fairly difficult to spot!

The error doesn’t appear if you don’t hoist the operator definitions. i.e. if you don’t move the operator definitions to the top of the test file. At the moment

you execute the test cases you have to have both operator defintions already in the operator table, the TPTP modal operartor and the TPTP first order operator.

Or did you use an other operator priority? I can still not validate it. I am now using build #22 and not anymore build #20. Maybe I have to wait one more day?

4df803a71a488ccff1edc9acc1229dedbd64cba6

Jean-Luc-Picard-2021 commented 4 months ago

The error doesn't happen only in the top-level. The error also happens when consulting from files. You can try yourself, now using the new build #22:

?-  ['kripke.p'].
%   library(aggregate) compiled into aggregate 0.02 sec, 120 clauses
%   quine.p compiled 0.02 sec, 73 clauses
ERROR: kripke.p:51:15: Syntax error: Operator expected
ERROR: kripke.p:54:16: Syntax error: Operator expected
ERROR: kripke.p:61:11: Syntax error: Operator expected
% kripke.p compiled 0.02 sec, 11 clauses

The source code is here:

quine.p.log kripke.p.log

JanWielemaker commented 4 months ago

See discussion at https://swi-prolog.discourse.group/t/swi-prolog-and-raylib/7608/32. Please do not followup here anymore.

Jean-Luc-Picard-2021 commented 4 months ago

It is not the case that (:)/2 is the culprit. Since it does parse with priority 600. You can try yourself.

It usually does parse ![Y]:p(Y), there is some error somewhere else, just comment out the TPTP modal operator definition:

/* Segerberg Models */
:- op( 600, fy, !).     % universal quantifier:  ![X]:
:- op( 600, fy, ?).     % existential quantifier:  ?[X]:
% :- op( 600, fy, []).    % necessity
:- op( 600, fy, <>).    % possibility

And you get in recent SWI-Prolog build #22 version:

?- X = ! [Y]:p(Y).
X = ![Y]:p(Y).

The bug is some nasty side effect of the op( 600, fy, []) definition. I still believe it confuses block and prefix.

Having an op( 600, fy, []) directive, should not retroactively make things unparsable that were parsable before.

Jean-Luc-Picard-2021 commented 4 months ago

Is there some elegant solution for that? Maybe the ISO core flag does that. I don’t see immediately that ISO core would forbid [] prefix operator, but ISO core surely doesn’t have [X] prefix operator.

How expensive would it be to also control extensions with the ISO core flag? Currenty the ISO core flag in SWI-Prolog controls some of syntax changes, like the “relaxing”, but not extensions like [X] as an operator:

https://www.swi-prolog.org/pldoc/man?section=flags

For example it is not the case that Ciao Prolog would also have the [X] is operator extension, at least you cannot enable it via changing the [] operator. This is what Ciao Prolog gives me:

/* Ciao Prolog */
?- op( 600, fy, []).
yes

?- X = [] p.
X = []p ?
yes

?- X = [a] p.
{SYNTAX ERROR: Malformed query}