Sindbad~EG File Manager

Current Path : /home/beeson/Otter-Lambda/yyy/prover/
Upload File :
Current File : //home/beeson/Otter-Lambda/yyy/prover/trigpoly.c

/* trigrational, recognizes rational functions of trig functions of a variable */
/* M. Beeson, for Mathpert */
/* See trigpoly.h for brief descriptions of the public functions here. */
/*
9.28.93 original date
8.6.98 last modified
*/


#define PROVER_DLL
#include "globals.h"
#include "prover.h"
#include "algaux.h"
#include "trigpoly.h"
#include "cancel.h"
#include "trig.h"
#include "polynoms.h"   /* ispolyin  */
#include "pvalaux.h"    /* isinteger */
#include "order.h"      /* monomial  */
#include "deval.h"      /* seminumerical */

static int trigrational_aux(term);
/*__________________________________________________________________*/
MEXPORT_PROVER int trigrational(term t)
/* Return 1 if t is a rational function of trigonometric functions
of one variable such as sin x, cos x.  The arguments of the trig
functions must all be the same atom x, or else x + � or x+n�)
Return 0 otherwise.   Equations of rational functions of trig arguments
are also acceptable.  Some trig function must actually occur; constants
are not acceptable.
Input checking will not allow nested = so we can allow it here.  */

{ term *atomlist;
  int natoms = atomsin(t,&atomlist);
  if(natoms > 2 || natoms == 0)
     { free2(atomlist);
       return 0;
     }
  if(natoms == 1 && ( equals(atomlist[0],pi) || TYPE(atomlist[0]) == INTEGER))
     { free2(atomlist);
       return 0;
     }
  if(natoms == 2)
     { if(
          (!equals(atomlist[0],pi) && !equals(atomlist[1],pi)) ||
          (equals(atomlist[0],pi) && TYPE(atomlist[1]) == INTEGER) ||
          (equals(atomlist[1],pi) && TYPE(atomlist[0]) == INTEGER)
         )
         { free2(atomlist);
           return 0;
         }
     }
  free2(atomlist);
  if(natoms == 0)
     return 0;
  return trigrational_aux(t);
}
/*____________________________________________________________________*/
static int trigrational_aux(term t)
/* do as trigrational, but ASSUME that there is at most one atom in t
   (other than possibly pi)  */
{ unsigned short f;
  unsigned short n;
  int i,err;
  term u,p,cancelled;
  if(OBJECT(t))
     return 1;
     /* constants are allowed, but e and pi aren't allowed. */
  if(ISATOM(t))
     return 0;
  f = FUNCTOR(t);
  if(f==SIN || f==COS || f==SEC || f==TAN || f==COT || f==CSC)
     { u = ARG(0,t);
       if(equals(u,pi))
          return 0;   /* we don't count sin � etc. because e.g. cot �
                         is undefined */
       if(ISATOM(u))
          return 1;
       /* but we also accept sin(x+�) etc., via the following code */
       if(FUNCTOR(u) != '+' || ARITY(u) != 2 || !ISATOM(ARG(0,u)))
          return 0;
       u = ARG(1,u);
       if(!contains(u,FUNCTOR(pi)))
          return 0;  /* without wasting time trying to cancel it */
       err = cancel(u,pi,&cancelled,&p);
       if(err)
          return 0;
       if(INTEGERP(p) || isinteger(p))
          return 1;
       return 0;
     }
  switch(f)
     { case '-' : return trigrational_aux(ARG(0,t));
       case '^' : return INTEGERP(ARG(1,t)) && trigrational_aux(ARG(0,t));
       case '=' : /* fall-through */
       case '+' : /* fall-through */
       case '/' : /* fall-through */
       case '*' : n = ARITY(t);
                  for(i=0;i<n;i++)
                     { if(!trigrational_aux(ARG(i,t)))
                          return 0;
                     }
                  return 1;
     }
  return seminumerical(t);  /* sqrt 3 for example is acceptable,
                          hence sqrt(3) tan x is acceptable. */
}
/*______________________________________________________*/
MEXPORT_PROVER int trigrat(term t, term x)
/* return 1 if t is a quotient of polynomials in positive (possibly fractional)
powers of x and trig functions of x.
Specifically:
    trigrat ::=  s/s | - s/s
    s ::= -s | s * s | s� where n > 0, s+s| seminumerical | x | trig(x)
Thus it rejects expressions like ln u involving variables other than x.
*/
{ if(NEGATIVE(t))
     return trigrat(ARG(0,t),x);
  if(FRACTION(t))
     return trigpoly(ARG(0,t),x) && trigpoly(ARG(1,t),x);
  return trigpoly(t,x);
}
/*______________________________________________________*/
MEXPORT_PROVER int trigrat2(term t, term x)
/* return 1 if t is a quotient of polynomials in positive (possibly fractional)
powers of x and trig functions of x.  Like trigrat except that it
accepts expressions not containing x as constants.
*/
{ if(NEGATIVE(t))
     return trigrat2(ARG(0,t),x);
  if(FRACTION(t))
     return trigpoly2(ARG(0,t),x) && trigpoly2(ARG(1,t),x);
  return trigpoly2(t,x);
}

