/*-*-MACSYMA-*-*/ /*Code added 7/5/80 by ELL for mapping all trig and hyper trig functions into sin and cos (in lower case)*/ /* 4:00pm Tuesday, 11 August 1981 -GJC Added more eval_when conditionals to complement the improvement in Defrule translation and to invoke TRANSCOMPILE. 11/20/83 11:08:42 reformatting and some streamlining for translation. -asb */ EVAL_WHEN([TRANSLATE], TRANSCOMPILE:TRUE, TR_BOUND_FUNCTION_APPLYP:FALSE, MODE_DECLARE(FUNCTION(EXPNLENGTH,ARGSLENGTH),FIXNUM))$ /* Variable definitions */ DEFINE_VARIABLE(BESTLENGTH,0,FIXNUM)$ DEFINE_VARIABLE(TRYLENGTH,0,FIXNUM)$ /* Properties */ /* The following properties are used to implement the four identities: FOO^2=GET(FOO,'UNITCOF) +GET(FOO,'COMPLEMENT_COF)*GET(FOO,'COMPLEMENT_FUNCTION)^2*/ PUT('SIN,'COS,'COMPLEMENT_FUNCTION)$ PUT('COS,'SIN,'COMPLEMENT_FUNCTION)$ PUT('SINH,'COSH,'COMPLEMENT_FUNCTION)$ PUT('COSH,'SINH,'COMPLEMENT_FUNCTION)$ PUT('COS,1,'UNITCOF)$ PUT('SIN,1,'UNITCOF)$ PUT('COSH,1,'UNITCOF)$ PUT('SINH,-1,'UNITCOF)$ PUT('COS,-1,'COMPLEMENT_COF)$ PUT('SIN,-1,'COMPLEMENT_COF)$ PUT('COSH,1,'COMPLEMENT_COF)$ PUT('SINH,1,'COMPLEMENT_COF)$ PUT('SIN,'TRIGONOMETRIC,'TYPE)$ PUT('COS,'TRIGONOMETRIC,'TYPE)$ PUT('SINH,'HYPER_TRIGONOMETRIC,'TYPE)$ PUT('COSH,'HYPER_TRIGONOMETRIC,'TYPE)$ /* Declarations */ EVAL_WHEN([TRANSLATE,BATCH,DEMO], MATCHDECLARE(A,TRUE))$ /* Predicates */ TRIGONOMETRICP(EXP):= IS(GET(INPART(EXP,0),'TYPE)='TRIGONOMETRIC OR GET(PIECE,'TYPE)='HYPER_TRIGONOMETRIC)$ /* Rules */ DEFRULE(TRIGRULE1,TAN(A),SIN(A)/COS(A))$ DEFRULE(TRIGRULE2,SEC(A),1/COS(A))$ DEFRULE(TRIGRULE3,CSC(A),1/SIN(A))$ DEFRULE(TRIGRULE4,COT(A),COS(A)/SIN(A))$ DEFRULE(HTRIGRULE1,TANH(A),SINH(A)/COSH(A))$ DEFRULE(HTRIGRULE2,SECH(A),1/COSH(A))$ DEFRULE(HTRIGRULE3,CSCH(A),1/SINH(A))$ DEFRULE(HTRIGRULE4,COTH(A),COSH(A)/SINH(A))$ /* Functions */ TRIGSIMP(X):= TRIGSIMP3(RADCAN(APPLY1(X, TRIGRULE1,TRIGRULE2,TRIGRULE3,TRIGRULE4, HTRIGRULE1,HTRIGRULE2,HTRIGRULE3,HTRIGRULE4)))$ TRIGSIMP3(EXPN):= (EXPN:TOTALDISREP(EXPN), RATSIMP(TRIGSIMP1(NUM(EXPN))/TRIGSIMP1(DENOM(EXPN)))) $ TRIGSIMP1(EXPN):=BLOCK( [LISTOFTRIGSQ, BESTLENGTH, TRYLENGTH], LISTOFTRIGSQ: LISTOFTRIGSQ(EXPN), BESTLENGTH: 999999, IF LISTOFTRIGSQ#[] THEN IMPROVE(EXPN,EXPN,LISTOFTRIGSQ) ELSE EXPN)$ IMPROVE(EXPN,SUBSOFAR,LISTOFTRIGSQ):= IF LISTOFTRIGSQ=[] THEN (IF (TRYLENGTH:EXPNLENGTH(SUBSOFAR))=2 THEN IF ATOM(EXPN:INPART(EXPN,1)) THEN RETURN([]) ELSE IF TRIGONOMETRICP(EXPN) THEN RETURN([[EXPN]]), INFLAG:TRUE, FOR ARG IN EXPN DO ANS:SPECIALUNION(LISTOFTRIGSQ(ARG),ANS), ANS)$ SPECIALUNION(LIST1,LIST2):= IF LIST1=[] THEN LIST2 ELSE IF LIST2=[] THEN LIST1 ELSE BLOCK([ALTERNATES:FIRST(LIST1)], FOR ALT IN ALTERNATES DO LIST2:UPDATE(ALT,GET(INPART(ALT,0),'COMPLEMENT_FUNCTION)), SPECIALUNION(REST(LIST1),LIST2))$ DECLARE(LIST2,SPECIAL)$ UPDATE(FORM, COMPLEMENT):=BLOCK( [ANS], DECLARE(ANS,SPECIAL), COMPLEMENT: APPLY(COMPLEMENT,[INPART(FORM,1)]), ANS: FOR ELEMENT IN LIST2 DO IF MEMBER(FORM, ELEMENT) THEN RETURN('FOUND) ELSE IF MEMBER(COMPLEMENT,ELEMENT) THEN RETURN( CONS([FORM,COMPLEMENT], DELETE(ELEMENT,LIST2))), IF ANS='FOUND THEN LIST2 ELSE IF ANS='DONE THEN CONS([FORM],LIST2) ELSE ANS)$ EXPNLENGTH(EXPR):=BLOCK( [INFLAG:TRUE], IF ATOM(EXPR) THEN 1 ELSE 1+ARGSLENGTH(ARGS(EXPR)))$ ARGSLENGTH(ARGS):= APPLY("+",MAP('EXPNLENGTH,ARGS))$