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)))))))
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)))))))