Sindbad~EG File Manager

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

/* M. Beeson, for MathXpert
Original date 4.14.96
modified 6.14.98
Reverse binomial theorem factoring operators
3.28.00 corrected factorcubeofdif, factor4thofdif, factornthofdif,
all of which returned (a+b)^n instead of (a-b)^n
*/

#define ALGEBRA_DLL
#include <string.h>
#include <assert.h>
#include "globals.h"
#include "tdefn.h"
#include "ops.h"
#include "probtype.h"
#include "factor.h"
#include "simpprod.h"
#include "prover.h"
#include "order.h"
#include "cancel.h"
#include "algaux.h"
#include "complex.h"
#include "polynoms.h"
#include "getprob.h"  /* show_ringflag  */
#include "pvalaux.h"
#include "eqn.h"      /* derivative_subterm */
#include "symbols.h"
#include "mathmode.h"   /* get_currenttopic */
#include "errbuf.h"
#include "mstring.h"
#include "advfact.h"   /* nthroot_aux */

/*_______________________________________________________________________*/
MEXPORT_ALGEBRA int factorcubeofsum(term t, term arg, term *next, char *reason)
/* a^3 + 3a^2 b + 3ab^2 + b^3 = (a+b)^3 */
{ term a,b,u,temp;
  int i,err;
  short saveit = get_nextassumption();
  if(FUNCTOR(t) != '+' || ARITY(t) != 4)
     return 1;
  err = nthroot_aux(ARG(0,t),three,&a);
  if(err)
     goto fail;
  err = nthroot_aux(ARG(3,t),three,&b);
  if(err)
     goto fail;
  if(!contains(a,'+') && !contains(b,'+'))
     { /* fail quickly if any summands of t contain '+', before we
          call polyval on sums containing powers of sums */
       for(i=1;i<3;i++)
          { if(contains(ARG(i,t),'+'))
                goto fail;
          }
     }

  /* Now, do the middle two terms have the form 3a^2 b + 3ab^2 ?
     We form that term, subtract it from the middle two terms,
     and see if it simplifies to zero. */
  copy(t,&temp);
  ARGREP(temp,0,tnegate(product3(three,make_power(a,two),b)));
  ARGREP(temp,3,tnegate(product3(three,a,make_power(b,two))));
  polyval(temp,&u);
  if(!ZERO(u))
     goto fail;
  *next = make_power(sum(a,b),three);
  HIGHLIGHT(*next);
  strcpy(reason,"a^3+3a^2b+3ab^2+b^3=(a+b)^3");
  return 0;
  fail:
     set_nextassumption(saveit);
     return 1;
}
/*_______________________________________________________________________*/
MEXPORT_ALGEBRA int factorcubeofdif(term t, term arg, term *next, char *reason)
/* a^3 - 3a^2 b + 3ab^2 - b^3 = (a-b)^3 */
{ term a,b,u,temp;
  short saveit = get_nextassumption();
  int i,err;
  if(FUNCTOR(t) != '+' || ARITY(t) != 4)
     return 1;
  if(!NEGATIVE(ARG(3,t)))
     return 1;
  err = nthroot_aux(ARG(0,t),three,&a);
  if(err)
     goto fail;
  err = nthroot_aux(ARG(0,ARG(3,t)),three,&b);
  if(err)
     goto fail;
  if(!contains(a,'+') && !contains(b,'+'))
     { /* fail quickly if any summands of t contain '+', before we
          call polyval on sums containing powers of sums */
       for(i=1;i<3;i++)
          { if(contains(ARG(i,t),'+'))
                goto fail;
          }
     }

  /* Now, do the middle two terms have the form -3a^2 b + 3ab^2 ?
     We form that term, subtract it from the middle two terms,
     and see if it simplifies to zero. */
  copy(t,&temp);
  ARGREP(temp,0,product3(three,make_power(a,two),b));
  ARGREP(temp,3,tnegate(product3(three,a,make_power(b,two))));
  polyval(temp,&u);
  if(!ZERO(u))
     goto fail;
  *next = make_power(sum(a,tnegate(b)),three);
  HIGHLIGHT(*next);
  strcpy(reason,"a^3-3a^2b+3ab^2-b^3=(a-b)^3");
  return 0;
  fail:
     set_nextassumption(saveit);
     return 1;
}

