Die Lebensdauer bereits berechneter Werte muß nun über den Aufruf der Funktion hinausgehen, und wir brauchen daher dafür eine globale Datenstruktur, im Hauptprogramm oder besser (wegen des Geheimnisprinzips) in einem eigenen Modul, das die Realisierung verbirgt.
Im Implementierungsmodul berechnen wir nun alle jemals benötigten Werte bereits zur Zeit der Initialisierung des Moduls:DEFINITION MODULE FibMod; (* Modul fuer Fibonacci-Zahlen, robust *) CONST MaxArg = 24; (* fuer groessere Argumente laeuft der Zahlbereich ueber *) PROCEDURE Fib(n: CARDINAL): CARDINAL; (* liefert die n-te Fibonacci-Zahl, falls 0 < n < MaxArg, sonst den illegalen Funktionswert 0 *) END FibMod.
Der Aufruf von Fib hat nun konstanten Aufwand. Will man nicht alle Werte auf Verdacht vorweg berechnen, so kann dies auch in Fib nachgeholt werden:IMPLEMENTATION MODULE FibMod; TYPE Index = 1 .. MaxArg; VAR FibZahl: ARRAY [Index] OF CARDINAL; Ind: Index; PROCEDURE Fib(n: CARDINAL): CARDINAL; BEGIN IF (n < 1) OR (n > MaxArg) THEN RETURN 0 ELSE RETURN FibZahl[n] END: END Fib; BEGIN (* Modul-Initialisierung *) FibZahl[1] := 1; FibZahl[2] := 1; FOR Ind := 3 TO MaxArg DO FibZahl[Ind] := FibZahl[Ind-1] + FibZahl[Ind-2]; END; END FibMod.
Zur Zeit der Modul-Initialisierung berechnen wir jetzt nur die Startwerte F(1) und F(2); alle anderen bis zum höchsten jeweils benötigten Wert werden erst bei Bedarf nachgezogen.IMPLEMENTATION MODULE FibMod; TYPE Index = 1 .. MaxArg; VAR FibZahl: ARRAY [Index] OF CARDINAL; Ind: Index; PROCEDURE Fib(n: CARDINAL): CARDINAL; BEGIN IF (n < 1) OR (n > MaxArg) THEN RETURN 0 ELSE WHILE Ind < n DO Ind := Ind + 1; FibZahl[Ind] := FibZahl[Ind-1] + FibZahl[Ind-2]; END; RETURN FibZahl[n] END: END Fib; BEGIN (* Modul-Initialisierung *) FibZahl[1] := 1; FibZahl[2] := 1; Ind := 2; END FibMod.