


RuleBase("D",{aVar,aFunc});
RuleBase("D",{aVar,aCount,aFunc});

Rule("D",2,1,IsList(aVar) And Not(IsList(aFunc)))
	Map("D",{aVar,FillList(aFunc, Length(aVar))});
Rule("D",2,1,IsList(aVar) And IsList(aFunc))
	Map("D",{aVar,aFunc});

Rule("D",2,3,True)
[
  MacroLocal(aVar);
  Apply("Deriv",{aVar,1,aFunc});
];

Rule("D",3,1,IsList(aVar) And Not(IsList(aFunc)))
	Map("D",{aVar,
                 FillList(aCount, Length(aVar)),
                 FillList(aFunc, Length(aVar))});
Rule("D",3,1,IsList(aVar) And IsList(aFunc))
	Map("D",{aVar,
                 FillList(aCount, Length(aVar)),
                 aFunc});
Rule("D",3,3,True)
[
  MacroLocal(aVar);
  Apply("Deriv",{aVar,aCount,aFunc});
];


HoldArg("D",aVar);
HoldArg("D",aFunc);

5 # (Deriv(_var,1)_func) <-- Deriv(var)func;
10 # (Deriv(_var,n_IsPositiveInteger)_func) <-- Deriv(var)Deriv(var,n-1)func;

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)Cos(_x)) <-- -(Deriv(var)x)*Sin(x);
2 # (Deriv(_var)Exp(_x)) <--  (Deriv(var)x)*Exp(x);
2 # (Deriv(_var)(_x / _y)) <--
    (y* (Deriv(var) x) - x* (Deriv(var) y))/ (y^2);
2 # (Deriv(_var)Tan(_x)) <-- ((Deriv(var) x) / (Cos(x)^2));
2 # (Deriv(_var)Ln(_x)) <-- ((Deriv(var) x) / x);
2 # (Deriv(_var)(_x ^ n_IsRationalOrNumber)) <--
    n * (Deriv(var) x) * (x ^ (n - 1));

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

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

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

2 # (Deriv(_var)ArcSin(_x)) <-- ((1 -(x ^ 2))^ -(1/2)) * (Deriv(var) x );
2 # (Deriv(_var)ArcCos(_x)) <-- -1*((1 -(x ^ 2))^ -(1/2)) * (Deriv(var)x );
2 # (Deriv(_var)ArcTan(_x)) <-- (1/ (1 + x ^ 2))*(Deriv(var) x);
2 # (Deriv(_var)Sqrt(_x)) <-- ((Deriv(var)x)/(2*Sqrt(x)));
2 # (Deriv(_var)Complex(_r,_i)) <-- Complex(Deriv(var)r,Deriv(var)i);


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);
];

/*
Diverge(_f,_b) <-- D(b)f;
Curl2(_f,_b) <--
      (D({b[2],b[3],b[1]}){f[3],f[1],f[2]}) -
      (D({b[3],b[1],b[2]}){f[2],f[3],f[1]});
*/

/*TODO remove?
*/
RuleBase("Diverge", {aFunc, aBasis});
Rule("Diverge", 2, 1, IsList(aBasis) And IsList(aFunc) And Length(aBasis) = Length(aFunc))
	Map("D", {aBasis,aFunc});

RuleBase("Curl", {aFunc, aBasis});

Rule("Curl", 2, 1, Length(aBasis)=Length(aFunc))
	{
		Apply("D",{aBasis[2],aFunc[3]})-Apply("D",{aBasis[3],aFunc[2]}),
		Apply("D",{aBasis[3],aFunc[1]})-Apply("D",{aBasis[1],aFunc[3]}),
		Apply("D",{aBasis[1],aFunc[2]})-Apply("D",{aBasis[2],aFunc[1]})
	};


