Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/trigcalc/
Upload File :
Current File : /usr/home/beeson/MathXpert/trigcalc/invsimp.c

/* operators for simplifying f(arcf(x)) and arcf(f(x)) */
/*
M. Beeson, for MathXpert
5.28.92  Original date
3.30.99 last modified
5.6.24  changed \theta to \\theta
*/

#include <string.h>
#include <assert.h>

#include "globals.h"
#include "ops.h"
#include "trig.h"
#include "prover.h"
#include "symbols.h"
#include "mathmode.h"   /* get_mathmode */
#include "match.h"    /* matchstring  */
#include "deval.h"
#include "pvalaux.h"  /* topflatten   */
#include "autosimp.h" /* SetShowStepArg */
#include "algaux.h"   /* path_to_difference */
/*____________________________________________________________________*/
/* tan(arcsin x) = x/\\sqrt (1-x^2) */
int tanasin(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != TAN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ASIN)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = make_fraction(x,sqrt1(sum(one,tnegate(make_power(x,two)))));
  HIGHLIGHT(*next);
  strcpy(reason,"tan(arcsin x) =        $x/\\sqrt (1-x^2)$");
  return 0;
}

/*____________________________________________________________________*/
/* tan(arccos x) = \\sqrt (1-x^2)/x */
int tanacos(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != TAN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ACOS)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = make_fraction(sqrt1(sum(one,tnegate(make_power(x,two)))),x);
  HIGHLIGHT(*next);
  strcpy(reason,"tan(arccos x) =          $\\sqrt (1-x^2)/x$");
  return 0;
}

/*____________________________________________________________________*/
/* tan(arctan x) = x */
int tanatan(term t, term arg, term *next, char *reason)
{ if(FUNCTOR(t) != TAN)
   return 1;
  if(FUNCTOR(ARG(0,t)) != ATAN)
     return 1;
  *next = ARG(0,ARG(0,t));
  HIGHLIGHT(*next);
  strcpy(reason,"tan(arctan x) = x");
  return 0;
}

/*____________________________________________________________________*/
/* sin(arcsin x) = x */
int sinasin(term t, term arg, term *next, char *reason)
{ if(FUNCTOR(t) != SIN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ASIN)
     return 1;
  *next = ARG(0,ARG(0,t));
  HIGHLIGHT(*next);
  strcpy(reason,"sin(arcsin x) = x");
  return 0;
}

/*____________________________________________________________________*/
/* sin(arccos x) = \\sqrt (1-x^2) */
int sinacos(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != SIN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ACOS)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = sqrt1(sum(one,tnegate(make_power(x,two))));
  HIGHLIGHT(*next);
  strcpy(reason,"$sin(arccos x)=\\sqrt (1-x^2)$");
  return 0;
}

/*____________________________________________________________________*/
/* sin(arctan x) = x/\\sqrt (x^2+1) */
int sinatan(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != SIN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ATAN)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = make_fraction(x,sqrt1(sum(make_power(x,two),one)));
  HIGHLIGHT(*next);
  strcpy(reason,"sin(arctan x) =          $x/\\sqrt (x^2+1)$");
  return 0;
}

/*____________________________________________________________________*/
/* cos(arcsin x) = \\sqrt (1-x^2) */
int cosasin(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != COS)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ASIN)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = sqrt1(sum(one,tnegate(make_power(x,two))));
  HIGHLIGHT(*next);
  strcpy(reason,"$cos(arcsin x)=\\sqrt (1-x^2)$");
  return 0;
}

/*____________________________________________________________________*/
/* cos(arccos x) = x */
int cosacos(term t, term arg, term *next, char *reason)
{ if(FUNCTOR(t) != COS)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ACOS)
     return 1;
  *next = ARG(0,ARG(0,t));
  HIGHLIGHT(*next);
  strcpy(reason,"cos(arccos x) = x");
  return 0;
}
/*____________________________________________________________________*/
/* cos(arctan x) = 1/\\sqrt (x^2+1) */
int cosatan(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != COS)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ATAN)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = make_fraction(one,sqrt1(sum(make_power(x,two),one)));
  HIGHLIGHT(*next);
  strcpy(reason,"cos(arctan x) =          $1/\\sqrt (x^2+1)$");
  return 0;
}
/*____________________________________________________________________*/
/* sec(arcsin x) = 1/\\sqrt (1-x^2) */
int secasin(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != SEC)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ASIN)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = reciprocal(sqrt1(sum(one,tnegate(make_power(x,two)))));
  HIGHLIGHT(*next);
  strcpy(reason,"sec(arcsin x) =        $1/\\sqrt (1-x^2)$");
  return 0;
}

