Sindbad~EG File Manager

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

/* csc and cot  identities, for MathXpert
   M. Beeson, 10.29.93
   Last modified 2.26.98
      This code is made from corresponding code for sec and tan
   identities by global search-and-replace.  If you change
   the sec and tan identities code change this too.
*/


#include <string.h>
#include "globals.h"
#include "ops.h"
#include "trig.h"
#include "match.h"
#include "order.h"
#include "cancel.h"
#include "prover.h"
#include "trigsq.h"
#include "symbols.h"
#include "pathtail.h"  /* set_pathtail */
#include "autosimp.h"  /* SetShowStepOperation */
#include "pvalaux.h"   /* ratpart2 */
/*__________________________________________________________________*/
int cscsqminuscotsq(term t, term arg, term *next, char *reason)
/* csc^2 a - cot^2 a = 1  */
{ term lhs,rhs,a;
  int err;
  lhs = sum(make_power(csc1(var0),two),tnegate(make_power(cot1(var0),two)));
  rhs = one;
  err = match(t,lhs,rhs,&a,next);   /* instantiate a and *next */
  if(err)
     { destroy_term(lhs);
       return 1;
     }
  HIGHLIGHT(*next);
  strcpy(reason,"csc^2 a - cot^2 a = 1");
  return 0;
}

/*__________________________________________________________________*/
int cotsquare1(term t, term arg, term *next, char *reason)
/* cot^2 a + 1 = csc^2 a */
{ term lhs,rhs,a;
  int err;
  lhs = sum(make_power(cot1(var0),two),one);
  rhs = make_power(csc1(var0),two);
  err = match(t,lhs,rhs,&a,next);   /* instantiate a and *next */
  if(err)
     { destroy_term(lhs);
       return 1;
     }
  HIGHLIGHT(*next);
  strcpy(reason,"cot^2 a + 1 = csc^2 a");
  return 0;
}

/*__________________________________________________________________*/
int cotsquare2(term t, term arg, term *next, char *reason)
/* csc^2 a - 1 = cot^2 a */
{ term lhs,rhs,a;
  unsigned short i,j;
  int err;
  unsigned short path[11];
  if(FRACTION(t) && get_mathmode() == AUTOMODE)
     { term x;
       int whicharg;
       term newnum,newdenom;;
       err = sq_aux(ARG(1,t),COT,&x,&whicharg);
       if(!err)
          { err = cotsquare2(ARG(0,t),arg,&newnum,reason);
            if(err)
               return 1;
            *next = make_fraction(newnum,ARG(1,t));
            path[0] = '/';
            path[1] = 1;
            path[2] = 0;
            if(FUNCTOR(ARG(0,t)) == '*' || FUNCTOR(ARG(0,t)) == '^')
               pathcat(path,get_pathtail());
            set_pathtail(path);
            return 0;
          }
       err = sq_aux(ARG(0,t),COT,&x,&whicharg);
       if(!err)
          { err = cotsquare2(ARG(1,t),arg,&newdenom,reason);
            if(err)
               return 1;
            *next = make_fraction(ARG(0,t),newdenom);;
            path[0] = '/';
            path[1] = 2;
            path[2] = 0;
            if(FUNCTOR(ARG(1,t)) == '*' || FUNCTOR(ARG(1,t)) == '^')
               pathcat(path,get_pathtail());
            set_pathtail(path);
            return 0;
          }
       return 1;
     }
  if(FUNCTOR(t) == '^' && get_mathmode() == AUTOMODE)
     { term temp;
       err = cotsquare2(ARG(0,t),arg,&temp,reason);
       if(err)
          return 1;
       *next = make_power(temp,ARG(1,t));
       path[0] = '^';
       path[1] = 1;
       path[2] = 0;
       return 0;
     }
  if(FUNCTOR(t) == '*' && get_mathmode() == AUTOMODE)
     { unsigned short n = ARITY(t);
       term u,temp;
       for(i=0;i<n;i++)
          { u = ARG(i,t);
            if(FUNCTOR(u) != '^' && FUNCTOR(u) != '+')
               continue;
            err = cotsquare2(u,arg,&temp,reason);
            if(!err)
               { path[0] = '*';
                 path[1] = i+1;
                 path[2] = 0;
                 if(FUNCTOR(u) == '^')
                    pathcat(path, get_pathtail());
                 set_pathtail(path);
               }
            break;
          }
       if(i==n)
          return 1;
       *next = make_term('*',n);
       for(j=0;j<n;j++)
          { if(j==i)
               ARGREP(*next,j,temp);
            else
               ARGREP(*next,j,ARG(j,t));
          }
       return 0;
     }
  lhs = sum(make_power(csc1(var0),two),minusone);
  rhs = make_power(cot1(var0),two);
  err = match(t,lhs,rhs,&a,next);   /* instantiate a and *next */
  if(err)
     { destroy_term(lhs);
       return 1;
     }
  HIGHLIGHT(*next);
  strcpy(reason,"csc^2 a - 1 = cot^2 a");
  return 0;
}
/*___________________________________________________________*/
int cotsqtocscsq(term t, term arg, term *next, char *reason)
/* cot^2 u = csc^2 u - 1.  But it also works on a sum, applying
this identity wherever possible to summands, even if the
summands are multiplied by conscotts, and simplifying the result.
*/

