Sindbad~EG File Manager
/* M. Beeson, for MathXpert.
Reverse trig operators.
Original date 2.10.97
Last modified 2.27.98
2.9.05 added include graphstr.h, mpdoc.h
3.14.23 changed theta to t to avoid "illegal character encoding"
5.13.24 more reasons in display math, and others just in $.
*/
#include <string.h>
#include <math.h>
#include <assert.h>
#include "globals.h"
#include "ops.h"
#include "trig.h"
#include "match.h"
#include "order.h"
#include "cancel.h"
#include "simpsums.h" /* collect */
#include "checkarg.h" /* needed by automode.h */
#include "graphstr.h"
#include "mpdoc.h"
#include "automode.h" /* get_intflag */
#include "mstring.h" /* mstring */
#include "deval.h"
#include "symbols.h"
#include "pvalaux.h" /* content_factor */
#include "mathmode.h" /* get_mathmode */
#include "calc.h" /* polyvalop */
#include "errbuf.h"
#include "autosimp.h" /* set_pathtail, SetShowStepOperation */
/*______________________________________________________________________*/
int sinsumrev(term t, term arg, term *next, char *reason)
/* sin u cos v + cos u sin v = sin(u+v) */
{ term lhs,rhs,a[2],temp;
int err;
lhs = sum(product(sin1(var0),cos1(var1)),product(cos1(var0),sin1(var1)));
rhs = sin1(sum(var0,var1));
err = match(t,lhs,rhs,a,&temp); /* instantiate a[0],a[1], and *next */
if(err)
{ destroy_term(lhs);
destroy_term(rhs);
return 1;
}
polyval(temp,next); /* this is important so that e.g. x + pi/6 - (x-pi/6)
becomes 2x. Preops checks for a non-sum in the
arg of the answer. */
strcpy(reason, "$$sin u cos v + cos u sin v=sin(u+v)$$");
HIGHLIGHT(*next);
return 0;
}
/*______________________________________________________________________*/
int sindifrev(term t, term arg, term *next, char *reason)
/* sin u cos v - cos u sin v = sin(u-v) */
{ term lhs,rhs,a[2],temp;
int err;
lhs = sum(product(sin1(var0),cos1(var1)),tnegate(product(cos1(var0),sin1(var1))));
rhs = sin1(sum(var0,tnegate(var1)));
err = match(t,lhs,rhs,a,&temp); /* instantiate a[0],a[1], and *next */
if(err)
{ destroy_term(lhs);
destroy_term(rhs);
return 1;
}
polyval(temp,next);
strcpy(reason, "$$sin u cos v -cos u sin v=sin(u-v)$$");
HIGHLIGHT(*next);
return 0;
}
/*______________________________________________________________________*/
int cossumrev(term t, term arg, term *next, char *reason)
/* cos u cos v - sin u sin v = cos(u+v) */
{ term lhs,rhs,a[2],temp;
int err;
lhs = sum(product(cos1(var0),cos1(var1)),tnegate(product(sin1(var0),sin1(var1))));
rhs = cos1(sum(var0,var1));
err = match(t,lhs,rhs,a,&temp); /* instantiate a[0],a[1], and *next */
if(err)
{ destroy_term(lhs);
destroy_term(rhs);
return 1;
}
polyval(temp,next);
strcpy(reason, "$$cos u cos v - sin u sin v=cos(u+v)$$");
HIGHLIGHT(*next);
return 0;
}
/*______________________________________________________________________*/
int cosdifrev(term t, term arg, term *next, char *reason)
/* cos u cos v + sin u sin v = cos(u-v) */
{ term lhs,rhs,a[2],temp;
int err;
lhs = sum(product(cos1(var0),cos1(var1)),product(sin1(var0),sin1(var1)));
rhs = cos1(sum(var0,tnegate(var1)));
err = match(t,lhs,rhs,a,&temp); /* instantiate a[0],a[1], and *next */
if(err)
{ destroy_term(lhs);
destroy_term(rhs);
return 1;
}
polyval(temp,next);
strcpy(reason, "$$cos u cos v + sin u sin v=cos(u-v)$$");
HIGHLIGHT(*next);
return 0;
}
/*______________________________________________________________________*/
int tansumrev(term t, term arg, term *next, char *reason)
/* (tan u+tan v)/(1-tan u tan v) = tan(u+v) */
{ term num,denom,a,b,c,u,v;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(num) != '+' || FUNCTOR(denom) != '+' ||
ARITY(num) != 2 || ARITY(denom) != 2
)
return 1;
if(!ONE(ARG(0,denom)) || !NEGATIVE(ARG(1,denom)))
return 1;
a = ARG(0,num);
b = ARG(1,num);
c = ARG(0,ARG(1,denom));
if(FUNCTOR(a) != TAN || FUNCTOR(b) != TAN ||
FUNCTOR(c) != '*' || ARITY(c) != 2
)
return 1;
u = ARG(0,a);
v = ARG(0,b);
if(
(equals(a,ARG(0,c)) && equals(b,ARG(1,c))) ||
(equals(a,ARG(1,c)) && equals(b,ARG(0,c)))
)
{ *next = tan1(sum(u,v));
HIGHLIGHT(*next);
strcpy(reason,"$$(tan u+tan v)/(1-tan u tan v) = tan(u+v)$$");
return 0;
}
return 1;
}
/*______________________________________________________________________*/
int tandifrev(term t, term arg, term *next, char *reason)
/* (tan u-tan v)/(1+tan u tan v) = tan(u-v) */
{ term num,denom,a,b,c,u,v;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(num) != '+' || FUNCTOR(denom) != '+' ||
ARITY(num) != 2 || ARITY(denom) != 2
)
return 1;
if(FUNCTOR(ARG(0,num)) != TAN || !NEGATIVE(ARG(1,num)) ||
FUNCTOR(ARG(0,ARG(1,num))) != TAN
)
return 1;
u = ARG(0,ARG(0,num));
v = ARG(0,ARG(0,ARG(1,num)));
if(ONE(ARG(0,denom)))
c = ARG(1,denom);
else if(ONE(ARG(1,denom)))
c = ARG(0,denom);
else
return 1;
if(FUNCTOR(c) != '*' || ARITY(c) != 2)
return 1;
a = ARG(0,c);
b = ARG(1,c);
if(
(equals(a,ARG(0,num)) && equals(b,ARG(0,ARG(1,num)))) ||
(equals(b,ARG(0,num)) && equals(a,ARG(0,ARG(1,num))))
)
{ *next = tan1(sum(u,tnegate(v)));
HIGHLIGHT(*next);
strcpy(reason, "$$(tan u-tan v)/ (1+tan u tan v) = tan(u-v)$$");
return 0;
}
return 1;
}
/*______________________________________________________________________*/
int cotsumrev(term t, term arg, term *next, char *reason)
/* (cot u cot v-1)/(cot u+cot v) = cot(u+v) */
{ term num,denom,a,b,c,u,v;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(num) != '+' || FUNCTOR(denom) != '+' ||
ARITY(num) != 2 || ARITY(denom) != 2 ||
!NEGATIVE(ARG(1,num)) || !ONE(ARG(0,ARG(1,num))) ||
FUNCTOR(ARG(0,num)) != '*' || ARITY(ARG(0,num)) != 2
)
return 1;
a = ARG(0,denom);
b = ARG(1,denom);
if(FUNCTOR(a) != COT || FUNCTOR(b) != COT)
return 1;
u = ARG(0,a);
v = ARG(0,b);
c = ARG(0,num);
if(
(equals(a,ARG(0,c)) && equals(b,ARG(1,c))) ||
(equals(b,ARG(0,c)) && equals(a,ARG(1,c)))
)
{ *next = cot1(sum(u,v));
HIGHLIGHT(*next);
strcpy(reason,"$$(cot u cot v-1)/(cot u+cot v) = cot(u+v)$$");
return 0;
}
return 1;
}
/*______________________________________________________________________*/
int cotdifrev(term t, term arg, term *next, char *reason)
/* (1+cot u cot v)/(cot v-cot u) = cot(u-v) */
{ term num,denom, u,v,a,b,c;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(num) != '+' || FUNCTOR(denom) != '+' ||
ARITY(num) != 2 || ARITY(denom) != 2 ||
!NEGATIVE(ARG(1,denom))
)
return 1;
a = ARG(0,denom);
b = ARG(0,ARG(1,denom));
if(FUNCTOR(a) != COT || FUNCTOR(b) != COT)
return 1;
u = ARG(0,a);
v = ARG(0,b);
if(ONE(ARG(0,num)))
c = ARG(1,num);
else if(ONE(ARG(1,num)))
c = ARG(0,num);
else
return 1;
if(FUNCTOR(c) != '*' || ARITY(c) != 2)
return 1;
if(
(equals(ARG(0,c),a) && equals(ARG(1,c),b)) ||
(equals(ARG(0,c),b) && equals(ARG(1,c),a))
)
{ *next = cot1(sum(u,tnegate(v)));
HIGHLIGHT(*next);
strcpy(reason,"$$(1+cot u cot v)/(cot v-cot u) = cot(u-v)$$");
return 0;
}
return 1;
}
/*______________________________________________________________________*/
int tanhalf1rev(term t, term arg, term *next, char *reason)
/* (sin t)/(1+cos t) = tan(t/2) */
{ term num,denom,u,a,b;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(num) != SIN)
return 1;
u = ARG(0,num);
if(FUNCTOR(denom) != '+' || ARITY(denom) != 2)
return 1;
a = ARG(0,denom);
b = ARG(1,denom);
if(
(ONE(a) && FUNCTOR(b) == COS && equals(ARG(0,b),u)) ||
(ONE(b) && FUNCTOR(a) == COS && equals(ARG(0,a),u))
)
{ *next = tan1(make_fraction(u,two));
HIGHLIGHT(*next);
strcpy(reason,"$$(sin t)/(1+cos t) = tan(t/2)$$");
return 0;
}
return 1;
}
/*______________________________________________________________________*/
int tanhalf2rev(term t, term arg, term *next, char *reason)
/* (1-cos t)/sin t = tan(t/2) */
{ term num,denom,u,b;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(denom) != SIN)
return 1;
u = ARG(0,denom);
if(FUNCTOR(num) != '+' || ARITY(num) != 2 ||
!ONE(ARG(0,num)) || !NEGATIVE(ARG(1,num)))
return 1;
b = ARG(0,ARG(1,num));
if(FUNCTOR(b) != COS || !equals(ARG(0,b),u))
return 1;
*next = tan1(make_fraction(u,two));
HIGHLIGHT(*next);
strcpy(reason,"$$(1-cos t)/sin t = tan(t/2)$$");
return 0;
}
/*______________________________________________________________________*/
int cothalf1rev(term t, term arg, term *next, char *reason)
/* (1+cos t)/(sin t) = cot(t/2) */
{ term num,denom,u;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(denom) != SIN)
return 1;
u = ARG(0,denom);
if(FUNCTOR(num) != '+' || ARITY(num) != 2)
return 1;
if(
(ONE(ARG(0,num)) && FUNCTOR(ARG(1,num)) == COS && equals(u,ARG(0,ARG(1,num)))) ||
(ONE(ARG(1,num)) && FUNCTOR(ARG(0,num)) == COS && equals(u,ARG(0,ARG(0,num))))
)
{ *next = cot1(make_fraction(u,two));
HIGHLIGHT(*next);
strcpy(reason,"$$(1+cos t)/(sin t) = cot(t/2)$$");
return 0;
}
return 1;
}
/*______________________________________________________________________*/
int cothalf2rev(term t, term arg, term *next, char *reason)
/* sin t/(1-cos t) = cot(t/2) */
{ term num,denom,u,b;
if(!FRACTION(t))
return 1;
num = ARG(0,t);
denom = ARG(1,t);
if(FUNCTOR(num) != SIN)
return 1;
u = ARG(0,num);
if(FUNCTOR(denom) != '+' || ARITY(denom) != 2 ||
!ONE(ARG(0,denom)) || !NEGATIVE(ARG(1,denom))
)
return 1;
b = ARG(0,ARG(1,denom));
if(FUNCTOR(b) != COS || !equals(ARG(0,b),u))
return 1;
*next = cot1(make_fraction(u,two));
HIGHLIGHT(*next);
strcpy(reason,"$$sin t/(1-cos t) = cot(t/2)$$");
return 0;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists