Функции 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) )
.. не очень много. Если бы кто-нибудь мог помочь или направить меня в правильном направлении, я был бы более чем благодарен.
2 ответа
Вот полное решение. Это довольно просто, поэтому я опущу полное объяснение. Спросите меня в комментариях, есть ли что-то, что вы сами не можете понять.
(С помощью 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)))
Вот подсказка, вот как вы можете это сделать (в псевдокоде):
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
Когда вы преобразуете это в код на Лиспе, вам наверняка понадобятся некоторые детали.