This is documentation for Mathematica 4, which was
based on an earlier version of the Wolfram Language.
View current documentation (Version 11.1)

 Documentation /  Mathematica /  Das Mathematica Buch /  Die Prinzipien von Mathematica /  Evaluierung von Ausdrücken /

Fortgeschrittenes Thema: Der EvaluierungsstapelFortgeschrittenes Thema: Unterbrechungen und Abbrüche

2.5.12 Fortgeschrittenes Thema: Kontrolle unendlicher Evaluierung

Mathematica handelt bei der Evaluierung von Ausdrücken nach dem allgemeinen Prinzip, so lange Transformationsregeln anzuwenden, bis sich die Ausdrücke nicht mehr ändern. Daraus folgt: Wenn Sie zum Beispiel eine Zuweisung wie x = x + 1 machen, geht Mathematica in eine Endlosschleife. Mathematica stoppt jedoch nach einer definierten Anzahl Schritte, die sich aus dem Wert der globalen Variablen $RecursionLimit ergibt. In jedem Fall können Sie Mathematica auch früher stoppen, indem Sie es unterbrechen.

Diese Zuweisung könnte eine Endlosschleife erzeugen. Mathematica stoppt nach einer Anzahl Schritte, die sich aus $RecursionLimit ergibt.

In[1]:= x = x + 1

Out[1]=

Stoppt Mathematica, ohne die Evaluierung zu beenden, so liefert es ein gehaltenes Ergebnis. Sie können die Evaluierung fortsetzen, indem Sie explizit ReleaseHold aufrufen.

In[2]:= ReleaseHold[%]

Out[2]=

Globale Variablen, die die unendliche Evaluierung einschränken

Hier ist eine zirkuläre Definition, deren Evaluierung durch $IterationLimit gestoppt wird.

In[3]:= {a, b} = {b, a}

Out[3]=

Die Variablen $RecursionLimit und $IterationLimit kontrollieren die zwei Grundwege, auf denen eine Evaluierung in Mathematica unendlich werden kann. $RecursionLimit beschränkt die maximale Tiefe des Evaluierungsstapels oder, äquivalent dazu, die maximale Verschachtelungstiefe, die in der durch Trace produzierten Listenstruktur auftreten würde. $IterationLimit beschränkt die maximale Länge jeder speziellen Evaluierungskette oder die maximale Länge jeder einzelnen Liste in der durch Trace produzierten Struktur.

$RecursionLimit und $IterationLimit werden in Vorgabe gleich Werten gesetzt, die sich für die meisten Berechnungen und die meisten Computersysteme eignen. Sie können diese Variablen jedoch in beliebige ganze Zahlen (jenseits einer unteren Schranke) oder in Infinity abändern. Beachten Sie: Auf den meisten Computersystemen sollten Sie niemals $RecursionLimit = Infinity vorgeben (siehe dazu Abschnitt 2.13.4).

Dies ändert $RecursionLimit und $IterationLimit in 20.

In[4]:= $RecursionLimit = $IterationLimit = 20

Out[4]=

Nun werden unendliche Definitionen wie diese nach nur 20 Schritten abgebrochen.

In[5]:= t = {t}

Out[5]=

Ohne eine End-Bedingung führt diese rekursive Definition zu endlosen Berechnungen.

In[6]:= fn[n_] := {fn[n-1], n}

Eine recht große Struktur wird aufgebaut, ehe die Berechnung gestoppt wird.

In[7]:= fn[10]

Out[7]=

Hier ist eine andere rekursive Definition.

In[8]:= fm[n_] := fm[n - 1]

In diesem Fall wird keine komplizierte Struktur aufgebaut, und die Berechnung wird durch $IterationLimit gestoppt.

In[9]:= fm[0]

Out[9]=

Es ist wichtig, zu wissen, daß Endlosschleifen nicht nur viel Zeit, sondern auch Speicherplatz beanspruchen können. Durch $IterationLimit beschränkte Berechnungen bauen normalerweise keine großen Zwischenstrukturen auf. Durch $RecursionLimit beschränkte tun dies hingegen häufig. In vielen Fällen ist der Umfang der produzierten Strukturen eine lineare Funktion des Wertes von $RecursionLimit. In einigen Fällen kann dieser jedoch exponentiell oder noch stärker mit $RecursionLimit anwachsen.

Eine Zuweisung wie x = x + 1 ist offensichtlich zirkulär. Wenn Sie jedoch kompliziertere rekursive Definitionen aufstellen, kann es sehr viel schwieriger werden, sicherzustellen, daß die Rekursion terminiert und daß sie nicht in einer Endlosschleife endet. Es sollte hauptsächlich geprüft werden, daß die rechten Seiten Ihrer Transformationsregeln sich immer von den linken Seiten unterscheiden. Dies stellt sicher, daß die Evaluierung immer „Fortschritt machen" wird, und daß Mathematica am Ende nicht einfach dieselbe Transformationsregel immer wieder auf denselben Ausdruck anwendet.

Einige der kniffligsten Fälle treten auf, wenn Sie Regeln haben, die von komplizierten /;-Bedingungen abhängen (siehe Abschnitt 2.3.5). Besonders schwer zu handhaben ist es, wenn die Bedingung eine „globale Variable" enthält. Es kann sein, daß Mathematica annimmt, daß die Evaluierung beendet ist, weil der Ausdruck sich nicht geändert hat. Als Nebeneffekt einer anderen Operation kann sich jedoch der Wert der globalen Variablen ändern und sollte so zu einem neuen Ergebnis in der Evaluierung führen. Dies wird am besten dadurch verhindert, indem man in /;-Bedingungen keine globalen Variablen einsetzt. Wenn alles fehlschlägt, dann können Sie Update[s] eingeben und damit Mathematica anweisen, alle Ausdrücke, die s enthalten, zu aktualisieren. Update[ ] weist Mathematica an, alle Ausdrücke zu aktualisieren.

Fortgeschrittenes Thema: Der EvaluierungsstapelFortgeschrittenes Thema: Unterbrechungen und Abbrüche