# Use Operators for Predicate Names

It is possible to give predicates operators as names so long as the operator is one of the predefined operators (listed [here][ops]) and is not already defined as a predicate. This saves a few bytes both when defining and calling the predicate since operator predicates do not need to be written in the normal `name(arg1,arg2,etc..)` form and can be called as one might expect with operators.

For one and two argument predicates, they can be give the names of unary and binary operators, respectively. For higher arity predicates, we can still avoid parentheses using pattern matching. For example if we have a predicate `A+B+C:-...`, Prolog will use its [operator precedence and associativity rules][ops] to transform it into `(A+B)+C:-...` which is a operator predicate where the first argument is pattern matched to `A+B`. Or `A-B+C*D:-...` which becomes `(A-B)+(C*D)` so its first argument is pattern matched to `A-B` and its second is pattern matched to `C*D`.

### Examples

    _+_+_.
    A-B+C*D:-between(A,B,C),C+D.
    \X:-X>1,X<10.
    X+Y:-length(Y,X),member(X,Y).



    5+[10,5,3,2,5],a+b+c,0-20+X*[2,4,6,5,40],\9.

The output will be `X = 5.`

[Try it Online!][tio-example]

## Corollary

Since [DCGs] are syntactic sugar for predicates they too can be given operators for names. This works as expected when calling them as DCGs either from a DCG or using the `phrase` predicates or others that are designed to work with DCGs. When calling them as predicates parentheses are required (eg `A+B-->...` must be called like `+(A,B,...)`) since DCG predicates take an additional two arguments for their difference lists. For operator named DCGs with more than two arguments using operator pattern matching then it is important to make sure when calling it as a predicate that the pattern matched operators are distributed correctly.

Giving operator names to DCGs that take no additional arguments can be useful if you need to call them within your program since then you can do so without using parentheses. Caution is required because it can be the case that what you save in parentheses you can lose to added spacing required to parse adjacent operators.

### Examples

    / -->a+b+X,X+d+e.
    A+B+C-->[A],[B],[C].


    X/[],member(c,X),phrase(f+o+o,Y),+(b+a,r,Z,[]).

Output will be

    X = [a, b, c, c, d, e],
    Y = [f, o, o],
    Z = [b, a, r].

[Try it online!][tio-dcgs]

## Caveats

With the unary operators `+` and `-`, Prolog will interpret `+20` or `-20` as numbers instead of a call to a `+/1` or `-/1` predicate. Predicates given unary `+` or `-` as names can still be called on number by using parentheses (`+(20)`, `-(20)`). If avoiding the extra bytes from parentheses is desirable other unary operators such as `\`, `$`, etc can be used as names instead.

The combination of pattern matching and operator named predicates is not entirely without flaws. If you have two predicates that have the same operator as their name and with pattern matching one is strictly more general than the other then the more general one may get called first or if the less general one fails (depending on their ordering in the source). For instance in the example above if `A-B+C*D` fails to match its input then Prolog will try calling `X+Y`. This will result in an error because `length/2` require `Y` to be an integer which it will not be since it will be in the form `C*D`. This can be avoided simply by making sure no two predicates have the same operator as their name or if that fails then using cuts and careful ordering of the source.


[tio-example]: https://tio.run/##DclZCoMwFAXQ/6xEfTchplpoKAWHRbygUqoEW3AoVnD5qZzP893WaR3l7/iE8KSTEoUsqUpqK3u/H94vUYESVYyKaiVatpIfKfieaiWYnJWTX8b9HTlwjNnPvd8ihotVCDk1qUaOCwzyDi/qaYCWRhMnjUGG65mZ7tDelBB/
[tio-dcgs]: https://tio.run/##DcgxDoMgAAXQnVN0hPwP3sAEvASVMICl1aQGA0OPTx3e8q5Wv/Wj@@8YY3poPSdkeHq8UIywcFjuDDYyuNsSzRh@CpFnOXNpcqNXvPaWepFvVFQ@FSEzEhtXhqiMEH8 "Prolog (SWI) – Try It Online"

[ops]: http://www.swi-prolog.org/pldoc/man?section=operators
[DCGs]: http://www.swi-prolog.org/pldoc/man?section=DCG