Реализуйте процедуру derivative
, находящую производную функции одной переменной по правилам дифференцирования. Пусть процедура принимает один аргумент — выражение на языке Scheme, которой задана функция, и возвращает также выражение на языке Scheme, соответствующее производной. Выражения должны быть пригодны для выполнения с помощью встроенной процедуры eval
.
Реализуйте нахождение производных константы, линейной, степенной, показательной (включая экспоненту), натурального логарифма, тригонометрических функций (синуса и косинуса), а также суммы, произведения, частного и композиции функций. Не следует ограничивать число слагаемых в сумме, множителей в произведении и функций в композиции. Упрощение выражений не требуется.
Ваша процедура должна находить решения по крайней мере следующих примеров:
Примеры вызова процедуры:
(derivative '(expt x 10)) ⇒ (* 10 (expt x 9))
(derivative '(* 2 (expt x 5))) ⇒ (* 2 (* 5 (expt x 4)))
Рекомендации:
-
Выбирайте наиболее общие формулы дифференцирования, обработку частных случаев разрабатывайте только при необходимости.
-
Так как упрощение выражений не предусматривается, вполне приемлемым будет результат вычисления, например, вида
(* 3 (/ 1 x))
, или(* 2 (expt x 1))
, или(* 0 (* 2 (expt x 2)))
. -
Разрабатывайте программу через тестирование. Для этого реализуйте каркас для юнит-тестирования. На основе приведенных выше примеров напишите набор тестов для вашей процедуры и ведите разработку так, чтобы добиться правильного выполнения всех тестов. Выполняйте тесты после каждого внесения изменений и дополнений в вашу программу.
-
Предложите способ сделать тесты нечувствительными к способу представления результата, где это возможно. Например,
(* (exp x) (sin x))
на(* (sin x) (exp x)))
и(/ 3 x)
(* 3 (/ 1 x))
должны проходить один и тот же тест.