AB6 Low-Level Programming
Implement the following functions using only the already imported functions. Additionally, the following language constructs are not permitted:
A counter machine consists of multiple registers. Each register can hold an integer ≥ 0. The value in each register can be incremented or decremented by one. If a register contains a 0 and is decremented then it still contains a 0 afterwards. Additionally, it can be checked whether the number contained in a register is 0. The following functions are available to control a counter machine.
inc :: CM -> Int -> CM
dec :: CM -> Int -> CM
isZero :: CM -> Int -> Bool
The function
inc
(
dec
) increments (decrements) register
arg2
by one. The first register is
1
.
The function
isZero
returns true iff the register
arg2
contains 0.
move :: CM -> CM
copy :: CM -> CM
add :: CM -> CM
mult :: CM -> CM
For a counter machine with \(k\) registers let \(R_i\) and \(R_i'\) denote the integers contained in register \(i\) at the beginning of the computation and at the end, respectively, for all \( 1 \leq i \leq k \).
The function
move
moves the value in the first register to the second for a counter machine with 2 registers, i.e. \(R_2' = R_1\).
The function
copy
copies the value in the first register to the second for a counter machine with 3 registers, i.e. \(R_1' = R_2' = R_1\).
The function
add
adds the value in the first and second register and writes the result to the third register for a counter machine with 3 registers, i.e. \(R_3' = R_1 + R_2\).
The function
mult
multiplies the value in the first and second register and writes the result to the third register for a counter machine with 4 registers, i.e. \(R_3' = R_1 \cdot R_2\).
Examples ('
_
' denotes an arbitrary number):
(move (CM [13,2])) = (CM [_,13])
(copy (CM [5,4,6])) = (CM [5,5,_])
(add (CM [3,4,19])) = (CM [_,_,7])
(mult (CM [2,3,0])) = (CM [_,_,6,_])
A stack machine is a generalization of counter machines where the registers contain strings instead of integers. A stack machine has the following operations and predicates. The last character of a string in a register can be removed. A character can be appended to the end of a string in a register. It can be checked whether the string in a register is empty or whether its last character equals a certain character. The following functions are available to control a stack machine.
push :: SM -> Int -> Char -> SM
pop :: SM -> Int -> SM
isEmpty :: SM -> Int -> Bool
isChar :: SM -> Int -> Char -> Bool
The function
push
appends the character
arg3
to the string in register
arg2
.
The function
pop
removes the last character from the string in register
arg2
(the string remains unchanged if it is empty).
The function
isEmpty
returns true iff the string in register
arg2
is empty.
The function
isChar
returns true iff the last character of the string in register
arg2
equals
arg3
.
reverse :: SM -> SM
move :: SM -> SM
copy :: SM -> SM
concat :: SM -> SM
substr :: SM -> SM
For a stack machine with \(k\) registers let \(R_i\) and \(R_i'\) denote the string contained in register \(i\) at the beginning of the computation and at the end, respectively, for all \( 1 \leq i \leq k \).
The function
reverse
writes the string contained in register 1 in reverse order to register 2 for a stack machine with 2 registers, i.e. \(R_2' = \text{reverse}(R_1)\).
The function
move
moves the string in register 1 to register 2 for a stack machine with 3 registers, i.e. \(R_2' = R_1\).
The function
copy
copies the string in register 1 to register 2 for a stack machine with 3 registers, i.e. \(R_1' = R_2' = R_1\).
The function
concat
appends the string in register 2 to the string in register 1 and writes the resulting string to register 3 for a stack machine with 3 registers, i.e. \(R_3' = R_1 R_2\).
The function
substr
writes the substring of \(R_1\) which starts from the \((|R_2|+1)\)-th character and has length \(|R_3|\) to register 4.
You may assume that strings in the stack machine only consist of the characters
'a','b','c'
.
Examples:
(reverse (SM ["abcaa","abb"])) = (SM [_,"aacba"])
(move (SM ["babc","abb","cab"])) = (SM [_,"babc",_])
(copy (SM ["babc","abb","cab"])) = (SM ["babc","babc",_])
(concat (SM ["cc","abab","ba"])) = (SM [_,_,"ccabab"])
(substr (SM ["abcabc","a","aaa",""])) = (SM [_,_,_,"bca"])