Navigation  without Java Scripts

/*****************************************************************************

        Copyright (c) My Company

Project: DIFF
FileName: DIFF.PRO
Purpose: No description
Written by: Visual Prolog
Comments:
******************************************************************************/
include "cgiexam.inc"

DOMAINS
TOKL = STRING*
EXP = var(STRING); int(INTEGER); plus(EXP,EXP); minus(EXP,EXP); mult(EXP,EXP);
    div(EXP,EXP); ln(EXP); cos(EXP); sin(EXP); tan(EXP); sec(EXP); potens(EXP,EXP)

PREDICATES
% Scanner
tokl(STRING,TOKL);
front(STRING,TOKL,TOKL);

% Parser
s_exp(TOKL,TOKL,EXP);
potensexp(TOKL,TOKL,EXP);
potensexp1(TOKL,TOKL,EXP,EXP);
multexp(TOKL,TOKL,EXP);
multexp1(TOKL,TOKL,EXP,EXP);
plusexp(TOKL,TOKL,EXP);
plusexp1(TOKL,TOKL,EXP,EXP);
elmexp(TOKL,TOKL,EXP);

% Differentiate
d(EXP,STRING,EXP);

%Reducer
reduce(EXP,EXP);
plusr(EXP,EXP,EXP);
minusr(EXP,EXP,EXP);
multr(EXP,EXP,EXP);
divr(EXP,EXP,EXP);
lnr(EXP,EXP)

% Convert expression to string
strexp(EXP,string);
strPOTENS(EXP,string);
strMULT(EXP,string);
strMINUS(EXP,string);
strDIV(EXP,string);
strPAR(EXP,string);

writeexp(EXP)

PREDICATES
nondeterm member(parm,parmlist)
runme(parmlist)
CLAUSES
member (X,[X|_]).
member (X,[_|Y]):-member(X,Y).
   
runme(Parmlist) :-
    member (parm("exp",STR),ParmList),
    tokl(STR,TOKL),
    s_exp(TOKL,OL,EXP), OL = [],
    d(EXP,"x",EXP1),
    write("<p><b>Differentiated expression:</b><br>\n"),
    writeexp(EXP1),
    write("<p><b>Reduced expression:</b><br>\n"),
    reduce(EXP1,EXP2),
    writeexp(EXP2).
runme (_) :-
    write ("<p>Error while executing Diff.exe\n").

GOAL
write("Content-type: text/html\n\n"),
write("<html>\n"),
write("<body>\n"),
    ParmList = cgi_GetParmList(),
    runme(ParmList),
    write("</body>\n"),
    write("</html>\n").

CLAUSES

/******************************************************
CLAUSES FOR DIFFERENTIATION
******************************************************/
d(int(_),_,int(0)).
d(var(X),X,int(1)):-!.
d(var(_),_,int(0)).
d(plus(U,V),X,plus(U1,V1)):-
    d(U,X,U1),
    d(V,X,V1).
d(minus(U,V),X,minus(U1,V1)):-
    d(U,X,U1),
    d(V,X,V1).
d(mult(U,V),X,plus(mult(U1,V),mult(U,V1))):-
    d(U,X,U1),
    d(V,X,V1).
d(div(U,V),X,div(minus(mult(U1,V),mult(U,V1)),mult(V,V))):-
    d(U,X,U1),
    d(V,X,V1).
d(ln(U),X,mult(div(int(1),U),U1)):-d(U,X,U1).
d(potens(E1,int(I)),X,mult(mult(int(I),potens(E1,int(I1))),EXP)):-
    I1=I-1,
    d(E1,X,EXP).
d(sin(U),X,mult(cos(U),U1)):-d(U,X,U1).
d(cos(U),X,minus(int(0),mult(sin(U),U1))):-d(U,X,U1).
d(tan(U),X,mult(potens(sec(U),int(2)),U1)):-d(U,X,U1).


/******************************************************
CLAUSES FOR SCANNING THE STRING
******************************************************/
tokl(STR,[TOK|TOKL]):-
    fronttoken(STR,TOK,STR1),!,
    tokl(STR1,TOKL).
tokl(_,[]).


/******************************************************
CLAUSES FOR PARSING OF AN EXPRESSION
******************************************************/
s_exp(IL,OL,EXP):-plusexp(IL,OL,EXP).

plusexp(IL,OL,EXP2):-
    multexp(IL,OL1,EXP1),
    plusexp1(OL1,OL,EXP1,EXP2).

plusexp1(["+"|IL],OL,EXP1,EXP3):-!,
    multexp(IL,OL1,EXP2),
    plusexp1(OL1,OL,plus(EXP1,EXP2),EXP3).
plusexp1(["-"|IL],OL,EXP1,EXP3):-!,
    multexp(IL,OL1,EXP2),
    plusexp1(OL1,OL,minus(EXP1,EXP2),EXP3).
plusexp1(IL,IL,EXP,EXP).

