Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/prover/
Upload File :
Current File : /usr/home/beeson/MathXpert/prover/fasttrig.c

/* M. Beeson for Mathpert
   Fast inference of common trig inequalities from interval inequalities.
   When used, the intervals will be assumptions.

Original date of file 1.6.94
Code last modified 1.7.96
1.29.98 file last modified
*/

#include <assert.h>
#include "globals.h"
#include "prover.h"
#include "trig.h"

static int fasttrig_pos(term p, term r, int strict);

/*_______________________________________________________________*/
static int notpioverfour(term a,term x)
/* return 1 if a is an interval_as_and term expressing that x lies
between multiples of pi/4.  Return 0 otherwise.
It is presumed that a is an interval_as_and.
*/

{ term l,r;
  l = ARG(0,ARG(0,a));
  r = ARG(1,ARG(1,a));
  if(!equals(x,ARG(1,ARG(0,a))))
     return 0;
    /* catch (1/4) n \pi   < x < (1/4)(n+1)\pi  */
  if(
     FUNCTOR(l) == '*' && ARITY(l) == 3 &&
     FUNCTOR(r) == '*' && ARITY(r) == 3 &&
     FRACTION(ARG(0,l)) && ONE(ARG(0,ARG(0,l))) &&
     equals(ARG(1,ARG(0,l)),four) &&
     ISATOM(ARG(1,l)) && TYPE(ARG(1,l)) == INTEGER &&
     equals(ARG(2,l),pi_term) &&
     FRACTION(ARG(0,r)) && ONE(ARG(0,ARG(0,r))) &&
     equals(ARG(1,ARG(0,r)),four) &&
     equals(ARG(2,r),pi_term) &&
     FUNCTOR(ARG(1,r)) == '+' && ONE(ARG(1,ARG(1,r))) &&
     equals(ARG(0,ARG(1,r)), ARG(1,l))
    )
     return 1;
  /* catch n\pi /4 < x < (n+1)\pi /4 */
  if(
     FRACTION(l) && equals(ARG(1,l),four) &&
     FRACTION(r) && equals(ARG(1,r),four) &&
     FUNCTOR(ARG(0,l)) == '*' && ARITY(ARG(0,l)) == 2 &&
     equals(ARG(1,ARG(0,l)),pi_term) && ISATOM(ARG(0,ARG(0,l))) &&
     TYPE(ARG(0,ARG(0,l))) == INTEGER &&
     FUNCTOR(ARG(0,r)) == '*' && ARITY(ARG(0,r)) == 2 &&
     equals(ARG(1,ARG(0,r)),pi_term) &&
     FUNCTOR(ARG(0,ARG(0,r))) == '+' &&
     ONE(ARG(1,ARG(0,ARG(0,r)))) &&
     equals(ARG(0,ARG(0,ARG(0,r))),ARG(0,ARG(0,l)))
    )
     return 1;
  return 0;
}

/*_______________________________________________________________*/
static int notpiovertwo(term a, term x)
/* return 1 if a is an interval_as_and term expressing that x lies
between multiples of pi/2.  Return 0 otherwise.
It is presumed that a is an interval_as_and.
*/

{ term l,r;
  l = ARG(0,ARG(0,a));
  r = ARG(1,ARG(1,a));
  if(!equals(x,ARG(1,ARG(0,a))))
     return 0;
  if(
     FUNCTOR(l) == '*' && ARITY(l) == 3 &&
     FUNCTOR(r) == '*' && ARITY(r) == 3 &&
     FRACTION(ARG(0,l)) && ONE(ARG(0,ARG(0,l))) &&
     equals(ARG(1,ARG(0,l)),two) &&
     ISATOM(ARG(1,l)) && TYPE(ARG(1,l)) == INTEGER &&
     equals(ARG(2,l),pi_term) &&
     FRACTION(ARG(0,r)) && ONE(ARG(0,ARG(0,r))) &&
     equals(ARG(1,ARG(0,r)),two) &&
     equals(ARG(2,r),pi_term) &&
     FUNCTOR(ARG(1,r)) == '+' && ONE(ARG(1,ARG(1,r))) &&
     equals(ARG(0,ARG(1,r)), ARG(1,l))
    )
     return 1;
       /* catch n\pi /2 < x < (n+1)\pi /2 */
  if(
     FRACTION(l) && equals(ARG(1,l),two) &&
     FRACTION(r) && equals(ARG(1,r),two) &&
     FUNCTOR(ARG(0,l)) == '*' && ARITY(ARG(0,l)) == 2 &&
     equals(ARG(1,ARG(0,l)),pi_term) && ISATOM(ARG(0,ARG(0,l))) &&
     TYPE(ARG(0,ARG(0,l))) == INTEGER &&
     FUNCTOR(ARG(0,r)) == '*' && ARITY(ARG(0,r)) == 2 &&
     equals(ARG(1,ARG(0,r)),pi_term) &&
     FUNCTOR(ARG(0,ARG(0,r))) == '+' &&
     ONE(ARG(1,ARG(0,ARG(0,r)))) &&
     equals(ARG(0,ARG(0,ARG(0,r))),ARG(0,ARG(0,l)))
    )
     return 1;
  return 0;
}
/*_______________________________________________________________*/
static int notpi(term a, term x)
/* return 1 if a is an interval_as_and term expressing that x lies
between multiples of pi.  Return 0 otherwise.
It is presumed that a is an interval_as_and.
*/

