Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/algebra/
Upload File :
Current File : //usr/home/beeson/MathXpert/algebra/logineq.c

/* M. Beeson, for MathXpert
9.22.92 original date
1.30.98 last modified
3.4.00  corrected lnleftineq1 and lnleftineq2
3.4.00  corrected logleftineq1 and logleftineq2
6.4.13  polylessexp
6.5.13  added logratbound and logpoly and algebraic
*/


#include <string.h>
#include "globals.h"
#include "ops.h"
#include "errbuf.h"
#include "prover.h"
#include "polynoms.h"
#include "pvalaux.h"  /* twoparts */
#include "logineq.h"


/* ____________________________________________________*/
static term ln3(term t)
/* takes the ln, returning u when t has the form e^u */
{ if(ATOMIC(t) || FUNCTOR(t) != '^' || !equals(ARG(0,t),eulere))
     return ln1(t);
  return ARG(1,t);
}
/* ____________________________________________________*/
static term log3(term t)
/* takes the log, returning u when t has the form 10^u */
{ if(ATOMIC(t) || FUNCTOR(t) != '^' || !equals(ARG(0,t),ten))
     return log1(t);
  return ARG(1,t);
}
/*______________________________________________________ */
int lnineq1(term ineq, term arg, term *next, char *reason)
    /* u < v => ln u < ln v, provided u > 0  */
{ unsigned f = FUNCTOR(ineq);
  int err;
  term u,v;
  if(f != '<' && f != '>')
     return 1;
  u = f == '<' ? ARG(0,ineq) : ARG(1,ineq);
  v = f == '<' ? ARG(1,ineq) : ARG(0,ineq);
  err = infer(lessthan(zero,u));
  if(err)
     { errbuf(0,english(1184));
        /* Left side isn't positive */
       return 1;
     }
  *next = f == '<' ? lessthan(ln3(u),ln3(v)) : greaterthan(ln3(v),ln3(u));
  strcpy(reason, f == '<' ? english(1623) : english(1653));
     /* u<v iff ln u < ln v */
     /* u>v iff ln u > ln v */
  return 0;
}
/*______________________________________________________ */
int lnineq2(term ineq, term arg, term *next, char *reason)
 /* u  \le  v => ln u  \le  ln v provided u > 0*/
{ unsigned f = FUNCTOR(ineq);
  int err;
  term u,v;
  if(f != LE && f != GE)
     return 1;
  u = f == LE ? ARG(0,ineq) : ARG(1,ineq);
  v = f == LE ? ARG(1,ineq) : ARG(0,ineq);
  err = infer(lessthan(zero,u));
  if(err)
     { errbuf(0, english(1184));
         /* Left side isn't positive */
       return 1;
     }
  *next = f == LE ? le(ln3(u),ln3(v)) : ge(ln3(v), ln3(u));
  strcpy(reason, f == '<' ? english(1625) : english(1626));
     /* u \le v iff ln u  \le  ln v */
     /* u \ge v iff ln u  \ge  ln v  */
  return 0;
}
/*______________________________________________________ */
int logineq1(term ineq, term arg, term *next, char *reason)
  /* u < v => log u < log v, provided u > 0 */
{ unsigned f = FUNCTOR(ineq);
  int err;
  term u,v;
  if(f != '<' && f != '>')
     return 1;
  u = f == '<' ? ARG(0,ineq): ARG(1,ineq);
  v = f == '<' ? ARG(1,ineq): ARG(0,ineq);
  err = infer(lessthan(zero,u));
  if(err)
     { errbuf(0, english(1184));
         /* Left side isn't positive */
       return 1;
     }
  *next = f == '<' ? lessthan(log3(u),log3(v)): greaterthan(log3(v),log3(u));
  strcpy(reason, f == '<' ? english(1624): english(1654));
    /* u<v iff log u < log v */
    /* u>v iff log u > log v */
  return 0;
}
/*______________________________________________________ */
int logineq2(term ineq, term arg, term *next, char *reason)
  /* u <= v => log u <= log v provided u > 0*/
{ unsigned f = FUNCTOR(ineq);
  int err;
  term u,v;
  if(f != LE && f != GE)
     return 1;
  u = f == LE ? ARG(0,ineq): ARG(1,ineq);
  v = f == LE ? ARG(1,ineq): ARG(0,ineq);
  err = infer(lessthan(zero,u));
  if(err)
     { errbuf(0, english(1184));
        /*  Left side isn't positive */
       return 1;
     }
  *next = f == LE ? le(log3(u),log3(v)): ge(log3(v),log3(u));
  strcpy(reason,f == LE ? english(1625): english(1626));
     /* u <= v iff log u <= log v */
     /* u >=v iff log u >= log v */
  return 0;
}
/*______________________________________________________ */
int expineq1(term ineq, term arg, term *next, char *reason)
  /* u < v => a^u < a^v  if a > 0, takes arg  = a */
{ unsigned short f = FUNCTOR(ineq);
  unsigned short g,h;
  int err;
  term u,v,left,right;
  if(f != '<' && f != '>')
     return 1;
  u = f == '<' ? ARG(0,ineq): ARG(1,ineq);
  v = f == '<' ? ARG(1,ineq): ARG(0,ineq);
  g = FUNCTOR(u);
  h = FUNCTOR(v);
  if(FUNCTOR(arg) == ILLEGAL)
     { if(g == LOGB)
          arg = ARG(0,u);
       else if(h == LOGB)
          arg = ARG(0,v);
       else if(g == LN || h == LN)
          arg = eulere;
       else if(g == LOG || h == LOG)
          arg = ten;
       else
          return 1;
    }
  err = infer(lessthan(zero,u));
  if(err)
     { errbuf(0, english(1184));
        /*  Left side isn't positive */
       return 1;
     }
  if(FUNCTOR(u) == LOGB && equals(ARG(0,u),arg))
     left = ARG(1,u);
  else
     left = make_power(arg,u);
  if(FUNCTOR(v) == LOGB && equals(ARG(0,v),arg))
     right = ARG(1,v);
  else
     right = make_power(arg,v);
  *next = f == '<' ? lessthan(left,right): greaterthan(right,left);
  strcpy(reason, f == '<' ? english(1627): english(1628));
   /* u < v iff a^u < a^v */
   /* u > v iff a^u > a^v */
  return 0;
}
/*______________________________________________________ */
int expineq2(term ineq, term arg, term *next, char *reason)
  /* u  \le  v => a^u  \le  a^v  if a > 0, takes arg in menu mode */
{ unsigned short f = FUNCTOR(ineq);
  unsigned short g,h;
  int err;
  term u,v,left,right;
  if(f != LE && f != GE)
     return 1;
  u = f == LE ? ARG(0,ineq) : ARG(1,ineq);
  v = f == LE ? ARG(1,ineq) : ARG(0,ineq);
  g = FUNCTOR(u);
  h = FUNCTOR(v);
  if(FUNCTOR(arg) == ILLEGAL)
     { if(g == LOGB)
          arg = ARG(0,u);
       else if(h == LOGB)
          arg = ARG(0,v);
       else if(g == LN || h == LN)
          arg = eulere;
       else if(g == LOG || h == LOG)
          arg = ten;
       else
          return 1;
    }
  err = infer(lessthan(zero,u));
  if(err)
     { errbuf(0, english(1184));
         /* Left side isn't positive */
       return 1;
     }
  if(FUNCTOR(u) == LOGB && equals(arg,ARG(0,u)))
     left = ARG(1,u);
  else
     left = make_power(arg,u);
  if(FUNCTOR(v) == LOGB && equals(arg,ARG(0,v)))
     right = ARG(1,v);
  else
     right = make_power(arg,v);
  *next = f == LE ? le(left,right): ge(right,left);
  strcpy(reason, f == LE ? english(1629): english(1630));
     /* u  \le  v iff a^u  \le  a^v */
     /* u  \ge  v iff a^u  \ge  a^v */
  return 0;
}
/*_________________________________________________________________*/
int lnrightineq1(term t, term arg, term *next, char *reason)
/* u < ln v iff e^u < v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != '<' && f != '>')
     return 1;
  u = f == '<' ? ARG(0,t) : ARG(1,t);
  right = f == '<' ? ARG(1,t) : ARG(0,t);
  if(FUNCTOR(right) != LN)
     return 1;
  v = ARG(0,right);
  if(FUNCTOR(u) == LN)
     left = ARG(0,u);
  else
     left = make_power(eulere,u);
  *next = f == '<' ? lessthan(left,v) : greaterthan(v,left);
  HIGHLIGHT(*next);
  strcpy(reason, f == '<' ? english(1631) : english(1635));
      /* u < ln v iff e^u < v */
      /* ln u > v iff u > e^v */
  return 0;
}
/*_________________________________________________________________*/
int lnrightineq2(term t, term arg, term *next, char *reason)
/* u  \le  ln v iff e^u  \le  v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != LE && f != GE)
     return 1;
  u = f == LE ? ARG(0,t) : ARG(1,t);
  right = f == LE ? ARG(1,t) : ARG(0,t);
  if(FUNCTOR(right) != LN)
     return 1;
  v = ARG(0,right);
  if(FUNCTOR(u) == LN)
     left = ARG(0,u);
  else
     left = make_power(eulere,u);
  *next = f == LE ? le(left,v) : ge(v,left);
  HIGHLIGHT(*next);
  strcpy(reason, f == LE ? english(1633): english(1634));
     /* u  \le  ln v iff e^u  \le  v */
     /* ln u  \ge  v iff u  \ge  e^v */
  return 0;
}
/*_________________________________________________________________*/
int lnleftineq1(term t, term arg, term *next, char *reason)
/* ln u < v iff u < e^v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != '<' && f != '>')
     return 1;
  v = f == '<' ? ARG(1,t) : ARG(0,t);
  left = f == '<' ? ARG(0,t) : ARG(1,t);
  if(FUNCTOR(left) != LN)
     return 1;
  u = ARG(0,left);
  if(FUNCTOR(v) == LN)
     right = ARG(0,v);
  else
     right = make_power(eulere,v);
  *next = f == '<' ? lessthan(u,right) : greaterthan(right,u);
  HIGHLIGHT(*next);
  strcpy(reason, f == '<' ? english(1632) : english(1636));
    /* ln u < v iff u < e^v */
    /* u > ln v iff e^u > v */
  return 0;
}
/*_________________________________________________________________*/
int lnleftineq2(term t, term arg, term *next, char *reason)
/* ln u  \le  v iff u  \le  e^v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != LE && f != GE)
     return 1;
  v = f == LE ? ARG(1,t) : ARG(0,t);
  left = f == LE ? ARG(0,t) : ARG(1,t);
  if(FUNCTOR(left) != LN)
     return 1;
  u = ARG(0,left);
  if(FUNCTOR(v) == LN)
     right = ARG(0,v);
  else
     right = make_power(eulere,v);
  *next = f == LE ? le(u,right) : ge(right,u);
  HIGHLIGHT(*next);
  strcpy(reason, f == LE ? english(1637) : english(1638));
    /* ln u  \le  v iff u  \le  e^v */
    /* u  \ge  ln v iff e^u  \ge  v */
  return 0;
}
/*_________________________________________________________________*/
int logrightineq1(term t, term arg, term *next, char *reason)
/* u < log v iff 10^u < v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != '<' && f != '>')
     return 1;
  u = f == '<' ? ARG(0,t) : ARG(1,t);
  right = f == '<' ? ARG(1,t) : ARG(0,t);
  if(FUNCTOR(right) != LOG)
     return 1;
  v = ARG(0,right);
  if(FUNCTOR(u) == LOG)
     left = ARG(0,u);
  else
     left = make_power(ten,u);
  *next = f == '<' ? lessthan(left,v) : greaterthan(v,left);
  HIGHLIGHT(*next);
  strcpy(reason, f == '<' ? english(1639) : english(1640));
      /* u < log v iff 10^u < v */
      /* log u > v iff u > 10^v */
  return 0;
}
/*_________________________________________________________________*/
int logleftineq1(term t, term arg, term *next, char *reason)
/* log u < v iff u < 10^v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != '<' && f != '>')
     return 1;
  v = f == '<' ? ARG(1,t) : ARG(0,t);
  left = f == '<' ? ARG(0,t) : ARG(1,t);
  if(FUNCTOR(left) != LOG)
     return 1;
  u = ARG(0,left);
  if(FUNCTOR(v) == LOG)
     right = ARG(0,v);
  else
     right = make_power(ten,v);
  *next = f == '<' ? lessthan(u,right) : greaterthan(right,u);
  HIGHLIGHT(*next);
  strcpy(reason, f == '<' ? english(1641) : english(1642));
    /* log u < v iff u < 10^v */
    /* u > log v iff 10^u > v */
  return 0;
}
/*_________________________________________________________________*/
int logrightineq2(term t, term arg, term *next, char *reason)
/* u  \le  log v iff 10^u  \le  v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != LE && f != GE)
     return 1;
  u = f == LE ? ARG(0,t) : ARG(1,t);
  right = f == LE ? ARG(1,t) : ARG(0,t);
  if(FUNCTOR(right) != LOG)
     return 1;
  v = ARG(0,right);
  if(FUNCTOR(u) == LOG)
     left = ARG(0,u);
  else
     left = make_power(ten,u);
  *next = f == LE ? le(left,v) : ge(v,left);
  HIGHLIGHT(*next);
  strcpy(reason, f == LE ? english(1643): english(1644));
     /* u  \le  log v iff 10^u  \le  v */
     /* log u  \ge  v iff u  \ge  10^v */
  return 0;
}
/*_________________________________________________________________*/
int logleftineq2(term t, term arg, term *next, char *reason)
/* log u  \le  v iff u  \le  10^v */
{ unsigned short f = FUNCTOR(t);
  term u,v,left,right;
  if(f != LE && f != GE)
     return 1;
  v = f == LE ? ARG(1,t) : ARG(0,t);
  left = f == LE ? ARG(0,t) : ARG(1,t);
  if(FUNCTOR(left) != LOG)
     return 1;
  u = ARG(0,left);
  if(FUNCTOR(v) == LOG)
     right = ARG(0,v);
  else
     right = make_power(ten,v);
  *next = f == LE ? le(u,right) : ge(right,u);
  HIGHLIGHT(*next);
  strcpy(reason, f == LE ? english(1645) : english(1646));
    /* log u <=  v iff u <= 10^v */
    /* u >= log v iff 10^u >= v */
  return 0;
}
/*______________________________________________________________________*/
/* For the comparison test in infinite series, we need to handle 
inequalities like n <= 2^(n/2),  which we want to reduce to 
n >= M for some constant M.  But we don't have an explicit 
formula for the constant.  So,  we introduce a new M.
*/
int polylessexp(term t, term arg, term *next, char *reason)
/* polynomial less than exponential */
{ unsigned short f = FUNCTOR(t);
  term left,right,M, c,s,b,deg,p,q;
  term n = get_eigenvariable();
  int err;
  if(f != LE && f != GE && f != '<' && f != '>')
     return 1;
  right = (f == LE|| f == '<') ? ARG(1,t) : ARG(0,t);
  left = (f == LE || f== '<') ? ARG(0,t) : ARG(1,t);
  if(! ispolyin(left,n) )
      return 1;
  if(FUNCTOR(right) == '*')
     { twoparts(right,n,&c,&s);
     }
  else if(FUNCTOR(right) == '^')
     s = right;
  else
     return 1;
  if(FUNCTOR(s) != '^' || !contains(ARG(1,s),FUNCTOR(n)))
     return 1;
  if(contains(ARG(0,s),FUNCTOR(n)) && !equals(ARG(0,s),n))
     return 1;

   b = ARG(1,s);
   err = check1(positive(ARG(0,s)));
   if(err) 
      return 1;
   if(FUNCTOR(b) == '+')
      { leading_term(b,n,zero,&c,&deg);
         err = check1(lessthan(zero,c));
         if(err)
            return 1;
         err = check1(lessthan(zero,deg));
         if(err)
            return 1;
      }
   else if(FUNCTOR(b) == '*' || FUNCTOR(b) == '^' || FRACTION(b))
      { twoparts(b,n,&p,&q);
        if(!ispolyin(q,n))
           return 1;
        err = check1(lessthan(zero,p));
        if(err) 
           return 1;
      }
   else
      return 1;
   /* OK, input has the right form; operation will succeed  */
   M = getnewintvar(t,"MmKkCc");
   *next = lessthan(M,n);
   HIGHLIGHT(*next);
   commentbuf(0,"!The new constant stands for a particular large number. The exact value is unimportant.");
   strcpy(reason,"exponentials eventually dominate polynomials");
   return 0;
}

