公共Lisp-如何组合这两个简单的多项式函数?

公共Lisp-如何组合这两个简单的多项式函数?,lisp,common-lisp,polynomial-math,Lisp,Common Lisp,Polynomial Math,我是Lisp新手,正在学习一些教程。下面是微分多项式的给定代码。我想简化它,以便(d)和(simplify)是一个功能/可以一步完成。我在想一些东西(defun differention(poly x)(simplify(d(poly x))),但后来它认为poly是一个函数,它不起作用 也许这不起作用,因为(d)的输入必须被引用?i、 e.(d'(+xy)'x) 很抱歉有这么多代码,但我认为最好把它们都放进去。相关功能位于底部 ;; ;; Constructors for polynomial

我是Lisp新手,正在学习一些教程。下面是微分多项式的给定代码。我想简化它,以便(d)和(simplify)是一个功能/可以一步完成。我在想一些东西
(defun differention(poly x)(simplify(d(poly x)))
,但后来它认为
poly
是一个函数,它不起作用

也许这不起作用,因为(d)的输入必须被引用?i、 e.
(d'(+xy)'x)

很抱歉有这么多代码,但我认为最好把它们都放进去。相关功能位于底部

;;
;; Constructors for polynomials
;;

(defun make-constant (num)
  num)

(defun make-variable (sym)
  sym)

(defun make-negation (poly)
  (list '- poly))

(defun make-sum (poly1 poly2)
  (list '+ poly1 poly2))

(defun make-difference (poly1 poly2)
  (list '- poly1 poly2))

(defun make-product (poly1 poly2)
  (list '* poly1 poly2))

(defun make-power (poly num)
  (list '** poly num))

;;
;; Recognizers for polynomials
;;

(defun constant-p (poly)
  (numberp poly))

(defun variable-p (poly)
  (symbolp poly))

(defun negation-p (poly)
  (and (listp poly) (eq (first poly) '-) (null (rest (rest poly)))))

(defun sum-p (poly)
  (and (listp poly) (eq (first poly) '+)))

(defun difference-p (poly)
  (and (listp poly) (eq (first poly) '-) (not (null (rest (rest poly))))))

(defun product-p (poly)
  (and (listp poly) (eq (first poly) '*)))

(defun power-p (poly)
  (and (listp poly) (eq (first poly) '**)))

;;
;; Selectors for polynomials
;;

(defun constant-numeric (const)
  const)

(defun variable-symbol (var)
  var)

(defun negation-arg (neg)
  (second neg))

(defun sum-arg1 (sum)
  (second sum))

(defun sum-arg2 (sum)
  (third sum))

(defun difference-arg1 (diff)
  (second diff))

(defun difference-arg2 (diff)
  (third diff))

(defun product-arg1 (prod)
  (second prod))

(defun product-arg2 (prod)
  (third prod))

(defun power-base (pow)
  (second pow))

(defun power-exponent (pow)
  (third pow))

;;
;; Unevaluated derivative
;;

(defun make-derivative (poly x)
    (list 'd poly x))

(defun derivative-p (poly)
  (and (listp poly) (eq (first poly) 'd)))

;;
;; Differentiation function
;;

(defun d (poly x)
  (cond
   ((constant-p poly) 0)
   ((variable-p poly) 
    (if (equal poly x) 
    1 
      (make-derivative poly x)))
      ((negation-p poly)
    (make-negation (d (negation-arg poly) x)))
   ((sum-p poly) 
    (make-sum (d (sum-arg1 poly) x) 
          (d (sum-arg2 poly) x)))
      ((difference-p poly)
    (make-difference (d (difference-arg1 poly) x)
             (d (difference-arg2 poly) x)))
   ((product-p poly) 
    (make-sum (make-product (product-arg1 poly) 
                (d (product-arg2 poly) x))
          (make-product (product-arg2 poly) 
                (d (product-arg1 poly) x))))
   ((power-p poly)
    (make-product (make-product (power-exponent poly)
                (make-power (power-base poly) 
                        (1- (power-exponent poly))))
          (d (power-base poly) x)))))

;;
;; Simplification function
;;

(defun simplify (poly)
  "Simplify polynomial POLY."
  (cond
   ((constant-p poly) poly)
   ((variable-p poly) poly)
      ((negation-p poly) 
    (let ((arg (simplify (negation-arg poly))))
      (make-simplified-negation arg)))
   ((sum-p poly)
    (let ((arg1 (simplify (sum-arg1 poly)))
      (arg2 (simplify (sum-arg2 poly))))
      (make-simplified-sum arg1 arg2)))
   ((product-p poly)
    (let ((arg1 (simplify (product-arg1 poly)))
      (arg2 (simplify (product-arg2 poly))))
      (make-simplified-product arg1 arg2)))
      ((difference-p poly)
    (let ((arg1 (simplify (difference-arg1 poly)))
      (arg2 (simplify (difference-arg2 poly))))
      (make-simplified-difference arg1 arg2)))
   ((power-p poly)
    (let ((base (simplify (power-base poly)))
      (exponent (simplify (power-exponent poly))))
      (make-simplified-power base exponent)))
   ((derivative-p poly) poly)))

(defun make-simplified-negation (arg)
  "Given simplified polynomial ARG, construct a simplified negation of ARG."
  (cond
   ((and (constant-p arg) (zerop arg)) arg)
   ((negation-p arg)                   (negation-arg arg))
   (t                                  (make-negation arg))))

(defun make-simplified-sum (arg1 arg2)
  "Given simplified polynomials ARG1 and ARG2, construct a simplified sum of ARG1 and ARG2."
  (cond
   ((and (constant-p arg1) (zerop arg1)) arg2)
   ((and (constant-p arg2) (zerop arg2)) arg1)
      ((negation-p arg1)                   (make-simplified-difference 
                     arg2 (negation-arg arg1)))
      ((negation-p arg2)                   (make-simplified-difference 
                     arg1 (negation-arg arg2)))
   (t                                   (make-sum arg1 arg2))))

(defun make-simplified-difference (arg1 arg2)
  "Given simplified polynomials ARG1 and ARG2, construct a simplified difference of ARG1 and ARG2."
  (cond
   ((and (constant-p arg2) (zerop arg2)) arg1)
   ((and (constant-p arg1) (zerop arg1)) (make-simplified-negation arg2))
   ((negation-p arg2)                    (make-simplified-sum 
                      arg1 (negation-arg arg2)))
   (t                                    (make-difference arg1 arg2))))

(defun make-simplified-product (arg1 arg2)
  "Given simplified polynomials ARG1 and ARG2, construct a simplified product of ARG1 and ARG2."
  (cond
   ((and (constant-p arg1) (zerop arg1)) (make-constant 0))
   ((and (constant-p arg2) (zerop arg2)) (make-constant 0))
   ((and (constant-p arg1) (= arg1 1))   arg2)
   ((and (constant-p arg2) (= arg2 1))   arg1)
      ((and (constant-p arg1) (= arg1 -1))  (make-simplified-negation arg2))
      ((and (constant-p arg2) (= arg2 -1))  (make-simplified-negation arg1))
   (t                                    (make-product arg1 arg2))))

(defun make-simplified-power (base exponent)
  "Given simplified polynomials BASE and EXPONENT, construct a simplified power with base BASE and exponent EXPONENT."
  (cond
   ((and (constant-p exponent) (= exponent 1))   base)
   ((and (constant-p exponent) (zerop exponent)) (make-constant 1))
   (t                                            (make-power base exponent))))

poly
的输入不需要“引用”。而不是

(d '(+ x y) 'x)
您可以编写以下任意内容:

(d (list '+ 'x 'y) 'x)

(d (make-sum 'x 'y) 'x)

(let ((ex 'x) (why 'y))
  (d (list '+ ex why) ex))
在这个问题中,你试图调用
d
,结果是
(poly x)
,它试图调用一个名为
poly
的函数(实际上,符号
poly
的函数绑定,或者其他一些可能的东西,但这可能比我们现在需要的更深入)使用变量的值
x

(defun differentiate (poly x)
  ;; call poly with the value of x to produce a value y, and
  ;; then call d with y to produce a value z, and then call
  ;; simplify with z.
  (simplify (d (poly x))))
这当然行不通,因为没有名为
poly
的函数,即使有,
d
也需要两个参数,而不是一个。相反,您应该做的第一件事是使用两个参数调用
d
,即变量
poly
x
的值,然后调用simplify,结果如下:

(defun differentiate (poly x)
  (simplify (d poly x)))
请注意,“关于您编写的代码问题的问题必须在问题本身中描述具体问题,并包括重现问题的有效代码。”“询问代码的问题必须表明对正在解决的问题的最低理解。包括尝试的解决方案,为什么不起作用,以及预期的结果。“您描述了您的一次尝试;什么不起作用?您是否遇到了错误,如果是,是什么?它是否执行时没有错误,但产生了与您预期不同的结果?