Упростите и оцените выражение в LISP

Я пытаюсь создать функцию lisp, которая оценивает и упрощает арифметику умножения и сложения. Функция должна работать таким образом, чтобы когда пользователь вызывает функцию (simplify-Mult'(* 1 2)) она печатала только 2 или (simplify-Mult'(*0 3 3 7)) печатала только 0.

Пока у меня это

(defun simplify-multiplication (lis)
    (if (not (null lis))
        (if (member '0 lis) 0
        (if (member '1 lis) cdr lis
                (if (listp (car lis))
                    (cons(simplify(car lis)))
                    (if (numberp (car lis))
                        (if (null (cdr lis))
                            lis
                            (cons (car lis) (simplify-multiplication (cdr lis)))
                        )
                        (if (eq (car lis) '+)
                            (cons (car lis) (simplify-multiplication (cdr lis)))
                            (if (eq (car lis) '*)
                                (cons (car lis) (simplify-multiplication (cdr lis)))
                                lis
                            )
                        )
                    )
                )

            )
        )
    )
)

person PistolPete    schedule 29.10.2015    source источник
comment
Пожалуйста, потратьте несколько минут, чтобы узнать о правильном Форматирование кода Лиспа.   -  person danlei    schedule 29.10.2015


Ответы (1)


Вы можете написать одну единственную функцию, которая применяет правила упрощения как для умножения, так и для сложения. Если вы хотите рекурсивно упростить выражение, сначала вам нужно упростить каждый из аргументов, а затем применить правила упрощения для соответствующей операции. Следующее может быть отправной точкой:

(defun simplify (lis)
  (if (atom lis)
    lis
    (let ((args (mapcar #'simplify (cdr lis))))
      (cond
        ((eql (car lis) '+)
          (setq args (remove 0 args))
          (case (length args)
            (0 0)
            (1 (car args))
            (otherwise (cons '+ args)) ))
        ((eql (car lis) '*)
          (if (member 0 args)
              0
              (progn
                (setq args (remove 1 args))
                (case (length args)
                  (0 1)
                  (1 (car args))
                  (otherwise (cons '* args)) ))))
        (T (cons (car lis) args)) ))))

Вы, вероятно, захотите добавить другие правила упрощения, такие как (* 2 (* 3 4)) => (* 2 3 4) и т. д., а также обнаружение неправильных выражений, таких как (упростить '(+)).

person Leo    schedule 29.10.2015