%mathpiper,def="Deriv"


5 # (Deriv(_var,1)_func) <-- Deriv(var)func;
5 # (Deriv(_var,0)_func) <-- func;
10 # (Deriv(_var,n_IsPositiveInteger)_func) <-- Deriv(var)Deriv(var,n-1)func;
10 # (Deriv(_var,n_IsNegativeInteger)_func) <-- Check(0, "Math", "Negative derivative");


// Need to clean out Sec(x) and friends
0 # (Deriv(_var) (_var)) <-- 1;
1 # (Deriv(_var)func_IsAtom) <-- 0;
2 # (Deriv(_var)_x + _y) <--  (Deriv(var)x) + (Deriv(var)y);
2 # (Deriv(_var)- (_x) ) <-- -Deriv(var)x;
2 # (Deriv(_var)_x - _y) <--  (Deriv(var)x) - (Deriv(var)y);
2 # (Deriv(_var)_x * _y) <-- (x*Deriv(var)y) + (Deriv(var)x)*y;
2 # (Deriv(_var)Sin(_x)) <--  (Deriv(var)x)*Cos(x);
2 # (Deriv(_var)Sinh(_x))<--  (Deriv(var)x)*Cosh(x);
2 # (Deriv(_var)Cosh(_x))<--  (Deriv(var)x)*Sinh(x);
2 # (Deriv(_var)Cos(_x)) <-- -(Deriv(var)x)*Sin(x);
2 # (Deriv(_var)Csc(_x)) <--  -(Deriv(var)x)*Csc(x)*Cot(x);
2 # (Deriv(_var)Csch(_x)) <-- -(Deriv(var)x)*Csch(x)*Coth(x);
2 # (Deriv(_var)Sec(_x)) <--  (Deriv(var)x)*Sec(x)*Tan(x);
2 # (Deriv(_var)Sech(_x)) <-- -(Deriv(var)x)*Sech(x)*Tanh(x);
2 # (Deriv(_var)Cot(_x)) <--  -(Deriv(var)x)*Csc(x)^2;
2 # (Deriv(_var)Coth(_x)) <--  (Deriv(var)x)*Csch(x)^2;

2 # (Deriv(_var)Tan(_x)) <-- ((Deriv(var) x) / (Cos(x)^2));
2 # (Deriv(_var)Tanh(_x)) <-- (Deriv(var)x)*Sech(x)^2;

2 # (Deriv(_var)Exp(_x)) <--  (Deriv(var)x)*Exp(x);

// When dividing by a constant, this is faster
2 # (Deriv(_var)(_x / _y))_(IsFreeOf(var,y)) <-- (Deriv(var) x) / y;
3 # (Deriv(_var)(_x / _y)) <--
    (y* (Deriv(var) x) - x* (Deriv(var) y))/ (y^2);

2 # (Deriv(_var)Ln(_x)) <-- ((Deriv(var) x) / x);
2 # (Deriv(_var)(_x ^ _n))_(IsRationalOrNumber(n) Or IsFreeOf(var, n)) <--
    n * (Deriv(var) x) * (x ^ (n - 1));

//2 # (Deriv(_var)(Abs(_x)))  <-- Sign(x)*(Deriv(var)x);
2 # (Deriv(_var)(Abs(_x)))  <-- (x/Abs(x))*(Deriv(var)x);
2 # (Deriv(_var)(Sign(_x))) <-- 0;

2 # (Deriv(_var)(if(_cond)(_body))) <--
	ListToFunction({ToAtom("if"),cond,Deriv(var)body});
2 # (Deriv(_var)((_left) else (_right))) <--
        ListToFunction({ToAtom("else"), (Deriv(var)left), (Deriv(var)right) } );

3 # (Deriv(_var)(_x ^ _n)) <-- (x^n)*Deriv(var)(n*Ln(x));

2 # (Deriv(_var)ArcSin(_x)) <-- (Deriv(var) x)/Sqrt(1 - (x^2));
2 # (Deriv(_var)ArcCos(_x)) <-- -(Deriv(var)x)/Sqrt(1 - (x^2));
2 # (Deriv(_var)ArcTan(_x)) <-- (Deriv(var) x)/(1 + x^2);

2 # (Deriv(_var)ArcSinh(_x)) <-- (Deriv(var) x)/Sqrt((x^2) + 1);
2 # (Deriv(_var)ArcCosh(_x)) <-- (Deriv(var) x)/Sqrt((x^2) - 1);
2 # (Deriv(_var)ArcTanh(_x)) <-- (Deriv(var) x)/(1 - x^2);

2 # (Deriv(_var)Sqrt(_x)) <-- ((Deriv(var)x)/(2*Sqrt(x)));
2 # (Deriv(_var)Complex(_r,_i)) <-- Complex(Deriv(var)r,Deriv(var)i);

LocalSymbols(var,var2,a,b,y)[
   2 # (Deriv(_var)Integrate(_var)(_y)) <-- y;
   2 # (Deriv(_var)Integrate(_var2,_a,_b)(y_IsFreeOf(var))) <--
         (Deriv(var)b)*(y Where var2 == b) -
         (Deriv(var)a)*(y Where var2 == a);
   3 # (Deriv(_var)Integrate(_var2,_a,_b)(_y)) <--
         (Deriv(var)b)*(y Where var2 == b) -
         (Deriv(var)a)*(y Where var2 == a) +
 	Integrate(var2,a,b) Deriv(var) y;
 ];



2 # (Deriv(_var)func_IsList)_(Not(IsList(var))) <--
    Map("Deriv",{FillList(var,Length(func)),func});


2 # (Deriv(_var)UniVariate(_var,_first,_coefs)) <--
[
  Local(result,m,i);
  result:=FlatCopy(coefs);
  m:=Length(result);
  For(i:=1,i<=m,i++)
  [
    result[i] := result[i] * (first+i-1);
  ];
  UniVariate(var,first-1,result);
];

%/mathpiper