% 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)).