/*______________________________________________________*/
MEXPORT_PROVER int trigpoly(term t, term x)
/* return 1 if t is a polynomial in x and trig functions of x,
as given by nonterminal s in the above grammar.
Examples:  x sin x is accepted, u sin x is rejected.  See
stricttrigpoly which rejects x sin x and trigpoly2 which
accepts u sin x, and stricttrigpoly2 which rejects
x sin x and u sin x but accepts u + sin x.
*/
{ unsigned short f = FUNCTOR(t);
  unsigned short n;
  int i;
  if(seminumerical(t) || equals(t,x))
     return 1;
  if(ISATOM(t))
     return 0;
  if(NEGATIVE(t))
     return trigpoly(ARG(0,t),x);
  if(FRACTION(t))
     return 0;
  if(TRIGFUNCTOR(f))
     return equals(ARG(0,t),x);
  if(f == '^')
     { if(INTEGERP(ARG(1,t)))
          return trigpoly(ARG(0,t),x);
       else
          return 0;
     }
  if(f != '+' && f != '*')
     return contains(t,FUNCTOR(x)) ? 0 : 1;
     /* accept for example ln u  as a trigpoly in x, where u
        doesn't contain x.
     */
  n = ARITY(t);
  for(i=0;i<n;i++)
     { if(!trigpoly(ARG(i,t),x))
          return 0;
     }
  return 1;
}

/*______________________________________________________*/
MEXPORT_PROVER int trigpoly2(term t, term x)
/* return 1 if t is a polynomial in x and trig functions of x,
but accepting expressions not containing x as constant.
*/
{ unsigned short f = FUNCTOR(t);
  unsigned short n;
  int i;
  if(ATOMIC(t))
     return 1;
  if(NEGATIVE(t))
     return trigpoly2(ARG(0,t),x);
  if(FRACTION(t))
     return 0;
  if(TRIGFUNCTOR(f))
     return equals(ARG(0,t),x);
  if(f == '^')
     { if(INTEGERP(ARG(1,t)))
          return trigpoly2(ARG(0,t),x);
       else
          return 0;
     }
  if(f != '+' && f != '*')
     return contains(t,FUNCTOR(x)) ? 0 : 1;
     /* accept for example ln u  as a trigpoly in x, where u
        doesn't contain x.
     */
  n = ARITY(t);
  for(i=0;i<n;i++)
     { if(!trigpoly2(ARG(i,t),x))
          return 0;
     }
  return 1;
}


