2011-11-17 49 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