en bilinear



Thank you show useful code
That code enables bilinear without  ev(..., nouns).


/* bilinear */

(%i11) en_bioutative(g);
(%i14) load("multiadditive");
(%i15) declare(g,multiadditive);
(%i16) g(5*x+4*z,2*u+3*v);
(%o16)         12 g(z, v) + 8 g(z, u) + 15 g(x, v) + 10 g(x, u)



----------------

swap_function_in_expr(f_from,f_to,expr):=scanmap(  lambda([x],if
atom(x) then x else if op(x) = f_from then substpart(f_to,x,0) else
x),expr);
/*usage
(%i2) swap_function_in_expr(f,k, h(f(x+a)+a)+f(f(x))*c);
(%o2)                     h(k(x + a) + a) + c k(k(x))

*/


:lisp (defun $tellsimp_func_name_swap  (expr_from expr_to fname_from
fname_to )  (proc-$tellsimp    (list      (mfuncall
'$swap_function_in_expr fname_from  fname_to  expr_from )
(mfuncall '$swap_function_in_expr fname_from  fname_to  expr_to )
)))


/*usage
is_op_p(expr,op_):=if atom(expr) then false else operatorp(expr,op_);
neg_expr_p(expr):=is_op_p(expr,"-");
matchdeclare([negexpr],neg_expr_p);

tellsimp_func_name_swap(f(negexpr),-f(-negexpr),f,h);
tellsimp_func_name_swap(f(negexpr),-f(-negexpr),f,g);

f(-x)
g(-x)
h(-x)

(%i7) f(-x);
(%o7)                               f(- x)
(%i8) g(-x);
(%o8)                               - g(x)
(%i9) h(-x);
(%o9)                               - h(x)

*/



en_bioutative(func):=block(
  matchdeclare (xx, all),
  matchdeclare (bb, lambda ([e], scalarp(e) and e # 1)),
  matchdeclare (uu, lambda ([e], not scalarp(e))),
  tellsimp_func_name_swap(_func_(xx, bb*uu), bb * _func_(xx, uu),_func_,func),
  tellsimp_func_name_swap(_func_(bb*uu, xx), bb * _func_(uu, xx),_func_,func)
);


/*usage
(%i11) en_bioutative(g);
(%o11)                  [grule5, grule4, grule3, false]
(%i12) g(5*x,y);
(%o12)                             5 g(x, y)
(%i13) g(5*x,10*y);
(%o13)                            50 g(x, y)
*/

---------------