/*__________________________________________________________________*/
MEXPORT_PROVER int trigpolyargs2(term t, term x)
/* return nonzero if t is a polynomial in u,v,..., where the u,v are
either x or trig functions whose args are polynomial functions of x.
Example:  x^2 + tan^3 (3x).  Return 0 otherwise. The nonzero return
value is 1 if there are no trig functions and 2 if there are trig
functions; that is it's 1 if t is really (equal to) a polynomial.
Accepts functions not containing x as constants, e.g. u sin x.
*/
{ unsigned short n,f;
  int i,ans, temp;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  if(TRIGFUNCTOR(f))
     return ispolyin(ARG(0,t),x) ? 2 : 0;
  if(f == '^')
     { term p = ARG(1,t);
       if(NEGATIVE(p))
          p = ARG(0,p);
       if(POSNUMBER(p))
          return trigpolyargs2(ARG(0,t),x);
       else
          return 0;
     }
  if(f == '-')
     return trigpolyargs2(ARG(0,t),x);
  if(f == '+' || f == '*')
     { n = ARITY(t);
       ans = 0;
       for(i=0;i<n;i++)
          { temp = trigpolyargs2(ARG(i,t),x);
            if(!temp)
               return 0;
            if(temp > ans)
               ++ans;
          }
       return ans;
     }
  if(f == '/' && !contains(ARG(1,t),FUNCTOR(x)))
     return trigpolyargs2(ARG(0,t),x);
  if(!contains(t,FUNCTOR(x)))
     return 1;   /* accept non-numerical constants like sqrt 2
                    as well as expressions like ln u which don't contain x */
  return 0;
}
/*__________________________________________________________________*/
MEXPORT_PROVER int trigalg(term t, term x)
/* return nonzero if t is an algebraic function of x and trig functions of x,
0 if not.  Expressions involving other variables are rejected.
Use trigalg2(t,x) to accept such expressions.
*/
{ unsigned short n,f;
  int i,ans, temp;
  if(OBJECT(t))
     return 1;
  if(ISATOM(t))
     return equals(t,x);
  f = FUNCTOR(t);
  if(TRIGFUNCTOR(f))
     return equals(ARG(0,t),x);
  if(f == '^')
     { term p = ARG(1,t);
       if(NEGATIVE(p))
          p = ARG(0,p);
       if(POSNUMBER(p) || RATIONALP(p))
          return trigalg(ARG(0,t),x);
       else
          return 0;
     }
  if(f == '-')
     return trigalg(ARG(0,t),x);
  if(f == '+' || f == '*' || f == '/')
     { n = ARITY(t);
       ans = 0;
       for(i=0;i<n;i++)
          { temp = trigalg(ARG(i,t),x);
            if(!temp)
               return 0;
            if(temp > ans)
               ++ans;
          }
       return ans;
     }
  if(seminumerical(t))
     return 1;   /* accept non-numerical constants like sqrt 2 */
  return 0;
}

/*______________________________________________________*/
MEXPORT_PROVER int trigalg2(term t, term x)
/* return 1 if t is a  built up from trigrats in x using +, *, -, and
rational powers, or more precisely, an algebraic function of x and trig
functions, whose args are polynomial in x.
Expressions not containing x are accepted as constants.
*/
{ unsigned short f = FUNCTOR(t);
  unsigned short n = ARITY(t);
  int i;
  if(ATOMIC(t))
     return 1;
  if(f == '+' || f == '*')
     { for(i=0;i<n;i++)
          { if(!trigalg2(ARG(i,t),x))
               return 0;
          }
       return 1;
     }
  if(f=='-')
     return trigalg2(ARG(0,t),x);
  if(f == '^')
     { term p = ARG(1,t);
       if(NEGATIVE(p))
          p = ARG(0,p);
       if(POSNUMBER(p))
          return trigalg2(ARG(0,t),x);
       else
          return 0;
     }
  if(f == '/')
     return (trigalg2(ARG(0,t),x) && trigalg2(ARG(1,t),x)) ? 1 : 0;
  if(!TRIGFUNCTOR(f))
     return 0;
  return ispolyin(ARG(0,t),x);
}
/*__________________________________________________________________*/
MEXPORT_PROVER int stricttrigpoly(term t, term x)
/* return nonzero if t is a polynomial in trig functions of x,
0 if not.  The 'strict' means it doesn't accept x or polynomials
in x, but only polynomials in sin x, cos x, etc.  It does not
accept expressions involving other variables; use
stricttrigpoly2 for that.
*/
{ unsigned short n,f;
  int i,ans, temp;
  if(OBJECT(t))
     return 1;
  if(ISATOM(t))
     return 0;
  f = FUNCTOR(t);
  if(TRIGFUNCTOR(f))
     return equals(ARG(0,t),x);
  if(f == '^')
     { if(POSNUMBER(ARG(1,t)))
          return stricttrigpoly(ARG(0,t),x);
       else
          return 0;
     }
  if(f == '-')
     return stricttrigpoly(ARG(0,t),x);
  if(f == '+' || f == '*')
     { n = ARITY(t);
       ans = 0;
       for(i=0;i<n;i++)
          { temp = stricttrigpoly(ARG(i,t),x);
            if(!temp)
               return 0;
            if(temp > ans)
               ++ans;
          }
       return ans;
     }
  if(f == '/' && !contains(ARG(1,t),FUNCTOR(x)))
     return stricttrigpoly(ARG(0,t),x);
  if(seminumerical(t))
     return 1;   /* accept non-numerical constants like sqrt 2 */
  return 0;
}