multexp(IL,OL,EXP2):-
    potensexp(IL,OL1,EXP1),
    multexp1(OL1,OL,EXP1,EXP2).

multexp1(["*"|IL],OL,EXP1,EXP3):-!,
    potensexp(IL,OL1,EXP2),
    multexp1(OL1,OL,mult(EXP1,EXP2),EXP3).
multexp1(["/"|IL],OL,EXP1,EXP3):-!,
    potensexp(IL,OL1,EXP2),
    multexp1(OL1,OL,div(EXP1,EXP2),EXP3).
multexp1(IL,IL,EXP,EXP).

potensexp(IL,OL,EXP2):-
    elmexp(IL,OL1,EXP1),
    potensexp1(OL1,OL,EXP1,EXP2),!.
potensexp1(["^"|IL],OL,EXP1,EXP3):-!,
    elmexp(IL,OL1,EXP2),
    potensexp1(OL1,OL,potens(EXP1,EXP2),EXP3).
potensexp1(IL,IL,EXP,EXP).

elmexp(["("|IL],OL,EXP):-
    s_exp(IL,OL1,EXP),
    front(")",OL1,OL),!.
elmexp(["ln","("|IL],OL,ln(EXP)):-
    s_exp(IL,OL1,EXP),
    front(")",OL1,OL),!.
elmexp(["sin","("|IL],OL,sin(EXP)):-
    s_exp(IL,OL1,EXP),
    front(")",OL1,OL),!.
elmexp(["cos","("|IL],OL,cos(EXP)):-
    s_exp(IL,OL1,EXP),
    front(")",OL1,OL),!.
elmexp(["tan","("|IL],OL,tan(EXP)):-
    s_exp(IL,OL1,EXP),
    front(")",OL1,OL),!.
elmexp(["-",TALSTR|IL],IL,int(INT)):-!,
    str_int(TALSTR,INTp),
    INT = -INTp.
elmexp([TALSTR|IL],IL,int(INT)):-str_int(TALSTR,INT),!.
elmexp([NAME|IL],IL,var(NAME)).

front(TOK,[TOK|L],L).


/******************************************************
CLAUSES FOR REDUCTION OF AN EXPRESSION
******************************************************/
reduce(plus(X,Y),R):-!,
    reduce(X,X1),
    reduce(Y,Y1),
    plusr(X1,Y1,R).
reduce(minus(X,Y),R):-!,
    reduce(X,X1),
    reduce(Y,Y1),
    minusr(X1,Y1,R).
reduce(mult(X,Y),R):-!,
    reduce(X,X1),
    reduce(Y,Y1),
    multr(X1,Y1,R).
reduce(div(X,Y),R):-!,
    reduce(X,X1),
    reduce(Y,Y1),
    divr(X1,Y1,R).
reduce(ln(X),R):-!,
    reduce(X,X1),
    lnr(X1,R).
reduce(potens(E,int(1)),E):-!.
reduce(R,R).

% CLAUSES FOR REDUCTION OF AN ADDITION EXPRESSION
plusr(int(0),X,X):-!.
plusr(X,int(0),X):-!.
plusr(int(X),int(Y),int(Z)):-!,
    X+Y=Z.
plusr(X,X,mult(int(2),X)):-!.
plusr(int(X),Y,Z):-
    X<0,
    T=-X,!,
    minusr(int(T),Y,Z).
plusr(Y,int(X),Z):-
    X<0,
    T=-X,!,
    minusr(int(T),Y,Z).
plusr(mult(int(I),X),X,mult(int(I1),X)):-!,
    I+1=I1.
plusr(X,mult(int(I),X),mult(int(I1),X)):-!,
    I+1=I1.
plusr(mult(int(I1),X),mult(int(I2),X),mult(int(I3),X)):-!,
    I1+I2=I3.
plusr(int(I),X,plus(X,int(I))):-!.
plusr(plus(X,int(I1)),int(I2),plus(X,int(I3))):-!,
    I1+I2=I3.
plusr(plus(X,int(I1)),plus(Y,int(I2)),plus(R,int(I3))):-!,
    I1+I2=I3,
    plusr(X,Y,R).
plusr(plus(X,int(I)),Y,plus(R,int(I))):-!,
    plusr(X,Y,R).
plusr(X,Y,plus(X,Y)).

% CLAUSES FOR REDUCTION OF A MINUS EXPRESSION
minusr(int(X),int(Y),int(Z)):-!,Z=X-Y.
minusr(X,int(0),X):-!.
minusr(X,X,int(0)):-!.
minusr(X,int(I),plus(int(I1),X)):-!,I1=-I.
minusr(X,Y,minus(X,Y)).

