使用 +、-、* 和 / 对表达式执行符号和数值运算的 LISP 函数

发布于 2024-10-20 13:14:31 字数 422 浏览 0 评论 0原文

我目前正在为一个小项目进行 LISP 练习,需要大力帮助。这可能或多或少是一个初学者的问题,但我绝对迷失在编写一个特定的函数,该函数接受两个未评估的函数并根据变量是否被赋值而输出结果。

一个例子是

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

我的目标是

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

编写 evalexp 函数,但我什至不知道从哪里开始。

到目前为止我已经

(defun evalexp (e b) )

..不多了。如果有人可以帮助或引导我朝好的方向发展,我将不胜感激。

I'm currently working on a LISP exercise for a small project and need severe help. This may be more or less of a beginner's question but I'm absolutely lost on writing a certain function that takes in two unevaluated functions and spits out the result dependent on if the variables were given an assignment or not.

An example would be

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

Where

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

My goal is to write the evalexp function but I can't even think of where to start.

So far I have

(defun evalexp (e b) )

.. not very much. If anyone could please help or lead me in a good direction I'd be more than appreciative.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世界如花海般美丽 2024-10-27 13:14:31

这是一个完整的解决方案。这非常简单,所以我将省略完整的解释。有什么不懂的可以在评论里问我。

(使用 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)))

Here's a full solution. It's pretty straightforward, so I'll leave out a full explanation. Ask me in the comments if there's anything you can't figure out yourself.

(Using eval to do the actual evaluation might not be what you want in your exercise/project. Look up "meta-circular interpreter" for another way.)

(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)))
人疚 2024-10-27 13:14:31

这里有一个提示,这就是你可以这样做的方式(用伪代码):

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 代码时,肯定会有一些细节需要解决。

Here's a hint, this is how you might do it (in pseudocode):

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

There will certainly be some details to work out as you convert this to Lisp code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文