Программа символьного дифференцирования с диспетчеризацией

В разделе 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)

Какие изменения потребуются в системе дифференцирования?


Комментарии отсутствуют.

Необходима авторизация

Вы должны авторизоваться для создания комментария.

Вход