{ term u,v,temp,c,s;
  int i,j,err,powerflag;
  unsigned short n;
  int success = 0;
  unsigned short path[11];
  if(FUNCTOR(t) == '/' && get_mathmode() == AUTOMODE)
     return sqinfract(t,COT,next,reason);
  if(FUNCTOR(t) == '=')
     { if(FUNCTOR(ARG(0,t)) == '^' &&
          FUNCTOR(ARG(0,ARG(0,t))) == COT &&
          iseven(ARG(1,ARG(0,t)))
         )
          { err = cotsqtocscsq(ARG(0,t),arg,&temp,reason);
            if(err)
               return 1;
            *next = equation(temp,ARG(1,t));
            path[0] = '=';
            path[1] = 1;
            path[2] = 0;
            set_pathtail(path);
            return 0;
          }
       else if(FUNCTOR(ARG(1,t)) == '^' &&
               FUNCTOR(ARG(0,ARG(1,t))) == COT &&
               iseven(ARG(1,ARG(1,t)))
              )
          { err = cotsqtocscsq(ARG(1,t),arg,&temp,reason);
            if(err)
               return 1;
            *next = equation(ARG(0,t),temp);
            path[0] = '=';
            path[1] = 2;
            path[2] = 0;
            set_pathtail(path);
            return 0;
         }
     }
  if(FUNCTOR(t)== '+' && contains(t,COT))
     { n = ARITY(t);
       v = make_term((unsigned short)'+',n);
       powerflag = 0;;
       for(i=0;i<n;i++)
          { u = ARG(i,t);
            if(FUNCTOR(u) == '^' && !equals(ARG(0,u),two))
               powerflag = 1;
            err = cotsqtocscsq(u,arg,&temp,reason);
            if(!err)
              { ARGREP(v,i,temp);
                success = 1;
                path[0] = '+';
                path[1] = i+1;
                path[2] = 0;
                if(FUNCTOR(u) == '*' || FUNCTOR(u) == '-')
                   pathcat(path,get_pathtail());
                set_pathtail(path);
                /* Now set powerflag if we don't want to call polyval on the result
                   because that will produce a too-large step for a student */
                temp = NEGATIVE(u) ? ARG(0,u) : u;
                if(FUNCTOR(temp) == '*')
                   { ratpart2(temp,&c,&s);
                     temp = s;
                   }
                if(FUNCTOR(temp) == '^' && !equals(ARG(1,temp),two))
                   powerflag = 1;
                if(FUNCTOR(temp) == '*')
                   powerflag = 1;
                PROTECT(ARG(i,v));
              }
           else
              ARGREP(v,i,u);
          }
       if(success)
          { if(powerflag)
               *next = v;
            else
               polyval(v,next);
            return 0;
          }
       return 1;
     }
  if(FUNCTOR(t) == '*')
     { n = ARITY(t);
       for(i=0;i<n;i++)
          { u = ARG(i,t);
            if(FUNCTOR(u) == '^' && FUNCTOR(ARG(0,u)) == COT)
               { err = cotsqtocscsq(u,arg,&temp,reason);
                 if(!err)
                    { path[0] = '*';
                      path[1] = i+1;
                      path[2] = 0;
                      set_pathtail(path);
                      break;
                    }
               }
          }
       if(i==n)
          return 1;
       *next = make_term('*',n);
       for(j=0;j<n;j++)
          { if(j==i)
               ARGREP(*next,j,temp);
            else
               ARGREP(*next,j,ARG(j,t));
          }
       return 0;
     }

  if(FUNCTOR(t) == '-')
     { err = cotsqtocscsq(ARG(0,t),arg,&temp,reason);
       if(err)
          return 1;
       *next = tnegate(temp);
       path[0] = '-';
       path[1] = 1;
       path[2] = 0;
       if(FUNCTOR(ARG(0,t)) == '*' || FUNCTOR(ARG(0,t)) == '+')
          pathcat(path,get_pathtail());
       set_pathtail(path);
       return 0;
     }
  if(FUNCTOR(t) != '^')
     return 1;
  if(FUNCTOR(ARG(0,t)) != COT)
     return 1;
  u = ARG(0,ARG(0,t));
  if(!equals(ARG(1,t),two))
     { err = cancel(ARG(1,t),two,&temp,&v);
       if(err)
         return 1;
       *next = make_power(sum(make_power(csc1(u),two),minusone),v);
     }
  else  /* exponentis two */
     *next = sum(make_power(csc1(u),two),minusone);
  HIGHLIGHT(*next);
  strcpy(reason,"cot^2 u = csc^2 u - 1");
  return 0;
}
/*___________________________________________________________*/
int cscsqtocotsq(term t, term arg, term *next, char *reason)
/* csc^2 u = cot^2 u + 1.  But it also works on a sum, applying
this identity wherever possible to summands, even if the
summands are multiplied by conscotts, and simplifying the result.
*/

