AB6 Low-Level Programmierung

Implementieren Sie die folgenden Funktionen nur unter Verwendung der bereits importierten Funktionen. Folgende Sprachkonstrukte dürfen nicht verwendet werden:

Teil 1: Zählmaschinen

Eine Zählmaschine besteht aus Registern, welche alle eine natürliche Zahl (inkl. 0) enthalten. Der Wert in jedem Register kann um eins erhöht oder verringert werden. Falls ein Register eine 0 enthält und verringert werden soll, so bleibt eine 0 im Register stehen. Außerdem kann geprüft werden, ob in einem Register die Zahl 0 steht. Folgende Funktionen stehen zur Verfügung, um eine Zählmaschine zu steuern.
inc    :: CM -> Int -> CM
dec    :: CM -> Int -> CM 
isZero :: CM -> Int -> Bool
Die Funktion inc (bzw. dec) erhöht (bzw. verringert) Register arg2 um eins. Das erste Register ist 1.
Die Funktion isZero ist wahr gdw. das Register arg2 eine 0 enthält.
move :: CM -> CM
copy :: CM -> CM
add  :: CM -> CM
mult :: CM -> CM
Für eine Zählmaschine mit \(k\) Registern soll \(R_i\) den Wert zu Beginn und \(R_i'\) den Wert zu Ende der Berechnung in Register \(i\) bezeichnen für alle \( 1 \leq i \leq k \).
Die Funktion move soll für eine Zählmaschine mit 2 Registern den Inhalt des ersten Registers ins zweite übertragen, also \(R_2' = R_1\).
Die Funktion copy soll für eine Zählmaschine mit 3 Registern den Inhalt des ersten Registers ins zweite kopieren, also \(R_1' = R_2' = R_1\).
Die Funktion add soll für eine Zählmaschine mit 3 Registern den Inhalt der ersten zwei Register addieren und ins dritte schreiben, also \(R_3' = R_1 + R_2\).
Die Funktion mult soll für eine Zählmaschine mit 4 Registern den Inhalt der ersten zwei Register multiplizieren und ins dritte schreiben, also \(R_3' = R_1 \cdot R_2\).
Beispiele ('_' steht für eine beliebige Zahl):

Teil 2: Stapelmaschinen

Eine Stapelmaschine ist eine Verallgemeinerung von Zählmaschinen, bei der Strings in den Registern enthalten sind. Eine solche Maschine verfügt über die folgenden Operationen und Prädikate. Das letzte Zeichen eines Strings aus einem Register kann entfernt werden. Ans Ende eines Strings aus einem Register kann ein beliebiges Zeichen aus dem Alphabet angehängt werden. Es kann geprüft werden, ob ein String in einem Register leer ist oder ob das letzte Zeichen dieses Strings gleich einem bestimmten Zeichen ist. Folgende Funktionen stehen zur Verfügung, um eine Stapelmaschine zu steuern.
push    :: SM -> Int -> Char -> SM
pop     :: SM -> Int -> SM
isEmpty :: SM -> Int -> Bool
isChar  :: SM -> Int -> Char -> Bool
Die Funktion push fügt das Zeichen arg3 ans Ende des Strings in Register arg2 hinzu.
Die Funktion pop entfernt das letzte Zeichen des Strings in Register arg2 (String bleibt unverändert falls leer).
Die Funktion isEmpty ist wahr gdw. der String in Register arg2 leer ist.
Die Funktion isChar ist wahr gdw. das letzte Zeichen des Strings in Register arg2 gleich arg3 ist.
reverse :: SM -> SM
move    :: SM -> SM
copy    :: SM -> SM
concat  :: SM -> SM
substr  :: SM -> SM
Für eine Stapelmaschine mit \(k\) Registern soll \(R_i\) den Wert zu Beginn und \(R_i'\) den Wert zu Ende der Berechnung in Register \(i\) bezeichnen für alle \( 1 \leq i \leq k \).
Die Funktion reverse soll für eine Stapelmaschine mit 2 Registern den Inhalt des ersten Registers umgedreht ins zweite Register schreiben, also \(R_2' = \text{reverse}(R_1)\).
Die Funktion move soll für eine Stapelmaschine mit 3 Registern den Inhalt des ersten Registers ins zweite Register schreiben, also \(R_2' = R_1\).
Die Funktion copy soll für eine Stapelmaschine mit 3 Registern den Inhalt des ersten Register ins zweite kopieren, also \(R_1' = R_2' = R_1\).
Die Funktion concat soll für eine Stapelmaschine mit 3 Registern den String aus Register 2 an den String aus Register 1 anhängen und in Register 3 schreiben, also \(R_3' = R_1 R_2\).
Die Funktion substr soll für eine Stapelmaschine mit 4 Registern den Teilstring von \(R_1\), welcher ab dem \((|R_2|+1)\)-ten Zeichen beginnt und Länge \(|R_3|\) hat in Register 4 schreiben.
Sie können davon ausgehen, dass die Strings in den Stapelmaschinen nur aus den Zeichen 'a','b','c' bestehen. Beispiele: