Программа символьного дифференцирования с диспетчеризацией
В разделе 2.3.2 описывается программа, которая осуществляет символьное дифференцирование:
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp) (if (same-variable? exp var) 1 0))
((sum? exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp) var)))
((product? exp)
(make-sum
(make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
<more rules can be added here>
(else (error "unknown expression type -- DERIV" exp))))
Можно считать, что эта программа осуществляет диспетчеризацию по типу выражения, которое требуется продифференцировать. В этом случае «меткой типа» элемента данных является символ алгебраической операции (например,
+
), а операция, которую нужно применить –
deriv
. Эту программу можно преобразовать в управляемый данными стиль, если переписать основную процедуру взятия производной в виде
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp) (if (same-variable? exp var) 1 0))
(else ((get 'deriv (operator exp)) (operands exp)
var))))
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))
а. Объясните, что происходит в приведенном фрагменте кода. Почему нельзя включить в операцию выбора, управляемого данными, предикаты
number?
и
same-variable?
?
б. Напишите процедуры для вычисления производных от суммы и произведения, а также дополнительный код, чтобы добавить их к таблице, которой пользуется приведенный фрагмент.
в. Выберите еще какое-нибудь правило дифференцирования, например для возведения в степень (упражнение 2.56 ), и установите его в систему.
г. В этой простой алгебраической системе тип выражения — это алгебраическая операция верхнего уровня. Допустим, однако, что мы индексируем процедуры противоположным образом, так что строка диспетчеризации в
deriv
выглядит как
((get (operator exp) 'deriv) (operands exp) var)
Какие изменения потребуются в системе дифференцирования?
Комментарии отсутствуют.