/*_______________________________________________________________________*/
MEXPORT_ALGEBRA int factor4thofsum(term t, term arg, term *next, char *reason)
/* a^4 + 4a^3 b + 6a^2b^2 + 3a b^3 + b^4 = (a+b)^4 */
{ term a,b,u,temp;
  short saveit = get_nextassumption();
  int i,err;
  if(FUNCTOR(t) != '+' || ARITY(t) != 5)
     return 1;
  err = nthroot_aux(ARG(0,t),four,&a);
  if(err)
     goto fail;
  err = nthroot_aux(ARG(3,t),four,&b);
  if(err)
     goto fail;
  if(!contains(a,'+') && !contains(b,'+'))
     { /* fail quickly if any summands of t contain '+', before we
          call polyval on sums containing powers of sums */
       for(i=1;i<4;i++)
          { if(contains(ARG(i,t),'+'))
                goto fail;
          }
     }

  /* Now, do the middle three terms have the form 4a^3 b + 6a^2b^2 + 4ab^3 ?
     We form that term, subtract it from the middle three terms,
     and see if it simplifies to zero. */

  temp = make_term('+',6);
  ARGREP(temp,0,ARG(1,t));
  ARGREP(temp,1,ARG(2,t));
  ARGREP(temp,2,ARG(3,t));
  ARGREP(temp,3, tnegate(product3(four,make_power(a,three),b)));
  ARGREP(temp,4, tnegate(product3(six,make_power(a,two),make_power(b,two))));
  ARGREP(temp,5, tnegate(product3(four,a,make_power(b,three))));
  polyval(temp,&u);
  if(!ZERO(u))
     goto fail;
  *next = make_power(sum(a,b),four);
  HIGHLIGHT(*next);
  strcpy(reason,"a^4+4a^3b+6a^2b^2+4ab^3+b^4=(a+b)^4");
  return 0;
  fail:
     set_nextassumption(saveit);
     return 1;
}

/*_______________________________________________________________________*/
MEXPORT_ALGEBRA int factor4thofdif(term t, term arg, term *next, char *reason)
/* a^4 - 4a^3 b + 6a^2b^2 - 3a b^3 + b^4 = (a-b)^4 */
{ term a,b,u,temp;
  short saveit = get_nextassumption();
  int i,err;
  if(FUNCTOR(t) != '+' || ARITY(t) != 5)
     return 1;
  err = nthroot_aux(ARG(0,t),four,&a);
  if(err)
     goto fail;
  err = nthroot_aux(ARG(3,t),four,&b);
  if(err)
     goto fail;
  if(!contains(a,'+') && !contains(b,'+'))
     { /* fail quickly if any summands of t contain '+', before we
          call polyval on sums containing powers of sums */
       for(i=1;i<3;i++)
          { if(contains(ARG(i,t),'+'))
                goto fail;
          }
     }

  /* Now, do the middle three terms have the form 4a^3 b + 6a^2b^2 + 4ab^3 ?
     We form that term, subtract it from the middle three terms,
     and see if it simplifies to zero. */

  temp = make_term('+',6);
  ARGREP(temp,0,ARG(1,t));
  ARGREP(temp,1,ARG(2,t));
  ARGREP(temp,2,ARG(3,t));
  ARGREP(temp,3, product3(four,make_power(a,three),b));
  ARGREP(temp,4, tnegate(product3(six,make_power(a,two),make_power(b,two))));
  ARGREP(temp,5, product3(four,a,make_power(b,three)));
  polyval(temp,&u);
  if(!ZERO(u))
     goto fail;
  *next = make_power(sum(a,tnegate(b)),four);
  HIGHLIGHT(*next);
  strcpy(reason,"a^4-4a^3b+6a^2b^2-4ab^3+b^4=(a-b)^4");
  return 0;
  fail:
     set_nextassumption(saveit);
     return 1;
}
/*_______________________________________________________________________*/
MEXPORT_ALGEBRA int factornthofsum(term t, term arg, term *next, char *reason)
/* a^n + na^(n-1)b + ...b^n = (a+b)^n*/
{ term a,b,c,u,apower,bpower,temp,nn;
  short saveit = get_nextassumption();
  int i,err;
  unsigned short n;
  if(FUNCTOR(t) != '+' || ARITY(t) <= 3)
     return 1;
  n = (unsigned short)( ARITY(t)-1);
  nn = make_int(n);
  err = nthroot_aux(ARG(0,t),nn,&a);
  if(err)
     goto fail;
  err = nthroot_aux(ARG(n,t),nn,&b);
  if(err)
     goto fail;
  if(!contains(a,'+') && !contains(b,'+'))
     { /* fail quickly if any summands of t contain '+', before we
          call polyval on sums containing powers of sums */
       for(i=1;i<n;i++)
          { if(contains(ARG(i,t),'+'))
                goto fail;
          }
     }

  /* Now, do the middle n-1 terms have the required form?
     We form that term, subtract it from the middle n-1 terms,
     and see if it simplifies to zero. */

  temp = make_term('+',(unsigned short)(2*n - 2));
  for(i=0;i<n-1;i++)
    ARGREP(temp,i,ARG(i+1,t));
  for(i=1;i<n;i++)
     { apower = i==n-1 ? a : make_power(a,make_int(n-i));
       bpower = i==1 ? b : make_power(b,make_int(i));
       err = binomial(nn,make_int(i),&c);
       if(err)
          return 1;
       ARGREP(temp,i+n-2,tnegate(product3(c,apower,bpower)));
     }
  polyval(temp,&u);
  if(!ZERO(u))
     goto fail;
  *next = make_power(sum(a,b),nn);
  HIGHLIGHT(*next);
  strcpy(reason,"a^n+na^(n-1)b+...b^n=(a+b)^n");
  return 0;
  fail:
     set_nextassumption(saveit);
     return 1;
}


/*_______________________________________________________________________*/
MEXPORT_ALGEBRA int factornthofdif(term t, term arg, term *next, char *reason)
/* a^n - na^(n-1)b + ...b^n = (a-b)^n */
{ term a,b,c,u,v,apower,bpower,temp,nn;
  short saveit = get_nextassumption();
  int i,err;
  unsigned short n;
  if(FUNCTOR(t) != '+' || ARITY(t) <= 3)
     return 1;
  n = (unsigned short)(ARITY(t)-1);
  nn = make_int(n);
  err = nthroot_aux(ARG(0,t),nn,&a);
  if(err)
     goto fail;
  if(n&1 && !NEGATIVE(ARG(n,t)))
     return 1;  /* last term must be negative when n is odd */
  err = nthroot_aux( (n&1) ? ARG(0,ARG(n,t)) : ARG(n,t),nn,&b);
  if(err)
     goto fail;
  if(!contains(a,'+') && !contains(b,'+'))
     { /* fail quickly if any summands of t contain '+', before we
          call polyval on sums containing powers of sums */
       for(i=1;i<n;i++)
          { if(contains(ARG(i,t),'+'))
                goto fail;
          }
     }

  /* Now, do the middle n-1 terms have the required form?
     We form that term, subtract it from the middle n-1 terms,
     and see if it simplifies to zero. */

  temp = make_term('+',(unsigned short)(2*n - 2));
  for(i=0;i<n-1;i++)
    ARGREP(temp,i,ARG(i+1,t));
  for(i=1;i<n;i++)
     { apower = i==n-1 ? a : make_power(a,make_int(n-i));
       bpower = i==1 ? b : make_power(b,make_int(i));
       err = binomial(nn,make_int(i),&c);
       if(err)
          return 1;
       v = product3(c,apower,bpower);
       if(i&1)
          ARGREP(temp,i+n-2,tnegate(v));
       else
          ARGREP(temp,i+n-2,v);
     }
  polyval(temp,&u);
  if(!ZERO(u))
     goto fail;
  *next = make_power(sum(a,tnegate(b)),nn);
  HIGHLIGHT(*next);
  strcpy(reason,"a^n-na^(n-1)b+...b^n=(a-b)^n");
  return 0;
  fail:
     set_nextassumption(saveit);
     return 1;
}

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