PLOGHELP OP Jonathan Laventhol Jun 1983 Revised: Kathryn Seifert Aug 1986 Revised: Simon Nichols May 1987 Revised: Adrian Howard Jul 1992 Operators and how to declare them. ?- op(, , ). Keywords: operators, precedence, type, fix, associativity CONTENTS - (Use g to access required sections) -- INTRODUCTION -- DECLARING OPERATORS -- PRECEDENCE -- ... REMOVING OPERATORS -- TYPE -- EXAMPLES -- CHANGING BACK TO STANDARD OPERATOR DECLARATIONS -- RELATED DOCUMENTATION -- INTRODUCTION ------------------------------------------------------- Operators in Prolog are a notational convenience for reading and writing certain compound terms, i.e. those whose principal functor has previously been declared as an operator using the evaluable predicate op/3. For example, the term: 2 + 1 is a compound term whose functor is named '+' of arity 2, with arguments 1 and 2. -- DECLARING OPERATORS ------------------------------------------------ A call of op/3 takes the following form: ?- op(, , ). and declares an atom A or a list of atoms L as operators with precedence P and type T (these terms are explained below). When a list of atoms L is given as the third argument to 'op', all of the atoms in the list will be declared as operators with the same associativity and type. Thus, ?- op(Prec, Type, Atom). declares Atom as an operator of given precedence and type, and ?- op(Prec, Type, [Atom|Atoms]). declares Atom and each member of Atoms as operators with the same precedence and type. Using 'op', any standard system operator declaration can be changed by the user. See PLOGHELP * OPERATORS for a list of the standard operator declarations which are made when POPLOG Prolog is loaded. -- PRECEDENCE --------------------------------------------------------- The precedence of an operator is indicated by an integer from 1 to 1999. It is used to disambiguate expressions where the structure of the term is not made explicit through the use of brackets. The lower the numerical value of the precedence, the greater the "binding power" of the operator. Given any term, the general rule is that the operator with the highest precedence, i.e. the operator which binds least tightly, is the principal functor (this can, of course, be changed by the appropriate use of brackets). In other words, the expression with the operator which binds most tightly is evaluated first. Thus, since the multiplication operator '*' has a numerically lower precedence value (21) than the addition operator '+' (31), the expression 1 + 4 * 3 is interpreted as 1 + (4 * 3) -- ... REMOVING OPERATORS --------------------------------------------- If instead of an integer the atom "off" is given then the specified operator is removed instead of being declared. For example: :- op(off, xfx, and). Will remove a previously declared operator and/2. -- TYPE --------------------------------------------------------------- The type of an operator encodes two pieces of information: it determines the "fix" (or position) of an operator and its associativity. An operator may appear in one of three positions: 1. INFIX -- the operator appears between its two arguments. 2. PREFIX -- the operator precedes its single argument. 3. POSTFIX -- the operator appears after its single argument. Infix operators are BINARY - they take two arguments - and prefix and postfix operators are UNARY - they take a single argument. If, in an expression, the argument to an operator with precedence P is a subexpression whose principal functor is an operator which also has a precedence of P, there is an ambiguity which must be resolved using the associativities of the operators. The possible values for indicating the type (fix and associativity) in an operator declaration are the following atoms: Prefix operators: fx fy Postfix operators: xf yf Infix operators: xfx xfy (right associative) yfx (left associative) The 'f' stands for the functor (i.e. the operator) and the 'x's and 'y's for its arguments; the choice of whether to indicate an argument by an 'x' or by a 'y' determines the associativity of the operator. An 'x' stands for a subexpression which can contain an operator whose precedence is numerically less than the precedence of the operator 'f', i.e. its principal functor must be of lower precedence, unless the subexpression is explicitly bracketed. A 'y' stands for a subexpression which can contain an operator with a precedence less than or the same as the precedence of the operator 'f'. A binary operator can be declared to be one of left associative, right associative or non-associative. For a given operator, such as '++', this choice determines how an expression such as: a ++ b ++ c is interpreted. After the declaration :- op(100, xfy, ++). % declare '++' to be right associative the following two expressions are equivalent: a ++ b ++ c a ++ (b ++ c) Conversely, after the declaration :- op(100, yfx, --). % declare '--' to be left associative the following two expressions are equivalent: a -- b -- c (a -- b) -- c Finally, given the declaration :- op(100, xfx, **). % declare '**' to be non-associative the following expression is ILLEGAL: a ** b ** c and requires bracketing. Similar considerations apply to prefix and postfix operators. After the declaration :- op(100, fy, not). % declare 'not' as a prefix operator the following expressions are equivalent: not not P not(not P) However, if 'not' were declared with type 'fx', only the second of the above expressions would be legal. -- EXAMPLES ----------------------------------------------------------- The division operator '/' is normally declared as a left associative infix operator (yfx) : :- op(21, yfx, /). Thus, the following expressions are equivalent: ?- X is 6 / 2 / 3. X = 1 ?  yes ?- X is (6 / 2) / 3. X = 1 ?  yes However, we can redefine '/' as a right associative operator: :- op(21, xfy, /). Now the following expressions are equivalent: ?- X is 6 / 2 / 3. X = 9 ?  yes ?- X is 6 / (2 / 3). X = 9 ?  yes The multiplication operator '*' is normally declared as an infix operator with precedence 21, and the addition operator '+' is normally declared as an infix operator with precedence 31. Thus, the following expressions are equivalent: ?- X is 9 * 2 + 7. X = 25 ?  yes ?- X is (9 * 2) + 7. X = 25 ?  yes -- CHANGING BACK TO STANDARD OPERATOR DECLARATIONS -------------------- If you have made some changes to the declarations of built-in Prolog operators and you wish to change them back to their standard declarations, use library DEFAULT_OPS. See PLOGHELP * DEFAULT_OPS for more details. -- RELATED DOCUMENTATION ---------------------------------------------- PLOGHELP * CURRENT_OP How to get the precedence, fix and atom of the current operator PLOGHELP * DEC10 Library file to change operator precedences to those of DEC10 Prolog PLOGHELP * DEFAULT_OPS How to restore operator precedences to their default values PLOGHELP * OPERATORS Operator declarations made when the Prolog system is loaded --- C.all/plog/help/op ------------------------------------------------- --- Copyright University of Sussex 1987. All rights reserved. ----------