%mathpiper,def="Monomials"

//Retract("CanBeMonomial",*);
//Retract("IsMonomial",*);
//Retract("FactorsMonomial",*);

10 # CanBeMonomial(_expr)<--Not (HasFunc(expr,ToAtom("+")) Or HasFunc(expr,ToAtom("-")));

10 # IsMonomial(expr_CanBeMonomial) <-- 
[
    Local(r);
    If( IsRationalFunction(expr),
        r := (VarList(Denominator(expr)) = {}),
        r := True
    );
];

15 # IsMonomial(_expr) <-- False;


10 # FactorsMonomial(expr_IsMonomial) <--
[
  If(InVerboseMode(),Tell("FactorsMonomial",expr));
  Local(den,num,Ns,flat,prod,quot,result,f,ff);
  If( IsRationalFunction(expr),
    [
      den := Denominator(expr);
      num := Flatten(Numerator(expr),"*");
    ],
    [
      den := 1;
      num := Flatten(expr,"*");
    ]
  );
  If(InVerboseMode(),Tell("     ",{num,den}));
  Ns  := Select(num, "IsComplex");
  If(InVerboseMode(),Tell("     ",Ns));
  If( Ns = {},
       If( den != 1, DestructiveInsert(num,1,1/den)),
       DestructiveReplace(num,Find(num,Ns[1]),Ns[1]/den)
  );
  If(InVerboseMode(),Tell("     ",num));
  result := {};
  ForEach(f,num)
  [
      If( IsComplex(f), 
          DestructiveAppend(result,{(f),1}),
          If( IsAtom(f),
              DestructiveAppend(result,{f,1}),
              DestructiveAppend(result,DestructiveDelete(FunctionToList(f),1))
          )
      );
  ];
  result;
];

%/mathpiper







%mathpiper_docs,name="IsMonomial",categories="User Functions;Predicates"
*CMD IsMonomial --- determine if {expr} is a Monomial
*STD
*CALL
	IsMonomial(expr)

*PARMS

{expr} -- an expression

*DESC

This function returns {True} if {expr} satisfies the definition of a {Monomial}.
Otherwise, {False}.
A {Monomial} is defined to be a single term, consisting of a product of numbers
and variables.

*E.G.
In> IsMonomial(24)
Result: True

In> IsMonomial(24*a*x^2*y^3)
Result: True

In> IsMonomial(24*a*x^2*y^3/15)
Result: True

In> IsMonomial(24*a*x^2*y^3/15+1)
Result: False
    
%/mathpiper_docs



%mathpiper_docs,name="FactorsMonomial",categories="User Functions;Polynomials (Operations)"
*CMD FactorsMonomial --- factorization of a monomial expression
*STD
*CALL
	FactorsMonomial(expr)

*PARMS

{expr} -- an expression representing a Monomial

*DESC

This function decomposes the {expr} into a product of numbers and variables 
raised to various powers.

The factorization is returned as a list of pairs.  The first member of
each pair is the factor (a number or a variable name), while the second
member is an integer denoting the power to which this factor should be
raised.

Thus, the factorization  
$expr = p1^n1 * ... * p9^n9$ 
is returned as {{(p1,n1), ..., (p9,n9)}}.

If {expr} is not a monomial, the function returns unevaluated.

NOTE: numerical factors are not decomposed into their prime factorization.

*E.G.

In> FactorsMonomial(24)
Result: {{24,1}}

In> FactorsMonomial(24/15)
Result: {{8/5,1}}

In> FactorsMonomial(24*a*x^2*y^3)
Result: {{24,1},{a,1},{x,2},{y,3}}

In> FactorsMonomial(24*a*x^2*y^3/15)
Result: {{8/5,1},{a,1},{x,2},{y,3}}

In> FactorsMonomial(24*a*x^2*y^3/15+1)
Result: FactorsMonomial((24*a*x^2*y^3)/15+1)
    
%/mathpiper_docs



