2011-03-08 99 views
0

對錶達式執行符號和數字操作的LISP函數我目前正在爲一個小型項目開展LISP練習,需要嚴格的幫助。這可能或多或少是一個初學者的問題,但我完全喪失了編寫某個函數的功能,這個函數需要兩個未評估的函數,並根據變量是否賦值分配結果。使用+, - ,*和/

一個例子是

(setq p1 '(+ x (* x (- y (/ z 2))))) 

(evalexp p1 '((x 2) (z 8))) 
    returns (+ 2 (* 2 (- y 4))) 

我的目標是編寫evalexp功能,但我也別想從哪裏開始。

到目前爲止,我有

(defun evalexp (e b)) 

..不是很多。如果任何人都可以請求幫助或帶領我走向一個好的方向,我會更感激。

+0

什麼「兩個不計算功能」? – 2011-03-08 06:14:28

回答

1

下面是一個完整的解決方案。這很直接,所以我會留下一個完整的解釋。如果有什麼你無法弄清楚自己,請在評論中問我。

(使用eval做實際的評估可能不是你在運動/項目想要的東西。查找「元圓解釋」的另一種方式。)

(defun apply-env (exp env) 
    (reduce (lambda (exp bdg) (subst (cadr bdg) (car bdg) exp)) 
      env :initial-value exp)) 

(defun try-eval (exp) 
    (if (atom exp) 
     exp 
     (let ((exp (mapcar #'try-eval exp))) 
     (if (every #'numberp (cdr exp)) 
      (eval exp) 
      exp)))) 

(defun evalexp (exp env) 
    (try-eval (apply-env exp env))) 
+0

這是驚人的,完美的作品。 LISP可以是一種優雅的語言,但如果你不理解它,它肯定會成爲一個真正的痛苦。我一直在試圖破解它,但我不認爲我會得到像你一樣簡單和整齊的東西。謝謝你,先生! – TomMElack 2011-03-08 17:56:16

0

這裏有一個提示,這是你會怎麼做(在僞代碼):

function replace(vars, list): 
    for each element of list: 
     if it's an atom: 
      if there's an association in vars: 
       replace atom with value in vars 
      else: 
       leave atom alone 
     else: 
      recursively apply replace to the sublist 

肯定會有一些細節需要處理,你將它轉換爲Lisp代碼。

+0

真棒謝謝你的即時回覆。我現在要嘗試着解決這個問題。非常感謝! – TomMElack 2011-03-08 05:04:24