1. Introduction
As an illustration of symbol manipulation and data abstraction, consider the design of a function that performs symbolic differentiation of algebraic expressions. We would like the function to take as arguments an algebraic expression and a variable and to return the derivative of the expression with respect to the variable. For example, if the arguments to the function are ax2+bx+c and x, the function should return 2ax+b. Symbolic differentiation is of special historical significance in Lisp. It was one of the motivating examples behind the development of a computer language for symbol manipulation.
In developing the symbolic-differentiation program, we will follow a data abstraction strategy. That is, we will first define a differentiation algorithm that operates on abstract objects such as “sums”, “products”, and “variables” without worrying about how these are represented. Only afterward will we address the representation problem.
2. Basic Program
We want a Clojure function (deriv exp var)
that allows doing symbolic differentiation using the following reduction rules:
\[\frac{dc}{dx} = 0\]
Where \(c\) is a constant or a variable different from \(x\). |
\[\frac{dx}{dx} = 1\]
|
\[\frac{d(u+v)}{dx}=\frac{du}{dx}+\frac{dv}{dx}\]
|
\[\frac{d(u\cdot v)}{dx}=u \left ( \frac{dv}{dx} \right ) + v \left ( \frac{du}{dx} \right )\]
|
We’ll use and define the following helper functions:
|
Is |
|
Are |
|
Is |
|
Augend of the sum |
|
Addend of the sum |
|
Construct the sum of |
|
Is |
|
Multiplicand of the product |
|
Multiplier of the product |
|
Construct the product of |
This is how the deriv
function should work:
(deriv '(+ x 3) 'x)
=> (+ 1 0)
(deriv '(* x y) 'x)
=> (+ (* x 0) (* y 1))
(deriv '(* (* x y) (+ x 3)) 'x)
=> (+ (* (* x y) (+ 1 0)) (* (+ x 3) (+ (* x 0) (* y 1))))
Modify the make-sum
and make-product
functions in order to reduce their answers to its simplest form. Here’s how this new version should work on the three previous examples:
(deriv '(+ x 3) 'x)
=> 1
(deriv '(* x y) 'x)
=> y
(deriv '(* (* x y) (+ x 3)) 'x)
=> (+ (* x y) (* (+ x 3) y))
3. Extended Program
Extend the basic program in order to implement the differentiation rule:
\[\frac{d(u^n)}{dx} = n \cdot u^{n-1} \left ( \frac{du}{dx} \right )\]
|
Add a new clause to the deriv
function and define appropriate functions exponentiation?
, base
, exponent
, and make-exponentiation
(you may use the symbol **
to denote exponentiation). Build in the rules that anything raised to the power 0 is 1 and anything raised to the power 1 is the thing itself.
4. Credits
This exercise was taken from chapter 2, section 2.3.2, of “Structure and Interpretation of Computer Programs”, second edition, by Harold Abelson, Gerald Jay Sussman, and Julie Sussman, published by The MIT Press.