[Question]
  [
Trigonometry has LOTS of identities. So many that you can expand most functions into sines and cosines of a few values. The task here is to do that in the fewest bytes possible.
# Identity list
Well, the ones we're using here.
```
sin(-x)=-sin(x)
sin(π)=0
cos(-x)=cos(x)
cos(π)=-1
sin(a+b)=sin(a)*cos(b)+sin(b)*cos(a)
cos(a+b)=cos(a)cos(b)-sin(a)sin(b)
```
For the sake of golfing, I've omitted the identities that can be derived from these. You are free to encode double-angles and such but it may cost you bytes.
# Input
* You should take in an expression as a string with an arbitrary number of terms consisting of a coefficient and some sine and cosine functions, each with an exponent and an arbitrary number of arguments.
* Coefficients will always be nonzero integers.
* Each argument will be a coefficient, followed by either a single latin letter or pi.
* You can decide whether to take in pi as `pi` or `π`. Either way remember that you're scored in bytes, not characters.
# Output
Output the same expression, but…
* All trig functions are either `sin` or `cos`.
* All arguments of trig functions are single variables, with no coefficients.
* All like terms are combined.
* Terms with a coefficient of 0 are removed.
* All factors in the same term that are the same function of the same variable are condensed into a single function with an exponent.
Note: Leading `+` signs are allowed, but not required. `a+-b` is allowed, and equivalent to `a-b`. If there are no terms with nonzero coefficients, then output either `0` or an empty string.
# Worked Example
We'll start with `sin(-3x)+sin^3(x)`. The obvious first thing to do would be to deal with the sign using the parity identity, leaving `-sin(3x)`. Next I can expand `3x` into `x+2x`, and apply the sine additive identity recursively:
```
-(sin(x)cos(2x)+cos(x)sin(2x))+sin^3(x)
-(sin(x)cos(2x)+cos(x)(sin(x)cos(x)+sin(x)cos(x)))+sin^3(x)
```
Next, some distributive property and like terms:
```
-sin(x)cos(2x)-2cos^2(x)sin(x)+sin^3(x)
```
Now, I expand the `cos(2x)` and apply the same reduction:
```
-sin(x)(cos(x)cos(x)-sin(x)sin(x))-2cos^2(x)sin(x)+sin^3(x)
-sin(x)cos^2(x)+sin^3(x)-2cos^2(x)sin(x)+sin^3(x)
2sin^3(x)-3sin(x)cos^2(x)
```
And now, it's finished!
# Test Cases
In addition to the following, all of the individual identities (above) are test cases. Correct ordering is neither defined nor required.
```
cos(2x)+3sin^2(x) => cos^2(x)+2sin^2(x)
sin(-4x) => 4sin^3(x)cos(x)-4sin(x)cos^3(x)
cos(a+2b-c+3π) => 2sin(a)sin(b)cos(b)cos(c)-sin(a)sin(c)cos^2(b)+sin(a)sin(c)sin^2(b)-cos(a)cos^2(b)cos(c)+cos(a)sin^2(b)cos(c)-2cos(a)sin(b)cos(b)sin(c)
sin(x+674868986π)+sin(x+883658433π) => 0 (empty string works too)
sin(x+674868986π)+sin(x+883658434π) => 2sin(x)
```
…and may the shortest program in bytes win.
  
[Answer]
# [Bracmat](https://github.com/BartJongejan/Bracmat), 221 bytes
```
(P=F v a b.!arg:((sin|cos):?F.?v)&(!v:@&(!F.!v)|!F$!v)|!arg:%?a_%?b&(P$!a)_(P$!b)|!arg)&(f=i a b n u.1+(!arg:e^(?n*((i|-i):?i)*?u+?b)&(!i*(sin.!u)+(cos.!u))^!n*f$(e^!b)|!arg:%?a_%?b&(f$!a)_(f$!b)|!arg)+-1)&(Z=.f$(P$!arg))
```
[Try it online!](https://tio.run/##jY7NboMwEITvfQosEbK2haUESl0k5J4455wDkY0gtdRCxF858O7UBlKuvXhXszPzWTUy/5bdPMMlSZ3BkY5iSDb3GKDV1ZTXLY5FysSAPUBD/GHelKEBTyh1l2G9ByFvB6E8uLhI4psdaj2ZVJlo2@pUTs9OFJZAkYGoCICefG36NSaip0JZhiYWzFCPKRi6XXCGKlK6UGTP2p1YrsRyJ1L/ZHquCTMJ@x8j4fnn8@sI96I7xqIYH03RtrquvLrv3KuLdgXPC/xMRvyy0NfNan5gVrqsI86C/UwD8lTPmzX8y0t6Jsr8iOTG9tBb10ijt5BH/J1HVtxaKedB9MrD4P/OcHH@Ag "Bracmat – Try It Online")
[Answer]
# Python3, 841 bytes
Longer than I hoped, but the logic is straightforward.
```
E=enumerate
S,O='sin','cos'
def f(e):
 e=[[(a,b,[([1,-1][j<0]*([1,j]['pi'==C]),C)for j,C in c for _ in range(1,abs(j)+1 if'pi'!=C else 2)],d)for a,b,c,d in i]for i in e]
 P=1
 while P:
  P=0
  for i,a in E(e):
   F=0
   for I,A in E(a):
    if len(A[2])>1:q,*w=A[2];l=[[(A[0],S,[q],1),(1,O,w,1)],[(A[0],S,w,1),(1,O,[q],1)]]if S==A[1]else[[(A[0],O,[q],1),(1,O,w,1)],[(-1*A[0],S,[q],1),(1,S,w,1)]];l=[u+a[:I]+a[I+1:]for u in l];e=e[:i]+e[i+1:]+l;F=1;break
   if F:P=1;break
 r={}
 for i in e:
  R,T={},1
  for a,b,[(C,V)],d in i:
   if C==-1 and'sin'==b:a*=-1
   if'pi'==V:
    if(L:=[[1,-1][abs(C)%2],0][b==S])==0:R,T={},0;break
    else:T*=L*a
   else:R[(b,V)]=R.get((b,V),0)+d;T*=a
  r[M]=r.get(M:=str(sorted(R.items())),0)+T
 return' + '.join(str(b)+''.join(f'{j}{["^"+str(l),""][l==1]}({k})'for(j,k),l in eval(a))for a,b in r.items()if b)
```
[Try it online!](https://tio.run/##tVTdbtowFL7PU3igKTZxKkwyxsI8qUKtVKlVK6h6Y7lTAqYNTUMbYDAhpL3hHokd2yTQtap2sxvr/H7nOz/J08/5/TQPOk/FdnvCVb54VEU8V86AXnJ3luYudYfTmeuM1BiNsSKRgxQXAsc0oQILRn0mxeRrUza0MpHCfUpdznuS0B4ZTws0oT2U5miItPJdi0Wc3ynMaJzM8IR4DKVjnfSB95DKZgq1iKQjk6uLDOlIJ6VSG1ItKumgK84ctLxPM4WugBLoTXhNCI110InlitCp8RjXGT22rti6oDDKVI6PRUuSbyx6po0l10o30y0ei6akAyqeJWWEAuFLugRJ0sq1rBw2SEpAHHDAYFK3UoJcvgnis8arEhZTGgYLLxbRmYT3zGOR6X@h@Weyq7gSUSo9JVLt8rLuKWfdpFDxg2P7Oo2u9paCrzcO2g9Qd9@n12ClbDc2u88evdHDNwOPdkg9zn2G4nxkzoHzJIobYLFeu@2bcpz4PILJ2aPQ6@2Rjy1Jm1IknA8k4bwZ7eo292zN1qPrBj9vxE6p9gVONBneP7pTc2wU2iTeqAuBOqwQF5IXxnkR8dm8wLNpMVcj3D9K5@pxhgkxCdfQvpovitxFHnKPJtM0xzo6IZ67U8fuerJZi9ptzdOejNBaTYqMcyY3eP2wIS5MCE/oA6GZmd@POIMbKk/U3HRZFAaWkK1jvhFGkf2EECw7AGXlwnSR3f6hk1W@AHaP6mCHhBXxQLgN8Io4T0Waz7H@AAmqt0qzH@jIFYEv9Lalw2xmCNJrAuEhAfkSMSwRAUnjhntcU96pa0fstRJ/6AW/fx3g679D2UPsEopwC6TESL4JMKJuH27l7fK6IRiofhNDwb5D4u8dw12XiZlKZdTEtdE3BKsYm@5ZYxmzw2xV1qqaxXLs/FZe@3PYaXe@dNrQqWdNnU7Q/tQJg5fN/7VA6LNKfdFvGfM6vsJ9bz6u@y/Uwv9ELXyPWhVkKwfUAh3eA6vuYXcO9ld5iFMm72mURff3tCuP6u3DzR2ibP8A)
]