(uiop:define-package :st-buchberger/src/polynomial-ring
(:mix :cl)
(:mix-reexport :st-buchberger/src/monomial-orderings)
(:export #:polynomial-ring #:initialize-instance
 #:print-object #:*ring* #:with-polynomial-ring
 #:variables #:base-field))

(in-package #:st-buchberger/src/polynomial-ring)


(defclass polynomial-ring (ring)
 ((variables
   :reader variables
   :initarg :variables
   :initform (error "You must specify at least one variable"))
  (base-field
   :reader base-field
   :initarg :base-field
   :initform 'rational)))

(defmethod initialize-instance :after ((ring polynomial-ring) &key)
 (flet ((make-variables ()
          (let ((vars (variables ring)))
            (if (consp vars)
                vars
                (list vars)))))
   (setf (slot-value ring 'variables) (make-variables))))

(defmethod print-object ((ring polynomial-ring) stream)
 (print-unreadable-object (ring stream :type t)
   (format stream "~@{~S ~S~^ ~}"
           :variables (variables ring)
           :base-field (base-field ring))))

(defvar *ring*
 (make-instance 'polynomial-ring :variables '(x y z))
 "Default polynomial ring")

(defmacro with-polynomial-ring (ring &body body)
 `(let ((*ring* ,ring))
    ,@body))