{ term l,r;
  l = ARG(0,ARG(0,a));
  r = ARG(1,ARG(1,a));
  if(!equals(x,ARG(1,ARG(0,a))))
     return 0;


  if(FUNCTOR(l) == '*' && ARITY(l) == 2 &&
     FUNCTOR(r) == '*' && ARITY(r) == 2 &&
     ISATOM(ARG(0,l)) && TYPE(ARG(0,l)) == INTEGER &&
     equals(ARG(1,l),pi_term) &&
     equals(ARG(1,r),pi_term) &&
     FUNCTOR(ARG(0,r)) == '+' && ONE(ARG(1,ARG(0,r))) &&
     equals(ARG(0,ARG(0,r)), ARG(0,l))
    )
     return 1;
  return 0;
}
/*_______________________________________________________________*/
static int notoddpiovertwo(term a, term x)
/* return 1 if a is an interval_as_and term expressing that x lies
between odd multiples of pi/2.  Return 0 otherwise.
It is presumed that a is an interval_as_and.
*/

{ term l,r;
  l = ARG(0,ARG(0,a));
  r = ARG(1,ARG(1,a));
  if(!equals(x,ARG(1,ARG(0,a))))
     return 0;

  if(FUNCTOR(l) == '+' && ARITY(l) == 2 &&
     FUNCTOR(r) == '+' && ARITY(r) == 2 &&
     equals(ARG(0,l), ARG(0,r)) &&
     FUNCTOR(ARG(0,l)) == '*' && ARITY(ARG(0,l)) == 2 &&
     ISATOM(ARG(0,ARG(0,l))) && TYPE(ARG(0,ARG(0,l))) == INTEGER &&
     equals(ARG(1,ARG(0,l)),pi_term) &&
     NEGATIVE(ARG(1,l)) &&
     equals(ARG(0,ARG(1,l)),ARG(1,r)) &&
     FRACTION(ARG(1,r)) &&
     equals(ARG(0,ARG(1,r)),pi_term) &&
     equals(ARG(1,ARG(1,r)),two)
    )
     return 1;
  return 0;
}
/*_______________________________________________________________*/
int domain_implies(term a, term b)
/* a is an interval_as_and;  b is an NE term or < or LE term;
return 1 if a involves an existential integer variable and
expresses a condition that implies b.   Example:  if a
is n\pi  < x < (n+1)\pi   and b is sin x != 0, return 1.
Return 0 for failure. */

{ unsigned g = FUNCTOR(b);
  unsigned f,h;
  term u,v,temp,x;
  u = ARG(0,b);
  v = ARG(1,b);
  if(g == LE && ZERO(ARG(0,b)))
     return fasttrig_pos(a,b,0);
  if(g == '<' && ZERO(ARG(0,b)))
     return fasttrig_pos(a,b,1);
  if(g == LE || g == '<')
     return 0;  /* can't handle other inequalities */
  if(ZERO(u) || ONE(u))  /* swap u and v */
     { temp = u;
       u = v;
       v = temp;
     }
  if(!ZERO(v) && !ONE(v) && !equals(v,minusone))
     return 0;
  f = FUNCTOR(u);
  if(ZERO(v) && (f == SEC || f == CSC) && !get_complex())
     return 1;  /* no hypothesis needed! */
  if(f == SEC && ONE(v))
     f = COS;
  if(f == CSC && ONE(v))
     f = SIN;
  if(f == '+' && ARITY(u)==2)
    /* handle  f(x)  \pm  1 != 0  for trig functions f in case
       x is known to not be a multiple of \pi /4, or in some
       other easy cases.
    */
     { if(ONE(ARG(1,u)) || equals(ARG(1,u),minusone))
          u = ARG(0,u);
       else if(ONE(ARG(0,u)))
          u = ARG(1,u);
       else
          return 0;
       if(FUNCTOR(u) == '^' && INTEGERP(ARG(1,u)))
           u = ARG(0,u);  /* handle  sin^n  \pm  1 != 0 too */
       h = FUNCTOR(u);
       if(!TRIGFUNCTOR(h))
          return 0;
       x = ARG(0,u);
       if(notpioverfour(a,x))
          /* In this case it doesn't matter what trigfunctor it is */
          return 1;
       if(h == SIN && notoddpiovertwo(a,x))
          return 1;
       if(h == COS && notpi(a,x))
          return 1;
       return 0;
     }
  x = ARG(0,u);
  if(!ATOMIC(x))
     return 0;
  if(ONE(v) && f == '^' && equals(ARG(1,u),two))
     { u = ARG(0,u);
       f = FUNCTOR(u);
       if(f!=COT && f!=TAN)
          return 0;
     }
  else if(f != SIN && f != COS && f != TAN && f != COT)
     return 0;
  if(!equals(x,ARG(1,ARG(0,a))))
     return 0;
   /* catch (1/2) n \pi   < x < (1/2)(n+1)\pi  */

  if(f==SIN || f==COS || ZERO(v))
     { if(notpiovertwo(a,x))
          return 1;
     /* catch n \pi   < x < (n+1)\pi , when f == SIN or TAN and v=0 or
        f == COS and v=1 or -1  */
       if(
          (
           ((f == SIN || f == TAN) && ZERO(v)) ||
           (f == COS && (ONE(v) || equals(v,minusone)))
          ) &&
          notpi(a,x)
        )
         return 1;
       /* catch n \pi  -\pi /2 < x < n\pi  + \pi /2, when f == COS or COT and v = 0,
          or   f == SIN and v = 1 or -1 */
       if(
          (
           ((f == COS || f == COT) && ZERO(v)) ||
           ( f==SIN && (ONE(v) || equals(v,minusone)))
          ) &&
          notoddpiovertwo(a,x)
         )
          return 1;
       return 0;
     }
  return notpioverfour(a,x);
}

