• Keine Ergebnisse gefunden

Das Variablenkonzept des symbolischen Rechnens

Wir hatten bereits gesehen, dass die Analyse symbolischer Ausdr¨ucke zur Laufzeit, die ja im Mittelpunkt des Interpreters eines CAS steht, weniger ¨Ahnlichkeiten zum Laufzeitverhalten einer klassischen Programmiersprache hat als vielmehr zu den Techniken, die Compiler oder Interpreter derselbenzur ¨Ubersetzungszeit verwenden.

Das trifft insbesondere auf das Variablenkonzept zu, in dem statt der klassischen Bestandteile Bezeichner, Wert, Speicherbereich und Datentyp, von denen in symbolischen Umgebungen so-wieso nur die ersten beiden eine Bedeutung besitzen, neben dem Bezeichner verschiedenartige

4Dort heißen die drei Funktionencar,cdrundcons.

H.-G. Gr¨abe: Einf¨uhrung in das symbolische Rechnen, Notizen zur Vorlesung 52

symbolische Informationen eine Rolle spielen, die wir als Eigenschaften dieses Bezeichners zu-sammenfassen wollen.

Die entscheidende Besonderheit in der Verwendung von Variablen in einem symbolischen Kontext besteht aber darin, dass sich Namensraum und Wertebereich ¨uberlappen. In der Tat ist in einem Ausdruck wiex2+ynicht klar, ob der Bezeichnerxhier imSymbolmodus f¨ur sich selbst steht oder imWertmodus Container eines anderen Werts ist. Mehr noch kann sich die Bedeutung je nach Kontext unterscheiden. So wird etwa in einem Aufruf

u:=integrate(1/(sin(x)*cos(x)-1),x);

xsymbolisch gemeint sein, selbst wennxbereits einen Wert besitzt.

Sehen wir uns diese Besonderheit des Varia-blenkonzepts zun¨achst in einigen MuPAD -Beispielen an. Durch die Zuweisungx:= 2 wur-de wur-der Bezeichner x aus dem Symbolmodus x in den Wertmodus ¨uberf¨uhrt. Der unter dem Bezeichner x gespeicherte Wert geht in die nachfolgende Auswertung vonpein. Die Zuwei-sung an xbeeinflusst also als Seiteneffekt das (zuk¨unftige) Auswerteverhalten vonp.

p:=9*x^3-37*x^2+47*x-19;

9x3−37x2+ 47x−19 x:=2;

p;

−1

Versuchen wir nun diese Umwandlung r¨ uck-g¨angig zu machen. Der erste Versuch f¨uhrt nicht zum Erfolg.

xist noch immer im Wertmodus, nun aber Con-tainer eines symbolischen Werts.

x:=free;

p;

9 free3−37 free2+ 47 free−19

Auch diese

”Verzweiflungstat“ hilft nicht wei-ter, denn bei einer Zuweisung wird die rechte Seite ausgewertet und deren Wert der linken Seite zugewiesen.

x:=x;

x:= free

Um x als Symbol zu verwenden, m¨ussen wir diese Auswertung verhindern, was inMuPAD durch die Funktionholderreicht werden kann.

Leider geht nun gar nichts mehr.

x:=hold(x);

p;

Error: Recursive definition [See ?MAXLEVEL]

Der Grund ist leicht gefunden: Da der unter pgespeicherte Ausdruck den Bezeichner xenth¨alt, wird untersucht, ob x im Wertmodus ist (ist es und hat x, sich selbst, als Wert), dieser Wert eingesetzt – was den aktuell f¨urpgefundenen Ausdruck nicht ver¨andert – und dieselbe Frage f¨ur denselben Ausdruck noch einmal gestellt. Wir kommen damit in eine Endlosschleife der st¨andigen Auswertung von x, die hier abgebrochen wird, wenn ein entsprechender Rekursionsz¨ahler eine vorgegebene Grenze ¨uberschreitet.

Nat¨urlich k¨onnte man f¨ur diesen Fall entweder die offensichtlich zu unendlicher Rekursion f¨uhrende Zuweisungx:=hold(x) unterbinden oder einfach mit dem Auswerten aufh¨oren, wenn sich nichts mehr ¨andert (Mathematica), aber beide Ans¨atze lassen sich leicht durch etwas komplexere Zu-weisungsnetze aushebeln.

Um den hier beabsichtigten Effekt zu erreichen, ben¨otigen wir also eine spezielle Anweisung, welche xaus dem Wertmodus in den Symbol-modus zur¨ucksetzt, in dem xkein Wert zuge-wiesen ist.

delete x;

p;

9x3−37x2+ 47x−19

Ahnliche Funktionen stehen in allen CAS zur Verf¨¨ ugung. Sie sind in der folgenden Tabelle aufge-listet.

Axiom )clear value x Maxima kill(x)

Maple x:=’x’

Mathematica Clear[x]

MuPAD delete x Reduce clear x

Tabelle 3: Bezeichner in den Symbolmodus zur¨ucksetzen

Maple suggeriert mit seiner Syntax, dass hier eine Selbstwert-Zuweisung erfolgt, aber intern ist es anders implementiert (und funktioniert auch anders als die Zuweisungx:=’y’).

Maximadagegen folgt einem anderen Auswer-teverhalten – es wirdpnur eine Ebene tief aus-gewertet und der Wert x = 2 nicht rekursiv eingesetzt. Daf¨ur muss zus¨atzlich ein Schalter infeval gesetzt oder die zus¨atzliche Evalua-tion durch eval getriggert werden. Das Aus-werteverhalten von Maxima ist noch deutlich komplexer, was hier nicht im Detail diskutiert werden kann.

p:9*x^3-37*x^2+47*x-19;

9x3−37x2+ 47x−19 x:2; p;

9x3−37x2+ 47x−19 p,infeval; /* oder p,eval; */

−1

Damit lassen sich unendliche Evaluationsschleifen durch rekursive Wertzuweisungen bereits im Ansatz vermeiden. Meist sind solche rekursiven Evaluationen auch nicht intendiert.

Bezeichner werden, wie bereits beschrieben, in einerSymboltabelleerfasst, um sie an allen Stellen, an denen sie im Quellcode auftreten, in einheitlicher Weise zu verarbeiten. F¨ur jeden Bezeichner existiertgenauein Eintrag in der Tabelle, unter dem auch weitere Informationen vermerkt sind.

Da in einem CAS jeder in irgendeinem Ausdruck auftretender Bezeichner – auch wenn er zun¨achst im Symbolmodus ist – sp¨ater in den Wertmodus ¨ubergehen kann, muss dieser Mechanismus der eindeutigen Referenzin einem solchen Kontext aufalleBezeichner von ihrem allerersten Auftreten in einem Ausdruck an angewendet werden. Dementsprechend wird bei der Analyse der einzelnen Eingaben jeder String, der einen Bezeichner darstellen k¨onnte, daraufhin gepr¨uft, ob er bereits in die Symboltabelle eingetragen ist. In diesem Fall wird eine Referenz an die entsprechende Stelle der Symboltabelle eingetragen. Andernfalls ist die Symboltabelle um einen neuen Eintrag zu erweitern.

In einigen CAS kann man sich diese Sym-boltabelle ganz oder teilweise anzeigen las-sen. In Mathematica sind die Bezeichner nach Kontexten geordnet, wobei die Kontex-te Global‘ (alle nutzerdefinierten Bezeichner) und System‘ (alle vom System eingef¨uhrten Bezeichner) die wichtigsten sind. F¨uhrt man in einer neu begonnenen Sitzung die Zuweisung u = (x+y)2 aus, so sind danach im Kontext Global‘ drei Symbole definiert, wovon u im Wertmodus, xund y dagegen (noch) im Sym-bolmodus sind.

u=(x+y)^2

Names["Global‘*"]

u x y

?u

Global‘u u= (x+y)2

?x

Global‘x

Mapleverf¨ugt sogar ¨uber zwei solche Funktionen. Die Funktionunameslistet alle Bezeichner im Symbolmodus (unassigned names) auf,anamesalle Bezeichner im Wertmodus.

H.-G. Gr¨abe: Einf¨uhrung in das symbolische Rechnen, Notizen zur Vorlesung 54

Zusammenfassung

In CAS treten Bezeichner in zwei verschiedenenModi, im Symbol- oder im Wertmodus auf.

Ein Bezeichner ist so lange im Symbolmodus, bis ihm ein Wert zugewiesen wird. Durch eine Wertzuweisung geht der Bezeichner in den Wertmodus ¨uber.

F¨ur einen Bezeichner im Wertmodus ist zwischen dem Bezeichner als Wertcontainer und dem Bezeichner als Symbol zu unterscheiden.

Durch eine spezielle Deklaration kann ein Bezeichner in den Symbolmodus zur¨uckversetzt werden. Dabei gehen alle Wertzuweisungen an diesen Bezeichner verloren.

Bezeichner werden in einer Symboltabelle zusammengefasst, um ihre eindeutige Referenzier-barkeit zu sichern.

Dieses einheitliche Management der Bezeichner f¨uhrt dazu, dass auch zwischen Variablenbezeich-nern und FunktionsbezeichVariablenbezeich-nern nicht unterschieden wird. Wir hatten beim Auflisten der dem System bekannten Symbole bereits an verschiedenen Stellen Funktionsbezeichner in trauter Ein-tracht neben Variablenbezeichnern stehen sehen. Dies ist auch deshalb erforderlich, weil in einen Ausdruck wie D(f), die Ableitung der einstelligen Funktion f, Funktionssymbole auf dieselbe Weise eingehen wie Variablensymbole in den Ausdrucksin(x).

CAS unterscheiden nicht zwischen Variablen- und Funktionsbezeichnern.

Da andererseits Funktionsdefinitionen ebenfalls symbolischer Natur sind und

”nur“ einer entspre-chenden Interpretation bed¨urfen, verwenden einige Systeme wie etwa Maple sogar das Zuwei-sungssymbol, um Funktionsdefinitionen mit einem Bezeichner zu verbinden.

Eine solche einheitliche Behandlung interner und externer Bezeichner erlaubt es auch, Systemva-riablen und selbst -funktionen zur Laufzeit zu ¨uberschreiben oder neue Funktionen zu erzeugen und (selbst in den compilierten Teil) einzubinden. Da dies zu unvorhersagbarem Systemverhalten f¨uhren kann, sind die meisten internen Funktionen allerdings vor ¨Uberschreiben gesch¨utzt.