Sourse Code for Symbolic differentiation
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)
GOAL
write("Write an expression: "),
readln(STR),
tokl(STR,TOKL),
s_exp(TOKL,OL,EXP), OL = [],
d(EXP,"x",EXP1),
write("\n Differentiated expression:\n "),
writeexp(EXP1),
write("\n\n Reduced expression:\n "),
reduce(EXP1,EXP2),
writeexp(EXP2).
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).