Using SWI-Prolog (threaded, 64 bits, version 8.5.3) on Windows 10.
Since the operator ('.')/2
is defined by SWI-Prolog, e.g.
?- current_op(A,B,.).
A = 100,
B = yfx.
?- X = point{x:1,y:2}.x.
X = 1.
and some old code, created before SWI-Prolog version 7.x, for Lambda Calculus is using .
, I.e. \X.T
which is causing
ERROR: Type error: `dict' expected, found `x' (an atom)
how can I suppress the operator ('.')/2
? Or what can I do to fix the error so it works with current SWI-Prolog?
The only reference to ./2
in the documents that gives a clue is
The compiler translates a goal that contains
.
/2 terms in its arguments into a conjunction of calls to ./3 defined in thesystem
module.
but I can not find where this occurs in the SWI-Prolog code.
Personal Notes (Click triangle to expand)
The term_expansion on ./2
is done here
From swipl-6.6.0\src\pl-atom.c
/* This code provides forward compatibility between 6.0 and 7.0
for shared objects that acts as plugin.
*/
static const atom_t special_atoms[] =
{ ATOM_nil, /* 0: [] */
ATOM_dot /* 1: .(_|_) or '$cons'(_,_) */
};
If one starts SWI-Prolog with the --traditional
options, e.g.
C:\Users\Groot>"C:\Program Files\swipl\bin\swipl-win.exe" --traditional --win_app
then
?- current_op(A,B,.).
false.
?- X = point{x:1,y:2}.x.
ERROR: Syntax error: Operator expected
ERROR: X = point{x:1,y:2
ERROR: ** here **
ERROR: }.x .
Another topic notes that open_dicts.pl might be of use. In searching the code I did not find what I seek.
For example code on how to change the meaning of the .
operators see this reply by Jan W. Note that does not covert the meaning of .
back to an atom, it just converts it to a operator different than the .
used with dicts.
I am thinking there should be some directive that says skip term_expansion/2 for this file for this pattern, but am not finding it.
The comment from the top of swipl-master\boot\expand.pl
<module> Prolog source-code transformation
This module specifies, together with dcg.pl, the transformation of terms
as they are read from a file before they are processed by the compiler.
The toplevel is expand_term/2. This uses three other translators:
* Conditional compilation
* term_expansion/2 rules provided by the user
* DCG expansion
Note that this ordering implies that conditional compilation directives
cannot be generated by term_expansion/2 rules: they must literally
appear in the source-code.
Term-expansion may choose to overrule DCG expansion. If the result of
term-expansion is a DCG rule, the rule is subject to translation into a
predicate.
Next, the result is passed to expand_bodies/2, which performs goal
expansion.
With regards to answer from Jan W.
The trick is to use term_expansion/2 or
goal_expansion/2
to rewrite the A.B term into something else. Of course, you can also change the source and use a different operator.
If I understand that correctly, there are 2 options.
- User term_expansion/2 to change how
.
is used as an operator. In other words substitute in different semantics for.
. - Change the
.
to another character which will not be changed by term_expansion2.
Since option 1 does not leave .
as an atom but converts into an operator that is not an option.
Since option 2 would change the syntax of a typical Lambda expression, e.g. λx.x
, to something like λx#x
I really want to avoid that.
In searching the source code found hook prolog_load_file/2. If this works it would be nice but probably viewed as an abuse of the predicate.