How to suppress the dot '.' operator for dict

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 the system module.

but I can not find where this occurs in the SWI-Prolog code.

Personal Notes (Click triangle to expand)

./3 definition in source code

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


?- current_op(A,B,.).

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

<module> Prolog source-code transformation

This module specifies, together with, 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

Next, the result is  passed  to   expand_bodies/2,  which  performs goal

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.

  1. User term_expansion/2 to change how . is used as an operator. In other words substitute in different semantics for ..
  2. 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.

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.

9 posts were split to a new topic: Is there a simple way to use the symbol “.” as just an atom like “+”, “*”, “-”, etc