Функции LISP, которые выполняют как символьные, так и числовые операции над выражениями с использованием +, -, * и / - PullRequest
0 голосов
/ 08 марта 2011

В настоящее время я работаю над 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 ]

1 голос
/ 08 марта 2011

Вот полное решение.Это довольно просто, поэтому я опущу полное объяснение.Спросите меня в комментариях, есть ли что-то, что вы сами не можете выяснить.

(Использование 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 голосов
/ 08 марта 2011

Вот подсказка, вот как вы можете это сделать (в псевдокоде):

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

Когда вы конвертируете это в код на Лиспе, вам наверняка понадобятся некоторые детали.

...