(defclass polynomial (ring-element)
((base-ring
:initarg :ring
:initform (error "You must specify a base ring")
:accessor base-ring)
(terms
:type hash-table
:initarg :terms
:initform (make-hash-table :test #'equalp)
:accessor terms)))
(defgeneric lt (poly)
(:documentation "Returns the leading term of a polynomial."))
(defgeneric lm (poly)
(:documentation "Returns the leading monomial of a polynomial.
That is, the leading term with 1 as coefficient"))
(defgeneric lc (poly)
(:documentation "Returns the leading coefficient of a polynomial"))
(defgeneric multideg (poly)
(:documentation "Returns the multidegree of a polynomial"))
(defun make-polynomial-from-term-list (term-list &key (ring *ring*))
"Return a polynomial on RING defined by TERM-LIST.
The terms are of the form (COEFFICIENT POWER-1 POWER-2 ...) where POWER-I is
the power to which the I-th indeterminate of RING is raised."
(let ((poly (make-instance 'polynomial :ring ring)))
(dolist (elem term-list poly)
(setf poly
(add poly
(make-instance 'term
:coefficient (first elem)
:monomial (make-array (1- (length elem))
:initial-contents (rest elem))))))))
(defun make-polynomial (sexp &key (ring *ring*))
"Return an instance of POLYNOMIAL in RING constructed from SEXP."
(flet ((get-indeterminates (term)
(parser:monomial-indeterminates (parser:term-monomial term))))
(loop :with poly := (make-instance 'polynomial :ring ring)
:and parsed := (parser:parse-polynomial sexp)
:and variables := (variables ring)
:for v := (make-array (length variables) :element-type '(integer 0)
:initial-element '0)
:for term :in (parser:polynomial-terms parsed)
:for c := (parser:term-coefficient term)
(defun mapterm (function polynomial)
"Apply FUNCTION to successive terms of POLYNOMIAL. Return list
of FUNCTION return values."
(let (results)
(doterms (tt polynomial results)
(push (funcall function tt) results))))