我是Lisp的新手,我正在学习一些教程。下面是用于区分多项式的给定代码。我想简化它,所以(d)和(简化)是一个功能/可以一步完成。我正在考虑(defun differentiate (poly x) (simplify (d (poly x))))
,但后来认为poly
是一个函数,它不起作用。
也许这不起作用,因为必须引用(d)的输入?即(d '(+ x y) '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))))
答案 0 :(得分:3)
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
和(defun differentiate (poly x)
(simplify (d poly x)))
的值,然后调用简化结果如下:
{{1}}