Sindbad~EG File Manager
/* infinite series "reversal" operations for summing series */
/* M. Beeson, for Mathpert */
/*
1.12.99 original date
1.13.99 last modified
6.5.13 corrected geomseries_aux
6.11.13 added && seminumerical(ARG(0,n) in four places prior to SetShowStepOperation(reversecollectpowers)
8.20.13 corrected sign in lnseriesrev in rseries.c
*/
#include <string.h>
#include <assert.h>
#include "globals.h"
#include "series.h"
#include "match.h"
#include "prover.h" /* getnewintvar1 */
#include "symbols.h"
#include "errbuf.h"
#include "psubst.h"
#include "pvalaux.h" /* twoparts */
#include "ssolve.h"
#include "islinear.h"
#include "cancel.h"
#include "pathtail.h"
#include "autosimp.h" /* SetShowStepOperation */
#include "deval.h" /* seminumerical */
/*_______________________________________________________________*/
#if 0
int oneminusxseriesrev(term t, term arg, term *next, char *reason)
/* 1 + x + x^2 + ... = 1/(1-x) */
{ term u,n,lo,x;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(FUNCTOR(u) != '^')
return 1;
if(!ZERO(lo))
return 1;
x = ARG(0,u);
if(contains(x,FUNCTOR(n)))
return 1;
*next = reciprocal(sum(one,tnegate(x)));
HIGHLIGHT(*next);
if(ARITY(t) == 4)
strcpy(reason,"$$sum(x^n,n,0,infinity) = 1/(1-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"1+x+x^2+... = 1/(1-x)");
else
strcpy(reason,"1+x+...+x^n... = 1/(1-x)");
return 0;
}
#endif
/*______________________________________________________________*/
static int geomseries_aux(term t, term arg, term *next, char *reason)
/* bring a series into geometric form using some other operator,
and call SetShowStepOperator and set_pathtail */
{ term u,v,n,num,denom,temp,base,exp;
int err;
unsigned short path[10];
n = ARG(1,t);
u = ARG(0,t);
if(FUNCTOR(u) == '^' && NEGATIVE(ARG(1,u)))
{ err = eliminatenegexp(u,arg,&v,reason);
*next = indexedsum(v,n,ARG(2,t),ARG(3,t));
path[0] = SUM;
path[1] = 1;
path[2] = 0;
set_pathtail(path);
SetShowStepOperation(eliminatenegexp);
return 0;
}
if(FRACTION(u))
{ denom = ARG(1,u);
num = ARG(0,u);
if(FUNCTOR(denom) == '^')
{ base = ARG(0,denom);
exp = ARG(1,denom);
}
}
if(FRACTION(u) && ONE(ARG(0,u)) && /* e.g. 1/2^n */
FUNCTOR(ARG(1,u)) == '^' && !contains(ARG(0,ARG(1,u)),FUNCTOR(n)) /* reject 1/n^n for example */
)
{ if(equals(exp,n))
{ u = make_power(reciprocal(base),n); /* e.g. (1/2)^n */
return oneminusxseriesrev(indexedsum(u,n,ARG(2,t),ARG(3,t)),arg,next,reason);
}
else if(FUNCTOR(exp) == '+' && is_linear_in(exp,n))
{ /* eg. 1/2^(n+3), convert this to 1/(2^n 2^3) */
err = reversecollectpowers(ARG(1,u),arg,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(reciprocal(temp),n,ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = 0;
set_pathtail(path);
return 0;
}
else if(FRACTION(exp)) /* e.g. 1/2^(n/2) */
{ if(equals(ARG(0,exp),n) && INTEGERP(ARG(1,exp)))
{ err = pulloutdenom(exp,arg,&temp,reason);
if(err)
return 1;
*next = sigma(reciprocal(make_power(base,temp)),n,ARG(2,t),ARG(3,t));
SetShowStepOperation(pulloutdenom);
path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = '^';
path[5] = 2;
path[6] = 0;
set_pathtail(path);
return 0;
}
else if(is_linear_in(ARG(0,exp),n) && INTEGERP(ARG(1,exp)))
{ err = pulloutrational(ARG(1,ARG(1,u)),arg,&temp,reason);
if(err)
return 1;
*next = sigma(reciprocal(make_power(base,temp)),n,ARG(2,t),ARG(3,t));
SetShowStepOperation(pulloutrational);
path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = '^';
path[5] = 2;
path[6] = 0;
set_pathtail(path);
return 0;
}
}
}
if(FRACTION(u) && /* e.g. 2^(n+1)/5^n */
FUNCTOR(num) == '^' && FUNCTOR(ARG(1,num)) == '+' && is_linear_in(ARG(1,num),n) && !contains(ARG(0,num),FUNCTOR(n)) &&
FUNCTOR(denom) == '^' && is_linear_in(exp,n) && !contains(base,FUNCTOR(n))
)
{ err = reversecollectpowers(num,arg,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(make_fraction(temp,denom),n,ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 1;
path[4] = 0;
set_pathtail(path);
return 0;
}
if(FRACTION(u) && /* e^(n pi_term)/a^(cn) = (e^pi_term)^n/a^(cn) */
FUNCTOR(num) == '^' &&
!contains(ARG(0,num),FUNCTOR(n)) &&
FUNCTOR(ARG(1,num)) == '*' && ARITY(ARG(1,num)) == 2 &&
equals(ARG(1,ARG(1,num)),n) &&
!contains(ARG(0,ARG(1,num)),FUNCTOR(n)) &&
FUNCTOR(denom) == '^' &&
!contains(base,FUNCTOR(n)) &&
is_linear_in(exp,n)
)
{ err = reversepowertopower1(ARG(0,u),arg,&v,reason);
if(!err)
{ path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 1;
path[4] = 0;
set_pathtail(path);
SetShowStepOperation(reversepowertopower1);
*next = indexedsum(make_fraction(v,ARG(1,u)),n,ARG(2,t),ARG(3,t));
return 0;
}
}
/* Now the same with the args of the product in the exponent of the numerator in the other order. */
if(FRACTION(u) && /* e^(npi)/a^(cn) = (e^pi_term)^n/a^(cn) */
FUNCTOR(num) == '^' &&
!contains(ARG(0,num),FUNCTOR(n)) &&
FUNCTOR(ARG(1,num)) == '*' && ARITY(ARG(1,num)) == 2 &&
equals(ARG(1,ARG(1,ARG(0,u))),n) &&
!contains(ARG(2,ARG(1,num)),FUNCTOR(n)) &&
FUNCTOR(ARG(1,u)) == '^' &&
!contains(base,FUNCTOR(n)) &&
is_linear_in(exp,n)
)
{ err = reversepowertopower2(num,arg,&v,reason);
if(!err)
{ path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 1;
path[4] = 0;
SetShowStepOperation(reversepowertopower2);
*next = indexedsum(make_fraction(v,denom),n,ARG(2,t),ARG(3,t));
return 0;
}
}
if(FRACTION(u) && /* 1/a^2n => 1/((a^2)^n) ; also a^n/e^(npi) = a^n/(e^pi_term)^n */
(ONE(num) || (FUNCTOR(num) == '^' && equals(ARG(1,ARG(0,u)),n) && !contains(ARG(0,ARG(0,u)),FUNCTOR(n)))) &&
FUNCTOR(denom) == '^' &&
FUNCTOR(exp) == '*' &&
ARITY(exp) == 2 &&
equals(ARG(1,exp),n) &&
!contains(ARG(0,exp),FUNCTOR(n))
)
{ err = reversepowertopower1(denom,arg,&v,reason);
if(!err)
{ path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = 0;
set_pathtail(path);
SetShowStepOperation(reversepowertopower1);
*next = indexedsum(make_fraction(num,v),n,ARG(2,t),ARG(3,t));
return 0;
}
}
/* Now the same with the args in the exponent in the other order */
if(FRACTION(u) && /* 1/a^2n => 1/((a^2)^n) ; also a^n/e^(npi) = a^n/(e^pi_term)^n */
(ONE(num) || (FUNCTOR(num) == '^' && equals(ARG(1,num),n) && !contains(ARG(0,num),FUNCTOR(n)))) &&
FUNCTOR(denom) == '^' &&
FUNCTOR(exp) == '*' &&
ARITY(exp) == 2 &&
equals(ARG(0,exp),n) &&
!contains(ARG(1,exp),FUNCTOR(n))
)
{ err = reversepowertopower2(denom,arg,&v,reason);
if(!err)
{ path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = 0;
set_pathtail(path);
SetShowStepOperation(reversepowertopower2);
*next = indexedsum(make_fraction(num,v),n,ARG(2,t),ARG(3,t));
return 0;
}
}
if(FRACTION(u) && ONE(num) && /* 1/a^2(n+3) => 1/(a^(4n+6) */
FUNCTOR(denom) == '^' &&
FUNCTOR(exp) == '*' &&
ARITY(exp) == 2 &&
is_linear_in(ARG(1,exp),n) &&
!contains(ARG(0,exp),FUNCTOR(n))
)
{ err = distriblaw(ARG(1,denom),arg,&v,reason);
if(err)
return 1;
path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = '^';
path[5] = 2;
path[6] = 0;
set_pathtail(path);
SetShowStepOperation(distriblaw);
*next = indexedsum(reciprocal(make_power(base,v)),n,ARG(2,t),ARG(3,t));
return 0;
}
if(FRACTION(u))
{ if(FUNCTOR(num) == '^' && equals(ARG(1,num),n) &&
FUNCTOR(denom) == '^' && equals(ARG(1,denom),n)
)
{ err = poweroutoffraction(u,arg,&v,reason);
if(err)
return 1;
SetShowStepOperation(poweroutoffraction);
path[0] = SUM;
path[1] = 1;
path[2] = 0;
set_pathtail(path);
PROTECT(v);
*next = indexedsum(v,n,ARG(2,t),ARG(3,t));
return 0;
}
}
return 1;
}
/*______________________________________________________________*/
int oneminusxseriesrev(term t, term arg, term *next, char *reason)
/* sum(x^n,n,0,infinity) = 1/(1-x) */
{ term u,n,temp,v,test;
int err;
unsigned short path[7];
if(FUNCTOR(t) != SUM || ARITY(t) < 4 || !equals(ARG(3,t),infinity))
return 1;
if(ONE(ARG(2,t)))
return 1;
n = ARG(1,t);
if(!ISATOM(n))
return 1;
u = ARG(0,t);
if(!ZERO(ARG(2,t)))
{ /* shift the index variable till it is zero */
/* But first make sure this is really a geometric series */
subst(sum(n,one),n,u,&test);
polyval(make_fraction(test,u),&v);
if(contains(v,FUNCTOR(n)))
return 1; /* not geometric */
err = seriesaddindex(t,ARG(2,t),next,reason);
if(err)
return 1;
SetShowStepOperation(seriesaddindex);
return 0;
}
err = geomseries_aux(t,arg,next,reason);
if(!err)
return 0;
if(FUNCTOR(u) != '^')
return 1;
if(!equals(ARG(1,u),n) && seminumerical(ARG(0,u)))
{ /* example, (1/2)^(n+3) */
if(FUNCTOR(ARG(1,u)) != '+' || !is_linear_in(ARG(1,u),n))
return 1;
err = reversecollectpowers(u,zero,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(temp,ARG(1,t),ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = 0;
set_pathtail(path);
return 0;
}
if(!equals(ARG(1,u),n))
return 1;
*next = make_fraction(one,sum(one,tnegate(ARG(0,u))));
HIGHLIGHT(*next);
if(ARITY(t)== 4)
strcpy(reason,"$$sum(x^n,n,0,infinity) = 1/(1-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"1+x+x^2+...= 1/(1-x)");
else
strcpy(reason, "1+x+...+x^n = 1/(1-x)");
return 0;
}
/*______________________________________________________________*/
int xoveroneminusxseriesrev(term t, term arg, term *next, char *reason)
/* sum(x^n,n,1,infinity) = x/(1-x) */
{ term u,n,temp;
unsigned short path[7];
int err;
if(FUNCTOR(t) != SUM || ARITY(t) < 4 || !equals(ARG(3,t),infinity))
return 1;
if(!ONE(ARG(2,t)))
return 1;
n = ARG(1,t);
if(!ISATOM(n))
return 1;
u = ARG(0,t);
if(FRACTION(u) && ONE(ARG(0,u)) && /* e.g. 1/2^n */
FUNCTOR(ARG(1,u)) == '^'
)
{ if(equals(ARG(1,ARG(1,u)),n))
u = make_power(reciprocal(ARG(0,ARG(1,u))),n); /* e.g. (1/2)^n */
else if(is_linear_in(ARG(1,ARG(1,u)),n) && seminumerical(ARG(0,u)))
{ /* eg. 1/2^(n+3), convert this to 1/(2^n 2^3) */
err = reversecollectpowers(ARG(1,u),arg,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(reciprocal(temp),n,ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = '/';
path[3] = 2;
path[4] = 0;
set_pathtail(path);
return 0;
}
else
return 1;
}
if(FUNCTOR(u) != '^')
return geomseries_aux(t,arg,next,reason);
if(!equals(ARG(1,u),n))
{ /* example, (1/2)^(n+3) */
if(FUNCTOR(ARG(1,u)) != '+' || !is_linear_in(ARG(1,u),n))
return 1;
err = reversecollectpowers(u,zero,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(temp,ARG(1,t),ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = 0;
set_pathtail(path);
return 0;
}
*next = make_fraction(ARG(0,u),sum(one,tnegate(ARG(0,u))));
HIGHLIGHT(*next);
if(ARITY(t) == 4)
strcpy(reason,"$$sum(x^n,n,1,infinity)=1/(1-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"x+x^2+x^3+...= x/(1-x)");
else
strcpy(reason, "x+x^2+...+x^n = x/(1-x)");
return 0;
}
/*______________________________________________________________*/
int xoveroneminusxseries2rev(term t, term arg, term *next, char *reason)
/* sum(x^n,n,1,infinity) = x/(1-x) */
{ return xoveroneminusxseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int xoveroneminusxseries3rev(term t, term arg, term *next, char *reason)
/* sum(x^n,n,1,infinity) = x/(1-x) */
{ return xoveroneminusxseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int xoveroneplusxseriesrev(term t, term arg, term *next, char *reason)
/* sum((-1)^(n+1)x^n,n,1,infinity) = x/(1+x) */
{ term u,n,temp;
unsigned short path[9];
int err;
if(FUNCTOR(t) != SUM || ARITY(t) < 4 || !equals(ARG(3,t),infinity))
return 1;
if(!ONE(ARG(2,t)))
return 1;
n = ARG(1,t);
if(!ISATOM(n))
return 1;
u = ARG(0,t);
if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' &&
equals(ARG(0,ARG(0,u)),minusone) &&
FUNCTOR(ARG(1,ARG(0,u))) == '+' &&
(
(equals(ARG(0,ARG(1,ARG(0,u))),n) && ONE(ARG(1,ARG(1,ARG(0,u))))) ||
(equals(ARG(0,ARG(1,ARG(0,u))),n) && equals(ARG(1,ARG(1,ARG(0,u))),minusone)) ||
(equals(ARG(1,ARG(1,ARG(0,u))),n) && ONE(ARG(0,ARG(1,ARG(0,u)))))
)
)
u = ARG(1,u);
else if(FUNCTOR(u) == '^' && NEGATIVE(ARG(0,u)))
u = make_power(ARG(0,ARG(0,u)),ARG(1,u));
if(FRACTION(u) && ONE(ARG(0,u)) && /* e.g. 1/2^n */
FUNCTOR(ARG(1,u)) == '^'
)
{ if(equals(ARG(1,ARG(1,u)),n))
u = make_power(reciprocal(ARG(0,ARG(1,u))),n); /* e.g. (1/2)^n */
else if(is_linear_in(ARG(1,ARG(1,u)),n)&& seminumerical(ARG(0,u)))
{ /* eg. 1/2^(n+3), convert this to 1/(2^n 2^3) */
err = reversecollectpowers(ARG(1,u),arg,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(reciprocal(temp),n,ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = FUNCTOR(ARG(0,t));
path[3] = path[2] == '*' ? 2 : 1;
path[4] = '/';
path[5] = 2;
path[6] = 0;
set_pathtail(path);
return 0;
}
else
return 1;
}
if(FUNCTOR(u) != '^')
return geomseries_aux(t,arg,next,reason);
if(!equals(ARG(1,u),n) && seminumerical(ARG(0,u)))
{ /* example, (1/2)^(n+3) */
if(FUNCTOR(ARG(1,u)) != '+' || !is_linear_in(ARG(1,u),n))
return 1;
err = reversecollectpowers(u,zero,&temp,reason);
if(err)
return 1;
PROTECT(temp);
*next = sigma(temp,ARG(1,t),ARG(2,t),ARG(3,t));
SetShowStepOperation(reversecollectpowers);
path[0] = SUM;
path[1] = 1;
path[2] = FUNCTOR(ARG(0,t));
path[3] = path[2] == '*' ? 2 : 1;
path[4] = 0;
set_pathtail(path);
return 0;
}
*next = make_fraction(ARG(0,u),sum(one,tnegate(ARG(0,u))));
HIGHLIGHT(*next);
if(ARITY(t) == 4)
strcpy(reason,"$$sum(x^n,n,1,infinity)=1/(1-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"x+x^2+x^3+...= x/(1-x)");
else
strcpy(reason, "x+x^2+...+x^n = x/(1-x)");
return 0;
}
/*______________________________________________________________*/
int xoveroneplusxseries2rev(term t, term arg, term *next, char *reason)
{ return xoveroneplusxseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int xoveroneplusxseries3rev(term t, term arg, term *next, char *reason)
/* sum(x^n,n,1,infinity) = x/(1-x) */
{ return xoveroneplusxseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneminusxseries2rev(term t, term arg, term *next, char *reason)
{ return oneminusxseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneminusxseries3rev(term t, term arg, term *next, char *reason)
{ return oneminusxseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneplusxseriesrev(term t, term arg, term *next, char *reason)
/* 1-x+x^2... = 1/(1+x) */
{ term u,n,lo,x;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(FUNCTOR(u) == '^' && NEGATIVE(ARG(0,u))) /* (-x)^n */
x = ARG(0,ARG(0,u));
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 && /* (-1)^n x^n */
FUNCTOR(ARG(0,u)) == '^' &&
FUNCTOR(ARG(1,u)) == '!' &&
equals(ARG(0,ARG(0,u)),minusone)
)
x = ARG(0,ARG(1,u));
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
if(!ZERO(lo))
return 1;
x = ARG(0,u);
*next = reciprocal(sum(one,x));
HIGHLIGHT(*next);
if(ARITY(t) == 4)
strcpy(reason,"$$sum((-1)^nx^n,n,0,infinity) = 1/(1+x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"1-x+x^2-... = 1/(1+x)");
else
strcpy(reason,"1-x+...+(-1)^nx^n... = 1/(1+x)");
return 0;
}
/*_______________________________________________________________*/
int oneplusxseries2rev(term t, term arg, term *next, char *reason)
{ return oneplusxseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneplusxseries3rev(term t, term arg, term *next, char *reason)
{ return oneplusxseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int lnseriesrev(term t, term arg, term *next, char *reason)
/* x+x^2/2+x^3/3+... = -ln(1-x) */
{ term u,n,lo,x;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ONE(lo))
return 1;
if(FRACTION(u) && equals(ARG(1,u),n) &&
FUNCTOR(ARG(0,u)) == '^' && equals(ARG(1,ARG(0,u)),n)
)
x = ARG(0,ARG(0,u));
else if(FUNCTOR(u) == '*' && FRACTION(ARG(0,u)) &&
ONE(ARG(0,ARG(0,u))) && equals(ARG(1,ARG(0,u)),n) &&
FUNCTOR(ARG(1,u)) == '^' && equals(ARG(1,ARG(1,u)),n)
)
x = ARG(0,ARG(1,u));
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
*next = tnegate(ln1(sum(one,tnegate(x))));
if(ARITY(t) == 4)
strcpy(reason,"$$sum(x^n/n,n,1,infinity) = -ln(1-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"x+x^2/2+x^3/3+... = -ln(1-x)");
else
strcpy(reason,"x+x^2/2+...+x^n/n+...= -ln(1-x)");
return 0;
}
/*_______________________________________________________________*/
int lnseries2rev(term t, term arg, term *next, char *reason)
{ return lnseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int lnseries3rev(term t, term arg, term *next, char *reason)
{ return lnseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int lnseriesminusrev(term t, term arg, term *next, char *reason)
/* x-x^2/2+x^3/3+... = ln(1+x) */
{ term u,n,lo,x;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ONE(lo))
return 1;
if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' && equals(ARG(0,ARG(0,u)),minusone) &&
FRACTION(ARG(1,u)) && equals(ARG(1,ARG(1,u)),n) &&
FUNCTOR(ARG(0,ARG(1,u))) == '^'
)
x = ARG(0,ARG(0,ARG(1,u)));
else if(FRACTION(u) && equals(ARG(1,u),n) &&
FUNCTOR(ARG(0,u)) == '*' && ARITY(ARG(0,u)) == 2 &&
FUNCTOR(ARG(0,ARG(0,u))) == '^' &&
equals(ARG(0,ARG(0,ARG(0,u))),minusone) &&
FUNCTOR(ARG(1,ARG(0,u))) == '^'
)
x = ARG(0,ARG(1,ARG(0,u)));
else if(FRACTION(u) && equals(ARG(1,u),n) &&
FUNCTOR(ARG(0,u)) == '^' && NEGATIVE(ARG(0,ARG(0,u)))
)
x = ARG(0,ARG(0,u));
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
*next = ln1(sum(one,x));
if(ARITY(t) == 4)
strcpy(reason,"$$sum((-1)^nx^n/n!,n,1,infinity) = ln(1+x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"x-x^2/2+x^3/3+... = ln(1+x)");
else
strcpy(reason,"x-x^2/2+...+x^n/n+... = ln(1+x)");
return 0;
}
/*_______________________________________________________________*/
int lnseriesminus2rev(term t, term arg, term *next, char *reason)
{ return lnseriesminusrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int lnseriesminus3rev(term t, term arg, term *next, char *reason)
{ return lnseriesminusrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int expseriesrev(term t, term arg, term *next, char *reason)
/* 1+x+x^2/2!+x^3/3!+... = e^x */
{ term u,n,lo,x;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FRACTION(u) && ONE(ARG(0,u)) &&
FUNCTOR(ARG(1,u)) == FACTORIAL &&
equals(ARG(0,ARG(1,u)),n)
)
x = one;
else if(FRACTION(u) && FUNCTOR(ARG(1,u)) == FACTORIAL &&
equals(ARG(0,ARG(1,u)),n) &&
FUNCTOR(ARG(0,u)) == '^' && equals(ARG(1,ARG(0,u)),n)
)
x = ARG(0,ARG(0,u));
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 && FRACTION(ARG(0,u)) &&
ONE(ARG(0,ARG(0,u))) &&
FUNCTOR(ARG(1,ARG(0,u))) == FACTORIAL &&
equals(ARG(0,ARG(1,ARG(0,u))),n) &&
FUNCTOR(ARG(1,u)) == '^' && equals(ARG(1,ARG(1,u)),n)
)
x = ARG(0,ARG(1,u));
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
*next = make_power(eulere,x);
if(ARITY(t) == 4)
strcpy(reason,"$$sum(x^n/n!,n,0,infinity) = e^x$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"1+x+x^2/2!+...=e^x");
else
strcpy(reason,"1+x+...+x^n/n!...=e^x");
return 0;
}
/*______________________________________________________________*/
int expseries2rev(term t, term arg, term *next, char *reason)
{ return expseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int expseries3rev(term t, term arg, term *next, char *reason)
{ return expseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int negexpseriesrev(term t, term arg, term *next, char *reason)
/* x-x^2/2!+x^3/3!+... = e^-x */
{ term u,n,lo,x;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FRACTION(u) && FUNCTOR(ARG(0,u)) == '^' && /* catch the case e^-1 */
equals(ARG(0,ARG(0,u)),minusone) &&
FUNCTOR(ARG(1,u)) == FACTORIAL &&
equals(ARG(0,ARG(1,u)),n)
)
x = one;
else if(FRACTION(u) && FUNCTOR(ARG(1,u)) == FACTORIAL &&
equals(ARG(0,ARG(1,u)),n) &&
FUNCTOR(ARG(0,u)) == '^' && NEGATIVE(ARG(0,ARG(0,u))) &&
equals(ARG(1,ARG(0,u)),n)
)
x = ARG(0,ARG(0,ARG(0,u)));
else if(FRACTION(u) && FUNCTOR(ARG(1,u)) == FACTORIAL &&
equals(ARG(0,ARG(1,u)),n) &&
FUNCTOR(ARG(0,u)) == '*' && ARITY(ARG(0,u)) == 2 &&
FUNCTOR(ARG(0,ARG(0,u))) == '^' &&
equals(ARG(0,ARG(0,ARG(0,u))),minusone) &&
FUNCTOR(ARG(1,ARG(0,u))) == '^' &&
equals(ARG(1,ARG(1,ARG(0,u))),n)
)
x = ARG(0,ARG(1,ARG(0,u))); /* (-1)^n x^n/n! */
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 && FRACTION(ARG(0,u)) &&
ONE(ARG(0,ARG(0,u))) &&
FUNCTOR(ARG(1,ARG(0,u))) == FACTORIAL &&
equals(ARG(0,ARG(1,ARG(0,u))),n) &&
FUNCTOR(ARG(1,u)) == '^' && NEGATIVE(ARG(0,ARG(1,u)))
)
x = ARG(0,ARG(0,ARG(1,u))); /* (-x)^n/n! */
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' && equals(ARG(1,ARG(0,u)),n) &&
equals(ARG(0,ARG(0,u)),minusone) &&
FRACTION(ARG(1,u)) &&
FUNCTOR(ARG(1,ARG(1,u))) == FACTORIAL &&
equals(ARG(0,ARG(1,ARG(1,u))),n) &&
FUNCTOR(ARG(0,ARG(1,u))) == '^' &&
equals(ARG(1,ARG(0,ARG(1,u))),n)
)
x = ARG(0,ARG(0,ARG(1,u))); /* (-1)^n (x^n/n!) */
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
*next = make_power(eulere,tnegate(x));
if(ARITY(t) == 4)
strcpy(reason,"$$sum((-1)^nx^n/n!,n,0,infinity) = e^(-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"1-x+x^2/2!+... = e^-x");
else
strcpy(reason,"1-x+...+(-1)^nx^n/n! = e^(-x)");
return 0;
}
/*______________________________________________________________*/
int negexpseries2rev(term t, term arg, term *next, char *reason)
{ return negexpseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int negexpseries3rev(term t, term arg, term *next, char *reason)
{ return negexpseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int sinseriesrev(term t, term arg, term *next, char *reason)
/* x-x^3/3!+x^5/5!+... = sin x */
{ term u,n,lo,x,num,denom,a,b;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FRACTION(u)) /* (-1)^n x^(2n+1)/(2n+1)! or (-x)^(2n+1)/(2n+1)! */
{ num = ARG(0,u);
denom = ARG(1,u);
if(FUNCTOR(denom) != FACTORIAL)
return 1;
if(FUNCTOR(ARG(0,denom)) != '+')
return 1;
if(!islinear(ARG(0,denom),n,&a,&b))
return 1;
if(!equals(two,a) || !ONE(b))
return 1;
/* denom is (2n+1)! or equal to it */
if(FUNCTOR(num)=='^' && NEGATIVE(ARG(0,num)) &&
(equals(ARG(1,num),ARG(0,denom)) || (islinear(ARG(1,num),n,&a,&b) && equals(two,a) && ONE(b)))
)
/* Now the exponent is 2n+1 */
x = ARG(0,ARG(0,num)); /* (-x)^(2n+1)/(2n+1)! */
else if(FUNCTOR(num) == '*' && ARITY(num) == 2 &&
FUNCTOR(ARG(0,num)) == '^' &&
equals(ARG(0,ARG(0,num)),minusone) &&
equals(ARG(1,ARG(0,num)),n) &&
FUNCTOR(ARG(1,num)) == '^' &&
equals(ARG(1,ARG(1,num)),ARG(0,denom))
)
x = ARG(0,ARG(1,num));
else
return 1;
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' &&
equals(ARG(1,ARG(0,u)),n) &&
equals(ARG(0,ARG(0,u)),minusone) &&
FRACTION(ARG(1,u))
)
{ num = ARG(0,ARG(1,u));
denom = ARG(1,ARG(1,u));
if(FUNCTOR(denom) != FACTORIAL)
return 1;
if(FUNCTOR(ARG(0,denom)) != '+')
return 1;
if(!islinear(ARG(0,denom),n,&a,&b))
return 1;
if(!equals(two,a) || !ONE(b))
return 1;
/* Now denom = 2n+1 */
if(FUNCTOR(num) == '^' && equals(ARG(1,num),ARG(0,denom)))
x = ARG(0,num); /* (-1)^n (x^n/(2n+1)!) */
else
return 1;
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 && /* (-1)^n/(2n+1)! x^(2n+1) */
FRACTION(ARG(0,u)) && FUNCTOR(ARG(1,u)) == '^' &&
FUNCTOR(ARG(1,ARG(0,u))) == FACTORIAL &&
FUNCTOR(ARG(0,ARG(1,ARG(0,u)))) == '+' &&
islinear(ARG(0,ARG(1,ARG(0,u))),n,&a,&b) && equals(two,a) && ONE(b) &&
equals(ARG(1,ARG(1,u)),ARG(0,ARG(1,ARG(0,u))))
)
x = ARG(0,ARG(1,u));
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
*next = sin1(x);
if(ARITY(t) == 4)
strcpy(reason,"$$sum((-1)^nx^(2n+1)/(2n+1)!,n,0,infinity) = sin x$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"x-x^3/3!+x^5/5!-... = sin x");
else
strcpy(reason,"$$series((-1)^nx^(2n+1)/(2n+1)!,n,0,infinity,2) = sin x$$");
return 0;
}
/*______________________________________________________________*/
int sinseries2rev(term t, term arg, term *next, char *reason)
{ return sinseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int sinseries3rev(term t, term arg, term *next, char *reason)
{ return sinseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int cosseriesrev(term t, term arg, term *next, char *reason)
/* 1-x^2/2!+x^4/4!+... = cos x */
{ term u,n,lo,x,num,denom;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FRACTION(u)) /* (-1)^n x^(2n)/(2n)! or (-x)^(2n)/(2n)! */
{ num = ARG(0,u);
denom = ARG(1,u);
if(FUNCTOR(denom) != FACTORIAL)
return 1;
if(FUNCTOR(ARG(0,denom)) != '*' || ARITY(ARG(0,denom)) != 2)
return 1;
if(!equals(two,ARG(0,ARG(0,denom))) || !equals(ARG(1,ARG(0,denom)),n))
return 1;
/* denom is (2n)! */
if(FUNCTOR(num)=='^' && NEGATIVE(ARG(0,num)))
{ if(!equals(ARG(1,num),ARG(0,denom)))
return 1;
/* Now the exponent is 2n */
x = ARG(0,ARG(0,num)); /* (-x)^(2n)/(2n)! */
}
else if(FUNCTOR(num) == '*' && ARITY(num) == 2 &&
FUNCTOR(ARG(0,num)) == '^' &&
equals(ARG(0,ARG(0,num)),minusone) &&
equals(ARG(1,ARG(0,num)),n) &&
FUNCTOR(ARG(1,num)) == '^' &&
equals(ARG(1,ARG(1,num)),ARG(0,denom))
)
x = ARG(0,ARG(1,num));
else
return 1;
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' &&
equals(ARG(1,ARG(0,u)),n) &&
equals(ARG(0,ARG(0,u)),minusone) &&
FRACTION(ARG(1,u))
)
{ num = ARG(0,ARG(1,u));
denom = ARG(1,ARG(1,u));
if(FUNCTOR(denom) != FACTORIAL)
return 1;
if(FUNCTOR(ARG(0,denom)) != '*' || ARITY(ARG(0,denom)) != 2)
return 1;
if(!equals(two,ARG(0,ARG(0,denom))))
return 1;
if(!equals(ARG(1,ARG(0,denom)),n))
return 1;
/* Now denom = 2n */
if(FUNCTOR(num) == '^' && equals(ARG(1,num),ARG(0,denom)))
x = ARG(0,num); /* (-1)^n (x^n/(2n)!) */
else
return 1;
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 && /* (-1)^n/(2n)! x^(2n) */
FRACTION(ARG(0,u)) && FUNCTOR(ARG(1,u)) == '^' &&
FUNCTOR(ARG(1,ARG(0,u))) == FACTORIAL &&
FUNCTOR(ARG(0,ARG(1,ARG(0,u)))) == '*' &&
ARITY(ARG(0,ARG(1,ARG(0,u)))) == 2 &&
equals(two,ARG(0,ARG(0,ARG(1,ARG(0,u))))) &&
equals(ARG(1,ARG(0,ARG(1,ARG(0,u)))),n)
)
x = ARG(0,ARG(1,u));
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
*next = cos1(x);
if(ARITY(t) == 4)
strcpy(reason,"$$sum((-1)^nx^(2n)/(2n)!,n,0,infinity) = cos x$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"1-x^2/2!+x^4/4!-... = cos x");
else
strcpy(reason,"$$series((-1)^nx^(2n)/(2n)!,n,0,infinity,2) = cos x$$");
return 0;
}
/*______________________________________________________________*/
int cosseries2rev(term t, term arg, term *next, char *reason)
{ return cosseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int cosseries3rev(term t, term arg, term *next, char *reason)
{ return cosseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int atanseriesrev(term t, term arg, term *next, char *reason)
/* x-x^3/3 +...(-1)^nx^(2n+1)/(2n+1) = arctan x */
{ term u,n,lo,x,num,denom,a,b;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FRACTION(u))
{ num = ARG(0,u);
denom = ARG(1,u);
if(FUNCTOR(denom) != '+' || ARITY(denom) != 2)
return 1;
if(!islinear(denom,n,&a,&b) || !equals(two,a) || !ONE(b))
return 1;
if(ONE(num))
x = one;
else
{ if(FUNCTOR(num) != '^')
return 1;
if(equals(ARG(1,num),denom))
x = ARG(0,num);
if(FUNCTOR(ARG(1,num)) != '+' || ARITY(ARG(1,num)) != 2)
return 1;
if(islinear(ARG(1,num),n,&a,&b) && equals(two,a) && ONE(b))
x = ARG(0,num);
else
return 1;
}
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 && /* (-1)^n x^(2n+1)/(2n+1) */
FUNCTOR(ARG(0,u)) == '^' && FRACTION(ARG(1,u)) &&
equals(ARG(1,ARG(0,u)),n) &&
equals(ARG(0,ARG(0,u)),minusone)
)
{ denom = ARG(1,ARG(1,u));
if(FUNCTOR(denom) != '+' || ARITY(denom) != 2)
return 1;
if(!islinear(denom,n,&a,&b) || !equals(two,a) || !ONE(b))
return 1;
num = ARG(0,ARG(1,u));
if(FUNCTOR(num) == '^' && FUNCTOR(ARG(1,num)) == '+' &&
ARITY(ARG(1,num)) == 2 &&
(equals(ARG(1,num),denom) || (islinear(ARG(1,num),n,&a,&b) && equals(two,b) && ONE(a)))
)
x = ARG(0,num);
else
return 1;
}
else
return 1;
*next = atan1(x);
HIGHLIGHT(*next);
if(ARITY(t) == 4)
strcpy(reason,"$$sum((-1)^nx^(2n+1)/(2n+1),n,0,infinity) = arctan x$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"x-x^3/3+x^5/5+... = arctan x");
else
strcpy(reason,"$$series((-1)^nx^(2n+1)/(2n+1),n,0,infinity,2) = arctan x$$");
return 0;
}
/*______________________________________________________________*/
int atanseries2rev(term t, term arg, term *next, char *reason)
{ return atanseriesrev(t,arg,next,reason);
}
/*______________________________________________________________*/
int atanseries3rev(term t, term arg, term *next, char *reason)
{ return atanseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneoveroneminusxkseriesrev(term t, term arg, term *next, char *reason)
/* sum(x^(nk),n,0,infinity)= 1/(1-x^k) */
{ term u,n,lo,x,b,k;
int err;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FUNCTOR(u) != '^')
return 1;
x = ARG(0,u);
if(contains(x,FUNCTOR(n)))
return 1;
err = cancel(ARG(1,u),n,&b,&k);
if(err)
return 1;
if(contains(k,FUNCTOR(n)))
return 1;
*next = reciprocal(sum(one,tnegate(make_power(ARG(0,u),k))));
HIGHLIGHT(*next);
strcpy(reason,"$1+x^k+x^(2k)+...+x^(nk)= 1/(1-x^k)$");
return 0;
}
/*_______________________________________________________________*/
int oneoveroneminusxkseries2rev(term t, term arg, term *next, char *reason)
{ return oneoveroneminusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneoveroneminusxkseries3rev(term t, term arg, term *next, char *reason)
{ return oneoveroneminusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneoveroneplusxkseriesrev(term t, term arg, term *next, char *reason)
/* sum((-1)^n x^(nk),n,0,infinity)= 1/(1+x^k) */
{ term u,n,lo,x,b,c,k;
int err;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(!ZERO(lo))
return 1;
if(FUNCTOR(u) == '^' && NEGATIVE(ARG(0,u)))
{ x = ARG(0,ARG(0,u));
b = ARG(1,u);
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' &&
equals(ARG(0,ARG(0,u)),minusone) &&
equals(ARG(1,ARG(0,u)),n) &&
FUNCTOR(ARG(1,u)) == '^'
)
{ x = ARG(0,ARG(1,u));
b = ARG(1,ARG(1,u));
}
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
err = cancel(b,n,&c,&k);
if(err)
return 1;
if(contains(k,FUNCTOR(n)))
return 1;
*next = reciprocal(sum(one,make_power(ARG(0,u),k)));
HIGHLIGHT(*next);
strcpy(reason,"$1-x^k+x^(2k)+...x^(nk) = 1/(1+x^k)$");
return 0;
}
/*_______________________________________________________________*/
int oneoveroneplusxkseries2rev(term t, term arg, term *next, char *reason)
{ return oneoveroneplusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int oneoveroneplusxkseries3rev(term t, term arg, term *next, char *reason)
{ return oneoveroneplusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int xmoveroneminusxkseriesrev(term t, term arg, term *next, char *reason)
/* x^m + x^(m+k) + ... x^(m+nk) = x^m/(1-x^k) */
{ term u,n,m,lo,x,b,k;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(FUNCTOR(u) != '^')
return 1;
x = ARG(0,u);
if(contains(x,FUNCTOR(n)))
return 1;
subst(lo,n,ARG(1,u),&b);
polyval(b,&m);
if(!islinear(ARG(1,u),n,&b,&k))
return 1;
*next = make_fraction(make_power(x,m),sum(one,tnegate(make_power(x,k))));
HIGHLIGHT(*next);
strcpy(reason,"$x^m+x^(k+m)+x^(2k+m)+... = x^m/(1-x^k)$");
return 0;
}
/*_______________________________________________________________*/
int xmoveroneminusxkseries2rev(term t, term arg, term *next, char *reason)
{ return xmoveroneminusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int xmoveroneminusxkseries3rev(term t, term arg, term *next, char *reason)
{ return xmoveroneminusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int xmoveroneplusxkseriesrev(term t, term arg, term *next, char *reason)
/* x^m - x^(m+k) + ... x^(m+nk) = x^m/(1+x^k) */
{ term u,n,m,lo,x,b,k,power;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(FUNCTOR(u) == '^' && NEGATIVE(ARG(0,u)))
{ x = ARG(0,ARG(0,u));
power = ARG(1,u);
}
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' && equals(ARG(0,ARG(0,u)),minusone) &&
equals(ARG(1,ARG(0,u)),n) && FUNCTOR(ARG(1,u)) == '^'
)
{ x = ARG(0,ARG(1,u));
power = ARG(1,ARG(1,u));
}
else
return 1;
if(contains(x,FUNCTOR(n)))
return 1;
subst(lo,n,power,&b);
polyval(b,&m);
if(!islinear(ARG(1,u),n,&b,&k))
return 1;
*next = make_fraction(make_power(x,m),sum(one,make_power(x,k)));
HIGHLIGHT(*next);
strcpy(reason,"$x^m-x^(k+m)+x^(2k+m)-... = x^m/(1+x^k)$");
return 0;
}
/*_______________________________________________________________*/
int xmoveroneplusxkseries2rev(term t, term arg, term *next, char *reason)
{ return xmoveroneplusxkseriesrev(t,arg,next,reason);
}
/*_______________________________________________________________*/
int xmoveroneplusxkseries3rev(term t, term arg, term *next, char *reason)
{ return xmoveroneplusxkseriesrev(t,arg,next,reason);
}
/*_________________________________________________________________*/
int geometricseriesfromkrev(term t, term arg, term *next, char *reason)
/* sum(x^n,n,k,infinity) = x^k/(1-x) */
{ term u,x,lo,n;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(FUNCTOR(u) != '^' || !equals(ARG(1,u),n))
return 1;
x = ARG(0,u);
*next = make_fraction(make_power(x,lo),sum(one,tnegate(x)));
HIGHLIGHT(*next);
if(ARITY(t)==4)
strcpy(reason,"$$sum(x^n,n,k,infinity) = x^k/(1-x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"$x^k+x^(k+1)+...=x^k/(1-x)$");
else
strcpy(reason,"$x^k+x^(k+1)+...x^n+... =x^k/(1-x)$");
return 0;
}
/*_________________________________________________________________*/
int geometricseriesfromk2rev(term t, term arg, term *next, char *reason)
{ return geometricseriesfromkrev(t,arg,next,reason);
}
/*_________________________________________________________________*/
int geometricseriesfromk3rev(term t, term arg, term *next, char *reason)
{ return geometricseriesfromkrev(t,arg,next,reason);
}
/*_________________________________________________________________*/
int geometricseriesminusfromkrev(term t, term arg, term *next, char *reason)
/* sum((-1)^n x^n,n,k,infinity) = x^k/(1+x) */
{ term u,x,lo,n;
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity))
return 1;
u = ARG(0,t);
n = ARG(1,t);
lo = ARG(2,t);
if(FUNCTOR(u) == '^' && NEGATIVE(ARG(0,u)) && equals(ARG(1,u),n))
x = ARG(0,ARG(0,u));
else if(FUNCTOR(u) == '*' && ARITY(u) == 2 &&
FUNCTOR(ARG(0,u)) == '^' &&
equals(ARG(0,ARG(0,u)),minusone) &&
equals(ARG(1,ARG(0,u)),n) &&
FUNCTOR(ARG(1,u)) == '6' &&
equals(ARG(1,ARG(1,u)),n)
)
x = ARG(0,ARG(1,u));
else
return 1;
*next = make_fraction(make_power(x,lo),sum(one,x));
HIGHLIGHT(*next);
if(ARITY(t)==4)
strcpy(reason,"$$sum((-1)^nx^n,n,k,infinity) = x^k/(1+x)$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"$x^k-x^(k+1)+...=x^k/(1+x)$");
else
strcpy(reason,"$x^k-x^(k+1)+...(-1)^nx^n+..=x^k/(1+x)$");
return 0;
}
/*_________________________________________________________________*/
int geometricseriesminusfromk2rev(term t, term arg, term *next, char *reason)
{ return geometricseriesminusfromkrev(t,arg,next,reason);
}
/*_________________________________________________________________*/
int geometricseriesminusfromk3rev(term t, term arg, term *next, char *reason)
{ return geometricseriesminusfromkrev(t,arg,next,reason);
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists