Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/yyy/algebra/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/yyy/algebra/sqineq.c

/* M Beeson, for MathXpert
Additional operations for inequalities with squares and square roots.
Original date 6.5.96
modified 2.27.98
3.28.00 modified several operations adding a guard to cause failure
on inappropriate input.
*/
#define ALGEBRA_DLL
#include <string.h>
#include <math.h>
#include "globals.h"
#include <assert.h>
#include "operator.h"
#include "ops.h"
#include "probtype.h"
#include "algaux.h"
#include "order.h"
#include "polynoms.h"
#include "eqn.h"
#include "factor.h"
#include "complex.h"   /* rootofunity */
#include "mstring.h"
#include "solvelin.h"
#include "prover.h"
#include "symbols.h"
#include "cancel.h"  /* naive_lcm */
#include "errbuf.h"
#include "deval.h"
#include "pvalaux.h"  /* iseven, obviously_positive */
#include "simpprod.h" /* square */
#include "advfact.h"
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq14(term t, term arg, term *next, char *reason)
/* u^2 < a => - sqrt a < u < sqrt a       */
{ unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = sqrtineq14(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(0,t);
  a = ARG(1,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(lessthan(zero,a));
  if(err)
     { errbuf(0,english(1570));  /* a must be positive */
       return 1;
     }
  err = sqrt_aux(usq,&u);
  if(err)
     return 1;
  err = sqrt_aux(a,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = and(lessthan(tnegate(sqrta),u), lessthan(u2,sqrta2));
  HIGHLIGHT(*next);
  strcpy(reason,english(2193));  /* $u^2<a iff -�a < u < �a$ */
  return 0;
}


/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq24(term t, term arg, term *next, char *reason)
/* u^2 � a => -�a � u � �a */
{ unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = sqrtineq24(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(0,t);
  a = ARG(1,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(le(zero,a));
  if(err)
     { errbuf(0,english(1571));  /* a must be non-negative */
       return 1;
     }
  err = sqrt_aux(usq,&u);
  if(err)
     return 1;
  err = sqrt_aux(a,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = and(le(tnegate(sqrta),u), le(u2,sqrta2));
  HIGHLIGHT(*next);
  strcpy(reason, english(2202));  /* $u^2�a iff -�a � u � �a$ */
  return 0;
}

/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq15(term t, term arg, term *next, char *reason)
/* a < u^2 => u < -�a or �a < u */
{ unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = sqrtineq15(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(1,t);
  a = ARG(0,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(le(zero,a));
  if(err)
     { errbuf(0,english(1571));  /* a must be non-negative */
       return 1;
     }
  err = sqrt_aux(usq,&u);
  if(err)
     return 1;
  err = sqrt_aux(a,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = or(lessthan(u,tnegate(sqrta)), lessthan(sqrta2,u2));
  HIGHLIGHT(*next);
  strcpy(reason, english(2194));  /* $a<u^2 iff u<-�a or �a<u$ */
  return 0;
}


/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq25(term t, term arg, term *next, char *reason)
 /* a � u^2 => u � -�a or �a � u */
 { unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = sqrtineq25(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(1,t);
  a = ARG(0,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(lessthan(zero,a));
  if(err)
     { errbuf(0,english(1570));  /* a must be positive */
       return 1;
     }
  err = sqrt_aux(usq,&u);
  if(err)
     return 1;
  err = sqrt_aux(a,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = or(le(u,tnegate(sqrta)), le(sqrta2,u2));
  HIGHLIGHT(*next);
  strcpy(reason, english(2195));  /* $a�u^2 iff u�-�a or �a�u$ */
  return 0;
}

/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval1(term t, term arg, term *next, char *reason)
/* a<u^2<b => -�b<u<-�a or �a<u<�b */
{ if(!interval_as_and(t))
     return 1;
  if(FUNCTOR(ARG(0,t)) != '<')
     return 1;
  if(FUNCTOR(ARG(1,t)) != '<')
     return 1;
  return sqrtinterval2(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval3(term t, term arg, term *next, char *reason)
/* -a<u^2<b =>  u^2 < b if 0 < a */
{ return sqrtinterval4(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval5(term t, term arg, term *next, char *reason)
/* -a<u^2�b =>  u^2 � b if 0 < a */
{ return sqrtinterval4(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval6(term t, term arg, term *next, char *reason)
/* -a�u^2<b =>  u^2 < b if 0 < a */
{ return sqrtinterval4(t,arg,next,reason);
}

/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval4(term t, term arg, term *next, char *reason)
/* -a<u^2<b =>  u^2 < b if 0 < a,
with any combination of < and LE in the interval
*/
{ term a,mid;
  unsigned short f,g;
  if(!interval_as_and(t))
     return 1;
  mid = ARG(1,ARG(0,t));
  a = ARG(0,ARG(0,t));
  f = FUNCTOR(ARG(0,t));
  if(!obviously_nonnegative(mid))
      return 1;
  if(f == '<' && infer(lessthan(a,zero)))
      { errbuf(0,english(1596));
        /* Left side must be negative. */
        return 1;
      }
  if(f == LE && infer(le(a,zero)))
      { errbuf(0,english(1597));
        /* Left side must not be negative */
        return 1;
      }
  *next = ARG(1,t);
  HIGHLIGHT(*next);
  g = FUNCTOR(ARG(1,t));
  if(f == '<' && g == '<')
     strcpy(reason, english(2196));  /* $-a<x^2<b$ iff $x^2<b$ */
  else if(f == LE && g == LE)
     strcpy(reason, english(2197));  /* $-a�x^2�b$ iff $x^2�b$ */
  else if(f == '<' && g == LE)
     strcpy(reason, english(2198));  /*  $-a<x^2�b$ iff $x^2�b$ */
  else if(f == LE && g == '<')
     strcpy(reason, english(2199));   /* $-a�x^2<b$ iff $x^2<b$ */
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval2(term t, term arg, term *next, char *reason)
/* a�u^2�b => -�b�u�-�a or �a�u�b */
{ int err;
  unsigned short f = FUNCTOR(ARG(0,t));
  unsigned short g = FUNCTOR(ARG(1,t));
  term a,b,sqrta,sqrtb,sqrta2,sqrtb2,usq,u,u2,u3,u4;
  if(!interval_as_and(t))
     return 1;
  a = ARG(0,ARG(0,t));
  b = ARG(1,ARG(1,t));
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  if(!constant(b))
     { errbuf(0, english(1573));  /* b must be constant */
       return 1;
     }
  if(f == '<')
     { err = infer(le(zero,a));
       if(err)
          { errbuf(0,english(1571));  /*  a must be non-negative */
            return 1;
          }
     }
  else
     { err = infer(lessthan(zero,a));
       if(err)
          { errbuf(0,english(1570));  /* a must be positive */
            return 1;
          }
     }
  err = infer(lessthan(zero,b));
  if(err)
     { errbuf(0, english(1572));  /* b must be positive */
       return 1;
     }
  usq = ARG(1,ARG(0,t));
  err = sqrt_aux(usq,&u);
  if(err)
     return 1;
  err = sqrt_aux(a,&sqrta);
  if(err)
     return 1;   /* assert(0) */
  err = sqrt_aux(b,&sqrtb);
  if(err)
     return 1;   /* assert(0) */
  copy(sqrta,&sqrta2);
  copy(sqrtb,&sqrtb2);
  copy(u,&u2);
  copy(u,&u3);
  copy(u,&u4);
  if(f == '<' && g == '<')
     { *next = or(
                  and(lessthan(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
                  and(lessthan(sqrta2,u3),lessthan(u4,sqrtb2))
                 );
       strcpy(reason,english(2148));
          /* $a<u^2<b => -�b<u<-�a$  or $�a<u<�b$ */
     }
  else if (f == LE && g == LE)
     { *next = or(
                  and(le(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
                  and(le(sqrta2,u3),le(u4,sqrtb2))
                 );
       strcpy(reason, english(2149));
           /* a�u^2�b => -�b�u�-�a  or �a�u�b */
     }
  else if (f == '<' && g == LE)
     {  *next = or(
                  and(le(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
                  and(lessthan(sqrta2,u3),le(u4,sqrtb2))
                 );

       strcpy(reason, english(2150));
          /* a<u^2�b => -�b�u<-�a  or �a<u�b */
     }
  else if (f == LE && g == '<')
     { *next = or(
                  and(lessthan(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
                  and(le(sqrta2,u3),lessthan(u4,sqrtb2))
                 );
       strcpy(reason, english(2151));
         /* a�u^2<b => -�b<u�-�a  or �a�u<�b */
     }
  HIGHLIGHT(*next);
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq13(term t, term arg, term *next, char *reason)
/* u^2� < a => -^2��a < u < ^2��a       */
{ unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2,m;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = rootineq13(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(0,t);
  a = ARG(1,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(lessthan(zero,a));
  if(err)
     { errbuf(0,english(1570));  /* a must be positive */
       return 1;
     }
  if(FUNCTOR(usq) != '^')
     return 1;
  m = ARG(1,usq);
  if(!iseven(m))
     return 1;
  if(!INTEGERP(m))
     { err = check(lessthan(zero,m));
       if(err)
          { errbuf(0,english(447)); /* Exponent must be positive. */
            return 1;
          }
     }
  u = ARG(0,usq);
  err = nthroot_aux(a,m,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = and(lessthan(tnegate(sqrta),u), lessthan(u2,sqrta2));
  HIGHLIGHT(*next);
  strcpy(reason, english(2200));
    /* $u^2� < a$ iff          $-^2��a < u < ^2��a$ */
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq23(term t, term arg, term *next, char *reason)
/* u^2� � a => -^2��a � u � ^2��a       */
{ unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2,m;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = rootineq23(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(0,t);
  a = ARG(1,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(le(zero,a));
  if(err)
     { errbuf(0,english(1571));  /* a must be non-negative */
       return 1;
     }
  if(FUNCTOR(usq) != '^')
     return 1;
  m = ARG(1,usq);
  if(!iseven(m))
     return 1;
  if(!INTEGERP(m))
     { err = check(lessthan(zero,m));
       if(err)
          { errbuf(0,english(447)); /* Exponent must be positive. */
            return 1;
          }
     }

  u = ARG(0,usq);
  err = nthroot_aux(a,m,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = and(lessthan(tnegate(sqrta),u), lessthan(u2,sqrta2));
  HIGHLIGHT(*next);
  strcpy(reason, english(2201));
  /* $u^2� � a$ iff          $-^2��a � u � ^2��a$ */
  return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq15(term t, term arg, term *next, char *reason)
/* a < u^2 => u < -sqrt a or sqrt a < u */
{ unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2,m;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = rootineq15(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(1,t);
  if(FUNCTOR(usq) != '^')
     return 1;
  m = ARG(1,usq);
  if(!iseven(m))
     return 1;
  if(!INTEGERP(m))
     { err = check(lessthan(zero,m));
       if(err)
          { errbuf(0,english(447)); /* Exponent must be positive. */
            return 1;
          }
     }

  if(!INTEGERP(m))
     { err = check(lessthan(zero,m));
       if(err)
          { errbuf(0,english(447)); /* Exponent must be positive. */
            return 1;
          }
     }
  u = ARG(0,usq);
  a = ARG(0,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(le(zero,a));
  if(err)
     { errbuf(0,english(1571));  /* a must be non-negative */
       return 1;
     }
  err = nthroot_aux(a,m,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = or(lessthan(u,tnegate(sqrta)), lessthan(sqrta2,u2));
  HIGHLIGHT(*next);
  strcpy(reason,english(2152));
    /* $a < u^2�$ iff          $u<-^2��a$ or $^2��a<u$ */
  return 0;
}


/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq25(term t, term arg, term *next, char *reason)
 /* a � u^2� => u � -^2��a or ^2��a � u */
 { unsigned short f = FUNCTOR(t);
  int err;
  term temp,u,u2,usq,a,sqrta,sqrta2,m;
  if(f == GE || f == '>')  /* reduce to LE or '<' */
     { invert(t,&temp);
       err = rootineq25(temp,arg,next, reason);
       if(err)
          { RELEASE(temp);
            return 1;
          }
       return 0;
     }
  if(f != '<' && f != LE)
     return 1;
  usq = ARG(1,t);
  if(FUNCTOR(usq) != '^')
     return 1;
  u = ARG(0,usq);
  m = ARG(1,usq);
  if(!iseven(m))
     return 1;
  if(!INTEGERP(m))
     { err = check(lessthan(zero,m));
       if(err)
          { errbuf(0,english(447)); /* Exponent must be positive. */
            return 1;
          }
     }

  a = ARG(0,t);
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  err = infer(lessthan(zero,a));
  if(err)
     { errbuf(0,english(1570));  /* a must be positive */
       return 1;
     }
  err = nthroot_aux(a,m,&sqrta);
  if(err)
     return 1;
  copy(u,&u2);
  copy(sqrta,&sqrta2);  /* avoid DAGs */
  *next = or(le(u,tnegate(sqrta)), le(sqrta2,u2));
  HIGHLIGHT(*next);
  strcpy(reason,english(2153));
    /* a�u^2 iff u�-�a or �a�u */
  return 0;
}

/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootinterval1(term t, term arg, term *next, char *reason)
/* a<u^2�<b => -^2��b<u<-^2��a or ^2��a<u<^2��b */
{ if(!interval_as_and(t))
     return 1;
  if(FUNCTOR(ARG(0,t)) != '<')
     return 1;
  if(FUNCTOR(ARG(1,t)) != '<')
     return 1;
  return rootinterval2(t,arg,next,reason);
}

/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootinterval2(term t, term arg, term *next, char *reason)
/* a�u^2��b => -^2��b�u�-^2��a or ^2��a�u�^2��b */
{ int err;
  unsigned short f = FUNCTOR(ARG(0,t));
  unsigned short g = FUNCTOR(ARG(1,t));
  term a,b,sqrta,sqrtb,sqrta2,sqrtb2,usq,u,u2,u3,u4,m;
  if(!interval_as_and(t))
     return 1;
  a = ARG(0,ARG(0,t));
  b = ARG(1,ARG(1,t));
  if(!constant(a))
     { errbuf(0,english(1569));  /* a must be constant */
       return 1;
     }
  if(!constant(b))
     { errbuf(0, english(1573));  /* b must be constant */
       return 1;
     }
  usq = ARG(1,ARG(0,t));
  if(FUNCTOR(usq) != '^')
     return 1;
  m = ARG(1,usq);
  if(!iseven(m))
    return 1;
  if(!INTEGERP(m))
     { err = check(lessthan(zero,m));
       if(err)
          { errbuf(0,english(447)); /* Exponent must be positive. */
            return 1;
          }
     }

  u = ARG(0,usq);
  if(f == '<')
     { err = infer(le(zero,a));
       if(err)
          { errbuf(0,english(1571));  /*  a must be non-negative */
            return 1;
          }
     }
  else
     { err = infer(lessthan(zero,a));
       if(err)
          { errbuf(0,english(1570));  /* a must be positive */
            return 1;
          }
     }
  err = infer(lessthan(zero,b));
  if(err)
     { errbuf(0, english(1572));  /* b must be positive */
       return 1;
     }
  err = nthroot_aux(a,m,&sqrta);
  if(err)
     return 1;   /* assert(0) */
  err = nthroot_aux(b,m,&sqrtb);
  if(err)
     return 1;   /* assert(0) */
  copy(sqrta,&sqrta2);
  copy(sqrtb,&sqrtb2);
  copy(u,&u2);
  copy(u,&u3);
  copy(u,&u4);
  if(f == '<' && g == '<')
     { *next = or(
                  and(lessthan(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
                  and(lessthan(sqrta2,u3),lessthan(u4,sqrtb2))
                 );
       strcpy(reason,english(2154));
         /* a<u^2�<b => -^2��b<u<-^2��a or ^2��a<u<^2��b */
     }
  else if (f == LE && g == LE)
     { *next = or(
                  and(le(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
                  and(le(sqrta2,u3),le(u4,sqrtb2))
                 );
       strcpy(reason, english(2155));
          /* a�u^2��b => -^2��b�u�-^2��a or ^2��a�u�^2��b") */
     }
  else if (f == '<' && g == LE)
     {  *next = or(
                  and(le(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
                  and(lessthan(sqrta2,u3),le(u4,sqrtb2))
                 );

       strcpy(reason, english(2156));
         /* a<u^2��b => -^2��b�u<-^2��a or ^2��a<u�^2��b */
     }
  else if (f == LE && g == '<')
     { *next = or(
                  and(lessthan(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
                  and(le(sqrta2,u3),lessthan(u4,sqrtb2))
                 );
       strcpy(reason, english(2157));
         /* a�u^2�<b iff -^2��b<u�-^2��a or ^2��a�u<^2��b */
     }
  HIGHLIGHT(*next);
  return 0;
}

/*______________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt1(term ineq, term arg, term *next, char *reason)
 /* 0 < u/sqrt v => 0 < uv */
 /* u/sqrt v > 0 => uv > 0 */
{ unsigned short f = FUNCTOR(ineq);
  unsigned short n,k,j;
  int i;
  char *r;
  term left,right,u,v,w,denom,temp,q;
  if(f != '<' && f != '>')
     return 1;
  if(f == '<')
     r = "$0 < u/�v => 0 < uv$";
  else
     r = "$u/�v > 0 => uv > 0$";
  left = ARG(f == '<' ? 0 : 1, ineq);
  right = ARG(f == '<' ? 1 : 0, ineq);
  if(!ZERO(left))
     return 1;
  if(!FRACTION(right))
     return 1;
  denom = ARG(1, right);
  if(FUNCTOR(denom) == SQRT)
     { v = ARG(0,denom);
       HIGHLIGHT(v);
       u = ARG(0,right);
       w = product(u,v);
       if(FUNCTOR(w) == '*')
          sortargs(w);
       if(f == '>')
          *next = greaterthan(w,zero);
       else
          *next = lessthan(zero,w);
       strcpy(reason,r);
       return 0;
     }
  if(FUNCTOR(denom) == '*')
     { /* extract the sqrt term (or terms) */
       n = ARITY(denom);
       v = make_term('*',n);
       q = make_term('*',n);
       k = j = 0;
       for(i=0;i<n;i++)
          { if(FUNCTOR(ARG(i,denom)) == SQRT)
               { ARGREP(v,k,ARG(0,ARG(i,denom)));
                 HIGHLIGHT(ARG(k,v));
                 ++k;
               }
            else
               { ARGREP(q,j,ARG(i,denom));
                 ++j;
               }
          }
       if(k == 0)
          return 1;  /* no SQRT term */
       else if(k == 1)
          { temp = ARG(0,v);
            RELEASE(v);
            v = temp;
          }
       else
          SETFUNCTOR(v,'*',k);
       if(j == 0)
          { RELEASE(q);
            q = one;
          }
       else if(j == 1)
          { temp = ARG(0,q);
            RELEASE(q);
            q = temp;
          }
       else
          SETFUNCTOR(q,'*',j);
       u = ARG(0,right);
       w = product(u,v);
       if(f == '<')
          *next = lessthan(zero, ONE(q) ? w : make_fraction(w,q));
       else
          *next = greaterthan(ONE(q) ? w : make_fraction(w,q),zero);
       strcpy(reason,r);
       return 0;
     }
  return 1;
}

/*______________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt2(term ineq, term arg, term *next, char *reason)
 /* u/sqrt v < 0 => uv < 0 */
 /* 0 > u/sqrt v => 0 > uv */
{ unsigned short f = FUNCTOR(ineq);
  unsigned short n,k,j;
  int i;
  term left,right,u,v,w,denom,temp,q;
  char *r;
  if(f != '<' && f != '>')
     return 1;
  if(f == '<')
     r = "$u/�v < 0 => uv < 0$";
  else
     r = "$0 > u/�v => 0 > uv$";
  left = ARG(f == '<' ? 0 : 1, ineq);
  right = ARG(f == '<' ? 1 : 0, ineq);
  if(!ZERO(right))
     return 1;
  if(!FRACTION(left))
     return 1;
  denom = ARG(1, left);
  if(FUNCTOR(denom) == SQRT)
     { v = ARG(0,denom);
       HIGHLIGHT(v);
       u = ARG(0,left);
       w = product(u,v);
       if(FUNCTOR(w) == '*')
          sortargs(w);
       if(f == '<')
          *next = lessthan(w,zero);
       else
          *next = greaterthan(zero,w);
       strcpy(reason,r);
       return 0;
     }
  if(FUNCTOR(denom) == '*')
     { /* extract the sqrt term (or terms) */
       n = ARITY(denom);
       v = make_term('*',n);
       q = make_term('*',n);
       k = j = 0;
       for(i=0;i<n;i++)
          { if(FUNCTOR(ARG(i,denom)) == SQRT)
               { ARGREP(v,k,ARG(0,ARG(i,denom)));
                 HIGHLIGHT(ARG(k,v));
                 ++k;
               }
            else
               { ARGREP(q,j,ARG(i,denom));
                 ++j;
               }
          }
       if(k == 0)
          return 1;  /* no SQRT term */
       else if(k == 1)
          { temp = ARG(0,v);
            RELEASE(v);
            v = temp;
          }
       else
          SETFUNCTOR(v,'*',k);
       if(j == 0)
          { RELEASE(q);
            q = one;
          }
       else if(j == 1)
          { temp = ARG(0,q);
            RELEASE(q);
            q = temp;
          }
       else
          SETFUNCTOR(q,'*',j);
       u = ARG(0,left);
       w = product(u,v);
       if(f == '<')
          *next = lessthan(ONE(q) ? w : make_fraction(w,q),zero);
       else
          *next = greaterthan(zero, ONE(q) ? w : make_fraction(w,q));
       strcpy(reason,r);
       return 0;
     }
  return 1;
}
/*________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt3(term ineq, term arg, term *next, char *reason)
 /* 0 <= u/sqrt v => 0 <= uv */
 /* u/sqrt v >= 0  => uv >= 0 */
{ unsigned short f = FUNCTOR(ineq);
  unsigned short n,k,j;
  int i;
  term left,right,u,v,w,denom,temp,q;
  char *r;
  if(f != LE && f != GE)
     return 1;
  if(f == LE)
     r = "$0 � u/�v => 0 � uv$";
  else
     r = "$u/�v � 0 => uv � 0$";
  left = ARG(f == LE ? 0 : 1, ineq);
  right = ARG(f == LE ? 1 : 0, ineq);
  if(!ZERO(right))
     return 1;
  if(!FRACTION(left))
     return 1;
  denom = ARG(1, left);
  if(FUNCTOR(denom) == SQRT)
     { v = ARG(0,denom);
       HIGHLIGHT(v);
       u = ARG(0,left);
       w = product(u,v);
       if(FUNCTOR(w) == '*')
          sortargs(w);
       if(f == LE)
          *next = le(zero,w);
       else
          *next = ge(w,zero);
       strcpy(reason,r);
       return 0;
     }
  if(FUNCTOR(denom) == '*')
     { /* extract the sqrt term (or terms) */
       n = ARITY(denom);
       v = make_term('*',n);
       q = make_term('*',n);
       k = j = 0;
       for(i=0;i<n;i++)
          { if(FUNCTOR(ARG(i,denom)) == SQRT)
               { ARGREP(v,k,ARG(0,ARG(i,denom)));
                 HIGHLIGHT(ARG(k,v));
                 ++k;
               }
            else
               { ARGREP(q,j,ARG(i,denom));
                 ++j;
               }
          }
       if(k == 0)
          return 1;  /* no SQRT term */
       else if(k == 1)
          { temp = ARG(0,v);
            RELEASE(v);
            v = temp;
          }
       else
          SETFUNCTOR(v,'*',k);
       if(j == 0)
          { RELEASE(q);
            q = one;
          }
       else if(j == 1)
          { temp = ARG(0,q);
            RELEASE(q);
            q = temp;
          }
       else
          SETFUNCTOR(q,'*',j);
       u = ARG(0,left);
       w = product(u,v);
       if(f == LE)
          *next = le(ONE(q) ? w : make_fraction(w,q),zero);
       else
          *next = ge(zero, ONE(q) ? w : make_fraction(w,q));
       strcpy(reason,r);
       return 0;
     }
  return 1;
}

/*______________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt4(term ineq, term arg, term *next, char *reason)
 /* u/sqrt v <= 0=> uv <= 0 */
 /* 0 >= u/sqrt v => 0 >= uv */
{ unsigned short f = FUNCTOR(ineq);
  unsigned short n,k,j;
  int i;
  term left,right,u,v,w,denom,temp,q;
  char *r;
  if(f != LE && f != GE)
     return 1;
  if(f == LE)
     r = "$u/�v � 0 => uv � 0$";
  else
     r = "$0 � u/�v => 0 � uv$";
  left = ARG(f == LE ? 0 : 1, ineq);
  right = ARG(f == LE ? 1 : 0, ineq);
  if(!ZERO(right))
     return 1;
  if(!FRACTION(left))
     return 1;
  denom = ARG(1, left);
  if(FUNCTOR(denom) == SQRT)
     { v = ARG(0,denom);
       HIGHLIGHT(v);
       u = ARG(0,left);
       w = product(u,v);
       if(FUNCTOR(w) == '*')
          sortargs(w);
       if(f == LE)
         *next = le(w,zero);
       else
         *next = ge(zero,w);
       strcpy(reason,r);
       return 0;
     }
  if(FUNCTOR(denom) == '*')
     { /* extract the sqrt term (or terms) */
       n = ARITY(denom);
       v = make_term('*',n);
       q = make_term('*',n);
       k = j = 0;
       for(i=0;i<n;i++)
          { if(FUNCTOR(ARG(i,denom)) == SQRT)
               { ARGREP(v,k,ARG(0,ARG(i,denom)));
                 HIGHLIGHT(ARG(k,v));
                 ++k;
               }
            else
               { ARGREP(q,j,ARG(i,denom));
                 ++j;
               }
          }
       if(k == 0)
          return 1;  /* no SQRT term */
       else if(k == 1)
          { temp = ARG(0,v);
            RELEASE(v);
            v = temp;
          }
       else
          SETFUNCTOR(v,'*',k);
       if(j == 0)
          { RELEASE(q);
            q = one;
          }
       else if(j == 1)
          { temp = ARG(0,q);
            RELEASE(q);
            q = temp;
          }
       else
          SETFUNCTOR(q,'*',j);
       u = ARG(0,left);
       w = product(u,v);
       if(f == LE)
          *next = le(ONE(q) ? w : make_fraction(w,q),zero);
       else
          *next = ge(zero, ONE(q) ? w : make_fraction(w,q));
       strcpy(reason,r);
       return 0;
     }
  return 1;
}

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