
op(+Precedence, +Associativity, ++Name)
local op(+Precedence, +Associativity, ++Name)
export op(+Precedence, +Associativity, ++Name)

   Declare operator syntax.

Arguments
   Precedence          Integer.
   Associativity       Atom.
   Name                Atom or List of atoms.

Type
   Syntax Settings

Description
   Declares Name as an operator of precedence Precedence and associativity
   Associativity. Operators are purely a syntactic convenience: they allow
   prefix-, infix- or postfix-syntax as an alternative to the canonical
   functor-syntax for structures with one or two arguments. If used
   carefully, they can contribute to making code more readable.

   Precedence is an integer in the range 0 to 1200. An operator with a lower
   precedence number binds its arguments more strongly than an operator with
   higher precendence number.

   The different classes of operators are distinguished through the
   Associativity argument:

    Operator class      Associativities
    ---------------------------------------------------------------
     prefix             fx, fy (unary) or fxx, fxy (binary)
     infix              xfx, xfy, yfx
     postfix            xf, yf

   x represents an argument whose precedence must be lower than that of the
   operator.  y represents an argument whose precedence must be lower or
   equal to that of the operator.  y should be used if one wants to allow
   chaining of operators.  The position of the y will determine the
   grouping within a chain of operators. Examples:

    Example declaration        will allow          to stand for
    ---------------------------------------------------------------
    :- op(500,xfx,in).         A in B              in(A,B)
    :- op(500,xfy,in).         A in B in C         in(A,in(B,C))
    :- op(500,yfx,in).         A in B in C         in(in(A,B),C)
    :- op(500,fx ,pre).        pre A               pre(A)
    :- op(500,fy ,pre).        pre pre A           pre(pre(A))
    :- op(500, xf,post).       A post              post(A)
    :- op(500, yf,post).       A post post         post(post(A))
    :- op(500,fxx,bin).        bin A B             bin(A,B)
    :- op(500,fxy,bin).        bin A bin B C       bin(A,bin(B,C))

   Prefix, infix and postfix operators are independent of each other and
   may coexist.  See the manual chapter on syntax about how ambiguities are
   resolved in this case.

   Operators can be local or exported, depending on the definition. The
   default is local, i.e. the following declarations are equivalent:

    :- op(500, xfy, before).
    :- local op(500, xfy, before).

   while

    :- export op(500, xfy, before).

   will export the operator to all modules that import the module containing
   the declaration.  There are also a number of predefined global operators,
   see the User Manual appendix for a complete list.

   Name may be a single atom or a list of atoms, in which case each is
   given the specified precedence and associativity.  A value of [] is
   interpreted as the empty list.  To declare [] as an operator, use
   e.g. op(500,fx,[[]]).

   A precedence of 0 has a special meaning.  It erases a local operator
   definition and/or hides a global operator of the same name and
   associativity class.



Modes and Determinism
   op(+, +, ++) is det

Modules
   This predicate is sensitive to its module context (tool predicate, see @/2).

Exceptions
     4 --- Any of the input arguments is uninstantiated.
     5 --- Precedence is not an integer.
     5 --- Name is not an atom or list of atoms.
     5 --- Associativity is not an atom.
     6 --- Precedence is not in range 0 to 1200.
     6 --- Associativity is not one of xf, xfx, fy, etc.

Examples
   
Success:
      [eclipse]: module(a).
      [a]: current_op(X, Y, +).    % there are two global operators
      X = 500
      Y = yfx     More? (;)
      X = 500
      Y = fx     More? (;)
      no (more) solution.
      [a]: display(a+b*c).         % see how it is parsed
      +(a, *(b, c))
      yes.

      [a]: op(100, xfy, +).        % define a local infix
      yes.
      [a]: display(a+b*c).         % parsed differently now!
      *(+(a, b), c)
      yes.

      [a]: op(0, xfy, +).          % just hide the global infix
      yes.
      [a]: current_op(X, Y, +).
      X = 500
      Y = fx     More? (;)
      no (more) solution.

Error:
      op(X, fx, aaa).             (Error 4).
      op(a, fx, aaa).             (Error 5).
      op(100, xfx, 1).            (Error 5).
      op(100, abc, fred).         (Error 6).
      op(100, xfx, aaa),
          op(100,xf,aaa).         (Error 43).





See Also
   current_op / 3, local / 1, export / 1
