(uiop:define-package :st-buchberger/src/ring-element
(:mix :cl)
(:mix-reexport :st-buchberger/src/ring)
(:export #:ring-element #:ring-division-by-zero
 #:ring-copy #:ring-zero-p #:ring-equal-p
 #:ring-identity-p
 #:ring+ #:ring- #:ring* #:ring/ #:ring-mod
 #:add #:sub #:mul #:divides-p #:div #:div-mod
 #:element->string #:ring-lcm #:base-ring))

(in-package :st-buchberger/src/ring-element)

;; (defgeneric monomial (future-term))
;; (defgeneric coefficient (future-term))

(defclass ring-element ()
 (base-ring)
 (:documentation "Base class for ring elements."))

(define-condition ring-division-by-zero (error)
 ((operands
   :initarg :operands
   :reader operands)))

(defgeneric ring-copy (element)
 (:documentation "Returns a deep copy of an element"))

(defgeneric ring-zero-p (element)
 (:documentation "Returns t if element is zero, nil otherwise"))

(defgeneric ring-equal-p (e1 e2)
 (:documentation "Returns t if e1 equals e2, nil otherwise"))

(defgeneric ring-identity-p (element)
 (:documentation "Returns t if element is the multiplicative
 identity, nil otherwise"))

(defgeneric ring+ (element &rest more-elements))
(defgeneric ring- (element &rest more-elements))
(defgeneric ring* (element &rest more-elements))
(defgeneric ring/ (element &rest more-elements))
(defgeneric ring-mod (element &rest more-elements))

(defgeneric add (e1 e2)
 (:documentation "Adds ring elements"))

(defgeneric sub (e1 e2)
 (:documentation "Subtracts ring elements"))

(defgeneric mul (e1 e2)
 (:documentation "Multiplies ring elements"))

(defgeneric divides-p (e1 e2)
 (:documentation "Returns t if e1 divides e2 in the base ring"))

(defgeneric div (e1 e2)
 (:documentation "Divides ring elements"))

(defgeneric divmod (element divisors)
 (:documentation "Returns quotient(s) and remainder if we are working
 in an Euclidean ring."))

(defgeneric element->string (element &key &allow-other-keys)
 (:documentation "Returns a human-readable string representation of
 an element"))

(defgeneric ring-lcm (e1 e2)
 (:documentation "Returns the LCM of e1 and e2"))