%mathpiper,def="-"

/* Subtraction arity 1 */

//50 # -0 <-- 0;
51 # -Undefined <-- Undefined;
54 # - (- _x)      <-- x;
55 # (- (x_IsNumber)) <-- SubtractN(0,x);
100 # _x - n_IsConstant*(_x)   <-- (1-n)*x;
100 # n_IsConstant*(_x) - _x   <-- (n-1)*x;

110 # - (_x - _y) <-- y-x;
111 # - (x_IsNumber / _y) <-- (-x)/y;	
LocalSymbols(x)
[
  200 # - (x_IsList) <-- MapSingle("-",x);
];

/* Subtraction arity 2 */
50  # x_IsNumber - y_IsNumber <-- SubtractN(x,y);
50  # x_IsNumber - y_IsNumber <-- SubtractN(x,y);
60  # Infinity - Infinity <-- Undefined;
100 # 0 - _x <-- -x;
100 # _x - 0 <-- x;
100 # _x - _x <-- 0;

110 # _x - (- _y) <-- x + y;
110 # _x - (y_IsNegativeNumber) <-- x + (-y);
111 # (_x + _y)- _x <-- y;
111 # (_x + _y)- _y <-- x;
112 # _x - (_x + _y) <-- - y;
112 # _y - (_x + _y) <-- - x;
113 # (- _x) - _y <-- -(x+y);
113 # (x_IsNegativeNumber) - _y <-- -((-x)+y);
113 # (x_IsNegativeNumber)/_y - _z <-- -((-x)/y+z);


/* TODO move to this precedence everywhere? */
LocalSymbols(x,y,xarg,yarg)
[
  10 # ((x_IsList) - (y_IsList))_(Length(x)=Length(y)) <--
  [
    Map({{xarg,yarg},xarg-yarg},{x,y});
  ];
];

240 # (x_IsList - y_IsNonObject)_Not(IsList(y)) <-- -(y-x);

241 # (x_IsNonObject - y_IsList)_Not(IsList(x)) <--
[
   Local(i,result);
   result:={};
   For(i:=1,i<=Length(y),i++)
   [ DestructiveInsert(result,i,x - y[i]); ];
   result;
];

250 # z_IsInfinity - Complex(_x,_y) <-- Complex(-x+z,-y);
250 # Complex(_x,_y) - z_IsInfinity <-- Complex(x-z,y);

251 # z_IsInfinity - _x <-- z;
251 # _x - z_IsInfinity <-- -z;

250 # Undefined - _y <-- Undefined;
250 # _x - Undefined <-- Undefined;
// fractions
210 # x_IsNumber - (y_IsNumber / z_IsNumber) <--(x*z-y)/z;
210 # (y_IsNumber / z_IsNumber) - x_IsNumber <--(y-x*z)/z;
210 # (x_IsNumber / v_IsNumber) - (y_IsNumber / z_IsNumber) <--(x*z-y*v)/(v*z);

%/mathpiper


%mathpiper_docs,name="-",categories="Operators"
*CMD - --- arithmetic subtraction or negation
*STD
*CALL

	x-y
Precedence: left-side:
*EVAL PrecedenceGet("-")
, right-side:
*EVAL RightPrecedenceGet("-")

	-x

*PARMS

{x} and {y} -- objects for which subtraction is defined

*DESC

The subtraction operators can work on integers,
rational numbers, complex numbers, vectors, matrices and lists.

These operators are implemented in the standard math library (as opposed
to being built-in). This means that they can be extended by the user.

*E.G.

In> 2-3
Result: -1;
In> - 3
Result: -3;
%/mathpiper_docs
