Car:+不是列表,lisp错误?

时间:2014-10-06 18:39:16

标签: syntax-error lisp

我正在尝试编写一个采用多项式的程序,并简化它们。每次我运行程序时,通过调用“(evalexp'((x 2)(z 8))p1)”我得到错误,“Car:+不是列表”。它应该返回“(+ 2(* 2( - y 4)))”这是我的代码:

(setq p1 '(+ x (* x (- y (/ z 2)))))
(setq p2 '(+ (- z 2) (* x 5)))
(setq p3 '(+ 1 a))
(setq p4 '(+ x (+ x (* x 0))))

(defun addexp (e1 e2) (list '+ e1 e2))
(defun subexp (e1 e2) (list '- e1 e2))
(defun mulexp (e1 e2) (list '* e1 e2))
(defun divexp (e1 e2) (list '/ e1 e2))

(defun deep-subst (old new expr)
  (cond
   ((null expr) 
     nil
   )
   ((listp (car expr))
    (cons (deep-subst old new (car expr)) (deep-subst old new (cdr expr)))
   )
   ((eq old (car expr)) 
    (cons new (deep-subst old new (cdr expr)))
   )
   (T   
    (cons (car expr) (deep-subst old new (cdr expr)))
    )
  )
)

(defun subst-bindings (expr bindinglist)
  (cond   
    ((null bindinglist) 
       expr )
    (T 
       (deep-subst (car (car bindinglist)) (car (cdr (car bindinglist))) 
        (subst-bindings expr (cdr bindinglist))
    ))))

(defun simplify-triple(op left-arg right-arg)
  (cond
    ((and (numberp left-arg) (numberp right-arg))
      (eval (list op left-arg right-arg))
    )
    ((and (eq op '+) (eql right-arg 0))
      left-arg
    )
    ((and (eq op '+) (eql left-arg 0))
      right-arg
    )
    ((and (eq op '-) (eql right-arg 0))
      left-arg
    )
    ((and (eq op '-) (eql right-arg left-arg))
      0
    )
    ((and (eq op '*) (eql right-arg 0))
      0
    )
    ((and (eq op '*) (eql left-arg 0))
      0
    )
    ((and (eq op '*) (eql right-arg 1))
      left-arg
    )
    ((and (eq op '*) (eql left-arg 1))
      right-arg
    )
    ((and (eq op '/) (eql left-arg 0))
      0
    )
    ((and (eq op '/) (eql right-arg 1))
      left-arg
    )
    ((and (eq op '/) (eql right-arg left-arg))
      1
    )

    (T
        (list op left-arg (simplify right-arg))
        ;(list op right-arg (simplify left-arg))
    )
  )
)

(defun simplify (exp)
  (cond
    ( (listp exp)
        (simplify-triple (car exp) (simplify (car (cdr exp))) (simplify (car (cdr (cdr exp)))))
    )   
    (T 
        exp)))


(defun evalexp (exp binding-list)
  (simplify (subst-bindings exp binding-list))
)

1 个答案:

答案 0 :(得分:3)

发现你的错误。您的大多数函数都声明接收表达式作为第一个参数,绑定作为第二个参数,但在您的示例中,您调用的函数将绑定作为第一个参数传递,表达式作为第二个参数传递。您必须调用(evalexp p1 '((x 2) (z 8)))或在函数定义上交换参数顺序(我建议使用此解决方案,因为它看起来更自然,看起来像@ rainer-joswig链接)。

特别是,subst-bindingsevalexp是需要更改的内容。