Sindbad~EG File Manager
/* integration operators involving arctrig or arc hypertrig functions,
not encountered in first-semester calculus */
/*
M. Beeson, for MathXpert
Original date 3.8.92
modified 2.27.98
12.31.99 corrected 'n' to 'nminustwo' in defn of uv in intsecpower
10.6.00 corrected intsecpower
11.21.00 corrected intcscpower
*/
#include <string.h>
#include <assert.h>
#define TRIGCALC_DLL
#include "globals.h"
#include "ops.h"
#include "trig.h"
#include "calc.h"
#include "match.h"
#include "algaux.h"
#include "factor.h"
#include "autosub.h"
#include "prover.h"
#include "symbols.h"
#include "pvalaux.h" /* isodd */
#include "psubst.h"
#include "errbuf.h"
#include "pathtail.h"
#include "autosimp.h"
static contains_arg(term t, unsigned short f, term *x);
static int intsubsin_aux(unsigned short, term, term, term *, char *);
/*_______________________________________________________________________*/
MEXPORT_TRIGCALC int inttoasin(term t, term arg, term *next, char *reason)
{ term u,x,a,temp,p;
int err;
if(FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t);
x = ARG(1,t);
err = matchstring(u,x,"/(1,sqrt(+(b,-(^(x,2)))))",&p);
if(err || depends(p,x))
return 1;
/* now u = 1/�(p-x^2) */
err = sqrt_aux(p,&a);
if(err)
return 1;
/* Now u = 1/�(a^2-x^2) */
if(ONE(a))
{ temp = asin1(x);
strcpy(reason,"$�1/�(1-t^2)dt=arcsin t$");
}
else
{ temp = product(make_fraction(one,a),asin1(make_fraction(x,a)));
strcpy(reason,"$�1/�(a^2-t^2)dt$ = (1/a)arcsin/(t/a)");
}
if(ARITY(t) == 2) /* an indefinite integral */
*next = temp;
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*_______________________________________________________________*/
MEXPORT_TRIGCALC int inttoerf(term t, term arg, term *next, char *reason)
/*�e^(-t^2) dt = ��/2 Erf(t) */
/*also �e^-(at^2) dt = ��/2 Erf(�a t) */
{ term a,x,c,v,temp,power;
int err;
if(FUNCTOR(t) != INTEGRAL)
return 1;
x = ARG(1,t);
if(FUNCTOR(ARG(0,t)) != '^')
return 1;
if(!equals(ARG(0,ARG(0,t)),eulere))
return 1;
power = ARG(1,ARG(0,t));
twoparts(power,x,&c,&v);
if (FUNCTOR(v)!='^' || !equals(ARG(0,v),x) || !equals(ARG(1,v),two))
return 1;
if(equals(c,minusone))
{ *next = product(make_fraction(sqrt1(pi),two),erf1(x));
strcpy(reason,"$�e^(-t^2)dt=��/2Erf(t)$");
goto out;
}
c = tnegate(c);
err = check(positive(c));
if(err)
{ errbuf(0, english(682)); /* Exponent must be negative */
return 1;
}
a = sqrt1(c);
err = value(a,&temp);
if(err==1) temp = a;
*next = product(make_fraction(sqrt1(pi),product(two,temp)),erf1(product(temp,x)));
strcpy(reason,"$�e^(-a^2t^2) dt$ = $��/(2a) Erf(at)$");
out:
if (ARITY(t)==4) /* a definite integral */
*next = evalat(*next,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*________________________________________________________________________*/
MEXPORT_TRIGCALC int inttoatanh(term t, term arg, term *next, char *reason)
/* �1/(a^2-t^2) dt = (1/a)arctanh(t/a) */
{ term u,x,a,b,temp;
int err;
if(FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t);
x = ARG(1,t);
err = matchstring(u,x,"/(1,+(b,-(^(x,2))))",&b);
if(err || depends(b,x))
return 1;
/* so now u = 1/(b - x^2) */
err = sqrt_aux(b,&a); /* see factor.c */
if(err)
return 1; /* the square root can't be taken */
if(ONE(a))
{ temp = atanh1(x);
strcpy(reason,"$�1/(1-t^2)dt=arctanh t$");
}
else
{ temp = product(make_fraction(one,a),atanh1(make_fraction(x,a)));
strcpy(reason,"$�1/(a^2-t^2) dt$ = (1/a)arctanh(t/a)");
}
if(ARITY(t) == 2) /* an indefinite integral */
*next = temp;
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*________________________________________________________________________*/
MEXPORT_TRIGCALC int inttoacoth(term t, term arg, term *next, char *reason)
/* �1/(t^2-a^2)dt=(1/a)arccoth(t/a) */
{ term u,x,a,b,temp;
int err;
if(FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t);
x = ARG(1,t);
err = matchstring(u,x,"/(1,+(b,^(x,2)))",&b);
if(err || depends(b,x))
return 1;
/* so now u = 1/(b + x^2) */
err = sqrt_aux(b,&a); /* see factor.c */
if(err)
return 1; /* the square root can't be taken */
if(ONE(a))
{ temp = atanh1(x);
strcpy(reason,"$�1/(1-t^2)dt=arctanh t$");
}
else
{ temp = product(make_fraction(one,a),atanh1(make_fraction(x,a)));
strcpy(reason,"$�1/(a^2-t^2) dt$ = (1/a)arctanh(t/a)");
}
if(ARITY(t) == 2) /* an indefinite integral */
*next = temp;
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*________________________________________________________________________*/
MEXPORT_TRIGCALC int inttolnratio1(term t, term arg, term *next, char *reason)
/* �1/(t^2-a^2)dt=(1/2a)ln |(t-a)/(t+a)| */
{ int err;
term x,a,b,asq,v,temp;
if(FUNCTOR(t) != INTEGRAL)
return 1;
x = ARG(1,t); /* variable of integration */
err = matchstring(ARG(0,t),x,"/(1,+(^(x,2),b))",&b);
if(err || depends(b,x))
return 1;
tneg(b,&asq);
err = sqrt_aux(asq,&a);
if(err)
return 1;
v = make_fraction(sum(x,tnegate(a)),sum(x,a));
temp = product(make_fraction(one,product(two,a)),ln1(abs1(v)));
strcpy(reason,"$�1/(t^2-a^2)dt$ = (1/2a)ln|(t-a)/(t+a)|");
if(ARITY(t) == 2) /* an indefinite integral */
{ SETPRIME(ARG(0,ARG(1,temp)));
/* mark the ABS term so prover won't
waste time trying to determine its sign */
*next = temp;
}
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*________________________________________________________________________*/
MEXPORT_TRIGCALC int inttolnratio2(term t, term arg, term *next, char *reason)
/* �1/(a^2-t^2)dt=(1/2a)ln|(t+a)/(a-t)| */
{ int err;
term x,a,asq,v,temp;
if(FUNCTOR(t) != INTEGRAL)
return 1;
x = ARG(1,t); /* variable of integration */
err = matchstring(ARG(0,t),x,"/(1,+(-(^(x,2)),a))",&asq);
if(err || depends(asq,x))
return 1;
err = sqrt_aux(asq,&a);
if(err)
return 1;
v = make_fraction(sum(x,a),sum(a,tnegate(x)));
temp = product(reciprocal(product(two,a)),ln1(abs1(v)));
strcpy(reason,"$�1/(t^2-a^2)dt$ = (1/2a)ln|(t+a)/(a-t)|");
if(ARITY(t) == 2) /* an indefinite integral */
{ SETPRIME(ARG(0,ARG(1,temp)));
/* Mark the abs term so prover won't waste time
trying to determine its sign */
*next = temp;
}
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*________________________________________________________________________*/
MEXPORT_TRIGCALC int inttolnratio3(term t, term arg, term *next, char *reason)
/* �1/�(t^2�c)dt)=ln |t+�(t^2�c)| */
{ int err;
term x,b,temp;
if(FUNCTOR(t) != INTEGRAL)
return 1;
x = ARG(1,t); /* variable of integration */
err = matchstring(ARG(0,t),x,"/(1,sqrt(+(^(x,2),b)))",&b);
if(err || depends(b,x))
return 1;
temp = ln1(abs1(sum(x,sqrt1(sum(make_power(x,two),b)))));
strcpy(reason,"$�1/�(t^2�c)dt)$ = $ln |t+�(t^2�c)|$");
if(ARITY(t) == 2) /* an indefinite integral */
{ SETPRIME(temp);
/* Mark the abs term so prover won't waste time
trying to determine its sign */
*next = temp;
}
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*________________________________________________________________________*/
MEXPORT_TRIGCALC int inttoacos(term t, term arg, term *next, char *reason)
/* �1/(t�(t^2-a^2))dt=(1/a)arccos(t/a) */
{ int err;
term x,a,b,asq,temp;
if(FUNCTOR(t) != INTEGRAL)
return 1;
x = ARG(1,t); /* variable of integration */
err = matchstring(ARG(0,t),x,"/(1,sqrt(+(^(x,2),b)))",&b);
if(err || depends(b,x))
return 1;
tneg(b,&asq);
err = sqrt_aux(asq,&a);
if(err)
return 1;
temp = product(reciprocal(a),acos1(make_fraction(x,a)));
strcpy(reason,"$�1/(t�(t^2-a^2))dt$ = (1/a)arccos(t/a)");
if(ARITY(t) == 2) /* an indefinite integral */
*next = temp;
else if (ARITY(t)==4) /* a definite integral */
*next = evalat(temp,x,ARG(2,t),ARG(3,t));
HIGHLIGHT(*next);
return 0;
}
/*_________________________________________________________________*/
static int sinsq_aux(term u, unsigned short f, term x, term *new)
/* substitute (1-cos(2x)/2) for sin^2 x (if f == SIN) or
(cos(2x)+1)/x for cos^2 x (if f == COS ) */
/* Return 0 if something is done that doesn't result in a
fractional exponent */
{ term target,v,twox,temp;
int err;
if(f!=SIN && f != COS)
return 1;
temp = product(two,x);
err = value(temp,&twox);
/* if x = 2t, don't leave cos(2�2t) but return cos(4t) */
if(err == 1)
twox = temp;
if(f==SIN)
{ target= make_power(sin1(x),two);
v = make_fraction(sum(one,tnegate(cos1(twox))),two);
}
else
{ target = make_power(cos1(x),two);
v = make_fraction(sum(cos1(twox),one),two);
}
HIGHLIGHT(v);
err = psubst(v,target,u,new);
if(err < 2 || equals(*new,u))
{ RELEASE(ARG(0,v));
RELEASE(v);
RELEASE(ARG(0,target));
RELEASE(target);
return 1;
}
return 0;
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsinsq(term t, term arg, term *next, char *reason)
/* sin^2 t = (1-cos 2t)/2 in integral */
{ term x,u,v,new2;
int err;
unsigned short path[MAXTAIL];
if(FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t);
if(!contains_arg(u,SIN,&x))
return 1;
err = sinsq_aux(u,SIN,x,&new2);
if(err)
return 1;
path[0] = INTEGRAL;
path[1] = 1;
path_to_difference(u,new2,path+2,1);
subterm_at_path(u,path+2,&v);
if(FUNCTOR(v) == '^' && FUNCTOR(ARG(0,v)) == SIN)
{ set_pathtail(path);
SetShowStepOperation(sinsqhalf2);
}
*next = ARITY(t)==2 ? integral(new2,ARG(1,t)): definite_integral(new2,ARG(1,t),ARG(2,t),ARG(3,t));
strcpy(reason,"sin^2 t = (1-cos 2t)/2");
return 0;
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intcossq(term t, term arg, term *next, char *reason)
/* cos^2 t =(1+cos 2t)/2 in integral */
{ term x,u,v,new2;
int err;
unsigned short path[MAXTAIL];
if(FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t);
if(!contains_arg(u,COS,&x))
return 1;
err = sinsq_aux(u,COS,x,&new2);
if(err)
return 1;
path[0] = INTEGRAL;
path[1] = 1;
path_to_difference(u,new2,path+2,1);
subterm_at_path(u,path+2,&v);
if(FUNCTOR(v) == '^' && FUNCTOR(ARG(0,v)) == COS)
{ set_pathtail(path);
SetShowStepOperation(cossqhalf2);
}
*next = ARITY(t)==2 ? integral(new2,ARG(1,t)): definite_integral(new2,ARG(1,t),ARG(2,t),ARG(3,t));
strcpy(reason,"cos^2 t = (1+cos 2t)/2");
return 0;
}
/*_________________________________________________________________*/
static int intsubsin_aux(unsigned short f, term t, term arg, term *next, char *reason)
/* f will be SIN, COS, TAN, SEC, COT, or CSC; does the work of the
next four operators below */
{ term u,x,w,c,v,q;
unsigned short g;
if(FUNCTOR(t) != INTEGRAL)
return 1;
x = ARG(1,t); /* variable of integration */
u = ARG(0,t); /* the integrand */
switch(f)
{ case SIN: g = COS; break;
case COS: g = SIN; break;
case TAN: g = SEC; break;
case SEC: g = TAN; break;
case COT: g = CSC; break;
case CSC: g = COT; break;
}
/* reciprocal of sin or cos */
if(FRACTION(u) && ONE(ARG(0,u)) && (f == SIN || f == COS) &&
FUNCTOR(ARG(1,u)) == g /* on 1/sin x use u = cos x */
)
{ w = ARG(0,ARG(1,u));
twoparts(w,x,&c,&v);
if(!equals(v,x))
return 1; /* sin(2x) or sin(x/2) acceptable but not sin(x^2) */
goto out;
}
/* reciprocals of odd powers of sin or cos */
if(FRACTION(u) && ONE(ARG(0,u)) && (f == SIN || f == COS) &&
FUNCTOR(ARG(1,u)) == '^' && FUNCTOR(ARG(0,ARG(1,u))) == g &&
(
(INTEGERP(ARG(1,ARG(1,u))) && ISODD(ARG(1,ARG(1,u)))) ||
isodd(ARG(1,ARG(1,u)))
)
)
{ w = ARG(0,ARG(0,ARG(1,u)));
twoparts(w,x,&c,&v);
if(!equals(v,x))
return 1; /* sin(2x) or sin(x/2) acceptable but not sin(x^2) */
goto out;
}
else if(!contains_arg(t,f,&w))
{ if(!contains_arg(t,g,&w))
return 1; /* fail quickly if it can't be relevant */
}
/* Now w is the arg of the trig function */
twoparts(w,x,&c,&v);
if(!equals(v,x))
return 1; /* sin(2x) or sin(x/2) acceptable but not sin(x^2) */
out:
u = getnewvar(t,"uvwsxyzt"); /* adds u to varlist */
if(FUNCTOR(u)==ILLEGAL)
{ errbuf(0, english(1448));
/* Too many subscripted variables, can't make more. */
return 1;
}
q = make_term(f,1);
ARGREP(q,0,w);
arg = equation(u,q);
return intsub(t,arg,next,reason); /* psubst knows enough trig to handle it! */
/* if intsub fails it takes u out of varlist again */
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsubsin(term t, term arg, term *next, char *reason)
/* u=sin x after using sin^2=1-cos^2 */
/* In auto mode, sin occurs to an odd power or intsinsq would have worked. */
/* The integrand must be a product, and after cancelling one power of sin(x),
intsinsq must work on the rest. */
{ return intsubsin_aux(SIN,t,arg, next,reason);
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsubcos(term t, term arg, term *next, char *reason)
/* u=cos x after using cos^2=1-sin^2 */
{ return intsubsin_aux(COS,t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsubtan(term t, term arg, term *next, char *reason)
/* u=tan x after using sec^2=1+tan^2 */
{ return intsubsin_aux(TAN,t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsubcot(term t, term arg, term *next, char *reason)
/* u=cot x after using csc^2=1+cot^2 */
{ return intsubsin_aux(COT,t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsubsec(term t, term arg, term *next, char *reason)
/* u=sec x after using tan^2=sec^2-1 */
{ return intsubsin_aux(SEC,t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsubcsc(term t, term arg, term *next, char *reason)
/* u=csc x after using cot^2=csc^2-1 */
{ return intsubsin_aux(SEC,t,arg,next,reason);
}
/*_________________________________________________________________*/
static int contains_arg(term t, unsigned short f, term *x)
/* if t contains a term f(v), instantiate *x to v and return 1;
if t contains no such subterm, return 0. f must be a unary functor. */
{ int i;
unsigned short n;
if(ATOMIC(t))
return 0;
n = ARITY(t);
if(n==1 && FUNCTOR(t) == f)
{ *x = ARG(0,t);
return 1;
}
for(i=0;i<n;++i)
{ if( contains_arg(ARG(i,t),f,x))
return 1;
}
return 0;
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int tantosecinint(term t, term arg, term *next, char *reason)
/* use tan^2 = sec^2-1 in integrand after saving out tan x sec x,
if possible, but if not possible, use the identity anyway. */
{ term u,v,w,q,p,s,tansq;
int r;
if (FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t); /* the integrand */
if(!contains_arg(u,TAN,&v))
return 1;
if(!equals(v,ARG(1,t)))
{ errbuf(0, english(1432));
/* Argument of tan must be the variable of integration */
return 1;
}
s = product(sec1(v),tan1(v));
polyval(make_fraction(u,s),&p);
q = sum(make_power(sec1(v),two),minusone);
HIGHLIGHT(q);
PROTECT(q);
tansq = make_power(tan1(v),two);
r= psubst(q,tansq,p,&w);
if(r <= 1)
{ /* It doesn't go. Forget about saving out tan x sec x */
r = psubst(q,tansq,u,&w);
if(r <= 1)
return 1;
}
else
polyval(product(w,s),&w);
*next = ARITY(t)==2 ? integral(w,ARG(1,t)) : definite_integral(w,ARG(1,t),ARG(2,t),ARG(3,t));
strcpy(reason,"$tan^2 u = sec^2u - 1$");
return 0;
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int cottocscinint(term t, term arg, term *next, char *reason)
/* use cot^2 = csc^2-1 in integrand after saving out csc x csc x, if
possible, but if not possible, use the identity anyway.
*/
{ term u,v,w,q,p,s,cotsq;
int r;
if (FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t); /* the integrand */
if(!contains_arg(u,TAN,&v))
return 1;
if(!equals(v,ARG(1,t)))
{ errbuf(0, english(1432));
/* Argument of tan must be the variable of integration */
return 1;
}
s = product(csc1(v),cot1(v));
polyval(make_fraction(u,s),&p);
q = sum(make_power(csc1(v),two),minusone);
HIGHLIGHT(q);
PROTECT(q);
cotsq = make_power(cot1(v),two);
r= psubst(q,cotsq,p,&w);
if(r <= 1)
{ /* It doesn't go. Forget about saving out cot x csc x */
r = psubst(q,cotsq,u,&w);
if(r <= 1)
return 1;
}
else
polyval(product(w,s),&w);
*next = ARITY(t)==2 ? integral(w,ARG(1,t)) : definite_integral(w,ARG(1,t),ARG(2,t),ARG(3,t));
strcpy(reason,"$cot^2 u = csc^2u - 1$");
return 0;
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intsecpower(term t, term arg, term *next, char *reason)
/* reduction formula for integrating sec� x;
needed for odd n -- even n can be done by substituting u = tan x */
{ term u,x,uv,a,b,n,nminusone,nminustwo,reduced;
int err;
if (FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t); /* the integrand */
x = ARG(1,t); /* variable of integration */
err = matchstring(u,x,"^(sec(x),a)",&n);
if(err || depends(n,x))
return 1;
err = infer(type(n,INTEGER));
if(err)
{ errbuf(0, english(683));
/* exponent of sec must be an integer */
return 1;
}
err = check(lessthan(two,n));
if(err)
{ errbuf(0, english(684));
/* exponent must be at least 3 */
return 1;
}
a = sum(n,minusone);
b = sum(n,tnegate(two));
err = value(a,&nminusone);
if(err==1)
nminusone=a;
err = value(b,&nminustwo);
if(err==1)
nminustwo=b;
uv = product3(reciprocal(nminusone),make_power(sec1(x),nminustwo),tan1(x));
reduced = ARITY(t)==2 ?
integral(make_power(sec1(x),nminustwo),x) :
definite_integral(make_power(sec1(x),nminustwo),x,ARG(2,t),ARG(3,t));
b = product(make_fraction(nminustwo,nminusone),reduced);
if(ARITY(t)==2)
a = uv;
else
a = evalat(uv,x,ARG(2,t),ARG(3,t));
*next = sum(a,b);
HIGHLIGHT(*next);
strcpy(reason, english(685)); /* reduce �sec� t dt */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_TRIGCALC int intcscpower(term t, term arg, term *next, char *reason)
/* reduction formula for integrating csc� x;
needed for odd n -- even n can be done by substituting u = tan x */
{ term u,x,uv,a,b,n,nminusone,nminustwo,reduced;
int err;
if (FUNCTOR(t) != INTEGRAL)
return 1;
u = ARG(0,t); /* the integrand */
x = ARG(1,t); /* variable of integration */
err = matchstring(u,x,"^(csc(x),a)",&n);
if(err || depends(n,x))
return 1;
err = infer(type(n,INTEGER));
if(err)
{ errbuf(0, english(1433));
/* Exponent of csc must be an integer */
return 1;
}
err = check(lessthan(two,n));
if(err)
{ errbuf(0, english(684));
/* exponent must be at least 3 */
return 1;
}
a = sum(n,minusone);
b = sum(n,tnegate(two));
err = value(a,&nminusone);
if(err==1)
nminusone=a;
err = value(b,&nminustwo);
if(err==1)
nminustwo=b;
uv = tnegate(product3(reciprocal(nminusone),make_power(csc1(x),nminustwo),cot1(x)));
reduced = ARITY(t)==2 ?
integral(make_power(csc1(x),nminustwo),x) :
definite_integral(make_power(csc1(x),nminustwo),x,ARG(2,t),ARG(3,t));
b = product(make_fraction(nminustwo,nminusone),reduced);
if(ARITY(t)==2)
a = uv;
else
a = evalat(uv,x,ARG(2,t),ARG(3,t));
*next = sum(a,b);
HIGHLIGHT(*next);
strcpy(reason, english(1434)); /* reduce �csc� t dt */
return 0;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists