MaxEvalDepth | Setzen der max. Berechnungstiefe |
Hold | das Argument nicht berechnen |
Eval | das Argument berechnen |
While | eine Schleife durchlaufen, solange eine Bedingung erfüllt ist |
Until | eine Schleife durchlaufen, bis eine Bedingung erfüllt ist |
If | eine Verzweigung |
SystemCall | einen Befehl an die Shell weitergeben |
Function | eine Funktion definieren |
Use | eine Datei laden |
For | eine Schleife in C-Syntax |
ForEach | alle Elemente einer Liste in einer Schleife abarbeiten |
Apply | eine Funktion anwenden |
MagArgs | eine Funktion auf alle Argumente anwenden |
Subst | eine Substitution durchführen |
WithValue | eine nur für die aktuelle Berechnung gültige Wertzuweisung |
/:, /:: | lokale Vereinfachungsregeln |
SetHelpBrowser | setzt den für die Hilfefunktion zu verwendenden HTML-Browser |
TraceStack | gibt im Fehlerfall den Inhalt des Stacks aus |
TraceExp | schrittweise Berechnung von Termen |
TraceRule | schrittweise Berechnung einer best. Funktion |
Das Festlegen einer max. Berechnungstiefe verhindert unendliche Rekursionen. Wird z.B. die Funktion f(x) := f(x) definiert, dann ruft sich die Funktion f(x) selber auf, was zu einer unendlichen Rekursion führt. Bei Erreichen der max. Berechnungstiefe wird die Rekursion abgebrochen. Indirekte Rekursionen wie z.B.
In> f(x) := f(x) Out> True; In> f(x) Error on line 1 in file [CommandLine] Max evaluation stack depth reached. Please use MaxEvalDepth to increase the stack size as needed. |
Bei komplexeren Berechnungen kann die max. Berechnungstiefe auch erreicht werden, ohne dass eine unendliche Rekursion vorliegt. In solchen Fällen kann die Berechnungstiefe mit MaxEvalDepth entsprechend angepasst werden.
In> 10 # g(0) <-- 1; Out> True; In> 20 # g(n_IsPositiveInteger) <-- 2 * g(n-1); Out> True; In> g(1001); Error on line 1 in file [CommandLine] Max evaluation stack depth reached. Please use MaxEvalDepth to increase the stack size as needed. In> MaxEvalDepth(10000); Out> True; In> g(1001); Out> 214301721437253464189685009812000362112280962341106721488750077674070210224 98722449863967576313917162551893458351062936503742905713846280871969155149397149 60786913554964846197084214921012474228375590836430609294996716388253479753511833 1087892154125829142392955373084335320859663305248773674411336138752; |
In> Echo({ Hold(1+1), "=", 1+1 }); 1+1 = 2 Out> True; |
In> a := x; Out> x; In> x := 5; Out> 5; In> a; Out> x; In> Eval(a); Out> 5; |
Ein verändertes Verhalten ergibt sich, wenn x bei der Zuweisung a := x bereits den Wert 5 hat. a würde dann ebenfalls den Wert 5 erhalten, da der Zuweisungsoperator die rechte Seite zunächst berechnet.
In> x := 0; Out> 0; In> While (x! < 10^6) [ Echo({x, x!}); x++; ]; 0 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 Out> True; |
In> x := 0; Out> 0; In> Until (x! > 10^6) [ Echo({x, x!}); x++; ]; 0 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 Out> True; |
In> mysign(x) := If (IsPositiveReal(x), 1, -1); Out> True; In> mysign(Pi); Out> 1; In> mysign(-2.5); Out> -1; |
In> mysign(a); Out> -1; |
In> mysign(_x)_IsNumber(N(x)) <-- If (IsPositiveReal(x), 1, -1); Out> True; |
Dieser Befehl darf im Rahmen der Funktion Secure nicht verwendet werden.
In> Function("FirstOf", {list}) list[1]; Out> True; In> FirstOf({a,b,c}); Out> a; |
Der Befehl wird meist in der Form
In> For (i:=1, i<=10, i++) Echo({i, i!}); 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 10 3628800 Out> True; |
In> ForEach(i,{2,3,5,7,11}) Echo({i, i!}); 2 2 3 6 5 120 7 5040 11 39916800 Out> True; |
In> Apply("+", {5,9}); Out> 14; In> Apply({{x,y}, x-y^2}, {Cos(a), Sin(a)}); Out> Cos(a)-Sin(a)^2; |
In> MapArgs(f(x,y,z),"Sin"); Out> f(Sin(x),Sin(y),Sin(z)); In> MapArgs({3,4,5,6}, {{x},x^2}); Out> {9,16,25,36}; |
In> Subst(x, Sin(y)) x^2+x+1; Out> Sin(y)^2+Sin(y)+1; In> Subst(a+b, x) a+b+c; Out> x+c; In> Subst(b+c, x) a+b+c; Out> a+b+c; |
Mit dem zweiten Funktionsaufruf wird dem ersten Element in der Liste von Variablen das erste Element der Werteliste zugewiesen, der zweiten Variablen der zweite Wert usw.
In> WithValue(x, 3, x^2+y^2+1); Out> y^2+10; In> WithValue({x,y}, {3,2}, x^2+y^2+1); Out> 14; |
In> Sin(x)*Ln(a*b) Out> Sin(x)*Ln(a*b); In> % /: { Ln(_x*_y) <- Ln(x)+Ln(y) } Out> Sin(x)*(Ln(a)+Ln(b)); |
Die Muster können dabei in einer der folgenden Formen angegeben werden:
Muster <- Ersetzung
{Muster, Ersetzung}
Lokale Regeln werden mit<- definiert, globale Regeln mit >--.
Der /: Operator durchläuft den Term von oben nach unten und versucht nacheinander die in der Liste angegebenen Regeln anzuwenden. Können die Regeln nicht angewendet werden, dann werden die Teilterme untersucht.
Manchmal ist es erforderlich, den /: Operator mehrfach anzuwenden.
Dazu dient der /:: Operator, der die Vereinfachungsregeln so oft
anwendet, bis sich der Term nicht mehr verändert.
Wenn sich die Regeln gegenseitig aufheben, kann dies zu einer unendlichen
Schleife führen. Dieser Fall kann erkannt werden, wenn zunächst der
/: Operator mehrfach angewendet wird.
In> Sin(u)*Ln(a*b) /: { Ln(_x*_y) <- Ln(x)+Ln(y) } Out> Sin(u)*(Ln(a)+Ln(b)); In> Sin(u)*Ln(a*b) /:: { a <- 2, b <- 3 } Out> Sin(u)*Ln(6); |
In> SetHelpBrowser("netscape") Out> "netscape"; In> ?? |
Für jeden Eintrag wird angezeigt, ob es sich um eine interne oder eine benutzerdefinierte Funktion handelt. Für benutzerdefinierte Funktionen wird zusätzlich angegeben, welche Regel bearbeitet wurde.
Die Funktion ist standardmäßig abgeschaltet, da sie die Ausführungsgeschwindigkeit stark beeinträchtigt.
In> f(x):=f(Sin(x)) Out> True; In> TraceStack(f(2)) Debug> 982 : f (Rule # 0 in body) Debug> 983 : f (Rule # 0 in body) Debug> 984 : f (Rule # 0 in body) Debug> 985 : f (Rule # 0 in body) Debug> 986 : f (Rule # 0 in body) Debug> 987 : f (Rule # 0 in body) Debug> 988 : f (Rule # 0 in body) Debug> 989 : f (Rule # 0 in body) Debug> 990 : f (Rule # 0 in body) Debug> 991 : f (Rule # 0 in body) Debug> 992 : f (Rule # 0 in body) Debug> 993 : f (Rule # 0 in body) Debug> 994 : f (Rule # 0 in body) Debug> 995 : f (User function) Debug> 996 : Sin (Rule # 0 in pattern) Debug> 997 : IsList (interne Funktion) Error on line 1 in file [CommandLine] Max evaluation stack depth reached. Please use MaxEvalDepth to increase the stack size as needed. |
Dieser Befehl erzeugt eine große Ausgabeflut. Bei etwas komplexeren Termen sollte daher der Befehl TraceRule verwendet werden.
In> TraceExp(2+3); TrEnter(2+3); TrEnter(2); TrLeave(2, 2); TrEnter(3); TrLeave(3, 3); TrEnter(IsNumber(x)); TrEnter(x); TrLeave(x, 2); TrLeave(IsNumber(x),True); TrEnter(IsNumber(y)); TrEnter(y); TrLeave(y, 3); TrLeave(IsNumber(y),True); TrEnter(True); TrLeave(True, True); TrEnter(MathAdd(x,y)); TrEnter(x); TrLeave(x, 2); TrEnter(y); TrLeave(y, 3); TrLeave(MathAdd(x,y),5); TrLeave(2+3, 5); Out> 5; |
Der Befehl eignet sich insbesondere zur Untersuchung von Funktionen, die von anderen Funktionen aufgerufen werden.
In> TraceRule(x+y) 2+3*5+4; TrEnter(2+3*5+4); TrEnter(2+3*5); TrArg(2, 2); TrArg(3*5, 15); TrLeave(2+3*5, 17); TrArg(2+3*5, 17); TrArg(4, 4); TrLeave(2+3*5+4, 21); Out> 21; |