/*____________________________________________________________________*/
/* sec(arccos x) = 1/x */
int secacos(term t, term arg, term *next, char *reason)
{ if(FUNCTOR(t) != SEC)
   return 1;
  if(FUNCTOR(ARG(0,t)) != ACOS)
     return 1;
  *next = reciprocal(ARG(0,ARG(0,t)));
  HIGHLIGHT(*next);
  strcpy(reason,"sec(arccos x) = 1/x");
  return 0;
}
/*____________________________________________________________________*/
/* sec(arctan x) = \\sqrt (x^2+1) */
int secatan(term t, term arg, term *next, char *reason)
{ term x;
  if(FUNCTOR(t) != SEC)
     return 1;
  if(FUNCTOR(ARG(0,t)) != ATAN)
     return 1;
  x = ARG(0,ARG(0,t));
  *next = sqrt1(sum(make_power(x,two),one));
  HIGHLIGHT(*next);
  strcpy(reason,"$sec(arctan x)=\\sqrt (x^2+1)$");
  return 0;
}
/*____________________________________________________________________*/
/* arctan(tan \\theta) = \\theta if  */
int atantan(term t, term arg, term *next, char *reason)
{ int err;
  term theta,p;
  double z;
  int sign = 1;
  long kk;
  if(FUNCTOR(t) != ATAN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != TAN)
     return 1;
  theta = ARG(0,ARG(0,t));
  if(seminumerical(theta))
     { deval(theta,&z);
       if(z < 0)
          { z = -z;
            sign = -1;
          }
       if(z < (double) 0xeffffffL)
          { kk = (long) (z / PI_DECIMAL + 0.5);
            if(kk == 0)
               *next = theta;
            else if(sign < 0)
               *next = sum(theta,make_fraction(product(make_int(kk),pi_term),two));
            else
               *next = sum(theta,tnegate(make_fraction(product(make_int(kk),pi_term),two)));
            HIGHLIGHT(*next);
            strcpy(reason, "$arctan(tan \\theta)=\\theta-n\\pi/2$");
            return 0;
          }
     }
  /* Now theta is not seminumerical */
  p = and(le(tnegate(make_fraction(pi_term,two)),theta),le(theta,make_fraction(pi_term,two)));
  err = infer(p);   /* Not 'check', else atantan2 never gets used */
  if(err)
     return 1;
  *next = theta;
  HIGHLIGHT(*next);
  strcpy(reason,"$arctan(tan \\theta) = \\theta$    ");
  strcat(reason,english(2179));   /* if -\\pi/2 < \\theta < \\pi/2 */
  return 0;
}
/*____________________________________________________________________*/
static int contains_int(term t)
/* t is a sum.  Return 1 if one of the summands is a constant of
integration or an indefinite integral, or a product containing
such a thing as a factor.
*/
{ unsigned short n;
  int i,j;
  term u,v;
  assert(FUNCTOR(t) == '+');
  n = ARITY(t);
  for(i=0;i<n;i++)
     { u = ARG(i,t);
       if(NEGATIVE(u))
          u = ARG(0,u);
       if((FUNCTOR(u) == INTEGRAL && ARITY(u) == 2) ||
          FUNCTOR(u) == CONSTANTOFINTEGRATION
         )
          break;
       if(FUNCTOR(u) == '*')
          { for(j=0; j<ARITY(u); j++)
               { v = ARG(j,u);
                 if((FUNCTOR(v) == INTEGRAL && ARITY(v) == 2) ||
                    FUNCTOR(v) == CONSTANTOFINTEGRATION
                   )
                    break;
               }
            if(j < ARITY(u))
                  break;
          }
     }
  return i<n ? 1 : 0;
}

