Ein wiederhole-Befehl
Einen neuen Befehl einführen
Interessant wäre eine Erweiterung des Befahlssatzes um einen wiederhole-Befehl.
[VW 2, WH 4 [VW 2, RE], VW 2]
Der wiederhole-Befehl soll dabei so ausgeführt werden.
WH 4 [VW 2, RE] wiederhole 4-mal die Befehlsfolge [VW 2, RE]
Aufgabe 1
Erkläre, was das Programm [VW 2, WH 4 [VW 2, RE], VW 2]
ausgehend von der Lage (0,0,N)
des Akteurs leistet.
Die Typdefinition erweitern
Um den wiederhole-Befehl verwenden zu können muss die Typdefinition erweitert werden:
type Befehl
= LI -- links
| RE -- rechts
| VW Int -- vorwärts ...
| WH Int (List Befehl) -- wiederhole ...
> WH 4 [VW 2,RE]
WH 4 [VW 2,RE] : Befehl
> WH 2 [VW 3,WH 4 [VW 2,RE]]
WH 2 [VW 3,WH 4 [VW 2,RE]]
: Befehl
Beachte, dass die Typdefinition jetzt rekursiv ist. Der neue Typname Befehl
kommt selbst bei der Definition des Datentyps Befehl
vor.
Das ist erlaubt und ermöglicht geschachtelte Daten.
Aufgabe 2
(a) Erkläre, warum die Befehle WH 4 [VW 2,RE]]
und WH 2 [VW 3,WH 4 [VW 2,RE]]
von der Typdefinition erfasst werden.
(b) Teste selbst weitere komplexe Befehle, die von der Typdefinition erfasst werden.
Die Befehlsausführung festlegen
Die Ausführung des WH
-Befehls ist etwas komplizierter. Hier ein Vorschlag für eine Umsetzung.
Ausführung des LI-Befehls:
((3,0,N), [LI, ...]) -> ((3,0,W), [...])
((2,1,O), [LI, ...]) -> ...
...
Ausführung des RE-Befehls:
((0,1,N), [RE, ...]) -> ((0,1,O), [...])
((-1,1,O), [RE, ...]) -> ...
...
Ausführung des VW-Befehls:
((2,1,N), [VW 2, ...]) -> ((2,3,N), [...])
((0,-1,O), [VW 2, ...]) -> ...
((-2,4,S), [VW 2, ...]) -> ...
((1,3,W), [VW 2, ...]) -> ...
...
Ausführung des WH-Befehls:
((0,2,N), [WH 4 [VW 2, RE], ...]) -> ((0,2,N), [VW 2, RE, WH 3 [VW 2, RE], ...])
((0,4,O), [WH 3 [VW 2, RE], ...]) -> ((0,4,O), [VW 2, RE, WH 2 [VW 2, RE], ...])
((2,4,S), [WH 2 [VW 2, RE], ...]) -> ...
((0,4,W), [WH 1 [VW 2, RE], ...]) -> ...
((0,4,N), [WH 0 [VW 2, RE], ...]) -> ((0,4,N), [...])
Aufgabe 3
Erkläre die bereits vorgegebenen Zustandsänderungen und ergänze die noch fehlenden.
Eine Implementierung ergänzen
Die Quelltext liefert wieder ein Gerüst für die Implementierung der Befehlsausführung.
type Befehl
= LI -- links
| RE -- rechts
| VW Int -- vorwärts ...
| WH Int (List Befehl) -- Wiederholung ...
type alias Programm = List Befehl
type Richtung
= N -- Norden
| O -- Osten
| S -- Süden
| W -- Westen
type alias Akteur = (Int, Int, Richtung)
type alias Zustand = (Akteur, Programm)
programm1: Programm
programm1 = [VW 2, RE, VW 4, LI, VW 2]
programm2: Programm
programm2 = [VW 2, WH 4 [VW 2, RE], VW 2]
programm3: Programm
programm3 = [WH 2 [VW 10, WH 4 [VW 2, RE]]]
akteur: Akteur
akteur = (0,0,N)
zustand: Zustand
zustand = (akteur, programm1)
exeProgramm: Zustand -> Zustand
exeProgramm ((posx, posy, richtung), programm) =
case programm of
[] ->
((posx, posy, richtung), programm)
befehl::restProgramm ->
case befehl of
LI ->
case richtung of
N -> exeProgramm ((posx, posy, W), restProgramm)
O -> exeProgramm ((posx, posy, N), restProgramm)
S -> exeProgramm ((posx, posy, O), restProgramm)
W -> exeProgramm ((posx, posy, S), restProgramm)
RE ->
case richtung of
N -> exeProgramm ((posx, posy, O), restProgramm)
O -> exeProgramm ((posx, posy, S), restProgramm)
S -> exeProgramm ((posx, posy, W), restProgramm)
W -> exeProgramm ((posx, posy, N), restProgramm)
VW x ->
case richtung of
N -> exeProgramm ((posx, posy+x, N), restProgramm)
O -> exeProgramm ((posx+x, posy, O), restProgramm)
S -> exeProgramm ((posx, posy-x, S), restProgramm)
W -> exeProgramm ((posx-x, posy, W), restProgramm)
WH n befehle ->
if n == 0 then
exeProgramm ...
else
exeProgramm ...
test =
exeProgramm (akteur, programm2)
> test
((0,4,N),[]) : Zustand
Aufgabe 4
Ergänze die fehlenden Teile im Quelltext. Teste anschließend mit unterschiedlichen Daten.