Prolog - precedence of operators - Bratko - Chapter 3

Viewed 148

I am working through the exercises in Chapter 3 in 'Prolog Programming for Artificial Intelligence' by Ivan Bratko.

Exercise 3.13 states:

Suggest an appropriate definition of operators ('was', 'of', 'the') to be able to write clauses like:

diana was the secretary of the department.

and then ask Prolog:

?- Who was the secretary of the department.

Who = diana

?- diana was What.

What = the secretary of the department.

The answer to this exercise is:

:- op(300, xfx, was).
:- op(200, xfx, of).
:- op(100, fx, the).

However, I am not sure what the structure of the term 'diana was the secretary of the department' would look like. I know that the operator with the highest precedence is the principal functor of the expression, so in this case the principal functor would be 'was'.

My answer for what the structure of the term is:

was(diana, of(the(secretary, the(department))).

I don't know if my answer is correct, so I was wondering if anyone could help clarify this.

1 Answers

An ISO predicate is write_canonical/1 [swi-doc] that prints such expression in a canonical way, for example:

?- write_canonical(Who was the secretary of the department).
was(_,of(the(secretary),the(department)))
true.

So we see that the/1 binds more close than of/2 and was/2.

Of course this is not just guesswork by Prolog, you define the precedence in your op/3 [swi-doc] call. The first parameter is the precedence. The documentation says that:

Precedence is an integer between 0 and 1200. (...) For x the precedence of the argument must be strictly lower. The precedence of a term is 0, unless its principal functor is an operator, in which case the precedence is the precedence of this operator. A term enclosed in parentheses ( ... ) has precedence 0.

So if the precedence is lower, it binds "closer". Brackets have a precedence of 0 and thus have "priority" over all other operators.

Since the the/1 operator in your definition has precedence 100, it thus means that the binds closer, and of/2 will bind on a higher level than the/1, and was/2 will bind on a higher level in the syntax tree than of/2.

If you thus want to add a fact that diana was the secretary of the department, you should write a fact like:

was(diana, of(the(secretary), the(department))).

Then we can query like:

?- Who was the secretary of the department.
Who = diana.
Related