# inverse function;
#inverse(a_+b_,x_):= If(isfree(a,x), replace(inverse(b,x),x,x-a), If(isfree(b,x), replace(inverse(a,x),x,x-b) ));
#inverse(a_+b_+c_,x_):= If(isfree(a,x), replace(inverse(b+c,x),x,x-a) );
#inverse(a_*b_,x_):=If(isfree(a,x), replace(inverse(b,x),x,x/a),If(isfree(b,x), replace(inverse(a,x),x,x/b) ));


inverse(c_+y_+y_^2, x_) := If(isfree(c,x), inverse(-y-1/2+sqrt(1-4*c)/2 and -y-1/2-sqrt(1-4*c)/2,x));
inverse(c_+b_*y_+y_^2, x_) := If(isfree(b,c,x), inverse(-y-b/2+sqrt(b^2-4*c)/2 and -y-b/2-sqrt(b^2-4*c)/2,x));
inverse(c_+y_+a_*y_^2, x_) := If(isfree(a,c,x), inverse(-y+(-1+sqrt(b^2-4*c))/(2a) and -y+(-1-sqrt(b^2-4*c))/(2a),x));
inverse(c_+b_*y_+a_*y_^2, x_) := If(isfree(a,b,c,x), inverse(-y+(-b+sqrt(b^2-4*c))/(2a) and -y+(-b-sqrt(b^2-4*c))/(2a),x));

inverse(c_+x_+x_^2, x_) := If(isfree(c,x), (-1/2+sqrt(1-4*c+4*x)/2 and -1/2-sqrt(1-4*c+4*x)/2));
inverse(c_+x_+a_*x_^2, x_) := If(isfree(a,c,x), ((-1+sqrt(1+4*a*x-4*a*c))/(2*a) and (-1-sqrt(1+4*a*x-4*a*c))/(2*a)) );
inverse(c_+b_*x_+x_^2, x_) := If(isfree(b,c,x), (-b/2+sqrt(b^2+4*x-4*c)/2 and -b/2-sqrt(b^2+4*x-4*c)/2));
inverse(c_+b_*x_+a_*x_^2, x_) := If(isfree(a,b,c,x), ((-b+sqrt(b^2-4*a*c+4*a*x))/(2*a) and (-b-sqrt(b^2-4*a*c+4*a*x))/(2*a)));

inverse(laplace(y_,x_,n_),x_):=inverselaplace(y,x,n);
inverse(d(y_,x_,n_),x_):=d(y,x,-n);
inverse(d(y_,x_),x_):=integrate(y,x);
inverse(integrate(y_,x_),x_):=d(y,x);
inverse(difference(y_,x_),x_):=sum(y,x);
inverse(sum(y_,x_),x_):=difference(y,x);
inverse(inverse(y_,x_),x_):=y;

inverse(y_/W(y_),x_):= replace(inverse(y,x),x,x*log(x));
inverse(y_/W(b_*y_),x_):= if(hasnot(b,x),replace(inverse(y,x),x,x*log(b*x)) );
inverse(W(y_)/y_,x_):= replace(inverse(y,x),x, -log(x)/x);
inverse(W(a_*y_)/y_,x_):= if(hasnot(a,x),replace(inverse(y,x),x, -1/a*log(x)/x) );
inverse(b_*W(a_*y_)/y_,x_):= if(hasnot(a,b,x),replace(inverse(y,x),x, -1/a*log(a*b*x)/x) );

inverse(y_^a_,x_):=If(isfree(a,x), replace(inverse(y,x),x,x^(1/a)), replace(inverse(a,x),x,W(log(y))) );
inverse(x_^x_,x_):=exp(W(log(x)));
inverse(x_^(x_^n_),x_):=if(hasnot(n,x),exp(1/n*W(n*log(x))));
inverse(x_^(n_*x_),x_):=if(hasnot(n,x),exp(W(1/n*log(x))));
inverse(y_^2,x_):=replace(inverse(y,x),x,sqrt(x)) and replace(inverse(y,x),x,-sqrt(x));

inverse(1/(1+y_)*y_,x_):=replace(inverse(y,x),x,x/(1-x));
inverse(y_*1/(1-y_),x_):=replace(inverse(y,x),x,x/(x+1));

inverse(cos(x_)+sin(x_),x_) :=asin(sqrt(2)/2*x)-pi/4;

inverse(a_*atan(y_)*b_+c_+f_,x_):=replace(inverse(y,x),x,tan((c+f)/a/b));

