:- op(700,xfx,:). :- op(200,xfy,@). go :- write('Want instructions? Type y or n and press return...'), nl, prompt(Old,'y/n? '), get(C), skip(10), tellall(C), prompt(Yn,'diff: '), dv. tellall(C) :- (C=89;C=121), emas(ty,'ecmi01.ai2_diffnotes'). tellall(C). dv :- repeat, read(T), (T=stop; derive(T), fail). derive(T:X) :- T : X, !. X : [U] :- X : U. X : [U|V] :- d(X,U,W), simplify(W,Z), Z : [V]. X : Y :- d(X,Y,W), simplify(W,Z), nl, output(Z), nl, nl. d(X,X,1). d(T,X,0) :- atomic(T). d(U+V,X,A+B) :- d(U,X,A), d(V,X,B). d(U-V,X,A+(-B)) :- d(U,X,A), d(V,X,B). d(-T,X,-R) :- d(T,X,R). d(K*U,X,K*W) :- integer(K), d(U,X,W). d(U*V,X,U*A+B*V) :- d(U,X,B), d(V,X,A). d(U/V,X,W) :- d(U*V@(-1),X,W). d(U@V,X,V*W*U@(V+(-1))) :- integer(V), d(U,X,W). d(U@V,X,Z*log(U)*U@V+V*W*U@(V+(-1))) :- d(U,X,W), d(V,X,Z). d(log(T),X,R*T@(-1)) :- d(T,X,R). d(exp(T),X,R*exp(T)) :- d(T,X,R). d(sin(T),X,R*cos(T)) :- d(T,X,R). d(cos(T),X,-R*sin(T)) :- d(T,X,R). d(tan(T),X,W) :- d(sin(T)/cos(T),X,W). simplify(X,X) :- atomic(X). simplify(X,Y) :- X =.. [Op,Z], simplify(Z,Z1), rewrite(Op,Z1,Y). simplify(X,Y) :- X =.. [Op,Z,W], simplify(Z,Z1), simplify(W,W1), rewrite(Op,Z1,W1,Y). rewrite(exp,K*log(X),W) :- binary(@,X,K,W). rewrite(-,A+B,C+D) :- unary(-,A,C), unary(-,B,D). rewrite(X,Y,Z) :- unary(X,Y,Z). rewrite(*,X,X,W) :- binary(@,X,2,W). rewrite(*,-X,X,W) :- binary(@,X,2,Z), unary(-,Z,W). rewrite(*,X,-X,W) :- binary(@,X,2,Z), unary(-,Z,W). rewrite(*,-X,-Y,Z) :- binary(*,X,Y,Z). rewrite(*,-X,Y,W) :- binary(*,X,Y,Z), unary(-,Z,W). rewrite(*,X,-Y,W) :- binary(*,X,Y,Z), unary(-,Z,W). rewrite(*,A@X,A@Y,W) :- binary(+,X,Y,Z), binary(@,A,Z,W). rewrite(*,X@A,Y@A,W) :- binary(*,X,Y,Z), binary(@,Z,A,W). rewrite(@,X*Y@(-1),-Z,W) :- binary(@,Y*X@(-1),Z,W). rewrite(X,Y,Z,W) :- binary(X,Y,Z,W). unary(-,-X,X). unary(-,0,0). unary(-,X,Y) :- integer(X),!,Y is -X. unary(-,X,Y) :- Y = -X. unary(log,1,0). unary(exp,0,1). unary(sin,0,0). unary(cos,0,1). unary(log,exp(X),X). unary(exp,log(X),X). unary(sin,-X,- sin(X)). unary(cos,-X,cos(X)). unary(Op,X,Y) :- Y =.. [Op,X]. binary(+,X,0,X). binary(+,X,-X,0). binary(+,0,X,X). binary(+,-X,X,0). binary(+,A,B+C,R+C) :- integer(A),integer(B),!,R is A+B. binary(+,A,B+C,R+B) :- integer(A),integer(C),!,R is A+C. binary(+,A,B+C,A+B+C). binary(+,A+B,C,R+B) :- integer(A),integer(C),!,R is A+C. binary(+,A+B,C,R+A) :- integer(B),integer(C),!,R is B+C. binary(+,A+B,C,A+B+C). binary(+,(sin(X))@2,(cos(X))@2,1). binary(+,(cos(X))@2,(sin(X))@2,1). binary(+,X,Y,Z) :- integer(X),integer(Y),!,Z is X+Y. binary(+,X,Y,X+Y). binary(*,X,1,X). binary(*,0,_,0). binary(*,1,X,X). binary(*,_,0,0). binary(*,-1,X,-X). binary(*,X,-1,X). binary(*,X,X@(-1),1). binary(*,X@(-1),X,1). binary(*,A,B*C,R*C) :- integer(A),integer(B),!,R is A*B. binary(*,A,B*C,R*B) :- integer(A),integer(C),!,R is A*C. binary(*,A,B*C,A*B*C). binary(*,A*B,C,R*B) :- integer(A),integer(C),!,R is A*C. binary(*,A*B,C,R*A) :- integer(B),integer(C),!,R is B*C. binary(*,A*B,C,A*B*C). binary(*,X,Y,Z) :- integer(X),integer(Y),!,Z is X*Y. binary(*,X,Y,X*Y). binary(@,1,_,1). binary(@,X,1,X). binary(@,_,0,1). binary(Op,X,Y,Z) :- Z =.. [Op,X,Y]. output(X) :- clean(X,Y), write(Y). clean(X,X) :- atomic(X). clean(X,Y) :- X =.. [Op,Z], clean(Z,Z1), Y =.. [Op,Z1]. clean(X,Y) :- X =.. [Op,Z,W], clean(Z,Z1), clean(W,W1), U =.. [Op,Z1,W1], change(U,Y). change(-Y+X,X-Y). change(X+(-Y),X-Y). change(X*Y@(-1),X/Y). change(X@(-1)*Y,Y/X). change(X,X).