| 記号の微分そして数値の計算
元のプログラムは、1970年代後期のD.H.D.ウォーレンとその同僚の仕事であると思います; 変形の部分は、Prologの部分でおこなわれたものです。
このプログラムにより数学の教科書に載っている規則によりエンジニアリング言語(例えば三角関数)を変換し、それからそれをさらに処理するために渡す(ここでは、数値を出す。)方法がわかります。
このプログラムは、記号ソルバーと数字ソルバーの組合せの例であり、再帰的データ構造(数学式)に関して働いている再帰的なプログラム(微分規則)の力を示す古典的な実例です。
微分規則のためのソースを下に紹介します。
% diff.min - symbolic differentiation rules
% diff(+Formula,+AfterVariable,-DifferentiatedFormula)
diff(X1,X2,1) :- var(X1), !, X1 == X2.
diff(C,X,0) :- constant(C,X),!.
diff(-U,X,-DU) :- diff(U,X,DU).
diff(U+V,X,DU+DV) :- diff(U,X,DU), diff(V,X,DV).
diff(U-V,X,DU-DV) :- diff(U,X,DU), diff(V,X,DV).
diff(C*U,X,C*DU) :- constant(C,X), diff(U,X,DU).
diff(U*V,X,DV*U+DU*V) :- \+ constant(U,X),!, diff(U,X,DU), diff(V,X,DV).
diff(U/V,X,DU) :- diff(U*V^ (-1),X,DU).
diff(U^C,X,C*DU*U ^ (C-1)) :- constant(C,X),!,diff(U,X,DU).
diff(ln(U),X,DU*U ^ (-1)) :- diff(U,X,DU).
diff(sin(X1),X,cos(X)) :- X1 == X.
diff(cos(X1),X,-sin(X)) :- X1 == X.
diff(exp(X1),X,exp(X)) :- X1 == X.
diff(GoF,X,DG*DF) :-
GoF =.. [G,F],
known_function(G),
Y =..[G,U],
diff(Y,U,DG),
diff(F,X,DF),
U = F.
diff(F,X,_DF) :- throw('Sorry, no rule for diff'(F,X)).
known_function(G) :- member(G,[ln,sin,cos,exp]).
% constant(+C,X) <- C is a constant expression with respect to X
constant(C,_X) :- atomic(C),!.
constant(C,_X) :- compound(C),
C = const(_NameOfSymbolicConstant),!. % a declared constant
constant(C,X) :-
compound(C), C =.. [BinOp,A,B],!,
binary_operator(BinOp), constant(A,X), constant(B,X).
constant(C,X) :-
compound(C), C =.. [UnOp,A],!,
unary_operator(UnOp), constant(A,X).
% binary_operator(+BinOp) <- BinOp is a binary operator
binary_operator(BinOp) :- member(BinOp,[-,+,*,/,^]).
% unary_operator(+UnOp) <- UnOp is a unary operator
unary_operator(UnOp) :- member(UnOp,[-,ln,exp,sin,cos]).
|