/*_________________________________________________________*/
static int fasttrig_pos(term p, term r, int strict)
/* finish fasttrig for the case q is 0 < r  or 0 <= r */
/* strict is nonzero if it's <, zero if it's LE       */

{ term a,b,n,u,x;
  unsigned fa,fb,f;
  a = ARG(0,ARG(0,p));
  b = ARG(1,ARG(1,p));
  fa = FUNCTOR(a);
  fb = FUNCTOR(b);
  if(strict && (fa == LE || fb == LE))
     return 0;
  x = ARG(1,ARG(0,p));
  f = FUNCTOR(r);
  if(!TRIGFUNCTOR(f) || !equals(x,ARG(0,r)))
     return 0;
  if(f == SEC)
    f = COS;
  if(f == CSC)
    f = SIN;
  /* That disposes of SEC and CSC */
  if(f == SIN)
  /* check for the open interval (2n\pi , 2n\pi  + \pi ) or (2n\pi , (2n+1)\pi )*/
     { if(ARITY(a) != 2 || !equals(ARG(1,a),pi_term))
          return 0;
       n = ARG(0,a);
       if(!ISATOM(n) || TYPE(n) != INTEGER)
          return 0;
       if(FUNCTOR(b) == '*' && equals(ARG(1,b),pi_term) && ARITY(b) == 2)
          /* check for (2n+1)\pi  */
          { u = ARG(0,b);
            if(FUNCTOR(u) == '+'  && ARITY(u) == 2 &&
               ONE(ARG(1,u)) && FUNCTOR(ARG(0,u)) == '*' &&
               ARITY(ARG(0,u)) == 2 && equals(ARG(0,ARG(0,u)),two) &&
               equals(ARG(1,ARG(0,u)),n)
              )
               return 1;
            return 0;
          }
       if(FUNCTOR(b) == '+' && ARITY(b) == 2 && equals(ARG(1,b),pi_term))
          { u = ARG(0,b);
            if(FUNCTOR(u) != '*' || ARITY(u) != 3)
               return 0;
            if(equals(ARG(0,u),two) & equals(ARG(1,u),n) && equals(ARG(2,u),pi_term))
               return 1;
            return 0;
          }
     }
  if(f == COS)
     /* check for the interval  2n\pi -\pi /2 < x < 2n\pi  + \pi /2  */
     { if(FUNCTOR(a) != '+' || FUNCTOR(b) != '+')
          return 0;
       if(ARITY(a) != 2 || ARITY(b) != 2)
          return 0;
       if(!NEGATIVE(ARG(1,a)) || !equals(ARG(0,ARG(1,a)),piover2) ||
          !equals(ARG(1,b),piover2)
         )
          return 0;
       u = ARG(0,a);
       if(FUNCTOR(u) != '*' || ARITY(u) != 3 || !equals(ARG(0,u),two) ||
          !ISATOM(ARG(1,u)) || !(TYPE(ARG(1,u)) == INTEGER) ||
          !equals(ARG(2,u),pi_term)
         )
          return 0;
       if(!equals(ARG(0,b),u))
          return 0;
       return 1;
     }
  if(f==TAN || f == COT)
  /* check for the interval n\pi < x < n\pi  + \pi /2  */
     { if(f == TAN && fb != '<')
          return 0;
       if(f == COT && fa != '<')
          return 0;
       if(FUNCTOR(a) != '*' || ARITY(a) != 2 || !equals(ARG(1,a),pi_term))
          return 0;
       n = ARG(0,a);
       if(!ISATOM(n) || !(TYPE(n)==INTEGER))
          return 0;
       if(FUNCTOR(b) != '+' || ARITY(b) != 2 || !equals(ARG(1,b),piover2))
          return 0;
       u = ARG(0,b);
       if(FUNCTOR(u) != '*' || !equals(ARG(0,u),n) || !equals(ARG(1,u),pi_term))
          return 0;
       return 1;
     }
  return 0;
}

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