/*__________________________________________________________________*/
MEXPORT_PROVER int stricttrigpoly2(term t, term x)
/* return nonzero if t is a polynomial in trig functions of x,
0 if not.  The 'strict' means it doesn't accept x or polynomials
in x, but only polynomials in sin x, cos x, etc.  The 2 means
it allows expressions not involving x as constants.
*/
{ unsigned short n,f;
  int i,ans, temp;
  if(ATOMIC(t))
     return !equals(t,x);
  f = FUNCTOR(t);
  if(TRIGFUNCTOR(f))
     return equals(ARG(0,t),x);
  if(f == '^')
     { if(POSNUMBER(ARG(1,t)))
          return stricttrigpoly2(ARG(0,t),x);
       else
          return 0;
     }
  if(f == '-')
     return stricttrigpoly2(ARG(0,t),x);
  if(f == '+' || f == '*')
     { n = ARITY(t);
       ans = 0;
       for(i=0;i<n;i++)
          { temp = stricttrigpoly2(ARG(i,t),x);
            if(!temp)
               return 0;
            if(temp > ans)
               ++ans;
          }
       return ans;
     }
  if(f == '/' && !contains(ARG(1,t),FUNCTOR(x)))
     return stricttrigpoly2(ARG(0,t),x);
  if(!contains(t,FUNCTOR(x)))
     return 1;   /* accept non-numerical constants like sqrt 2
                    as well as expressions in other variables */
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_PROVER int eqpoly2(term t)
/*  Return 1 if t is equal to a multivariate polynomiall; 0 if not.
For example a product of polynomials satisfies poly2.  This is different
from mvpoly2 in that mvpoly2 also allows entire functions to occur.
*/

{ unsigned short n,i;
  unsigned short f = FUNCTOR(t);
  if(monomial(t))
     return 1;
  if(ATOMIC(t))
     return 1;
  n = ARITY(t);
  if(f == '*' || f == '+')
     { for(i=0;i<n;i++)
          { if(!eqpoly2(ARG(i,t)) )
               return 0;
          }
       return 1;
     }
  if(f == '^' && INTEGERP(ARG(1,t)) && !ZERO(ARG(1,t)))
     return eqpoly2(ARG(0,t));
  if(f == '-')
     return eqpoly2(ARG(0,t));
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_PROVER int algpoly(term t)
/* return 1 if t is an algebraic function without division
i.e. is built up from +,-,*, ROOT, SQRT, and positive constant numerical
exponents, including positive fractions, with additional restrictions
described below.
   This is the test used in autolimit for applying divnumdenom; the
numerator and denom of the limitand must be algpoly's.
*/
{ unsigned short f,n;
  int i;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  n = ARITY(t);
  if(f == '^')
     { if(!POSNUMBER(ARG(1,t)))
          return 0;
       return algpoly(ARG(0,t));
     }
  if(f == ROOT)
     { if(!INTEGERP(ARG(0,t)))
          return 0;
       return algpoly(ARG(1,t));
     }
  if(f == SQRT || f == '-')
     return algpoly(ARG(0,t));
  if(f == '*' || f == '+')
     { for(i=0;i<n;i++)
          { if(!algpoly(ARG(i,t)))
               return 0;
          }
       return 1;
     }
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_PROVER int algpoly3(term t)
/* return 1 if t is an algebraic function without division
i.e. is built up from +,-,*, ROOT, SQRT, ABS, and positive constant numerical
exponents, including positive fractions, with additional restrictions
described below.  This is used in limval_aux.
*/
{ unsigned short f,n;
  int i;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  n = ARITY(t);
  if(f == '^')
     { if(!POSNUMBER(ARG(1,t)))
          return 0;
       return algpoly3(ARG(0,t));
     }
  if(f == ROOT)
     { if(!INTEGERP(ARG(0,t)))
          return 0;
       return algpoly3(ARG(1,t));
     }
  if(f == SQRT || f == '-' || f == ABS)
     return algpoly3(ARG(0,t));
  if(f == '*' || f == '+')
     { for(i=0;i<n;i++)
          { if(!algpoly3(ARG(i,t)))
               return 0;
          }
       return 1;
     }
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_PROVER int algrat(term t)
/* return 1 if t is an algebraic function built up from '/',
+,-,*, ROOT, SQRT, ABS, and positive constant numerical
exponents, including positive fractions, with additional restrictions
described below.  This is used in limval_aux.  Note that
these functions can have jumps, e.g. abs(x)/x.
*/
{ unsigned short f,n;
  int i;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  n = ARITY(t);
  if(f == '^')
     { if(!POSNUMBER(ARG(1,t)))
          return 0;
       return algrat(ARG(0,t));
     }
  if(f == ROOT)
     { if(!INTEGERP(ARG(0,t)))
          return 0;
       return algrat(ARG(1,t));
     }
  if(f == SQRT || f == '-' || f == ABS)
     return algrat(ARG(0,t));
  if(f == '*' || f == '+' || f == '/')
     { for(i=0;i<n;i++)
          { if(!algrat(ARG(i,t)))
               return 0;
          }
       return 1;
     }
  return 0;
}

/*_________________________________________________________________*/
MEXPORT_PROVER int algpoly2(term t)
/* return 1 if t is an algebraic function without division
i.e. is built up from +,-,*, ROOT, SQRT, and positive constant numerical
exponents, including positive fractions, with additional restrictions
described below.
   This is the test used in autolimit for applying sumleadingterm:
numerator and denom of the limitand must be algpoly2's.
   It's also the test used for sumleadingterm.  In order to avoid
applying sumleadingterm to sqrt(x+h)-sqrt(x), which is correct but
too big a step, we require that an algpoly2 have only eqpoly2's
inside sums.
*/
{ unsigned short f,n;
  int i;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  n = ARITY(t);
  if(f == '^')
     { if(!POSNUMBER(ARG(1,t)))
          return 0;
       return algpoly2(ARG(0,t));
     }
  if(f == ROOT)
     { if(!INTEGERP(ARG(0,t)))
          return 0;
       return algpoly2(ARG(1,t));
     }
  if(f == SQRT || f == '-')
     return algpoly2(ARG(0,t));
  if(f == '*')
     { for(i=0;i<n;i++)
          { if(!algpoly2(ARG(i,t)))
               return 0;
          }
       return 1;
     }
  if(f == '+')
     { for(i=0;i<n;i++)
          { if(!eqpoly2(ARG(i,t)))  /* Not algpoly2 */
               return 0;
          }
       return 1;
     }
  return 0;
}

/*_________________________________________________________________*/
MEXPORT_PROVER int algebraic_in2(term t, term x)
/* return 1 if t is an algebraic function of x,
i.e. is built up from +,-,*, /,ROOT, SQRT, and positive constant numerical
exponents, including positive fractions.  It accepts expressions not
containing x as constants.
   This is the test used in limval for using leading terms at infinity,
where trig functions have no leading terms.
*/
{ unsigned short f,n;
  int i;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  n = ARITY(t);
  if(f == '^')
     { if(POSNUMBER(ARG(1,t)))
          return algebraic_in2(ARG(0,t),x);
       if(NEGATIVE(ARG(1,t)) && POSNUMBER(ARG(0,ARG(1,t))))
          return algebraic_in2(ARG(0,t),x);
       return 0;
     }
  if(f == ROOT)
     { if(!INTEGERP(ARG(0,t)))
          return 0;
       return algebraic_in2(ARG(1,t),x);
     }
  if(f == SQRT || f == '-')
     return algebraic_in2(ARG(0,t),x);
  if(f == '/')
     return algebraic_in2(ARG(0,t),x) && algebraic_in2(ARG(1,t),x);
  if(f != '*' && f != '+')
     return contains(t,FUNCTOR(x)) ? 0 : 1;
  for(i=0;i<n;i++)
     { if(!algebraic_in2(ARG(i,t),x))
          return 0;
     }
  return 1;
}
/*____________________________________________________________________*/
MEXPORT_PROVER int logpoly2(term t, term x)
/* Return 1 if t is a log or power of log of trigpolyargs2 in x */
{ if(FUNCTOR(t) == '^' && !contains(ARG(1,t),FUNCTOR(x)))
     t = ARG(0,t);
  if(FUNCTOR(t) == LN || FUNCTOR(t) == LOG)
     return trigpolyargs2(ARG(0,t),x);
  if(FUNCTOR(t) == LOGB)
     return trigpolyargs2(ARG(1,t),x);
  return 0;
}

/*____________________________________________________________________*/
MEXPORT_PROVER int logtrigalg(term t, term x)
/* Return a if t is a log or power of log of trigalg in x */
{ if(FUNCTOR(t) == '^' && !contains(ARG(1,t),FUNCTOR(x)))
     t = ARG(0,t);
  if(FUNCTOR(t) == LN || FUNCTOR(t) == LOG)
     return trigalg(ARG(0,t),x);
  if(FUNCTOR(t) == LOGB)
     return trigalg(ARG(1,t),x);
  return 0;
}

/*____________________________________________________________________*/
MEXPORT_PROVER int logtrigalg2(term t, term x)
/* Return 1 if t is a log or power of log of trigalg2 in x */
{ if(FUNCTOR(t) == '^' && !contains(ARG(1,t),FUNCTOR(x)))
     t = ARG(0,t);
  if(FUNCTOR(t) == LN || FUNCTOR(t) == LOG)
     return trigalg2(ARG(0,t),x);
  if(FUNCTOR(t) == LOGB)
     return trigalg2(ARG(1,t),x);
  return 0;
}

/*_____________________________________________________*/
MEXPORT_PROVER int logexpalg(term t, term x)
/* built up from logs and exponentials and algebraic operations (no trig) */
/* These functions have finitely many zeroes and the class is closed
under derivatives, so they are eventually monotone, and hence can be used
in the integral test for convergence of series. */

{ unsigned short f,n;
  int i;
  if(ATOMIC(t))
     return 1;
  f = FUNCTOR(t);
  n = ARITY(t);
  if(f == '^' || f == '/')
     return logexpalg(ARG(0,t),x) && logexpalg(ARG(1,t),x);
  if(f == ROOT || f == LOG)
     return logexpalg(ARG(1,t),x);
  if(f == SQRT || f == '-' || f == LN)
     return logexpalg(ARG(0,t),x);
  if(f != '*' && f != '+')
     return contains(t,FUNCTOR(x)) ? 0 : 1;
  for(i=0;i<n;i++)
     { if(!logexpalg(ARG(i,t),x))
          return 0;
     }
  return 1;
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists