Im Folgenden werden wir die Fakultätsfunktion als imperativen Algorithmus entwerfen.
Fakultätsfunktion:
0
!
=
1
,
x
!
=
x
⋅
(
x
−
1
)
!
für
x
>
0
{\displaystyle 0!=1,x!=x\cdot (x-1)!~{\text{für}}~x>0}
F
A
C
v
a
r
X
,
Y
:
i
n
t
;
{\displaystyle FAC~var~X,Y:int;}
i
n
p
u
t
X
;
{\displaystyle inputX;}
Y
:=
1
{\displaystyle Y:=1}
w
h
i
l
e
X
>
1
d
o
Y
:=
Y
⋅
X
;
X
:=
X
−
1
{\displaystyle while~X>1~do~Y:=Y\cdot X;~X:=X-1}
o
u
t
p
u
t
Y
{\displaystyle output~Y}
Es ist:
[
[
F
A
C
]
]
(
x
)
=
{
x
!
für
x
≥
0
1
s
o
n
s
t
{\displaystyle [\![FAC]\!](x)=\left\{{\begin{array}{ll}x!&{\text{für}}~x~\geq 0\\1&sonst\end{array}}\right.}
Falls die Bedingung der while-Schleife
x
≠
0
{\displaystyle x\neq 0}
lautet, dann ist:
[
[
F
A
C
]
]
(
x
)
=
{
x
!
für
x
≥
0
⊥
s
o
n
s
t
{\displaystyle [\![FAC]\!](x)=\left\{{\begin{array}{ll}x!&{\text{für}}~x~\geq 0\\\bot &sonst\end{array}}\right.}
Gesucht ist das Ergebnis des Aufrufs FAC(3).
Die Abkürzung der while
β
{\displaystyle \beta }
für die Zeile ist
w
h
i
l
e
X
>
1
d
o
Y
:=
Y
⋅
X
;
X
:=
X
−
1
{\displaystyle while~X>1~do~Y:=Y\cdot ~X;X:=X-1}
Die Signatur der Semantikfunktion ist
[
[
F
A
C
]
]
:
i
n
t
→
i
n
t
{\displaystyle [\![FAC]\!]:int\to int}
Die Funktion ist durch Lesen von Y im Endzustand Z definiert
[
[
F
A
C
]
]
(
w
)
=
Z
(
Y
)
{\displaystyle [\![FAC]\!](w)=Z(Y)}
Der Endzustand ist definiert durch
Z
=
[
[
α
]
]
(
Z
0
)
{\displaystyle Z=[\![\alpha ]\!](Z_{0})}
, wobei
α
{\displaystyle \alpha }
die Folge aller Anweisungen des Algorithmus ist.
Der initiale Zustand
Z
0
{\displaystyle Z_{0}}
ist definiert als
Z
0
=
(
X
=
w
,
Y
=
⊥
)
{\displaystyle Z_{0}=(X=w,Y=\bot )}
Die Zustände abkürzend ohne Variablennamen sind
Z
0
=
(
w
,
⊥
)
{\displaystyle Z_{0}=(w,\bot )}
Z
=
[
[
α
]
]
(
Z
0
)
{\displaystyle Z=[\![\alpha ]\!](Z_{0})}
=
[
[
α
]
]
(
3
,
⊥
)
{\displaystyle =[\![\alpha ]\!](3,\bot )}
=
[
[
Y
:=
1
;
w
h
i
l
e
β
]
]
(
3
,
⊥
)
{\displaystyle =[\![Y:=1;while~\beta ]\!](3,\bot )}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
Y
:=
1
]
]
(
3
,
⊥
)
)
{\displaystyle =[\![while~\beta ]\!]([\![Y:=1]\!](3,\bot ))}
=
[
[
w
h
i
l
e
β
]
]
(
3
,
⊥
)
Y
←
1
{\displaystyle =[\![while~\beta ]\!](3,\bot )Y\leftarrow 1}
=
[
[
w
h
i
l
e
β
]
]
(
3
,
1
)
{\displaystyle =[\![while~\beta ]\!](3,1)}
=
{
Z
f
a
l
l
s
Z
(
B
)
=
f
a
l
s
e
[
[
w
h
i
l
e
B
d
o
α
′
]
]
(
[
[
α
′
]
]
(
Z
)
)
s
o
n
s
t
{\displaystyle =\left\{{\begin{array}{ll}Z&falls~Z(B)=false\\\,[\![while~B~do~\alpha ']\!]([\![\alpha ']\!](Z))&sonst\end{array}}\right.}
=
{
(
3
,
1
)
f
a
l
l
s
Z
(
X
>
1
)
=
(
3
>
1
)
=
f
a
l
s
e
[
[
w
h
i
l
e
β
]
]
(
[
[
Y
:=
Y
⋅
X
;
x
:=
X
−
1
]
]
(
Z
)
)
s
o
n
s
t
{\displaystyle =\left\{{\begin{array}{ll}(3,1)&falls~Z(X>1)=(3>1)=false\\\,[\![while~\beta ]\!]~([\![Y:=Y\cdot X;~x:=X-1]\!](Z))&sonst\end{array}}\right.}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
Y
:=
Y
⋅
X
;
X
:=
X
−
1
]
]
(
3
,
1
)
)
{\displaystyle =[\![while~\beta ]\!]([\![Y:=Y\cdot X;~X:=X-1]\!](3,1))}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
X
:=
X
−
1
]
]
(
[
[
Y
:=
Y
⋅
X
]
]
(
3
,
1
)
)
)
{\displaystyle =[\![while~\beta ]\!]([\![X:=X-1]\!]([\![Y:=Y\cdot X]\!](3,1)))}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
X
:=
X
−
1
]
]
(
3
,
3
)
)
{\displaystyle =[\![while~\beta ]\!]([\![X:=X-1]\!](3,3))}
=
[
[
w
h
i
l
e
β
]
]
(
2
,
3
)
{\displaystyle =[\![while~\beta ]\!](2,3)}
=
{
(
2
,
3
)
f
a
l
l
s
Z
(
X
>
1
)
=
(
2
>
1
)
=
f
a
l
s
e
[
[
(
w
h
i
l
e
β
)
]
]
(
[
[
Y
:=
Y
⋅
X
;
X
:=
X
−
1
]
]
(
Z
)
)
s
o
n
s
t
{\displaystyle =\left\{{\begin{array}{ll}(2,3)&falls~Z(X>1)=(2>1)=false\\\,[\![(while~\beta )]\!]~([\![Y:=Y\cdot X;~X:=X-1]\!](Z))&sonst\end{array}}\right.}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
Y
:=
Y
⋅
X
;
X
:=
X
−
1
]
]
(
2
,
3
)
)
{\displaystyle =[\![while~\beta ]\!]([\![Y:=Y\cdot X;~X:=X-1]\!](2,3))}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
X
:=
X
−
1
]
]
(
[
[
Y
:=
Y
⋅
X
]
]
(
2
,
3
)
)
)
{\displaystyle =[\![while~\beta ]\!]([\![X:=X-1]\!]([\![Y:=Y\cdot X]\!](2,3)))}
=
[
[
w
h
i
l
e
β
]
]
(
[
[
X
:=
X
−
1
]
]
(
2
,
6
)
)
{\displaystyle =[\![while~\beta ]\!]([\![X:=X-1]\!](2,6))}
=
[
[
w
h
i
l
e
β
]
]
(
1
,
6
)
{\displaystyle =[\![while~\beta ]\!](1,6)}
=
{
(
1
,
6
)
f
a
l
l
s
Z
(
X
>
1
)
=
(
1
>
1
)
=
f
a
l
s
e
[
[
(
w
h
i
l
e
β
)
]
]
(
[
[
Y
:=
Y
⋅
X
;
X
:=
X
−
1
]
]
(
Z
)
)
s
o
n
s
t
{\displaystyle =\left\{{\begin{array}{ll}(1,6)&falls~Z(X>1)=(1>1)=false\\\,[\![(while~\beta )]\!]~([\![Y:=Y\cdot X;~X:=X-1]\!](Z))&sonst\end{array}}\right.}
=
(
1
,
6
)
{\displaystyle =(1,6)}
Das bedeutet
Z
=
[
[
α
]
]
(
Z
0
)
{\displaystyle Z=[\![\alpha ]\!](Z_{0})}
=
[
[
α
]
]
(
3
,
⊥
)
{\displaystyle =[\![\alpha ]\!](3,\bot )}
...
=
(
1
,
6
)
{\displaystyle =(1,6)}
Damit gilt
[
[
F
A
C
]
]
(
3
)
=
Z
(
Y
)
=
6
{\displaystyle [\![FAC]\!](3)=Z(Y)=6}
Der Übergang von der 3. auf die 4. Zeile folgt der Definition der Sequenz, indem der Sequenzoperator in einen geschachtelten Funktionsaufruf umgesetzt wird. Nur in der 5. Zeile wurde eine Wertzuweisung formal umgesetzt,später sind sie einfach verkürzt direkt ausgerechnet. In der 7. Zeile haben wir die Originaldefinition der Iteration eingesetzt (nur mit Kürzel α' statt α, da α bereits verwendet wurde). Dies entspricht im Beispiel α' = {Y:= Y · X; X:= X - 1}. Das Z in der 7. und 8. Zeile steht für den Zustand (3,1). (In späteren Zeilen analog für den jeweils aktuellen Zustand.)Bei diesem Beispiel sieht man folgendes sehr deutlich: Die Ausführung einer while-Schleife erfolgt analog zur rekursiven Funktionsdefinition!
Da die Vorlesungsinhalte auf dem Buch Algorithmen und Datenstrukturen: Eine Einführung mit Java von Gunter Saake und Kai-Uwe Sattler aufbauen, empfiehlt sich dieses Buch um das hier vorgestellte Wissen zu vertiefen. Die auf dieser Seite behandelten Inhalte sind in Kapitel 3.3.3 zu finden.