Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble defining an infix binary operator in prolog

I'm just new to prolog. I want to define an infix binary operator "rA" which gives me the area of a rectangle when I give the width and breadth of rectangle. This is the code i have:

:-op(300, xfy, rA).

rA(X,Y,R) :- R is X*Y.

The code works fine when I do this:

1 ?- rA(3,4,A).
A = 12. 

What I cant figure out is defining it as a infix binary operator. I get this error:

2 ?- A is 3 rA 4.
ERROR: evaluable `3 rA 4' does not exist 

Thanks

like image 494
BuddyW Avatar asked Dec 20 '22 21:12

BuddyW


2 Answers

You cannot do this in standard Prolog. However, SWI-Prolog used to support user definitions of arithmetic functions but that feature is, I believe, deprecated in recent releases. Check the documentation. A possible alternative is to take advantage of the term-expansion mechanism that several Prolog systems (including SWI-Prolog) define and goal-expand is/2 goals to deal with calls that make use of user-defined arithmetic functions. Something like:

goal_expansion(X is Expression, X is ExpandedExpression) :-
    % traverse and transform Expression

But remember that goal_expansion/2 is called repeatedly until a fix-point is reached. So, be aware of endless loops resulting from trying to expand an already expanded arithmetic expression. One way to solve it is to cache the results of the expansion using a dynamic predicate that is checked when calling goal_expansion/2. The caching dynamic predicate can be abolished e.g. when the end of the file you're processing:

term_expansion(end_of_file, _) :-
    abolish(...), % the argument will be the predicate indicator of the caching predicate
    fail.

When expanding end_of_file is advised to fail after performing whatever actions are necessary as there could be other (orthogonal) expansions also relying on the expansion of end_of_file.

like image 113
Paulo Moura Avatar answered Jan 16 '23 04:01

Paulo Moura


You've got a good answer by Paulo, anyway here is an example of the details required to instruct SWI-Prolog about your function:

22 ?- [user].
|: :- arithmetic_function(rA/2).
|: rA(X,Y,Z) :- Z is X*Y.
% user://1 compiled 0.07 sec, 3 clauses
true.

23 ?- F is rA(3,6).
F = 18.

24 ?- [user].
|: :-op(300,xfx,rA).
% user://2 compiled 0.02 sec, 1 clauses
true.

25 ?- F is 3 rA 6.
F = 18.
like image 34
CapelliC Avatar answered Jan 16 '23 04:01

CapelliC