Suche…


Bemerkungen

Dies soll die Auswertungsreihenfolge so eindeutig wie möglich erklären. Es ist wahrscheinlich weniger ideal als Einführung in die Mathematica-Ausführung geeignet. Es baut auf Mathematicas tutorial/Evaluation auf, indem es die Reihenfolge erläutert, in der verschiedene Regeln angewendet werden, und erklärt, welche Funktionen von der Evaluierungsmaschine speziell behandelt werden.

Bewertungskontexte

Zu jedem Zeitpunkt wird Code in einem Kontext ausgeführt. Ein Kontext besteht aus einer Reihe von Ersetzungsregeln (seinem Wörterbuch) und einer Priorität, in der sie ausgewertet werden sollten. Wir fassen fünf Arten von Kontexten mit unterschiedlichen Verhaltensweisen und Einschränkungen zusammen: * Set Context * Block Context * Übereinstimmender Context * ReplaceAll Context * ReplaceRepeated Context

Festlegen von Kontexten

Ein Set-Kontext ist derjenige, der durch einen Satz von Set [] - Operationen definiert wird (die Funktion, die häufiger geschrieben wird = ). Das Hauptbeispiel ist die primäre Ausführungsumgebung. Das Wörterbuch wird immer dann geändert, wenn ein Set [] für eine Variable ausgeführt wird, die sich sonst nicht in einem Bereich befindet. Die anderen Instanzen von Set Contexts ergeben sich aus Paketen. Ein Paketkontext bezieht sich auf seinen übergeordneten Kontext, indem alle Muster innerhalb des Pakets zu Mustern innerhalb des übergeordneten Kontext mit einem entsprechenden Präfix werden (eine Definition foo[x_]=3*x wird zu InnerPackageName\ foo [x _] = 3 * x `).

Satzkontexte können nur Regeln enthalten, denen ein "Tag" zugeordnet ist, eine Zeichenfolge, die dem Kopf zugeordnet ist, um die Anwendbarkeit der Regel schneller zu identifizieren. Eine Anwendung von Set[yyy_,zzz_] bestimmt ein Tag, indem geprüft wird, ob yyy ein Symbol ist. Wenn ja, dann ist es das Tag. Andernfalls wird yyy[[0]] und dann yyy[[0,0]] usw. überprüft. Wenn es irgendwann als ein Symbol bestimmt wird, wird dies als Tag verwendet. Ist es stattdessen ein Nicht-Symbolatom (z. B. String, Integer, Real ...), wird ein Fehler ausgegeben, und es wird keine Regel erstellt.

Die Funktionen UpSet (geschrieben ^= ) und TagSet (geschrieben /: / = ) (und ihre Verwandten UpSetDelayed und TagSetDelayed) ermöglichen das Zuordnen einer Regel zu einem anderen Tag. Es gibt immer noch die Einschränkung, dass das Tag ein Symbol sein muss. UpSet ordnet es den einzelnen Argumenten im Ausdruck zu, oder deren Kopf, wenn es sich um eine Funktion mit einem Kopfsymbol handelt. Wenn Sie beispielsweise UpSet für f[a,b,c+d,e[f,g],5,h[i][j][k],p_] wird die erstellte Regel mit a , b , e , und h . Den Argumenten c+d , 5 und p_ ist nichts zugeordnet und es wird eine Fehlermeldung angezeigt. Die Zuweisung wird für jedes der Argumente weiterhin erfolgreich sein, und (wie später in der Auswertungsreihenfolge klargestellt wird) funktioniert für fast alle Zwecke. TagSet ist wie UpSet, Sie können jedoch genau ein Symbol für das Tag angeben. Das Symbol muss noch ein Element sein, das von Set oder UpSet gesetzt werden kann (ein oberstes Symbol im Kopf oder die Argumente). Zum Beispiel ist TagSet[f, f[a,b[c]], 2] akzeptabel und TagSet[f, f[a,b[c]], 2] die Definition f . TagSet[a, f[a,b[c]], 2] und TagSet[b, f[a,b[c]], 2] sind ebenfalls zulässig, aber TagSet[c, f[a,b[c]], 2] ist nicht.

Regeln in einem Kontext benötigen eine Anwendungspriorität, da es für einen bestimmten Ausdruck viele Regeln geben kann. (Dies gilt auch für ReplaceAll- und ReplaceRepeated-Kontexte, die jedoch sehr unterschiedlich behandelt werden.) Die Priorität soll im Allgemeinen der Spezifität des Musters entsprechen. Wenn ein Ausdruck a[q][b[c,d],e[f,g]] , wobei der Kopf und die Argumente so vollständig wie möglich ausgewertet werden (siehe unten TODO), beginnen Sie mit der Suche nach mit Tags versehenen Regeln mit b die zutreffen; dann mit e Regeln; dann mit a Regeln. Innerhalb jedes Regelwerks wird eine Reihenfolge nach den Regeln eines bestimmten Symbols beibehalten. Regeln ohne Leerzeichen (z. B. f[a,b]=3 ) werden automatisch oben platziert und in kanonischer Reihenfolge (Sortierreihenfolge) sortiert. Jedes Mal, wenn eine neue Regel hinzugefügt wird, durchläuft der Kernel die Liste. Wenn eine Regel genau die gleiche LHS hat, wird sie an Ort und Stelle ersetzt. Ansonsten führt es einen Vergleich der Spezifität durch. Wenn eine Regel X, die bereits in der Liste enthalten ist, als "weniger genau" als die neue Regel Y bestimmt wird, wird Y unmittelbar vor X platziert. Andernfalls wird die Liste fortgesetzt. Wenn keine Regel weniger genau ist, wird die Regel am Ende der Liste platziert. Die Überprüfung der Spezifität ist komplizierter und wird im folgenden Abschnitt genauer beschrieben.

Regelspezifität

* Wenn zwei Ausdrücke haben keine Instanz von BlankSequence ( __ ), BlankNullSequence ( ___ ), Optional ( : ), Alternatives ( | ), wiederholten ( .. ), RepeatedNull ( ... ) oder optionaler Argumenten ( _. ), Dann Sie können strukturell verglichen werden. Wenn zwei äquivalente Ausdrucksbäume X und Y gegeben sind, bei denen alle Leerzeichen in Y auch Leerzeichen in X sind, X jedoch Leerzeichen enthält, bei denen Y dies nicht ist, dann ist Y genauer. * Wenn zwei Ausdrücke sind äquivalent , außer dass einige Fälle von _ werden mit ersetzt worden __ in dem anderen Ausdruck oder __ ersetzt wurden withh ___ , dann ist die erstere spezifisch ist. * Wenn Strippen eine weitere Optional ( : ) (oder optional _. ) Hinsichtlich der anderen Ausdruck gibt, dann ist die letztere spezifischer. * Wenn eine bestimmte Auswahl von Alternativen den anderen Ausdruck ergibt, ist der letztere spezifischer. * Wenn alle Instanzen von RepeatedNull[foo] durch Repeated[foo] oder Repeated[foo] durch foo , ergibt sich der andere Ausdruck. Letzteres ist spezifischer. * Einige dieser Regeln können auf einmal angewendet werden, sind aber derzeit nicht anwendbar wissen, was die Fälle dafür sind. * Kombinationen von Ausdrücken wie _List und {___} sollten sie theoretisch identisch behandeln, aber der Vergleich scheint seltsam kontextabhängig zu sein und gelegentlich auf die eine oder andere Weise _List .

Kontext blockieren

Ein Blockkontext ist insofern restriktiver, als die LHS einer Regel in einem Block nur ein Symbol sein kann. Das heißt, nur Definitionen der Form f=2+x , nicht f[x_]=2+x . (Unter praktischen Gesichtspunkten können Funktionen immer noch mit Definitionen wie "Set [Block" ") erstellt werden, da alle neuen Definitionen während der Bewertung des Blocks wie üblich an den umgebenden Kontext weitergeleitet werden wird einen Satz von Variablen "spiegeln" und Definitionen bereitstellen, die die des umgebenden Kontextes verdecken können. Definitionen aus dem umgebenden Kontext sind während der Auswertung des inneren Ausdrucks weiterhin verfügbar. Da einem Symbol nur Definitionen zugeordnet werden können, gibt es keine Ahnung Priorität wie oben.

Übereinstimmender Kontext

Nachdem eine Regel abgeglichen wurde, gibt es lokal gebundene Definitionen für Variablen. Dies geschieht lexikalisch . Das heißt, es wird in den gebundenen Definitionen für Variablen im Ausdruck subsitiert, ohne etwas anderes auszuwerten. Erst wenn alle Untersetzungen aufgetreten sind, beginnt der Ausdruck als Ganzes wieder von oben. Die Hauptmethode, mit der übereinstimmende Kontexte erstellt werden, ist eine Regel aus einem Satzkontext oder einer Regel. Zum Beispiel in

g[a_]:=a+x;
f[x_]:=x+g[1];
f[x^2]
(*Yields 1+x+x^2 *)

Bei Übereinstimmung der f[x_] -Regel mit f[y] wird das Symbol x an den Wert x^2 gebunden. Es führt die eine Ersetzung durch, aber da es g nicht auswertet, gibt es x^2+g[1] . Dieser wird dann im umgebenden Set Context erneut ausgewertet und wird zu 1+x+x^2 . Der wesentliche Unterschied bei der Bewertung in einem abgeglichenen Kontext besteht darin, dass die Ersetzung nicht rekursiv ist. Wenn es x->x^2 subsituiert, wiederholt es sich selbst bei seinen eigenen Ergebnissen nicht.

Übereinstimmende Kontexte werden insbesondere mit With , Module , Function und Replace . Viele andere Funktionen erstellen sie intern, zum Beispiel verwendet Plot diesen Kontexttyp zur Auswertung des zu plottenden Ausdrucks.

ReplaceRepeated Context

Ein ReplaceRepeated-Kontext wird erstellt, wenn eine Anwendung von ReplaceRepeated auftritt. Dies unterscheidet sich dahingehend, dass es als Regel-LHS einen beliebigen Ausdruck haben kann, einschließlich solcher ohne Tag wie _[_] . In diesem Sinne ist es der flexibelste Kontext. Es kann auch mehrere Regeln enthalten, die miteinander in Konflikt stehen können. Daher muss eine Priorität beibehalten werden. Ein ReplaceRepeated-Kontext wendet die erste Regel in der Liste zuerst an, wo dies möglich ist. Wenn es nicht passt, wird mit dem zweiten fortgefahren und so weiter. Wenn zu irgendeinem Zeitpunkt eine Regel übereinstimmt, kehrt sie zur ersten Regel zurück und beginnt von vorne. Wenn zu irgendeinem Zeitpunkt eine Regelanwendung auftritt und keine Änderung auftritt, wird sie beendet - auch wenn andere Regeln in der Liste später Änderungen vornehmen würden. Dies bedeutet, dass alle weniger spezifischen Regeln, die sich früher in der Liste befinden, verhindern, dass spätere Regeln verwendet werden. ReplaceRepeated a_->a an die Spitze der ReplaceRepeated der gesamte ReplaceRepeated sofort beendet.

ReplaceAll Context

Ein ReplaceAll-Kontext wird erstellt, wenn eine Anwendung von ReplaceAll auftritt. Seine Funktionsweise ist der von ReplaceRepeated ähnlich, da die Priorität der Regelanwendung in der Liste in der Reihenfolge angezeigt wird, wenn zwei auf derselben Ebene des Ausdrucks angewendet werden können. Es ist jedoch wie ein Matched Context, dass die ersetzten Inhalte nicht weiter ausgewertet werden, auch nicht durch spätere Regeln . Beispielsweise ergibt x/.{x->y,y->z} y . Daher ist es falsch, eine Anwendung von ReplaceAll anzuzeigen, bei der jede Regel der Reihe nach angewendet wird. Stattdessen durchquert es den Baum und sucht nach anwendbaren Regeln. Wenn etwas gefunden wird, das passt, führt es die Ersetzung aus und kehrt dann in den Baum zurück, ohne den neuen Baum zu durchqueren. Es ist auch erwähnenswert, dass versucht wird, Regeln von oben nach unten anzuwenden, was möglicherweise dazu führt, dass die Liste nicht in der richtigen Reihenfolge läuft. Zum Beispiel,

Cos[1 + 2 Sqrt[Sin[x]]] /. {Cos[_] -> 5, Sin[_] :> (Print[1]; 10)}
Cos[1 + 2 Sqrt[Sin[x]]] /. {Sin[_] :> (Print[1]; 10), Cos[_] -> 5}

beide ergeben 5 ohne etwas zu drucken. Da Cos[_] mit einer höheren Ebene des Baums übereinstimmt, wird diese zuerst angewendet.

Hold und Evaluate und die Ausführungsreihenfolge

Die Reihenfolge der Auswertung HoldFirst gegebenem Ausdruck wie HoldFirst : * Den Kopf so genau wie möglich HoldFirst * Wenn der Kopf eine Hold Eigenschaft ( HoldFirst , HoldRest , HoldAll , HoldAllComplete ) hat, dann * Die relevanten Argumente HoldAllComplete . Wenn es sich nicht um HoldAllComplete , prüfen Sie, ob der Kopf Evaluate . Ist dies der Fall, Evaluate Sie das Evaluate und markieren Sie es trotzdem. * Überprüfen Sie die Argumente für Unevaluated Instanzen und Unevaluated sie gegebenenfalls, sofern nicht die Eigenschaft HoldAllComplete vorhanden ist. * Reduzieren Sie Argumente aus Sequence , es sei denn, SequenceHold wird angewendet. * Listable Sie die Attribute Flat , Listable , Orderless . * Wende die mit den Upvalues ​​des Arguments verbundene Bewertung (ihre Tags) an. * Wende die mit dem Kopf verbundene Bewertung an.

Wenn die Auswertung eines Ausdrucks abgeschlossen ist, wird er als vollständig ausgewertet markiert. Nachfolgende Auswertungen, die diesen Ausdruck treffen, versuchen nicht, ihn zu bewerten. Wenn eine neue Regel für ein darin definiertes Symbol definiert ist, wird das Flag entfernt und kann erneut ausgewertet werden. Der bemerkenswerte Ort, an dem dies fehlschlägt, ist Condition ( \; ): Eine Bedingungsregel könnte bei der ersten Bewertung möglicherweise nicht zutreffen. Wenn ein nicht verbundenes Symbol Werte ändert und die Bedingung jetzt gilt, wird der Ausdruck weiterhin als vollständig ausgewertet markiert und ändert sich dadurch nicht. Die Funktion Update ist insofern einzigartig, als sie ihr Argument unabhängig von ihrem bereits bewerteten Status auswertet, was zu einer Art "Cache-Leerung" führt.

Es gibt eine Reihe von anderen Funktionen , die oft angesehen werden als außergewöhnlich, wie Hold , Defer , ReplacePart , Extract oder ReleaseHold . Diese Effekte können alle durch Attribute (wie HoldAll ) und normale Funktionsdefinition erzielt werden und müssen nicht vom Evaluator eindeutig behandelt werden.

Anwendung von "ReplaceAll" und "ReplaceRepeated"

Beispiel, wie ReplaceAll höchstens einmal eine Regel anwendet, während ReplaceRepeated dies in einer Schleife ReplaceRepeated , die Anwendung jedoch immer von der ersten Regel aus ReplaceRepeated startet.

x + a /. {
  a_ + z :> (Print[0]; DoneA),
   a_ + x :> (Print[1]; y + z), 
   a_ + y :> (Print[2]; DoneB)}

(* Prints "1", yields "y+z" *)

x + a //. {
  a_ + z :> (Print[0]; DoneA),
   a_ + x :> (Print[1]; y + z), 
   a_ + y :> (Print[2]; DoneB)}

(* Prints "1", then prints "0", yields "DoneA" *)

Blase sortieren

Blasensortierung mit Regeln und Ersetzungen:

list = {1, 4, 2, 3, 6, 7, 8, 0, 1, 2, 5, 4}

list //. {fsts___, x_, y_, lsts___} :> {fsts, y, x, lsts} /; y < x

(* 
    Out[1] := {1, 4, 2, 3, 6, 7, 8, 0, 1, 2, 5, 4}
    Out[1] := {0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8}
*)


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow