%mathpiper,def="IsRationalFunction"

//Retract("IsRationalFunction",*);

10 # IsRationalFunction(_expr)_(Length(VarList(expr))=0) <-- False;

15 # IsRationalFunction(_expr) <-- IsRationalFunction(expr,VarList(expr));

10 # IsRationalFunction(expr_IsRationalOrNumber,_var) <-- False;

15 # IsRationalFunction(_expr,var_IsAtom)_(Type(expr)="/" Or Type(-expr)="/") <-- 
[
    If (IsPolynomial(Numerator(expr),var) And IsPolynomial(Denominator(expr),var),
        Contains(VarList(Denominator(expr)),var),
        False
    );
];

20 # IsRationalFunction(_expr,vars_IsList)_(Type(expr)="/" Or Type(-expr)="/") <-- 
[
    If (IsPolynomial(Numerator(expr),vars) And IsPolynomial(Denominator(expr),vars),
        Intersection(vars, VarList(expr)) != {},
        False
    );
];

60000 # IsRationalFunction(_expr,_var) <-- False;


%/mathpiper

    


%mathpiper_docs,name="IsRationalFunction",categories="Programmer Functions;Predicates",access="experimental"

*CMD IsRationalFunction --- test for a Rational Function
*STD
*CALL
	IsRationalFunction(expr)
	IsRationalFunction(expr,var)
	IsRationalFunction(expr,vars)

*PARMS

{expr} -- expression to test
{var}  -- (optional) variable
{vars} -- (optional) a list of variables

*DESC

This function tests whether the expression {expr} is a Rational
Function of the variable {var}.  If a list of variables {vars} is
provided, the test is made w.r.t.  all the variables in the list, and
returns True if any one of them succeeds.  If {var} is omitted, the
test is made w.r.t. the list VarList(expr).

*E.G.

In> IsRationalFunction(3,x)  
Result: False
In> IsRationalFunction(3)      
Result: False;
In> IsRationalFunction(3.5,x)
Result:  False
In> IsRationalFunction(3.5)
Result:  False 
In> IsRationalFunction(3/5,x)
Result:  False 
In> IsRationalFunction(3/5)
Result:  False 
In> IsRationalFunction(x,y)
Result:  False 
In> IsRationalFunction(x)
Result:  False 
In> IsRationalFunction(x/y,x)
Result:  False 
In> IsRationalFunction(x/y,y)
Result:  True
In> IsRationalFunction(x/y)
Result:  True 
In> IsRationalFunction(x/5,x)
Result:  False 
In> IsRationalFunction(x/5)
Result:  False 
In> IsRationalFunction(5/x,x)
Result:  True 
In> IsRationalFunction(-5/x,x)
Result:  True 
In> IsRationalFunction(5/x)
Result:  True 
In> IsRationalFunction(-5/x)
Result:  True 
In> IsRationalFunction(5/x,y)
Result:  False 
In> IsRationalFunction(5/x,{y})
Result:  False 
In> IsRationalFunction(5/x,{y,x})
Result:  False
In> IsRationalFunction(5/y)
Result:  True 
In> IsRationalFunction(1-1/x,x)
Result:  False 
In> IsRationalFunction(1-1/x)
Result:  False

%/mathpiper_docs




%mathpiper,scope="nobuild",subtype="manual_test"

Tell(1,IsRationalFunction(3,x));
Tell(2,IsRationalFunction(3.5,x));
Tell(3,IsRationalFunction(3/5,x));
Tell(4,IsRationalFunction(x,y));
Tell(5,IsRationalFunction(x/y,x));
Tell(6,IsRationalFunction(x/5,x));
Tell(7,IsRationalFunction(5/x,x));
Tell(8,IsRationalFunction(5/y,x));
Tell(9,IsRationalFunction(1-1/x,x));
Tell(11,IsRationalFunction(3));
Tell(12,IsRationalFunction(3.5));
Tell(13,IsRationalFunction(3/5));
Tell(14,IsRationalFunction(x));
Tell(15,IsRationalFunction(x/y));
Tell(16,IsRationalFunction(x/5));
Tell(17,IsRationalFunction(5/x));
Tell(18,IsRationalFunction(5/y));
Tell(19,IsRationalFunction(-5/y));
Tell(20,IsRationalFunction(1-1/x));

%/mathpiper

    %output,preserve="false"
      Result: True
      
      Side Effects:
      << 1 >> IsRationalFunction(3,x) : False 
      << 2 >> IsRationalFunction(3.5,x) : False 
      << 3 >> IsRationalFunction(3/5,x) : False 
      << 4 >> IsRationalFunction(x,y) : False 
      << 15 >> expr : x/y 
      <<     >> var : x 
      <<  >> Denominator(expr) : y 
      << 5 >> IsRationalFunction(x/y,x) : False 
      << 15 >> expr : x/5 
      <<     >> var : x 
      <<  >> Denominator(expr) : 5 
      << 6 >> IsRationalFunction(x/5,x) : False 
      << 15 >> expr : 5/x 
      <<     >> var : x 
      <<  >> Denominator(expr) : x 
      << 7 >> IsRationalFunction(5/x,x) : True 
      << 15 >> expr : 5/y 
      <<     >> var : x 
      <<  >> Denominator(expr) : y 
      << 8 >> IsRationalFunction(5/y,x) : False 
      << 9 >> IsRationalFunction(1-1/x,x) : False 
      << 11 >> IsRationalFunction(3) : False 
      << 12 >> IsRationalFunction(3.5) : False 
      << 13 >> IsRationalFunction(3/5) : False 
      << 14 >> IsRationalFunction(x) : False 
      << 15 >> expr : x/y 
      <<     >> var : x 
      <<  >> Denominator(expr) : y 
      << 15 >> IsRationalFunction(x/y) : False 
      << 15 >> expr : x/5 
      <<     >> var : x 
      <<  >> Denominator(expr) : 5 
      << 16 >> IsRationalFunction(x/5) : False 
      << 15 >> expr : 5/x 
      <<     >> var : x 
      <<  >> Denominator(expr) : x 
      << 17 >> IsRationalFunction(5/x) : True 
      << 15 >> expr : 5/y 
      <<     >> var : y 
      <<  >> Denominator(expr) : y 
      << 18 >> IsRationalFunction(5/y) : True 
      << 15 >> expr : (-5)/y 
      <<     >> var : y 
      <<  >> Denominator(expr) : y 
      << 19 >> IsRationalFunction(-5/y) : True 
      << 20 >> IsRationalFunction(1-1/x) : False 
      
.   %/output





