2011-11-17 97 views
0

我试图让这个函数在输入 时显示文字expr2和expr1。输入的数据是(+ x y)的形式。为Lisp函数返回参数

(DEFUN deriv (expr var) ; function name and arguments 
    (COND ((ATOM expr)  ; check for atomic expression (variable or constant) 
       (IF (EQL expr var) 
        1  
        0  
      ))  
     ((EQL (FIRST expr) '+) (deriv-add (SECOND expr) (THIRD expr) var)) 
     ((EQL (FIRST expr) '-) (deriv-minus (SECOND expr) (THIRD expr) var)) 
     ((EQL (FIRST expr) '*) (deriv-multi (SECOND expr) (THIRD expr) var)) 
     ((EQL (FIRST expr) '/) (deriv-divide (SECOND expr) (THIRD expr) var)) 
     (T (ERROR "UNKNOWN arithmetic operator")) 
) 
) 

(DEFUN deriv-multi (expr1 expr2 var) 
    (LIST '+ (* (deriv expr1 var) expr2) (* expr1 (deriv expr2 var))) 
) 

(SETQ e2 '(* (+ x y) (+ y 7))) 
(DERIV e2 'x) 

回答

3

这是一个很好的基本介绍Lisp语言:

http://www.cs.cmu.edu/~dst/LispBook/

'的Common Lisp:一个温柔的介绍符号计算' 由戴维·S·图尔茨基。

免费PDF。

顺便说一句,你的功能什么都不显示。它调用函数'LIST'。为什么在expr1expr2附近有括号?

关于你的代码:

  • 这是很好的编码风格Lisp中使用自我解释的代码。由于您可以使用符号来真正命名事物(而不是概念的缩写),因此可以使用描述性符号。输入更长的符号通常通过在编辑器中使用符号完成来完成。这可以让你摆脱评论。

  • 不添加额外的空间。写紧凑的代码。

  • 格式化您的代码很好,很紧凑。

  • 使用缩进和额外的线,其中它有助于阅读代码

实施例:

(defun derive (expression variable) 
    (if (atom expression) 
     (if (eql expression variable) 1 0) 
    (funcall (case (first expression) 
       (+ #'derive-addition) 
       (- #'derive-subtraction) 
       (* #'derive-multiplication) 
       (/ #'derive-division) 
       (otherwise (error "unknown arithmetic operator"))) 
      (second expression) (third expression) variable))) 

(defun derive-multiplication (expression1 expression2 variable) 
    (list '+ 
     (* (derive expression1 variable) 
      expression2) 
     (* expression1 
      (derive expression2 variable)))) 

以上功能仍然有错误,这是很容易解决。你不想执行乘法。

(defun test() 
    (assert (equal (derive '(* (+ x y) (+ y 7)) 'x) 
       '(+ (* (+ 1 0) 
         (+ y 7)) 
        (* (+ x y) 
         (+ 0 0))))))) 
+0

我添加了更多的代码,以更好地展示它试图用于什么。 – Brian

+0

@Brian:expr1周围的圆括号是什么? –

+0

对不起,这是一个错误。我删除了它们。 – Brian