%mathpiper,def="/"

/* Division */

50 # 0 / 0 <-- Undefined;

52 # x_IsPositiveNumber / 0 <-- Infinity;
52 # x_IsNegativeNumber / 0 <-- -Infinity;
55 # (_x / y_IsNumber)_(IsZero(y)) <-- Undefined;
55 # 0 / _x <-- 0;
// unnecessary rule (see #100 below). TODO: REMOVE
//55 # x_IsNumber / y_IsNegativeNumber <-- (-x)/(-y);

56 # (x_IsNonZeroInteger / y_IsNonZeroInteger)_(GcdN(x,y) > 1) <--
     [
       Local(gcd);
       Bind(x,x);
       Bind(y,y);
       Bind(gcd,GcdN(x,y));
       QuotientN(x,gcd)/QuotientN(y,gcd);
     ];

57 # ((x_IsNonZeroInteger * _expr) / y_IsNonZeroInteger)_(GcdN(x,y) > 1) <--
     [
       Local(gcd);
       Bind(x,x);
       Bind(y,y);
       Bind(gcd,GcdN(x,y));
       (QuotientN(x,gcd)*expr)/QuotientN(y,gcd);
     ];

57 # ((x_IsNonZeroInteger) / (y_IsNonZeroInteger * _expr))_(GcdN(x,y) > 1) <--
     [
       Local(gcd);
       Bind(x,x);
       Bind(y,y);
       Bind(gcd,GcdN(x,y));
       QuotientN(x,gcd)/(QuotientN(y,gcd)*expr);
     ];

57 # ((x_IsNonZeroInteger * _p) / (y_IsNonZeroInteger * _q))_(GcdN(x,y) > 1) <--
     [
       Local(gcd);
       Bind(x,x);
       Bind(y,y);
       Bind(gcd,GcdN(x,y));
       (QuotientN(x,gcd)*p)/(QuotientN(y,gcd)*q);
     ];

60 # (x_IsDecimal / y_IsNumber)  <-- DivideN(x,y);
60 # (x_IsNumber  / y_IsDecimal) <-- DivideN(x,y); 
60 # (x_IsNumber  / y_IsNumber)_(InNumericMode()) <-- DivideN(x,y);


90 # x_IsInfinity / y_IsInfinity <-- Undefined;
95  # x_IsInfinity / y_IsNumber <-- Sign(y)*x;
95  # x_IsInfinity / y_IsComplex <-- Infinity;

90 # Undefined / _y <-- Undefined;
90 # _y / Undefined <-- Undefined;


100 # _x / _x <-- 1;
100 # _x /  1 <-- x;
100 # (_x / y_IsNegativeNumber) <-- -x/(-y);
100 # (_x / - _y) <-- -x/y;

150 # (_x) / (_x) ^ (n_IsConstant) <-- x^(1-n);
150 # (_x) ^ (n_IsConstant) * (_x) <-- x^(n-1);
150 # Sqrt(_x) / (_x) ^ (n_IsConstant) <-- x^(1/2-n);
150 # (_x) ^ (n_IsConstant) / Sqrt(_x) <-- x^(n-1/2);
150 # (_x) / Sqrt(_x) <-- Sqrt(x);

// fractions
200 # (_x / _y)/ _z <-- x/(y*z);
230 # _x / (_y / _z) <-- (x*z)/y;

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


250 # (x_IsList / _y)_(Not(IsList(y))) <--
[
   Local(i,result);
   result:={};
   For(i:=1,i<=Length(x),i++)
   [ DestructiveInsert(result,i,x[i] / y); ];
   result;
];

250 # (_x / y_IsList)_(Not(IsList(x))) <--
[
   Local(i,result);
   result:={};
   For(i:=1,i<=Length(y),i++)
   [ DestructiveInsert(result,i,x/y[i]); ];
   result;
];

250 # _x / Infinity <-- 0;
250 # _x / (-Infinity) <-- 0;


400 # 0 / _x <-- 0;

%/mathpiper


%mathpiper_docs,name="/",categories="Operators"
*CMD / --- arithmetic division
*STD
*CALL

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

*PARMS

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

*DESC

The division operator can work on integers,
rational numbers, complex numbers, vectors, matrices and lists.

This operator is 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> 6/2
Result: 3;

*SEE %_v1
%/mathpiper_docs
