% generated: 7 March 1990 % option(s): % % (deriv) times10 % % David H. D. Warren % % symbolic derivatives #ifndef MERCURY #include "harness.cpp" data(_Data). benchmark(_Data, quad(E1, E2, E3, E4)) :- ops8(E1), divide10(E2), log10(E3), times10(E4). #define num(n) n #define cut ! #else #define cut true :- module deriv. :- import_module int, io. :- interface. :- type expr ---> log(expr) ; expr * expr ; expr / expr ; x ; num(int) ; expr + expr ; expr - expr ; - expr ; ^(expr, int) ; exp(expr) . :- type quad ---> quad(expr, expr, expr, expr). :- pred benchmark(quad). :- mode benchmark(out) is det. :- pred main(io__state, io__state). :- mode main(di, uo) is det. :- implementation. :- import_module require. benchmark(quad(E1, E2, E3, E4)) :- ops8(E1), divide10(E2), log10(E3), times10(E4). main --> { ops8(E1) }, print_expr(E1), io__write_string("\n\n"), { divide10(E2) }, print_expr(E2), io__write_string("\n\n"), { log10(E3) }, print_expr(E3), io__write_string("\n\n"), { times10(E4) }, print_expr(E4), io__write_string("\n"). :- pred times10(expr). :- mode times10(out) is det. :- pred log10(expr). :- mode log10(out) is det. :- pred ops8(expr). :- mode ops8(out) is det. :- pred divide10(expr). :- mode divide10(out) is det. :- pred d(expr, expr, expr). :- mode d(in, in, out) is det. :- pred print_expr(expr, io__state, io__state). :- mode print_expr(in, di, uo) is det. print_expr(x) --> io__write_string("x"). print_expr(num(N)) --> io__write_int(N). print_expr(log(E)) --> io__write_string("log("), print_expr(E), io__write_string(")"). print_expr(exp(E)) --> io__write_string("exp("), print_expr(E), io__write_string(")"). print_expr(^(E, N)) --> io__write_string("^("), print_expr(E), io__write_string(", "), io__write_int(N), io__write_string(")"). print_expr(E1 + E2) --> io__write_string("("), print_expr(E1), io__write_string(" + "), print_expr(E2), io__write_string(")"). print_expr(E1 - E2) --> io__write_string("("), print_expr(E1), io__write_string(" - "), print_expr(E2), io__write_string(")"). print_expr(E1 * E2) --> io__write_string("("), print_expr(E1), io__write_string(" * "), print_expr(E2), io__write_string(")"). print_expr(E1 / E2) --> io__write_string("("), print_expr(E1), io__write_string(" / "), print_expr(E2), io__write_string(")"). print_expr(-E) --> io__write_string("- ("), print_expr(E), io__write_string(")"). #endif #ifdef AQUARIUS_DECLS :- mode((d(E, X, R) :- ground(E), rderef(E), ground(X), rderef(X) )). #endif ops8(E) :- d((x + num(1)) * ((^(x, 2) + num(2)) * (^(x, 3) + num(3))), x, E). divide10(E) :- d(((((((((x / x) / x) / x) / x) / x) / x) / x) / x) / x, x, E). log10(E) :- d(log(log(log(log(log(log(log(log(log(log(x)))))))))), x, E). times10(E) :- d(((((((((x * x) * x) * x) * x) * x) * x) * x) * x) * x, x, E). #ifdef NUPROLOG_DECLS :- d(E, X, R) when E and X. #endif #ifdef SICSTUS_DECLS :- block d(-, ?, ?). #endif d(U + V, X, DU + DV) :- cut, d(U, X, DU), d(V, X, DV). d(U - V, X, DU - DV) :- cut, d(U, X, DU), d(V, X, DV). d(U * V, X, DU * V + U * DV) :- cut, d(U, X, DU), d(V, X, DV). d(U / V, X, (DU * V - U * DV) / ^(V, 2)) :- cut, d(U, X, DU), d(V, X, DV). d(^(U, N), X, DU * num(N) * ^(U, N1)) :- cut, N1 is N - 1, d(U, X, DU). d(-U, X, -DU) :- cut, d(U, X, DU). d(exp(U), X, exp(U) * DU) :- cut, d(U, X, DU). d(log(U), X, DU / U) :- cut, d(U, X, DU). #ifdef MERCURY d(x, X, num(1)) :- ( X = x -> true ; error("differentiating wrt nonvariable") ). #else d(X, X, num(1)) :- cut. #endif d(num(_), _, num(0)).