Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Prolog operator definitions have xfx?

For languages such as Java and C which allow syntactic sugar with operators, i.e. infix, they use precedence and associativity.

Prolog also uses associativity:
left-associative - yfx
right-associative - xfy

but why is there xfx?

The only thing I have found on the internet giving any more clarity is

xfx means that the operator 'dominates' upon its branches, while xfy or yfx stand for 'list construction', in sense that allow chaining expressions of same priority.

from: Interpretation of Prolog's operator in an exercise by CapelliC

If the answer can include examples where xfx is needed because xfy and yfx fail/don't have meaning, that would be appreciated.

For Prolog reference: The Prolog Built-in Directive op

As false notes:

Please note that the operators you give in above link differ from both the standard and SWI! They are outdated by at least 10 years. As an example, it should be current_op(200,fy,-).

After reading the two current answers by CapelliC and false it became clear that non-associative was the key word to locating more relevant information. So Operator associativity now make more sense with regards to xfx when paying attention to non-associative section.

like image 827
Guy Coder Avatar asked Feb 15 '23 17:02

Guy Coder


2 Answers

The specifier of an operator denotes the class (prefix, infix, postfix) and associativity of an operator.

xfx means that the operator does not permit any form of associativity. In other words: it does not nest with operators of the same priority. However, it does still nest with operators of a lower priority.

The largest part of such operators are predicates of arity two that are used for comparison-like meaning and where nesting would have - at least - an entirely different meaning than what the predicate is about. They are all located at priority 700: High enough to allow all arithmetic operators to work without bracketing ; low enough to work with control constructs and related meta-predicates that expect goals as arguments. Think of (\+)/1, (;)/2, (',')/2.

Consider =<: If you want to state that X is between 1 and 3 you cannot write 1 =< X =< 3 because neither (1 =< X) =< 3 nor 1 =< (X =< 3) make sense in Prolog. In fact, both would lead to an evaluation error. You have to write 1 =< X, X =< 3. which means =<(1, X), =<(X, 3).

For some cases it might make sense to nest, think of (A = B) = P. Here, the first = is just a functor like any other of arity 2, while the second = is the built-in predicate (=)/2 for equality/unification. But such cases are rare and it is worth highlighting them with an extra pair of round brackets.

Note also that :- :- a. is invalid syntax, because (:-)/1 again does not nest.

Arithmetic operators are typically left associative since you process them left-to-right like 1+2+4, first computing 1+2 and only then adding 4. The notable exception is (^)/2: This is so, because (X^Y)^Z =:= X^(Y*Z) whereas (X^(Y^Z)) denotes a term that cannot be expressed with simpler operators.

like image 132
false Avatar answered Feb 23 '23 09:02

false


For instance, (:-)/2 it's clearly an operator that can used only once, because it separates the head from the body.

The separation is 'relative', you could have in a rule, for instance

my_rule :- assertz((a :- b, c)).

Here is the full list of (default) xfx operators from SWI-Prolog

?- setof((X,Y), current_op(X,xfx,Y), L), maplist(writeln, L).
200, (**)
700, (<)
700, (=)
700, (=..)
700, (=:=)
700, (=<)
700, (==)
700, (=@=)
700, (=\=)
700, (>)
700, (>=)
700, (@<)
700, (@=<)
700, (@>)
700, (@>=)
700, (\=)
700, (\==)
700, (\=@=)
700, (as)
700, (is)
1200, (-->)
1200, (:-)
like image 34
CapelliC Avatar answered Feb 23 '23 09:02

CapelliC