PROGRAM DERIVE;

USES RPN,ALGEBRA;

TYPE ELT=RECORD S,D:STRING; END;
     TBL=ARRAY[1..40] OF ELT;

VAR  PILE:^TBL;

CONST
       NB_FONC=16 ;
       FNR:ARRAY[1..16] OF STRING=('EXP',
'SQR','SQRT','LN','SIN','COS','TAN','ASIN','ACOS','ATAN',
                  'SINH','COSH','TANH','ASINH','ACOSH','ATANH');

      DER:ARRAY[1..16] OF STRING=('EXP x',
'2*x','1/(2*SQRT(x))','1/x','COS(x)','(-SIN(x))','1+(TAN(x))^2',
'1/SQRT(1-x^2)','(-1/SQRT(1-x^2))','1/(1+x^2)',
'COSH(x)','SINH(x)','1/(COSH(x))^2','1/SQRT(1+x^2)','1/SQRT(x^2-1)','1/(1-x^2)');

PROCEDURE RMPL(A,B:STRING;VAR R:STRING);
 VAR I:BYTE;
 BEGIN
  R:='';
  FOR I:=1 TO LENGTH(A) DO IF A[I]='x'
   THEN
    IF ((A[I-1]='(') AND (A[I+1]=')')) OR SIMPLE(B)
     THEN R:=R+B ELSE R:=R+'('+B+')'
   ELSE R:=R+A[I];
 END;

PROCEDURE MUL(A,B:STRING;VAR R:STRING);
 BEGIN
  IF (A='0') OR (B='0') THEN R:='0' ELSE
  IF (A='1') AND (B='1') THEN R:='1' ELSE
  IF A='1' THEN R:=B ELSE
  IF B='1' THEN R:=A ELSE
   BEGIN
    IF NOT SIMPLE(A) THEN A:='('+A+')';
    IF NOT SIMPLE(B) THEN B:='('+B+')';
    R:=A+'*'+B;
   END;
 END;

PROCEDURE PLUS(VAR A,B,R:STRING);
 BEGIN
  IF (A='0') AND (B='0') THEN R:='0' ELSE
  IF A='0' THEN R:=B ELSE
  IF B='0' THEN R:=A ELSE
  R:=A+'+'+B;
 END;

PROCEDURE MOINS(VAR A,B,R:STRING);
 BEGIN
  IF (A='0') AND (B='0') THEN R:='0' ELSE
  IF A='0' THEN R:='-'+B ELSE
  IF B='0' THEN R:=A ELSE
  R:=A+'-'+B;
 END;

PROCEDURE SUR(A,B:STRING;VAR R:STRING);
 BEGIN
  IF (A='0') THEN R:='0' ELSE
   BEGIN
    IF NOT SIMPLE(A) THEN A:='('+A+')';
    IF NOT SIMPLE(B) THEN B:='('+B+')';
    R:=A+'/'+B;
   END;
 END;

PROCEDURE PUIS(A,B:STRING;VAR R:STRING);
 BEGIN
  IF (B='0') OR (A='1') THEN R:='1' ELSE
  IF (A='0') THEN R:='0' ELSE
  IF B='1' THEN R:=A ELSE
   BEGIN
    IF NOT SIMPLE(A) THEN A:='('+A+')';
    IF NOT SIMPLE(B) THEN B:='('+B+')';
    R:=A+'^'+B;
   END;
 END;

