(uiop:define-package :st-buchberger/src/ideal
(:mix :cl)
(:mix-reexport :st-buchberger/src/groebner)
(:export #:ideal #:make-ideal #:basis #:member-p))
(in-package #:st-buchberger/src/ideal)
(defclass ideal ()
((ring
:initarg :ring
:initform (error "You must specify a ring for the polynomial ideal.")
:accessor ring)
(generators
:initarg :generators
:initform (error "You must provide a set of generators for the ideal.")
:accessor generators)
(cached-basis)))
(defun make-ideal (&rest generators)
"Create a new ideal generated by the elements contained in the
GENERATORS list."
(when generators
(let* ((g (first generators))
(base-ring (base-ring g)))
(unless (every (lambda (x) (eq x base-ring))
(mapcar #'base-ring (rest generators)))
(error "Every generator must belong to the same ring."))
(make-instance 'ideal
:ring base-ring
:generators (make-array (length generators)
:element-type (class-of g)
:initial-contents generators)))))
(defmethod print-object ((ideal ideal) stream)
(print-unreadable-object (ideal stream :type t)
(format stream "~@{~S ~S~^ ~}"
:ring (slot-value ideal 'ring)
:generators (slot-value ideal 'generators))))
(defgeneric basis (ideal)
(:documentation "Returns an array of generators for `ideal'."))
(defmethod basis ((ideal ideal))
(with-slots (cached-basis) ideal
(setf cached-basis (reduced-groebner (generators ideal)))
cached-basis))
(defgeneric member-p (element ideal))
(defmethod member-p ((element ring-element) (ideal ideal))
(with-slots (generators cached-basis) ideal
(unless (and (slot-boundp ideal 'cached-basis) cached-basis)
(setf cached-basis (basis ideal)))
(ring-zero-p (ring-mod element cached-basis))))
Response:
text/plain