% CLAUSES FOR REDUCTION OF A MULTIPLICATION EXPRESSION
multr(int(X),int(Y),int(Z)):-!,X*Y=Z.
multr(int(0),_,int(0)):-!.
multr(_,int(0),int(0)):-!.
multr(int(1),X,X):-!.
multr(X,int(1),X):-!.
multr(M,plus(X,Y),plus(X1,Y1)):-!,
    multr(M,X,X1),multr(M,Y,Y1).
multr(M,minus(X,Y),minus(X1,Y1)):-!,
    multr(M,X,X1),multr(M,Y,Y1).
multr(plus(X,Y),M,plus(X1,Y1)):-!,
    multr(M,X,X1),multr(M,Y,Y1).
multr(minus(X,Y),M,minus(X1,Y1)):-!,
    multr(M,X,X1),multr(M,Y,Y1).
multr(mult(int(I1),X),int(I2),M1):-!,
    I1*I2=I3,
    multr(int(I3),X,M1).
multr(int(I1),mult(int(I2),X),M1):-!,
    I1*I2=I3,
    multr(int(I3),X,M1).
multr(mult(int(I1),X),mult(int(I2),Y),mult(int(I3),R)):-!,
    I1*I2=I3,
    multr(X,Y,R).
multr(mult(int(I),X),Y,mult(int(I),R)):-!,
    multr(X,Y,R).
multr(X,int(I),mult(int(I),X)):-!.
multr(potens(X,int(I1)),potens(X,int(I2)),potens(X,int(I3))):-!,
    I3=I1+I2.
multr(X,potens(X,int(I)),potens(X,int(I1))):-!,
    I1=I+1.
multr(potens(X,int(I)),X,potens(X,int(I1))):-!,
    I1=I+1.
multr(X,X,potens(X,int(2))):-!.
multr(X,Y,mult(X,Y)).

% CLAUSES FOR REDUCTION OF A DIVISION EXPRESION
divr(int(0),_,int(0)):-!.
divr(_,int(0),var("'endless'")):-!,write("division by zero"),nl.
divr(X,int(1),X):-!.
divr(X,Y,div(X,Y)).

% CLAUSES FOR REDUCTION OF A LOGARITHM EXPRESSION
lnr(int(0),var("endless")):-!,write("logarithm error"),nl.
lnr(int(1),int(0)):-!.
lnr(X,ln(X)).



/******************************************************
CLAUSE FOR WRITING OF AN EXPRESSION
******************************************************/
writeexp(EXP):-
    strexp(EXP,STR),
    write(STR).

/*
CLAUSES FOR CONVERTING AN EXPRESSION TO A STRING
*/
% Taken from the old writeexp clauses

strexp(var(NAME),NAME).
strexp(int(INT),INTSTR) :-
str_int(INTSTR,INT).
strexp(ln(EXP),STR) :-
strPAR(EXP,STRp),
concat("ln",STRp,STR).
strexp(sin(EXP),STR) :-
strPAR(EXP,STRp),
concat("sin",STRp,STR).
strexp(cos(EXP),STR) :-
strPAR(EXP,STRp),
concat("cos",STRp,STR).
strexp(tan(EXP),STR) :-
strPAR(EXP,STRp),
concat("tan",STRp,STR).
strexp(sec(EXP),STR) :-
strPAR(EXP,STRp),
concat("sec",STRp,STR).
strexp(plus(EXP1,EXP2),STR):-
strexp(EXP1,STR1),
concat(STR1,"+",STR3),
strexp(EXP2,STR2),
concat(STR3,STR2,STR).
strexp(minus(EXP1,EXP2),STR):-
strexp(EXP1,STR1),
concat(STR1,"-",STR3),
strMINUS(EXP2,STR2),
concat(STR3,STR2,STR).
strexp(mult(EXP1,EXP2),STR):-
strMINUS(EXP1,STR1),
concat(STR1,"*",STR3),
strMULT(EXP2,STR2),
concat(STR3,STR2,STR).
strexp(div(EXP1,EXP2),STR):-
strMULT(EXP1,STR1),
concat(STR1,"/",STR3),
strDIV(EXP2,STR2),
concat(STR3,STR2,STR).
strexp(potens(EXP1,EXP2),STR):-
strDIV(EXP1,STR1),
concat(STR1,"^",STR3),
strPOTENS(EXP2,STR2),
concat(STR3,STR2,STR).

strPOTENS(div(X,Y),STR):-!,strPAR(div(X,Y),STR).
strPOTENS(X,STR):-strDIV(X,STR).

strDIV(mult(X,Y),STR):-!,strPAR(mult(X,Y),STR).
strDIV(X,STR):-strMULT(X,STR).

strMULT(minus(X,Y),STR):- !,strPAR(minus(X,Y),STR).
strMULT(X,STR):-strMINUS(X,STR).

strMINUS(plus(X,Y),STR):-!,strPAR(plus(X,Y),STR).
strMINUS(X,STR):-strexp(X,STR).

strPAR(EXP,STR):-
strexp(EXP,STR1),
concat("(",STR1,STR2),
concat(STR2,")",STR).