Restklassenringe

Ein Restklassenring Z/nZ ist eine Menge von ganzen Zahlen von 0 einschließlich bis n ausschließlich zusammen mit den Verknüpfungen + und *, die den folgenden Regeln genügen müssen:

Für alle a und b sind a + b und a * b ebenfalls Elemente der Menge.
Für alle a, b und c ist (a + b) + c = a + (b + c).
Für alle a gilt 0 + a = a + 0 = a.
Für alle a existiert ein b mit a + b = 0.
Für alle a und b gilt a + b = b + a.
Für alle a, b und c ist (a * b) * c = a * (b * c).
Für alle a, b und c ist a * (b + c) = (a * b) + (a * c).
Für alle a, b und c ist (a + b) * c = (a * c) + (b * c).
Für alle a gilt 1 * a = a * 1 = a.

Implementiert wird ein Restklassenring durch zwei Klassen - eine für den Ring und eine für seine Elemente - und einige zugehörige Methoden.

Instanzen der Klasse residue-class-ring reräsentieren den Restklassenring an sich und speichern den Modulus.

(defstruct residue-class-ring (modulus)
  (and
    (integer? modulus)
    (greater? modulus 1)))

(defmethod get-modulus ((this residue-class-ring))
  t
  (. this modulus))

Instanzen der Klasse residue-class repräsentieren die Elemente des Restklassenrings. Sie verweisen auf den Restklassenring und enthalten einen Wert, der die Restklasse identifiziert.

(defclass residue-class ())

(defmethod initialize ((this residue-class) (ring residue-class-ring) value)
  (integer? value)
  (progn
    (.= this ring ring)
    (.= this value
      (with-slots (modulus) ring
        (if
          (< value 0)
          (let
            ((pos-value (+ modulus (rem value modulus))))
              (if
                (= pos-value modulus)
                0
                pos-value))
            (rem value modulus))))
    (freeze this)))

(defmethod get-ring ((this residue-class))
  t
  (. this ring))

(defmethod get-value ((this residue-class))
  t
  (. this value))

(defmethod same-ring? ((this residue-class) (that residue-class))
  t
  (= (get-ring this) (get-ring that)))

Für zwei Elemente aus dem selben Restklassenring sind die Verknüpfungen + und * wie folgt definiert:

(defmethod add ((this residue-class) (that residue-class))
  (same-ring? this that)
  (new residue-class
    (get-ring this)
    (+ (get-value this) (get-value that))))

(defmethod times ((this residue-class) (that residue-class))
  (same-ring? this that)
  (new residue-class
    (get-ring this)
    (* (get-value this) (get-value that))))

Die Subtraktion wird auf die Addition des Inversen bezüglich + zurückgeführt.

(defmethod sub ((this residue-class) (that residue-class))
  (same-ring? this that)
  (new residue-class
    (get-ring this)
    (- (get-value this) (get-value that))))

Die Division benötigt das Inverse bezüglich *, das mit modinv berechnet werden kann, wenn der Wert und der Modulus teilerfremd sind. Wenn die Division nicht durchgeführt werden kann, wird eine Ausnahme ausgelöst.
  
(defmethod quotient ((this residue-class) (that residue-class))
  (same-ring? this that)
  (new residue-class
    (get-ring this)
    (* (get-value this)
       (catch-and-apply
         nil
         (lambda (name value)
           (throw
             (quote no-multiplicative-inverse)
             (get-value that)))
         (modinv
           (get-value that)
           (get-modulus (get-ring this)))))))


residue-class.sheet.xml