en bilinear



I made function en_bilinear

usage :

(%i23) en_bilinear(k);
(%o23)              [krule4, krule3, krule2, krule1, false]
(%i24) k(3*x+y,u+10*v);
(%o24)               map(lambda([e], k(xx, e)), 10 v + u)
(%i25) ev(k(3*x+y,u+10*v),nouns);
(%o25)          10 (k(y, v) + 3 k(x, v)) + k(y, u) + 3 k(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);

: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 )
)))


en_bilinear(func):=block(
  matchdeclare (xx, all),
  matchdeclare (pp, lambda ([e], not atom(e) and op(e) = "+")),
  tellsimp_func_name_swap(_func_(pp, xx), 'map(lambda ([e], _func_(e,
xx)), pp),_func_,func),
  tellsimp_func_name_swap(_func_(xx, pp), 'map(lambda ([e], _func_(xx,
e)), pp),_func_,func),
  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)
);