方案 - 使用 table 的导数

Scheme - Deriviative using table

我正在尝试使用下面的代码在方案中获取导数。谁能告诉我哪里出错了?我已经尝试了一段时间了。

(define d3
  (λ (e)
    (cond ((number? e) 0)
      ((equal? e 'x) 1)
      (else
       ;; We handle only BINARY ops here, and only + and *
       (let ((op (car e)) (args (cdr e)))
         (apply (lookup op d-op-table) args))))))


(define d-op-table
  (list(list '+ (λ (u v) (+ (d3 u) (d3 v))))
       (list '+ (λ (u1 v1)
             (list '(* u1 (d v1)))(list '(* (d u1) v1))))))

(define lookup
  (λ (op table)
    (if (equal? op (caar table))
    (cadar table)
    (lookup op (cdr table)))))

当我 运行 函数时,出现以下错误。我输入, (d3 '(* 2 x)).

    caar: contract violation
  expected: (cons/c pair? any/c)
  given: '()

查找 table 不正确,有时您评估表达式,但其他人您只是引用它们,而不评估它们。例如,'(* u1 (d v1)) 只会计算为 '(* u1 (d v1)),实际上并未计算导数!乘法的情况看起来特别糟糕,它甚至没有正确的搜索键 *.

这更接近您的预期,请注意您需要做更多的工作来实际检测哪些表达式可以简化 - 例如:(* 0 x)0,但它应该足以得到你开始了:

(define d-op-table
  (list (list '+ (λ (u v) (list '+ (d3 u) (d3 v))))
        (list '* (λ (u v)
                   (list '+
                         (list '* u (d3 v))
                         (list '* (d3 u) v))))))

现在你的例子有效了:

(d3 '(* 2 x))
=> '(+ (* 2 1) (* 0 x))

如果你想写一个真正有用的微分程序,最好看看SICP