/*____________________________________________________________________*/
/* arctan(tan \theta ) = \theta  + c1 */
int atantan2(term t, term arg, term *next, char *reason)
{ int i,j,k;
  term u,v,a,newu,x,newc;
  unsigned short n;
  unsigned short path[MAXTAIL];
  int sign = 1;
  term denom = one;
  char *r = "arctan(tan x) = x + c1";
  int mathmode = get_mathmode();
  if(mathmode == SELECTIONMODE)
     { if(FUNCTOR(t) != ATAN)
          return 1;
       if(FUNCTOR(ARG(0,t)) != TAN)
          return 1;
       *next = ARG(0,ARG(0,t));
       HIGHLIGHT(*next);
       strcpy(reason,r);
       return 0;
     }
 /* Now we're in menu mode or auto mode. Apply it
    only in a linear combination with an integral or
    a constant of integration.  It isn't called in automode
    unless there is an ATAN occurring as a summand or
    a factor of a summand; including the case where the
    summand is negative.
*/
  if(FUNCTOR(t) != '+')
     return 1;
  /* Check if there is an integral or constant of integration */
  if(!contains_int(t))
     return 1;
      /* OK, you can go ahead and apply the operator to t */
  n = ARITY(t);
  /* x must be SOME variable to pass to matchstring */
  x = var0;
  for(i=0;i<n;i++)
     { u = ARG(i,t);
       if(NEGATIVE(u))
          { sign = -1;
            u = ARG(0,u);
          }
       if(FRACTION(u) && constant(ARG(1,u)))
          { u = ARG(0,u);
            denom = ARG(1,u);
          }
       if(!matchstring(u,x,"arctan(tan(a))",&a))
          { newu = a;
            HIGHLIGHT(newu);
            break;
          }
       if(FUNCTOR(u)=='*')
          { for(j=0;j<ARITY(u);j++)
               { v = ARG(j,u);
                 if(!matchstring(v,x,"arctan(tan(a))",&a))
                    { newu = make_term('*',ARITY(u));
                      HIGHLIGHT(a);
                      for(k=0;k<ARITY(u);k++)
                         ARGREP(newu,k, k==j ? a : ARG(k,u));
                      break;
                    }
               }
            if(j < ARITY(u))
               break;
          }
     }
  if(i==n)
     return 1;
  SetShowStepArg(atan1(tan1(a)));
  if(!ONE(denom))
     newu = make_fraction(newu,denom);
  if(sign < 0)
     newu = tnegate(newu);
  *next = make_term('+',n);
  for(j=0;j<n;j++)
     { if(j==i)
          ARGREP(*next,j, newu);
       else if(FUNCTOR(ARG(j,t)) == CONSTANTOFINTEGRATION)
          { newc = constant_of_integration(ARG(j,t),zero);
            /* this makes it depend on the same variables as the old
               constant of integration, but get a new subscript. */
            HIGHLIGHT(newc);
            ARGREP(*next,j,newc);
          }
       else
          ARGREP(*next,j,ARG(j,t));
     }
  if(FUNCTOR(newu) == '+')
     *next = topflatten(*next);
  strcpy(reason,r);
  path_to_difference(t,*next,path,1);
  set_pathtail(path);
  return 0;
}

/*____________________________________________________________________*/
/* arcsin(sin \theta ) = \theta  if -\pi /2 \le \theta \le \pi /2 */
int asinsin(term t, term arg, term *next, char *reason)
{ int err;
  term theta,p;
  if(FUNCTOR(t) != ASIN)
     return 1;
  if(FUNCTOR(ARG(0,t)) != SIN)
     return 1;
  theta = ARG(0,ARG(0,t));
  p = and(le(tnegate(make_fraction(pi_term,two)),theta),le(theta,make_fraction(pi_term,two)));
  err = check1(p);
  if(err)
     return 1;
  *next = theta;
  HIGHLIGHT(*next);
  strcpy(reason,"$arcsin(sin \\theta) = \\theta$    ");
  strcat(reason, english(2179));  /* if -pi/2 le theta le pi/2 */
  return 0;
}

/*____________________________________________________________________*/
/* arccos(cos theta) = theta if 0 \le theta \le \pi */
int acoscos(term t, term arg, term *next, char *reason)
{ int err;
  term theta,p;
  if(FUNCTOR(t) != ACOS)
     return 1;
  if(FUNCTOR(ARG(0,t)) != COS)
     return 1;
  theta = ARG(0,ARG(0,t));
  p = and(le(zero,theta),le(theta,pi_term));
  err = check1(p);
  if(err)
     return 1;
  *next = theta;
  HIGHLIGHT(*next);
  strcpy(reason,"$arccos(cos \\theta) = \\theta$    ");
  strcat(reason, english(2180));   /* if 0 \le \theta \le \pi */
  return 0;
}

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