/*______________________________________________________________________*/
int logpoly(term t, term x)
/* return 1 if t is  log(poly in x), or a rational power of such a term.  */
{ term u,v;
  unsigned short f = FUNCTOR(t);
  if(f == '^')
      { u = ARG(0,t);
        v = ARG(1,t);
        if(NEGATIVE(v))
            v = ARG(0,v);
        if(INTEGERP(v) || RATIONALP(v))
            return logpoly(u,x);
        return 0;
      }
   if(f != LN)
      return 0;
   u = ARG(0,t);
   if(ispolyin(u,x))
      return 1;
   return 0;
}
/*______________________________________________________________________*/
int algebraic(term t, term x)
/* return 1 if t is an algebraic function of x, 0 if not */
{ term u,v;
  unsigned short n;
  int i;
  unsigned short f = FUNCTOR(t);
  if(ispolyin(t,x))
     return 1;
  if(f == '^')
     { u = ARG(0,t);
       v = ARG(1,t);
       if(NEGATIVE(v))
           v = ARG(0,v);
       if(INTEGERP(v) || RATIONALP(v))
           return algebraic(u,x);
     }
  if(f == SQRT || f == '-')
     return algebraic(ARG(0,t),x);
  if(f == ROOT)
     return algebraic(ARG(1,t),x);
  if(f != '*' && f != '+' && f != '/')
     return 0;
  n = ARITY(t);
  for(i=0;i<n;i++)
     { if(!algebraic(ARG(i,t),x))
          return 0;
     }
  return 1;
}
     

  