{ term u,v,temp,c,s;
  int i,j,err,powerflag;
  unsigned short n;
  unsigned short path[11];
  int success = 0;
  if(FUNCTOR(t) == '/' && get_mathmode() == AUTOMODE)
     return sqinfract(t,CSC,next,reason);
  if(FUNCTOR(t) == '=')
     { if(FUNCTOR(ARG(0,t)) == '^' &&
          FUNCTOR(ARG(0,ARG(0,t))) == CSC &&
          iseven(ARG(1,ARG(0,t)))
         )
          { err = cscsqtocotsq(ARG(0,t),arg,&temp,reason);
            if(err)
               return 1;
            *next = equation(temp,ARG(1,t));
            path[0] = '=';
            path[1] = 1;
            path[2] = 0;
            set_pathtail(path);
            return 0;
          }
       else if(FUNCTOR(ARG(1,t)) == '^' &&
               FUNCTOR(ARG(0,ARG(1,t))) == CSC &&
               iseven(ARG(1,ARG(1,t)))
              )
          { err = cscsqtocotsq(ARG(1,t),arg,&temp,reason);
            if(err)
               return 1;
            *next = equation(ARG(0,t),temp);
            path[0] = '=';
            path[1] = 2;
            path[2] = 0;
            set_pathtail(path);
            return 0;
         }
     }
  if(FUNCTOR(t)== '+' && contains(t,CSC))
     { n = ARITY(t);
       v = make_term((unsigned short)'+',n);
       powerflag = 0;
       for(i=0;i<n;i++)
          { u = ARG(i,t);
            if(FUNCTOR(u) == '^' && !equals(ARG(1,u),two))
               powerflag = 1;
            err = cscsqtocotsq(u,arg,&temp,reason);
            if(!err)
               { ARGREP(v,i,temp);
                 success = 1;
                 path[0] = '+';
                 path[1] = i+1;
                 path[2] = 0;
                 if(FUNCTOR(u) == '*' || FUNCTOR(u) == '-')
                    pathcat(path,get_pathtail());
                 set_pathtail(path);
                 /* Now set powerflag if we don't want to call polyval on the result
                    because that will produce a too-large step for a student */
                 temp = NEGATIVE(u) ? ARG(0,u) : u;
                 if(FUNCTOR(temp) == '*')
                    { ratpart2(temp,&c,&s);
                      temp = s;
                    }
                 if(FUNCTOR(temp) == '^' && !equals(ARG(1,temp),two))
                    powerflag = 1;
                 if(FUNCTOR(temp) == '*')
                    powerflag = 1;
                 PROTECT(ARG(i,v));
               }
            else
               ARGREP(v,i,u);
          }
       if(success)
          { if(powerflag)
               *next = v;
            else
               polyval(v,next);
            return 0;
          }
       return 1;
     }
  if(FUNCTOR(t) == '*')
     { n = ARITY(t);
       for(i=0;i<n;i++)
          { u = ARG(i,t);
            if(FUNCTOR(u) == '^' && FUNCTOR(ARG(0,u)) == CSC)
               { err = cscsqtocotsq(u,arg,&temp,reason);
                 if(!err)
                    { path[0] = '*';
                      path[1] = i+1;
                      path[2] = 0;
                      set_pathtail(path);
                      break;
                    }
               }
          }
       if(i==n)
          return 1;
       *next = make_term('*',n);
       for(j=0;j<n;j++)
          { if(j==i)
               ARGREP(*next,j,temp);
            else
               ARGREP(*next,j,ARG(j,t));
          }
       return 0;
     }

  if(FUNCTOR(t) == '-')
     { err = cscsqtocotsq(ARG(0,t),arg,&temp,reason);
       if(err)
          return 1;
       *next = tnegate(temp);
       path[0] = '-';
       path[1] = 1;
       path[2] = 0;
       if(FUNCTOR(ARG(0,t)) == '*' || FUNCTOR(ARG(0,t)) == '+')
          pathcat(path,get_pathtail());
       set_pathtail(path);
       return 0;
     }
  if(FUNCTOR(t) != '^')
     return 1;
  if(FUNCTOR(ARG(0,t)) != CSC)
     return 1;
  u = ARG(0,ARG(0,t));
  if(!equals(ARG(1,t),two))
     { err = cancel(ARG(1,t),two,&temp,&v);
       if(err)
         return 1;
       *next = make_power(sum(make_power(cot1(u),two),one),v);
     }
  else  /* exponentis two */
     *next = sum(make_power(cot1(u),two),one);
  HIGHLIGHT(*next);
  strcpy(reason,"csc^2 u = cot^2 u + 1");
  return 0;
}

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