%mathpiper,def="+"

/* Addition */

100 # + _x  <-- x;

50 # x_IsNumber + y_IsNumber <-- AddN(x,y);

100 # 0 + _x    <-- x;
100 # _x + 0    <-- x;
100 # _x + _x   <-- 2*x;
100 # _x + n_IsConstant*(_x)   <-- (n+1)*x;
100 # n_IsConstant*(_x) + _x   <-- (n+1)*x;
101 # _x + - _y <-- x-y;
101 # _x + (- _y)/(_z) <-- x-(y/z);
101 # (- _y)/(_z) + _x  <-- x-(y/z);
101 # (- _x) + _y <-- y-x;
102 # _x + y_IsNegativeNumber <-- x-(-y);
102 # _x + y_IsNegativeNumber * _z <-- x-((-y)*z);
102 # _x + (y_IsNegativeNumber)/(_z) <-- x-((-y)/z);
102 # (y_IsNegativeNumber)/(_z) + _x  <-- x-((-y)/z);
102 # (x_IsNegativeNumber) + _y <-- y-(-x);
// fractions
150 # _n1 / _d + _n2 / _d <-- (n1+n2)/d;

200 # (x_IsNumber + _y)_Not(IsNumber(y)) <-- y+x;
200 # ((_y + x_IsNumber) + _z)_Not(IsNumber(y) Or IsNumber(z)) <-- (y+z)+x;
200 # ((x_IsNumber + _y) + z_IsNumber)_Not(IsNumber(y)) <-- y+(x+z);
200 # ((_x + y_IsNumber) + z_IsNumber)_Not(IsNumber(x)) <-- x+(y+z);
// fractions
210 # x_IsNumber + (y_IsNumber / z_IsNumber) <--(x*z+y)/z;
210 # (y_IsNumber / z_IsNumber) + x_IsNumber <--(x*z+y)/z;
210 # (x_IsNumber / v_IsNumber) + (y_IsNumber / z_IsNumber) <--(x*z+y*v)/(v*z);


//  220 # + x_IsList          <-- MapSingle("+",x);	// this rule is never active

220 # (xlist_IsList + ylist_IsList)_(Length(xlist)=Length(ylist)) <-- Map("+",{xlist,ylist});

SumListSide(_x, y_IsList) <--
[
   Local(i,result);
   result:={};
   For(i:=1,i<=Length(y),i++)
   [ DestructiveInsert(result,i,x + y[i]); ];
   result;
];

240 # (x_IsList + _y)_Not(IsList(y)) <-- SumListSide(y,x);
241 # (_x + y_IsList)_Not(IsList(x)) <-- SumListSide(x,y);

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;

%/mathpiper




%mathpiper,scope="nobuild",subtype="test_suite"
//This fold is used to test the + operator.
    Verify(3 + 2 , 5);
%/mathpiper



%mathpiper_docs,name="+",categories="Operators"
*CMD + --- arithmetic addition
*STD
*CALL

	x+y
	+x
Precedence:
*EVAL PrecedenceGet("+")

*PARMS

{x} and {y} -- objects for which arithmetic addition is defined


*DESC

The addition 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: 5;
%/mathpiper_docs