FUNCTION ENCORE(VAR DANS,VERS:STRING):BOOLEAN;
VAR R:BOOLEAN;
 BEGIN
  VERS:='';
  WHILE (DANS[0]<>#0) AND (DANS[1]=' ') DO DELETE(DANS,1,1);
  WHILE (DANS[0]<>#0) AND (DANS[1]<>' ') DO
   BEGIN
    VERS:=VERS+DANS[1];
    DELETE(DANS,1,1)
    END;
  ENCORE:=VERS<>'';
 END;

PROCEDURE DERIVATION(EXPR,DER_DE:STRING) ;
 VAR I,J,PC:WORD;
     A,B,C,D,E,CH:STRING;
     PS:ELT;
      R:REAL;

  BEGIN
   PC:=0;
   WHILE ENCORE(EXPR,CH) DO
    BEGIN
     IF CH=DER_DE
      THEN
       BEGIN
        INC(PC);
        PILE^[PC].S:=DER_DE;
        PILE^[PC].D:='1';
       END ELSE
      IF CH='+' THEN
       BEGIN
        PLUS(PILE^[PC-1].S,PILE^[PC].S,PS.S);
        PLUS(PILE^[PC-1].D,PILE^[PC].D,PS.D);
        DEC(PC);
        PILE^[PC]:=PS;
       END ELSE
      IF CH='-' THEN
       BEGIN
        MOINS(PILE^[PC-1].S,PILE^[PC].S,PS.S);
        MOINS(PILE^[PC-1].D,PILE^[PC].D,PS.D);
        DEC(PC);
        PILE^[PC]:=PS;
       END ELSE
      IF CH='*' THEN
       BEGIN
        MUL(PILE^[PC-1].S,PILE^[PC].S,PS.S);
        MUL(PILE^[PC-1].D,PILE^[PC].S,A);
        MUL(PILE^[PC-1].S,PILE^[PC].D,B);
        PLUS(A,B,PS.D);
        DEC(PC);
        PILE^[PC]:=PS;
       END ELSE
      IF CH='/' THEN
       BEGIN
        SUR(PILE^[PC-1].S,PILE^[PC].S,PS.S);
        MUL(PILE^[PC-1].D,PILE^[PC].S,A);
        MUL(PILE^[PC-1].S,PILE^[PC].D,B);
        MOINS(A,B,C);
        PS.D:='('+C+')/SQR('+PILE^[PC].S+')';
        DEC(PC);
        PILE^[PC]:=PS;
       END ELSE
      IF CH='^' THEN
       BEGIN
        IF PILE^[PC].D='0' THEN
         BEGIN
          IF NOMBRE(PILE^[PC].S,R)
           THEN
            BEGIN
             A:=EXP_PUIS(PILE^[PC-1].S,R-1,TRUE);
             B:=A;
             MUL(PILE^[PC].S,B,A);
             MUL(PILE^[PC-1].D,A,B);
             C:=EXP_PUIS(PILE^[PC-1].S,R,TRUE);
            END
           ELSE
            BEGIN
             B:='1';
             MOINS(PILE^[PC].S,B,A);
             PUIS(PILE^[PC-1].S,A,B);
             MUL(PILE^[PC].S,B,A);
             MUL(PILE^[PC-1].D,A,B);
             PUIS(PILE^[PC-1].S,PILE^[PC].S,C);
            END;

          DEC(PC);
          PILE^[PC].S:=C;
          PILE^[PC].D:=B
         END ELSE
          BEGIN
             B:='1';
             MOINS(PILE^[PC].S,B,A);
             PUIS(PILE^[PC-1].S,A,B);
             MUL(PILE^[PC].S,B,A);
             MUL(PILE^[PC-1].D,A,B);
             PUIS(PILE^[PC-1].S,PILE^[PC].S,C);
             MUL(PILE^[PC].D,C,A);
             RMPL('LN(x)',PILE^[PC-1].S,D);
             MUL(D,A,E);
             PLUS(B,E,A);
            DEC(PC);
            PILE^[PC].S:=C;
            PILE^[PC].D:=A

          END;

         END ELSE
       IF CH[1]='~' THEN
        BEGIN
         J:=1;
         DELETE(CH,1,1);
         WHILE (J<NB_FONC) AND (FNR[J]<>CH) DO INC(J);
         A:=DER[J];
         RMPL(A,PILE^[PC].S,B);
         MUL(PILE^[PC].D,B,C);
         PILE^[PC].S:=CH+'('+PILE^[PC].S+')';
         PILE^[PC].D:=C;
        END ELSE

       BEGIN
        INC(PC);
        PILE^[PC].S:=CH;
        PILE^[PC].D:='0'
       END;
  END;
    END;

PROCEDURE DIFF(EXPRESSION,_VARIABLE:STRING;VAR RESULT:STRING);
VAR EX:EXPRESS;
 BEGIN
  CONSTRUIT_ARBRE(EXPRESSION,EX);
  EXPRESSION:='';
  TO_RPN(EX,EXPRESSION);
  KILL(EX);
  NEW(PILE);
  FILLCHAR(PILE^,SIZEOF(PILE^),0);
  DERIVATION(EXPRESSION,_VARIABLE);
  RESULT:=PILE^[1].D;
  DISPOSE(PILE)
 END;

VAR S:STRING;

BEGIN
 WRITELN;
 READLN(S);
 DIFF(S,'X',S);
 WRITELN(S);
END.
