Sindbad~EG File Manager
/* 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