inverse(exp(y_)*y_,x_):= replace(inverse(y,x),x,W(x));
inverse(exp(y_)*y_^n_,x_):= if(hasnot(n,x),replace(inverse(y,x),x, n*W(x^(1/n)/n)) );
inverse(exp(a_*y_)*y_,x_):= if(hasnot(a,x),replace(inverse(y,x),x, 1/a*W(a*x)) );
inverse(exp(a_*y_)*y_^n_,x_):= if(hasnot(a,n,x),replace(inverse(y,x),x, n/a*W(a*x^(1/n)/n)) );
inverse(exp(x_)*x_,x_):= W(x);
inverse(exp(y_)+y_,x_):= replace(inverse(y,x),x, x-W(exp(x)));
inverse(exp(x_)+n_*x_,x_):= if(hasnot(n,x), x/n-W(exp(x/n)/n) );
inverse(b_*exp(c_+x_)+x_,x_):= x-W(b*exp(c+x));
inverse(exp(c_+x_)+x_,x_):= x-W(exp(c+x));
inverse(exp(x_)+exp(x_)*x_,x_):= W(exp(1)*x)-1;
inverse(exp(a_*x_)+exp(b_*x_),x_):= if(hasnot(a,b,x) and a== -b, acosh(x/2)/b );
inverse(exp(x_)+exp(-x_),x_):= acosh(x/2);
inverse(exp(x_)-exp(-x_),x_):= asinh(x/2);
inverse(c_*exp(x_)+c_*exp(-x_),x_):= if(hasnot(c,x),acosh(1/2/c*x) );
inverse(exp(x_),x_):= log(x);

inverse(log(y_)*y_,x_):= replace(inverse(y,x),x, exp(W(x)));
inverse(log(y_)*y_^n_,x_):= if(hasnot(n,x),replace(inverse(y,x),x, exp(1/n*W(n*x))) );
inverse(log(y_)+y_,x_):= replace(inverse(y,x),x, W(exp(x)));
inverse(log(y_)+b_*y_,x_):= if(isfree(b,x), replace(inverse(y,x),x, W(b*exp(x))/b) );
#inverse(y_+log(y_)*y_,x_):= replace(inverse(y,x),x, exp(W(exp(1)*x)-1));
inverse(y_+log(y_)*y_,y_):= exp(W(exp(1)*y)-1);
inverse(b_*y_+log(y_)*y_,y_):= if(isfree(b,x), exp(W(exp(b)*y)-b) );
inverse(log(c_+x_)+x_,x_):= W(exp(c+x))-c;
inverse(b_*log(c_+x_)+x_,x_):= b*W(exp(c/b+x/b)/b)-c;
inverse(log(c_+y_)+x_+y_,y_):= W(exp(c-x+y))-c;
inverse(b_*log(c_+y_)+x_+y_,y_):= b*W(exp((c-x+y)/b)/b)-c;
inverse(a_+log(c_+y_)+x_+y_,y_):= W(exp(c-a-x+y))-c;
inverse(a_+b_*log(c_+y_)+x_+y_,y_):= b*W(exp((c-a-x+y)/b)/b)-c;

inverse((x_+c_)/x_,x_):=c/(x-1);
inverse(1/(x_+c_),x_):=1/x-c;
inverse(1/(x_-c),x_):=1/x+c;
inverse(1/(exp(x_)+exp(-x_)),x_):=asech(x)/2;
inverse(1/(exp(x_)-exp(-x_)),x_):=acsch(x)/2;
inverse(1/(exp((-x_))+exp(x_))*((-exp((-x_)))+exp(x_)),x_):=atanh(x);
inverse(1/(-exp((-x_))+exp(x_))*((exp((-x_)))+exp(x_)),x_):=acoth(x);
inverse(1/x_,x_):=1/x;

inverse(when(a_,y_),x_):=when(a,inverse(y,x));

inverse(mittag(a_,y_),x_):=replace(inverse(y,x),x,ln(1-a,x));
inverse(ln(a_,y_),x_):=replace(inverse(y,x),x,mittag(1-a,x));
inverse(li(a_,y_),x_):=replace(inverse(y,x),x,inverseli(1-a,x));
inverse(Ei(a_,y_),x_):=replace(inverse(y,x),x,inverseEi(1-a,x));
inverse(erf(a_,y_),x_):=replace(inverse(y,x),x,inverseerf(1-a,x));
inverse(erfi(a_,y_),x_):=replace(inverse(y,x),x,inverseerfi(1-a,x));
inverse(sin(a_,x_),x_):= asin(x)-pi/2*a;
inverse(cos(a_,x_),x_):= acos(x)-pi/2*a;
inverse(tan(a_,y_),x_):= replace(inverse(y,x),x,inversetan(-a,x));
inverse(cot(a_,y_),x_):= replace(inverse(y,x),x,inversecot(-a,x));
inverse(csc(a_,y_),x_):= replace(inverse(y,x),x,inversecsc(-a,x));
inverse(sec(a_,y_),x_):= replace(inverse(y,x),x,inversesec(-a,x));
inverse(asin(a_,y_),x_):= replace(inverse(y,x),x,sin(1-a,x));
inverse(acos(a_,y_),x_):= replace(inverse(y,x),x,cos(1-a,x));
inverse(atan(a_,y_),x_):= replace(inverse(y,x),x,tan(1-a,x));
inverse(acot(a_,y_),x_):= replace(inverse(y,x),x,cot(-a,x));
inverse(acsc(a_,y_),x_):= replace(inverse(y,x),x,csc(-a,x));
inverse(asec(a_,y_),x_):= replace(inverse(y,x),x,sec(-a,x));
inverse(sinh(a_,x_),x_):= asinh(x)-pi/2*a*i;
inverse(cosh(a_,x_),x_):= acosh(x)-pi/2*a*i;
inverse(tanh(a_,y_),x_):= replace(inverse(y,x),x,inversetanh(-a,x));
inverse(coth(a_,y_),x_):= replace(inverse(y,x),x,inversecoth(-a,x));
inverse(csch(a_,y_),x_):= replace(inverse(y,x),x,inversecsch(-a,x));
inverse(sech(a_,y_),x_):= replace(inverse(y,x),x,inversesech(-a,x));
inverse(asinh(a_,y_),x_):= replace(inverse(y,x),x,sinh(1-a,x));
inverse(acosh(a_,y_),x_):= replace(inverse(y,x),x,cosh(1-a,x));
inverse(atanh(a_,y_),x_):= replace(inverse(y,x),x,tanh(1-a,x));
inverse(acoth(a_,y_),x_):= replace(inverse(y,x),x,coth(-a,x));
inverse(acsch(a_,y_),x_):= replace(inverse(y,x),x,csch(-a,x));
inverse(asech(a_,y_),x_):= replace(inverse(y,x),x,sech(-a,x));
inverse(pow(a_,b_),x_):=if(hasnot(b,x),replace(inverse(a,x),x,pow(x,1/b)));
inverse(pow(x_,b_),x_):=if(hasnot(b,x),pow(x,1/b));

#inverse(abs(y_),x_):=replace(inverse(y,x),x,x) and replace(inverse(y,x),x,-x);
inverse(mod(x_,c_)+(-1),x_):= inversemod(x,c);
inverse(abs(x_),x_):= x and -x;
inverse(W(x_),x_):=exp(x)*x;
inverse(Phi(x_),x_):=sqrt(2)*inverseerf(2x-1);
inverse(log(x_),x_):= exp(x);
inverse(log(a_,x_),x_):=a^x;
inverse(log10(x_),x_):= 10^x;
inverse(log(x_+(1+x_^2)^0.5),x_):=sinh(x);
inverse(log(x_+(-1+x_^2)^0.5),x_):=cosh(x);
inverse(log((1+x_)/(1-x_)),x_):= tanh(x/2);
inverse(log((1+x_)/(-1+x_)),x_):= coth(x/2);
inverse(log((1+(x_^2+1)^0.5)/x_),x_):=csch(x/2);
inverse(log((1+(1-x_^2)^0.5)/(1-(1-x_^2)^0.5)),x_):=sech(x/2);

inverse(sin(x_),x_):= asin(x);
inverse(cos(x_),x_):= acos(x);
inverse(tan(x_),x_):= atan(x);
inverse(cot(x_),x_):= acot(x);
inverse(sec(x_),x_):= asec(x);
inverse(csc(x_),x_):= acsc(x);

inverse(sinh(x_),x_):= asinh(x);
inverse(cosh(x_),x_):= acosh(x);
inverse(tanh(x_),x_):= atanh(x);
inverse(coth(x_),x_):= acoth(x);
inverse(sech(x_),x_):= asech(x);
inverse(csch(x_),x_):= acsch(x);

inverse(asin(x_),x_):= sin(x);
inverse(acos(x_),x_):= cos(x);
inverse(atan(x_),x_):= tan(x);
inverse(acot(x_),x_):= cot(x);
inverse(asec(x_),x_):= sec(x);
inverse(acsc(x_),x_):= csc(x);

inverse(asinh(x_),x_):= sinh(x);
inverse(acosh(x_),x_):= cosh(x);
inverse(atanh(x_),x_):= tanh(x);
inverse(acoth(x_),x_):= coth(x);
inverse(asech(x_),x_):= sech(x);
inverse(acsch(x_),x_):= csch(x);

inverse(sqrt(x_),x_):= x^2;
inverse(cbrt(x_),x_):= x^3;

inverse(x_,x_):=x;

inverse(a_=b_,c_):=swap(a=b,x,y);
#inverse(mod(x_,c_)=1,x_):= inversemod(x,c);
inverse(a_ and b_, x_):= (inverse(a,x) and inverse(b,x));


inverse(y_):=inverse(y,x);
inverse(a_=b_):=swap(a=b,x,y);