Существует несколько способов определения функций, и Maxima действительно не имеет способа обнаружить какой-либо из них. Вот попытка, которая смотрит на свойства символа Lisp, чтобы увидеть, что там.
/* fboundp.mac -- detect different kinds of functions in Maxima
* copyright 2020 by Robert Dodier
* I release this work under terms of the GNU General Public License
*
* Examples:
*
/* Simplifying function defined in Lisp: */
fboundp(sin);
true;
fboundp_simplifying(sin);
true;
/* DEFUN (ordinary argument-evaluating) function defined in Lisp: */
fboundp(expand);
true;
fboundp_ordinary_lisp(expand);
true;
/* DEFMSPEC (argument-quoting) function defined in Lisp: */
fboundp(kill);
true;
fboundp_quoting(kill);
true;
/* Maxima ordinary function: */
(kill(foo),
foo(x) := x,
fboundp(foo));
true;
fboundp_ordinary_maxima(foo);
true;
/* Maxima array function: */
(kill(bar),
bar[x](y) := x*y,
fboundp(bar));
true;
fboundp_array_function(bar);
true;
/* Maxima macro: */
(kill(baz),
baz(x) ::= buildq([x], x),
fboundp(baz));
true;
fboundp_maxima_macro(baz);
true;
*
*/
fboundp(a) :=
fboundp_simplifying(a)
or fboundp_ordinary_lisp(a)
or fboundp_quoting(a)
or fboundp_ordinary_maxima(a)
or fboundp_array_function(a)
or fboundp_maxima_macro(a);
fboundp_simplifying(a) :=
symbolp(a) and ?get(a, ?operators) # false;
fboundp_ordinary_lisp(a) :=
symbolp(a) and ?fboundp(a) # false;
fboundp_quoting(a) :=
symbolp(a) and ?get(a, ?mfexpr\*) # false;
fboundp_ordinary_maxima(a) :=
symbolp(a) and ?mget(a, ?mexpr) # false;
fboundp_array_function(a) :=
symbolp(a) and ?mget(a, ?aexpr) # false;
fboundp_maxima_macro(a) :=
symbolp(a) and ?mget(a, ?mmacro) # false;
EDIT: Я сделал отдельную функцию для проверки каждого вида функций, и я провёл тест для symbolp
чтобы убедиться, что проверка свойств (?get
и ?mget
) не даст сбоев.