# Current_arithmetic_function/1 - Ever wanted to check if something is an arithmetic function?

current_arithmetic_function/1
is/2

``````?- X is abs(sin(5)).
X = 0.9589242746631385.
``````
``````?- current_arithmetic_function(abs(sin(X))).
true.
``````

``````?- current_arithmetic_function(Head),numbervars(Head).
...
``````

As a portability person, I have to point out that current_arithmetic_function/1 is SWI-specific and not supported by any other Prolog system that I know of. As such, it isnâ€™t useful when youâ€™re writing code for multiple systems and want to check if an arithmetic function is supported by the current system. On non-SWI systems, the only way to check if an arithmetic function exists is to try calling it and check if it throws an error or not.

You can define a helper predicate like this that checks if an arithmetic function exists. This will use current_arithmetic_function/1 if possible and fall back to catch/3 otherwise. (Although for this use case current_arithmetic_function/1 doesnâ€™t offer that much benefit, so it may be simpler to just always use the catch/3-based solution.)

``````:- if(predicate_property(current_arithmetic_function(_), _)).
% Use current_arithmetic_function/1 if possible (supported by SWI).
check_arithmetic_function(FuncCall) :-
current_arithmetic_function(FuncCall).
:- else.
% Otherwise try to call the function and see if it works or not.
check_arithmetic_function(FuncCall) :-
catch(_Res is FuncCall, _Error, false).
:- endif.
``````

Example usage:

``````% SWI
?- check_arithmetic_function(log(2, 4)).
false.
?- check_arithmetic_function(ceil(1.5)).
true.
% SICStus
| ?- check_arithmetic_function(log(2, 4)).
yes
| ?- check_arithmetic_function(ceil(1.5)).
no
``````

Might be wise to check the error. Should be `error(type_error(evaluable, Name/Arity), _)`. It still isnâ€™t satisfactory though. For example code analysis cannot easily use this as it doesnâ€™t have concrete values for the arguments and there is no easy way to know what arguments are valid for a function. `current_arithmetic_function/1` (or something similar) should have been in the ISO core standard â€¦

1 Like