/*______________________________________________________________________*/
/* For the comparison test in infinite series, we need to handle 
inequalities like (ln n)^2 <= 2(n+1)/n^(1/3),  which we want to reduce to 
n >= M for some constant M.  But we don't have an explicit 
formula for the constant.  So,  we introduce a new M.
*/
int logratbound(term t, term arg, term *next, char *reason)
/* polynomial less than exponential */
{ unsigned short f = FUNCTOR(t);
  term left,right,M,u;
  term n = get_eigenvariable();
  int err;
  if(f != LE && f != GE && f != '<' && f != '>')
     return 1;
  right = (f == LE|| f == '<') ? ARG(1,t) : ARG(0,t);
  left = (f == LE || f== '<') ? ARG(0,t) : ARG(1,t);
  if(! logpoly(left,n)  || !algebraic(right,n) )
      return 1;
  err = limval(limit(arrow(n,infinity), right), &u);
  if(err || !equals(u,infinity))
     return 1;

   /* OK, input has the right form; operation will succeed  */
   M = getnewintvar(t,"MmKkCc");
   *next = lessthan(M,n);
   HIGHLIGHT(*next);
   commentbuf(0,"!The new constant stands for a particular large number. The exact value is unimportant.");
   strcpy(reason,"algebraic functions dominate logarithms");
   return 0;
}
    



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