Sindbad~EG File Manager
/* Evaluate trig functions menu operators for MathXpert */
/*
M. Beeson
Original date 11.19.91
Last modified 7.27.98
11.21.00 removed comments #pragma argsused
4.12.01 added two lines to combine3045
4.8.97 added cast to (int) on strlen
5.6.13 eliminated ltoa in favor of sprintf
10.24.23 eliminated OEM for \deg and \pi
2.3.24 corrected trigreason to use \\deg instead of hardcoded number for degree symbol
*/
#include <string.h>
#include <math.h>
#include <assert.h>
#include <stdio.h>
#include "globals.h"
#include "ops.h"
#include "trig.h"
#include "cancel.h"
#include "prover.h"
#include "order.h" /* numerical */
#include "deval.h" /* nearint */
#include "polynoms.h"
#include "algaux.h"
#include "pvalaux.h"
#include "symbols.h"
#include "errbuf.h"
#include "dispfunc.h"
#include "mstring.h"
static term degrees_to_radians(term k);
static void trigreason(char *reason, unsigned short f, int flag, long k);
/*_________________________________________________________________________*/
#define RADIANS 0
#define DEGREES 1
static void trigreason(char *reason, unsigned short f, int flag, long k)
/* k is an angle in degrees between 0 and 359 which is a multiple
of 30 or 45 degrees. Return a reason string in *reason showing
its value. flag is either RADIANS or DEGREES; use this in generating
an appropriate reason string. */
{ functor_string(f,SCREEN,reason);
reason[3] = 32;
if(flag==DEGREES)
{ sprintf(reason+4,"%ld",k);
strcat(reason,"$\\deg$ = ");
}
else
{ mstring(degrees_to_radians(make_int(k)),reason+4);
strcat(reason," = ");
}
mstring(trig_aux(f,k),reason + strlen(reason));
}
/*_________________________________________________________________________*/
static term degrees_to_radians(term k)
/* convert degrees to radians */
{ term ans,u,v;
if(ZERO(k))
return zero;
u = product(pi_term,k);
v = make_int(180L);
polyval(make_fraction(u,v),&ans);
return ans;
}
/*_________________________________________________________________________*/
static term radians_to_degrees(term rad)
/* convert radians to degrees */
{ term ans,u;
if(ZERO(rad))
return zero;
u = product(make_int(180L),rad);
polyval(make_fraction(u,pi_term),&ans);
return ans;
}
/*_________________________________________________________________________*/
int mod360(term t, term arg, term *next, char *reason)
/* find coterminal angle < 360 \deg */
{ unsigned short f = FUNCTOR(t);
term u,theta,val,three_sixty,temp;
char buffer[10];
int err;
if(ATOMIC(t) || !TRIGFUNCTOR(f))
return 1;
u = ARG(0,t);
if(FUNCTOR(u) != DEG)
{ errbuf(0, english(701));
/* Angle is not expressed in degrees. */
return 1;
}
theta = ARG(0,u);
if(!numerical(theta) && value(theta,&val))
/* nonzero return from value is nonnumerical value */
{ errbuf(0, english(702));
/* Can't do arithmetic with that angle */
return 1;
}
three_sixty = make_int(360L);
err = tmod(theta,three_sixty,&temp);
if(err || equals(theta,temp))
return 1;
*next = make_term(f,1);
ARGREP(*next,0,deg1(temp));
if(equals(t,*next))
return 1; /* angle already between 0 and 360 */
functor_string(f,SCREEN,buffer);
strcpy(reason,buffer);
strcat(reason,"(u) = ");
strcat(reason,buffer);
strcat(reason,"$(u+360\\deg)$");
HIGHLIGHT(*next);
return 0;
}
/*__________________________________________________________________*/
int mod2pi(term t, term arg, term *next, char *reason)
/* find coterminal angle < 2 \pi */
{ unsigned short f = FUNCTOR(t);
term theta,val,temp,u,cancelled,v;
double a;
char buffer[10];
int err;
if(ATOMIC(t) || !TRIGFUNCTOR(f))
return 1;
theta = ARG(0,t);
/* The next block of code deals with for example sin(x+2k\\pi )
which has to go to sin(x); but in automode, this should
happen through operators sinperiodic etc, so that
sin(x+2\\pi ) is dealt with by sinsum and not by this
operator under the topic _trig_addition. */
if(get_mathmode() == MENUMODE &&
FUNCTOR(theta) == '+' &&
contains(theta,PI_ATOM)
)
{ err = periodic3(t,next,reason);
if(!err)
return 0;
}
err = polyval(make_fraction(theta,pi_term),&u);
if(!err)
{ if(POSNUMBER(u))
{ err = tmod(u,two,&temp);
if(err || equals(u,temp))
return 1;
}
else if(NEGATIVE(u) && POSNUMBER(ARG(0,u)))
{ err = tmod(ARG(0,u),two,&temp);
if(err || equals(ARG(0,u),temp))
return 1;
polyval(sum(product(two,pi_term),tnegate(temp)),&temp);
}
else /* u is symbolic */
{ err = cancel(u,product(two,pi_term),&cancelled, &v);
if(!err && isinteger(v))
temp = zero;
else
return 1;
}
*next = make_term(f,1);
polyval(product(temp,pi_term),ARGPTR(*next));
/* polyval used here to change (1/2) pi to pi/2 */
goto out;
}
/* Now pi doesn't cancel */
if(!numerical(theta) || value(theta,&val))
/* nonzero return from value is nonnumerical value */
{ badval:
errbuf(0, english(702));
/* Can't do arithmetic with that angle */
return 1;
}
u = make_term(MOD,2);
ARGREP(u,0,theta);
ARGREP(u,1,product(two,pi_term));
err = deval(u,&a);
if(err) goto badval;
*next = make_term(f,1);
ARGREP(*next,0,make_double(a));
out:
if(equals(*next,t))
return 1; /* angle already between 0 and 2\\pi */
HIGHLIGHT(ARG(0,*next));
functor_string(f,SCREEN,buffer);
strcpy(reason,buffer);
strcat(reason,"(u) = ");
strcat(reason,buffer);
strcat(reason,"$(u+2\\pi)$");
HIGHLIGHT(*next);
return 0;
}
/*__________________________________________________________________*/
int sin90(term t, term arg, term *next, char *reason)
/* angle is multiple of 90\deg */
/* calculate trig function of a multiple of pi/2, whether argument is
in degrees or radians */
{ term u,v,w,ninety,cancelled;
unsigned short f=FUNCTOR(t);
int err;
long k;
if(ATOMIC(t) || !TRIGFUNCTOR(f))
return 1;
if(FUNCTOR(ARG(0,t)) == DEG)
{ u = ARG(0,ARG(0,t));
if(ZERO(u))
v = zero;
else
{ ninety = make_int(90L);
err = cancel(u,ninety,&cancelled,&v);
if(err)
return 1;
}
}
else /* angle interpreted as radians */
{ u = ARG(0,t);
if(ZERO(u))
v = zero;
else
{ err = polyval(make_fraction(product(two,u),pi_term),&v);
if(err || !isinteger(v))
return 1;
}
}
err = tmod(v,four,&w);
if(!err && OBJECT(w) && TYPE(w)==INTEGER)
{ /* w is 0,1,2, or 3 */
k = INTDATA(w);
assert(k >=0 && k < 4);
*next = trig_aux(f,k*90);
goto out;
}
/* in case of sin(0.5 pi_term), v will now be 2 * 0.5 */
if(numerical(v))
{ double zz;
deval(v,&zz);
if(zz != BADVAL && nearint(zz,&k))
{k &= 0x0003; /* k = k%4 even for k negative */
*next = trig_aux(f,k*90);
goto out;
}
else
return 1;
}
/* Sometimes we can calculate the value even when tmod fails,
e.g. sin(n\\pi ) is always zero even though we don't know whether
n is even or odd */
k = 27; /* means we don't know its real value */
if(f == SIN || f == TAN || f == CSC)
{ err = cancel(v,two,&cancelled,&w); /* see if the angle is a multiple of pi */
if(!err)
{ err = infer(type(w,INTEGER));
if(err)
return 1;
/* yes, it's a multiple of pi */
*next = (f==CSC ? undefined : zero);
goto out;
}
return 1;
}
if(f == COS || f == COT || f == SEC)
{ err = cancel(sum(v,one),two,&cancelled,&w); /* is it an odd multiple of pi/2 ? */
if(!err)
{ err = infer(type(w,INTEGER));
if(err)
return 1;
*next = (f == SEC ? undefined : zero);
goto out;
}
}
return 1;
out:
HIGHLIGHT(*next);
if(k!=27)
trigreason(reason,f,(FUNCTOR(ARG(0,t))==DEG ? DEGREES: RADIANS), k*90);
else if(f==SIN || f == TAN || f == CSC)
{ strcpy(reason, english(703)); /* multiple of */
if(FUNCTOR(ARG(0,t))==DEG)
strcat(reason,"$180\\deg$");
else
strcat(reason,"$\\pi$");
}
else /* f == COS, SEC, or COT */
{ strcpy(reason, english(704)); /* odd multiple of */
if(FUNCTOR(ARG(0,t))==DEG)
strcat(reason, "$90\\deg$");
else
strcat(reason, "$\\pi/2$");
}
return 0;
}
/*__________________________________________________________________*/
int sin0(term t, term arg, term *next, char *reason)
/* sin 0 = 0 */
{ term u;
unsigned short f=FUNCTOR(t);
if(ATOMIC(t) || f != SIN)
return 1;
u = ARG(0,t);
if(ISZERO(u) || (FUNCTOR(u) == DEG && ISZERO(ARG(0,u))))
{ *next = zero;
strcpy(reason, "sin 0 = 0");
HIGHLIGHT(*next);
return 0;
}
return 1;
}
/*__________________________________________________________________*/
int cos0(term t, term arg, term *next, char *reason)
/* cos 0 = 1 */
{ term u;
unsigned short f=FUNCTOR(t);
if(ATOMIC(t) || f != COS)
return 1;
u = ARG(0,t);
if(ISZERO(u) || (FUNCTOR(u) == DEG && ISZERO(ARG(0,u))))
{ *next = one;
strcpy(reason, "cos 0 = 1");
HIGHLIGHT(*next);
return 0;
}
return 1;
}
/*__________________________________________________________________*/
int tan0(term t, term arg, term *next, char *reason)
/* tan 0 = 0 */
{ term u;
unsigned short f=FUNCTOR(t);
if(ATOMIC(t) || f != TAN)
return 1;
u = ARG(0,t);
if(ISZERO(u) || (FUNCTOR(u) == DEG && ISZERO(ARG(0,u))))
{ *next = zero;
strcpy(reason, "tan 0 = 0");
HIGHLIGHT(*next);
return 0;
}
return 1;
}
/*__________________________________________________________________*/
int sin30(term t, term arg, term *next, char *reason)
/* use 1-2- sqrt 3 triangle */
{ term u,v,w,thirty,cancelled;
unsigned short f = FUNCTOR(t);
int err;
long k;
if( ATOMIC(t) || !TRIGFUNCTOR(f) )
return 1;
if(FUNCTOR(ARG(0,t)) == DEG)
{ u = ARG(0,ARG(0,t));
if(ZERO(u))
v = zero;
else
{ thirty = make_int(30L);
err = cancel(u,thirty,&cancelled,&v);
if(err)
return 1;
}
}
else /* angle interpreted as radians */
{ u = ARG(0,t);
if(ZERO(u))
v = zero;
else
{ err = polyval(make_fraction(product(six,u),pi_term),&v);
if(err || !isinteger(v))
return 1;
}
}
err = tmod(v,make_int(12L),&w);
if(!err && OBJECT(w) && TYPE(w)==INTEGER)
{ /* w is 0,1,2,...11 */
k = INTDATA(w);
assert(k >=0 && k < 12);
if(k%3 == 0) /* angle is a multiple of \\pi /2 */
{ if(!get_polyvalfunctionflag()) /* don't do this while using polyval */
errbuf(0, english(705));
/* Use \"angle is multiple of 90\deg \" instead. */
return 1;
}
*next = trig_aux(f,k*30);
goto out;
}
if(numerical(v))
{ double zz;
deval(v,&zz);
if(zz != BADVAL && nearint(zz,&k))
{ k = k %12;
if(k<0) k = 12-k;
*next = trig_aux(f,k*30);
goto out;
}
else
return 1;
}
return 1;
out:
HIGHLIGHT(*next);
trigreason(reason,f,(FUNCTOR(ARG(0,t))==DEG ? DEGREES: RADIANS), k*30);
return 0;
}
/*__________________________________________________________________*/
int sin45(term t, term arg, term *next, char *reason)
/* use 1-1-\sqrt 2 triangle */
{ term u,v,w,fortyfive,cancelled;
unsigned short f = FUNCTOR(t);
int err;
long k;
if(ATOMIC(t) || !TRIGFUNCTOR(f) )
return 1;
if(FUNCTOR(ARG(0,t)) == DEG)
{ u = ARG(0,ARG(0,t));
if(ZERO(u)) v = zero;
else
{ fortyfive = make_int(45L);
err = cancel(u,fortyfive,&cancelled,&v);
if(err)
return 1;
}
}
else /* angle interpreted as radians */
{ u = ARG(0,t);
err = polyval(make_fraction(product(four,u),pi_term),&v);
/* cancel won't cancel pi out of 3pi/4, so we use polyval instead */
if(err || !isinteger(v))
return 1;
}
err = tmod(v,eight,&w);
if(!err && OBJECT(w) && TYPE(w) == INTEGER)
{ /* w is 0,1,2,...7 */
k = INTDATA(w);
assert(k >=0 && k < 8);
if(!(k&1)) /* k is even */
{ if(!get_polyvalfunctionflag())
errbuf(0, english(705));
/* Use \"angle is multiple of 90\deg \" instead. */
return 1;
}
*next = trig_aux(f,k*45);
goto out;
}
if(numerical(v))
{ double zz;
deval(v,&zz);
if(zz != BADVAL && nearint(zz,&k))
{ k = k % 8;
if(k<0) k = 8-k;
*next = trig_aux(f,k*45);
goto out;
}
else
return 1;
}
return 1;
out:
HIGHLIGHT(*next);
trigreason(reason,f,(FUNCTOR(ARG(0,t))==DEG ? DEGREES: RADIANS), k*45);
return 0;
}
/*__________________________________________________________________*/
int radtodeg(term t, term arg, term *next, char *reason)
/* change radians to degrees in arg of a trig functor */
{ unsigned short f = FUNCTOR(t);
term degrees;
int sign;
double z;
long kk;
term u;
if(ATOMIC(t) || !TRIGFUNCTOR(f))
return 1;
u = ARG(0,t);
if(FUNCTOR(u) == DEG)
{ errbuf(0,english(1364));
return 1; /* Angle is already in degrees. */
}
*next = make_term(f,1);
if(!seminumerical(ARG(0,t)))
{ errbuf(0, english(1856));
/* You can only convert a specific, numerical angle to degrees. */
return 1;
}
degrees = radians_to_degrees(ARG(0,t));
if(NEGATIVE(degrees))
{ sign = -1;
degrees = ARG(0,degrees);
}
else
sign = 1;
if(!OBJECT(degrees) && !NUMBER(degrees))
{ deval(degrees,&z);
if(z < 0)
{ sign *= -1;
z = -z;
}
if(nearint(z,&kk))
degrees = make_int(kk);
else
degrees = make_double(z);
}
if(sign == -1)
ARGREP(*next,0, tnegate(deg1(degrees)));
else
ARGREP(*next,0,deg1(degrees));
HIGHLIGHT(*next);
strcpy(reason, english(706)); /* radians to degrees */
return 0;
}
/*__________________________________________________________________*/
int degtorad(term t, term arg, term *next, char *reason)
/* change degrees to radians */
/* works either on deg(x) or f(deg(x)) where f is a trig functor */
{ unsigned short f = FUNCTOR(t);
if(TRIGFUNCTOR(f) && FUNCTOR(ARG(0,t)) == DEG)
{ *next = make_term(f,1);
ARGREP(*next,0,degrees_to_radians(ARG(0,ARG(0,t))));
strcpy(reason, english(707)); /* degrees to radians */
HIGHLIGHT(ARG(0,*next));
return 0;
}
if (FUNCTOR(t) != DEG)
return 1;
*next = degrees_to_radians(ARG(0,t));
strcpy(reason, english(707)); /* degrees to radians */
HIGHLIGHT(*next);
return 0;
}
/*__________________________________________________________________*/
int combine3045(term t, term arg, term *next, char *reason)
/* angle = a 30\deg + b 45\deg etc. */
/* If t is a trig function of \theta \deg , express \theta as a linear combination of
30 and 45 degrees */
{ long s,k,b;
unsigned short f = FUNCTOR(t);
term theta;
if(ATOMIC(t) || !TRIGFUNCTOR(f) )
return 1;
if(FUNCTOR(ARG(0,t)) != DEG)
{ errbuf(0, english(708));
/* First express the angle in degrees. */
return 1;
}
theta = ARG(0,ARG(0,t)); /* the angle in degrees */
if(FUNCTOR(theta) == '-')
{ errbuf(0, english(709));
/* This only works on positive angles. */
return 1;
}
if(! ISINTEGER(theta))
return 1;
s = INTDATA(theta);
if(s%15)
return 1; /* must be divisible by 15 for this to work */
if(s%45 == 0 || s%30 == 0)
return 1; /* don't work on multiples of 45 or 30 */
k = s/15;
b = k/3;
*next = make_term(f,1);
if( k-3*b == 2)
{
ARGREP(*next,0,
sum(deg1(make_int(30)),
product(make_int(b),deg1(make_int(45)))
)
);
strcpy(reason, english(710)); /* angle = 30\deg + b 45\deg */
}
else
{ --b;
ARGREP(*next,0,
sum(deg1(make_int(60)),
product(make_int(b),deg1(make_int(45)))
)
);
strcpy(reason, english(711)); /* angle = 60\deg + b 45\deg */
}
HIGHLIGHT(*next);
return 0;
}
/*_____________________________________________________________________*/
int zeroesofsin(term t, term arg, term *next, char *reason)
/* sin(k\\pi ) = 0; does not work if argument is in degrees */
{ term u,cancelled,n;
int err;
if(FUNCTOR(t) != SIN)
return 1;
u = ARG(0,t);
if(ISZERO(u))
{ strcpy(reason,"sin 0 = 0");
*next = zero;
return 0;
}
if(equals(u,pi_term))
{ strcpy(reason,"$sin \\pi = 0$");
*next = zero;
return 0;
}
if(NEGATIVE(u))
u = ARG(0,u);
if(FUNCTOR(u) != '*')
return 1;
err = cancel(u,pi_term,&cancelled,&n);
if(err)
return 1;
if(isinteger(n))
goto out;
if(contains(n,'/'))
return 1; /* it can't be an integer if it contains a fraction */
err = infer(type(n,INTEGER));
if(err)
return 1;
out:
strcpy(reason,"$sin k\\pi = 0$");
*next = zero;
return 0;
}
/*_____________________________________________________________________*/
int zeroesoftan(term t, term arg, term *next, char *reason)
/* tan(k\\pi ) = 0 */
{ term u,cancelled,n;
int err;
if(FUNCTOR(t) != TAN)
return 1;
u = ARG(0,t);
if(ZERO(u))
{ strcpy(reason,"tan 0 = 0");
*next = zero;
return 0;
}
if(equals(u,pi_term))
{ strcpy(reason,"$tan \\pi = 0$");
*next = zero;
return 0;
}
if(NEGATIVE(u))
u = ARG(0,u);
if(FUNCTOR(u) != '*')
return 1;
err = cancel(u,pi_term,&cancelled,&n);
if(err)
return 1;
if(isinteger(n))
goto out;
if(contains(n,'/'))
return 1; /* it can't be an integer if it contains a fraction */
err = infer(type(n,INTEGER));
if(err)
return 1;
out:
strcpy(reason,"$tan k\\pi = 0$");
*next = zero;
return 0;
}
/*_____________________________________________________________________*/
int onesofcos(term t, term arg, term *next, char *reason)
/* cos(2k\\pi ) = 1 */
{ term u,cancelled,n,twopi;
int err;
if(FUNCTOR(t) != COS)
return 1;
u = ARG(0,t);
if(ZERO(u))
{ strcpy(reason,"cos 0 = 1");
*next = one;
return 0;
}
if(NEGATIVE(u))
u = ARG(0,u);
if(FUNCTOR(u) != '*')
return 1;
if(!contains(u,FUNCTOR(pi_term)))
return 1;
twopi = product(two,pi_term);
err = cancel(u,twopi,&cancelled,&n);
if(err)
{ RELEASE(twopi);
return 1;
}
if(isinteger(n))
goto out;
if(contains(n,'/'))
{ RELEASE(twopi);
return 1; /* it can't be an integer if it contains a fraction */
}
err = infer(type(n,INTEGER));
if(err)
{ RELEASE(twopi);
return 1;
}
out:
strcpy(reason,"$cos 2k\\pi = 1$");
*next = one;
return 0;
}
/*_____________________________________________________________________*/
int sinperiodic(term t, term arg, term *next, char *reason)
/* sin(u+2\\pi ) = sin u */
{ if(FUNCTOR(t) != SIN || ATOMIC(ARG(0,t)))
return 1;
return periodic3(t,next,reason);
}
/*_____________________________________________________________________*/
int cosperiodic(term t, term arg, term *next, char *reason)
/* cos(u+2\\pi ) = cos u */
{ if(FUNCTOR(t) != COS || ATOMIC(ARG(0,t)))
return 1;
return periodic3(t,next,reason);
}
/*_____________________________________________________________________*/
int tanperiodic(term t, term arg, term *next, char *reason)
/* tan(u+\\pi ) = tan u */
{ if(FUNCTOR(t) != TAN || ATOMIC(ARG(0,t)))
return 1;
return periodic3(t,next,reason);
}
/*_____________________________________________________________________*/
int sinsqperiodic(term t, term arg, term *next, char *reason)
/* sin^2(u+pi_term) = sin^2 u */
{ term u,m;
int err;
if(FUNCTOR(t) != '^' || FUNCTOR(ARG(0,t)) != SIN)
return 1;
u = ARG(0,ARG(0,t));
m = ARG(1,t);
if(
(INTEGERP(m) && ISEVEN(m))
||
!infer(even(m))
)
{ err = periodic3(tan1(u),next,reason);
/* send a TAN term to periodic3 so it will use period pi */
if(err)
return 1;
/* Now convert the fake TAN answer in *next to a sinsq answer */
*next = make_power(sin1(ARG(0,*next)),m);
strcpy(reason,"$sin^2(u+\\pi) = sin^2 u$");
return 0;
}
return 1;
}
/*_____________________________________________________________________*/
int cossqperiodic(term t, term arg, term *next, char *reason)
/* cos^2(u+\\pi ) = cos^2 u */
{ term u,m;
int err;
if(FUNCTOR(t) != '^' || FUNCTOR(ARG(0,t)) != COS)
return 1;
u = ARG(0,ARG(0,t));
m = ARG(1,t);
if(
(INTEGERP(m) && ISEVEN(m))
||
!infer(even(m))
)
{ err = periodic3(tan1(u),next,reason);
/* send a TAN term to periodic3 so it will use period pi */
if(err)
return 1;
/* Now convert the fake TAN answer in *next to a cossq answer */
*next = make_power(cos1(ARG(0,*next)),m);
strcpy(reason,"$cos^2(u+\\pi ) = cos^2 u$");
return 0;
}
return 1;
}
/*_____________________________________________________________________*/
int secsqperiodic(term t, term arg, term *next, char *reason)
/* sec^2(u+\\pi ) = sec^2 u */
{ term u,m;
int err;
if(FUNCTOR(t) != '^' || FUNCTOR(ARG(0,t)) != SEC)
return 1;
u = ARG(0,ARG(0,t));
m = ARG(1,t);
if(
(INTEGERP(m) && ISEVEN(m))
||
!infer(even(m))
)
{ err = periodic3(tan1(u),next,reason);
/* send a TAN term to periodic3 so it will use period pi */
if(err)
return 1;
/* Now convert the fake TAN answer in *next to a secsq answer */
*next = make_power(sec1(ARG(0,*next)),m);
strcpy(reason,"$sec^2(u+\\pi ) = sec^2 u$");
return 0;
}
return 1;
}
/*_____________________________________________________________________*/
int cscsqperiodic(term t, term arg, term *next, char *reason)
/* csc^2(u+\\pi ) = csc^2 u */
{ term u,m;
int err;
if(FUNCTOR(t) != '^' || FUNCTOR(ARG(0,t)) != CSC)
return 1;
u = ARG(0,ARG(0,t));
m = ARG(1,t);
if(
(INTEGERP(m) && ISEVEN(m))
||
!infer(even(m))
)
{ err = periodic3(tan1(u),next,reason);
/* send a TAN term to periodic3 so it will use period pi */
if(err)
return 1;
/* Now convert the fake TAN answer in *next to a secsq answer */
*next = make_power(csc1(ARG(0,*next)),m);
strcpy(reason,"$csc^2(u+\\pi ) = csc^2 u$");
return 0;
}
return 1;
}
/*_____________________________________________________________________*/
int cotperiodic(term t, term arg, term *next, char *reason)
/* cot(u+\\pi ) = cot u */
{ if(FUNCTOR(t) != COT || ATOMIC(ARG(0,t)))
return 1;
return periodic3(t,next,reason);
}
/*_____________________________________________________________________*/
int cscperiodic(term t, term arg, term *next, char *reason)
/* csc(u+2\\pi ) = csc u */
{ if(FUNCTOR(t) != CSC || ATOMIC(ARG(0,t)))
return 1;
return periodic3(t,next,reason);
}
/*_____________________________________________________________________*/
int secperiodic(term t, term arg, term *next, char *reason)
/* sec(u+2\\pi ) = sec u */
{ if(FUNCTOR(t) != SEC || ATOMIC(ARG(0,t)))
return 1;
return periodic3(t,next,reason);
}
/*_____________________________________________________________________*/
int sinhalfperiod1(term t, term arg, term *next, char *reason)
/* sin u = -sin(u-pi_term) */
{ term u,v,w;
int err;
double z;
if(FUNCTOR(t) != SIN)
return 1;
u = ARG(0,t);
if(FUNCTOR(u) == DEG)
{ v = ARG(0,u);
err = value(sum(v, tnegate(make_int(180))),&w);
if(err)
{ if(seminumerical(v))
{ deval(v,&z);
if(z != BADVAL)
w = make_double(z);
else
return 1;
}
else
return 1;
}
*next = tnegate(sin1(deg1(w)));
}
else
{ polyval(sum(u,tnegate(pi_term)),&w);
*next = tnegate(sin1(w));
}
strcpy(reason,"$sin u = -sin(u-\\pi )$");
return 0;
}
/*_____________________________________________________________________*/
int coshalfperiod1(term t, term arg, term *next, char *reason)
/* cos u = -cos(u-pi_term) */
{ term u,v,w;
int err;
double z;
if(FUNCTOR(t) != COS)
return 1;
u = ARG(0,t);
if(FUNCTOR(u) == DEG)
{ v = ARG(0,u);
err = value(sum(v, tnegate(make_int(180))),&w);
if(err)
{ if(seminumerical(v))
{ deval(v,&z);
if(z != BADVAL)
w = make_double(z);
else
return 1;
}
else
return 1;
}
*next = tnegate(cos1(deg1(w)));
}
else
{ polyval(sum(u,tnegate(pi_term)),&w);
*next = tnegate(cos1(w));
}
strcpy(reason,"$cos u = -cos(u-\\pi )$");
return 0;
}
/*_____________________________________________________________________*/
int sinhalfperiod2(term t, term arg, term *next, char *reason)
/* sin u = sin(pi-u) */
{ term u,v,w;
int err;
double z;
if(FUNCTOR(t) != SIN)
return 1;
u = ARG(0,t);
if(FUNCTOR(u) == DEG)
{ v = ARG(0,u);
err = value(sum(make_int(180),tnegate(v)),&w);
if(err)
{ if(seminumerical(v))
{ deval(v,&z);
if(z != BADVAL)
w = make_double(z);
else
return 1;
}
else
return 1;
}
*next = sin1(deg1(w));
}
else
{ polyval(sum(pi_term,tnegate(u)),&w);
*next = sin1(w);
}
strcpy(reason,"$sin u = sin(\\pi -u)$");
return 0;
}
/*_____________________________________________________________________*/
int coshalfperiod2(term t, term arg, term *next, char *reason)
/* cos u = -cos(pi-u) */
{ term u,v,w;
int err;
double z;
if(FUNCTOR(t) != COS)
return 1;
u = ARG(0,t);
if(FUNCTOR(u) == DEG)
{ v = ARG(0,u);
err = value(sum(make_int(180),tnegate(v)),&w);
if(err)
{ if(seminumerical(v))
{ deval(v,&z);
if(z != BADVAL)
w = make_double(z);
else
return 1;
}
else
return 1;
}
*next = tnegate(cos1(deg1(w)));
}
else
{ polyval(sum(pi_term,tnegate(u)),&w);
*next = tnegate(cos1(w));
}
strcpy(reason,"$cos u = -cos(\\pi -u)$");
return 0;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists