Hey
I need your help for a program in common lisp. The program has to do with polynomial manipulation.
My problem is when i do simple arithmetic operations does not accept any letters e.g (p+ x 4)
(defun p+ (p1 p2)
(list '+ p1 p2))
(defun p+ (p1 p2)
(+ p1 p2))
How can i make it in order to accept letters as well ?
Thanks in advance
accept both numbers and letters
Re: accept both numbers and letters
I'm not sure to understand - do you need something like the following?
(defmacro p+ (p1 p2)
`(list '+ ',p1 ',p2))
ciao
(defmacro p+ (p1 p2)
`(list '+ ',p1 ',p2))
ciao
Re: accept both numbers and letters
p+ is a function which means it gets its arguments evaluated. 4 evaluates to itself, but x would evaluate to what ever x is bound to, which looks like nothing in this case. To prevent evaluation of an object you quote it; (quote x) would be the quoted form of x. Because quoting is so common, you have a read macro to do it automatically, and so you can just write 'xnakias wrote:Hey
I need your help for a program in common lisp. The program has to do with polynomial manipulation.
My problem is when i do simple arithmetic operations does not accept any letters e.g (p+ x 4)
(defun p+ (p1 p2)
(list '+ p1 p2))
(defun p+ (p1 p2)
(+ p1 p2))
How can i make it in order to accept letters as well ?
Thanks in advance
Now then while (list '+ 'x 4) makes sense, (+ 'x 4) does not because 'x is not a number, so only your first definition for p+ would work with (p+ 'x 4)
Re: accept both numbers and letters
But how can i use the defmacro in order to simplify any given polynomial e.g (x + y)(x + y) → x2 + 2xy + y2
Thanks for replying.
Thanks for replying.
Code: Select all
;; Constructors
(defun make-constant (num)
num)
(defun make-variable (sym)
sym)
;;(defun p+ (poly1 poly2)
;; (list '+ poly1 poly2))
(defmacro p+ (poly1 poly2)
`(list '+ ',poly1 ',poly2))
(defmacro p* (poly1 poly2)
`(list '* ',poly1 ',poly2))
;;(defun p* (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 sum-p (poly)
(and (listp poly) (eq (first 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 sum-arg1 (sum)
(second sum))
(defun sum-arg2 (sum)
(third sum))
(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)))
;;
;; Simplification function
;;
(defun simplify (poly)
"Simplify polynomial POLY."
(cond
((constant-p poly) poly)
((variable-p poly) poly)
((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)))
((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-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)
(t (p+ 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)
(t (p* 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))))
Re: accept both numbers and letters
There's some code here.nakias wrote:how can i use the defmacro in order to simplify any given polynomial e.g (x + y)(x + y) → x2 + 2xy + y2
You don't need a macro if you're doing the simplification at runtime. You just quote the arguments, as in (simplify '(* (+ x 1) (+ x -1))).
Once a product is expanded, you can sort it by the symbols in each term, group the terms, and add up their coefficients.
--Dan B.