:

## Pattern Based Transforms

Maple
This topic was developed in a discussion with Mad Math. In Maple, pattern based transforms can be done using following Subs procedure,
```Define:=()->
define(subsindets([args],specfunc(anything,args[1]),
y->subsindets(y,indexed,x->convert(op(0,x),function,[op(x)])))[]):

Subs:=proc(a,b) local T,c;
Define(T,T(subs(`&*`=`*`,`&+`=`+`,lhs(a)))=rhs(a));
c:=subsindets(b,subs(map(y->y=op(2,y),
indets(subsindets(lhs(a),indexed,
x->convert(op(0,x),function,[op(x)])),symbol::type)),lhs(a)),T);
eval(c,T=(x->x)) end:```
For example,
```Subs(f([x::anything,y::anything])=p(x+y), f([a,b])+f(c));

p(a + b) + f(c)

Subs(a::identical(x)^n::anything=r(n), [1,x,x^2,x^3]);

[1, x, r(2), r(3)]

Subs(eps(i::anything,j::anything,k::anything) &*
eps(i::anything,j::anything,l::anything)=delta(k,l),
eps(a,b,c)*eps(a,b,d));

delta(c, d)

Subs(K[i::anything,k::anything]&*K[j::anything,k::anything] = s(i,j),
K[a,c]*K[b,c]);

s(a, b)
```
With sequences the situation is slightly different, because there is no such type as an expression sequence. Nevertheless, Subs can be used. For example,
```Subs(a::specfunc(anything,f)=p('op(a),op(a),op(a)'), f(a,b,c));

p(a, b, c, a, b, c, a, b, c)

Subs(a::specfunc(anything,f)=g('0,op(a),0,op(a),0'), f(x,y,z)+f());

g(0, x, y, z, 0, x, y, z, 0) + g(0, 0, 0)
```
Actually, for cases with one underscore (i.e. not for sequences), notation can be made very close to Mathematica notation,
````&/`:=proc(a,b) local S;
S:=selectremove(x->sprintf("%s",x)[-1]="_",
indets(subsindets(lhs(b),indexed,
x->convert(op(0,x),function,[op(x)])),name));
Subs(subs(map(x->x=x::anything,S[1]),
map(x->x=cat(x,`_`)::identical(x),S[2]),lhs(b))=
subs(map(x->nprintf("%s",sprintf("%s",x)[1..-2])=x,S[1]),
map(x->x=cat(x,`_`),S[2]),rhs(b)),a) end:

(f([a,b])+f(c)) &/ (f([x_,y_])=p(x+y));

p(a + b) + f(c)

[1,x,x^2,x^3] &/ (x^n_=r(n));

[1, x, r(2), r(3)]

(eps(a,b,c)*eps(a,b,d)) &/ (eps(i_,j_,k_)&*eps(i_,j_,l_)=delta(k,l));

delta(c, d)

(K[a,c]*K[b,c]) &/ (K[i_,k_]&*K[j_,k_] = s(i,j));

s(a, b)```
For the operator precedence reasons, one has to add parentheses in both sides of &/. Here is another example,
```z:=sin(x)-sin(x*(1-exp(-x))):

z &/ (sin(x_)&+((-1)&*sin(y_))=trigsubs(sin(x)-sin(y))[]);

2 cos(- x/2 - 1/2 x (1 - exp(-x))) sin(x/2 - 1/2 x (1 - exp(-x)))
```

﻿