wolfram-mathematica
Evaluatie bestelling
Zoeken…
Opmerkingen
Dit zou de evaluatieorde zo ondubbelzinnig mogelijk moeten verklaren. Het is waarschijnlijk minder ideaal geschikt als introductie op de uitvoering van Mathematica. Het bouwt voort op Mathematica's tutorial/Evaluation door de volgorde uit te leggen waarin verschillende regels worden toegepast en uit te leggen welke functies speciaal door de evaluatie-engine worden behandeld.
Evaluatiecontexten
Code wordt op elk moment binnen een context uitgevoerd. Een context bestaat uit een set vervangingsregels (het woordenboek) en een prioriteit waarin deze moeten worden geëvalueerd. We groeperen vijf soorten contexten met verschillend gedrag en beperkingen: * Set Context * Block Context * Matched Context * ReplaceAll Context * ReplaceRepeated Context
Contexten instellen
Een setcontext is die welke wordt gedefinieerd door een set set [] -handelingen (de functie vaker geschreven = ). Het belangrijkste voorbeeld is de primaire uitvoeringsomgeving. Het woordenboek wordt gewijzigd wanneer een Set [] wordt uitgevoerd op een variabele die anders niet wordt gehanteerd. De andere instanties van Set Contexts komen voort uit pakketten. Een pakketcontext is gerelateerd aan de bovenliggende context doordat alle patronen binnen het pakket ook patronen binnen de bovenliggende context worden, met een passend voorvoegsel (een definitie foo[x_]=3*x wordt InnerPackageName\ foo [x _] = 3 * x `).
Setcontexten kunnen alleen regels bevatten waaraan een "Tag" is gekoppeld, een tekenreeks die aan het hoofd is gekoppeld om de toepasbaarheid van de regel sneller te identificeren. Een toepassing van Set[yyy_,zzz_] zal een Tag bepalen door te controleren of yyy een symbool is. Als dat zo is, dan is het de tag. Anders wordt yyy[[0]] en vervolgens yyy[[0,0]] enzovoort gecontroleerd. Als het op een bepaald punt wordt bepaald als een symbool, dan wordt dat als de tag genomen. Als het in plaats daarvan een niet-symboolatoom is (zoals String, Geheel getal, Real ...), geeft dit een foutmelding en wordt er geen regel gemaakt.
De functies UpSet (geschreven ^= ) en TagSet (geschreven /: / = ) (en hun neven UpSetDelayed en TagSetDelayed) maken het mogelijk om een regel aan een andere Tag te koppelen. Er is nog steeds de beperking dat de tag een symbool moet zijn. UpSet zal het koppelen aan elk van de argumenten in de uitdrukking, of hun hoofd als ze een functie zijn met een symbool voor een hoofd. Als u bijvoorbeeld UpSet op f[a,b,c+d,e[f,g],5,h[i][j][k],p_] wordt de gecreëerde regel gekoppeld aan a , b , e , en h . Aan de argumenten c+d , 5 en p_ is niets gekoppeld en er wordt een foutmelding weergegeven. De opdracht zal nog steeds slagen voor elk van de argumenten en (zoals later in de evaluatie volgorde zal worden verduidelijkt) zal het nog steeds voor bijna alle doeleinden werken. TagSet lijkt op UpSet, maar u kunt precies één symbool voor de tag opgeven. Het symbool moet nog steeds iets zijn dat kan worden ingesteld door Set of UpSet (een symbool op het hoogste niveau in de kop of de argumenten). TagSet[f, f[a,b[c]], 2] is bijvoorbeeld acceptabel en zal de definitie associëren met f ; TagSet[a, f[a,b[c]], 2] en TagSet[b, f[a,b[c]], 2] zijn ook acceptabel, maar TagSet[c, f[a,b[c]], 2] is dat niet.
Regels binnen een context hebben een toepassingsprioriteit nodig, omdat er veel regels kunnen zijn die op een bepaalde uitdrukking van toepassing zijn. (Dit is ook waar in ReplaceAll en ReplaceRepeated Contexts, maar ze behandelen het heel anders). De prioriteit is in het algemeen bedoeld om overeen te komen met de specificiteit van het patroon. Gegeven een uitdrukking a[q][b[c,d],e[f,g]] om te evalueren, met het hoofd en de argumenten allemaal zo volledig geëvalueerd als ze zullen zijn (zie hieronder TODO), begin met het zoeken naar getagde regels met b die van toepassing zijn; vervolgens regels gelabeld met e ; dan regels gelabeld met a . Binnen elke set regels wordt een volgorde gehandhaafd op de regels die bij een bepaald symbool horen. Regels zonder spaties (bijvoorbeeld f[a,b]=3 ) worden automatisch boven gebracht en gesorteerd in canonieke volgorde (de volgorde van sorteren). Telkens wanneer een nieuwe regel wordt toegevoegd, doorloopt de kernel de lijst; als een regel exact dezelfde LHS heeft, wordt deze ter plekke vervangen. Anders doet het een specificiteitsvergelijking. Als wordt bepaald dat regel X die al in de lijst staat "minder specifiek" is dan de nieuwe regel Y, wordt Y onmiddellijk voor X geplaatst. Anders gaat deze door de lijst. Als geen regel minder specifiek is, wordt de regel aan het einde van de lijst geplaatst. De specificiteitscontrole is ingewikkelder en wordt in meer detail in het onderstaande gedeelte gegeven.
Regelspecificiteit
* Als twee uitdrukkingen geen geval van BlankSequence ( __ ), BlankNullSequence ( ___ ), Optioneel ( : ), Alternatives ( | ), herhaalde ( .. ), RepeatedNull ( ... ), of optionele argumenten ( _. ), Dan ze kunnen structureel worden vergeleken. Gegeven twee equivalente expressiebomen X en Y, waarbij alle spaties in Y ook spaties in X zijn, maar X spaties heeft waar Y dat niet doet, dan is Y specifieker. * Als twee expressies equivalent zijn, behalve dat sommige instanties van _ zijn vervangen door __ in de andere expressie, of __ zijn vervangen doorh ___ , dan is de eerste specifieker. * Als strippen nog Optioneel ( : ) (of optioneel _. ) Termen geeft andere uitdrukking, waarna de laatste specifieker. * Als een bepaalde reeks keuzes uit Alternatieven de andere uitdrukking geeft, is deze laatste specifieker. * Als het vervangen van alle instanties van RepeatedNull[foo] door Repeated[foo] , of Repeated[foo] door foo , de andere uitdrukking geeft, is deze laatste specifieker * Sommige combinaties van deze regels kunnen in één keer worden toegepast, maar het is momenteel niet weet wat de gevallen hiervoor zijn. * Combinatie van uitdrukkingen zoals _List en {___} zouden ze in theorie identiek moeten behandelen, maar de vergelijking lijkt vreemd context-afhankelijk te zijn, waardoor ze af en toe op een of andere manier worden gerangschikt.
Blokkeer context
Een blokcontext is restrictiever, omdat het LHS van een regel in een blok alleen een symbool kan zijn. Dat wil zeggen, alleen definities van de vorm f=2+x , niet f[x_]=2+x . (Merk op dat vanuit een praktisch oogpunt functies nog steeds kunnen worden geconstrueerd met definities zoals `Set [Blok is gerelateerd aan de bovenliggende context, omdat nieuwe definities tijdens de evaluatie van het Blok normaal worden doorgestuurd naar de omringende context, maar het zal een aantal variabelen "schaduwen", waardoor definities worden verkregen die die van de omringende context kunnen verbergen. Definities van de omringende context zijn nog steeds toegankelijk tijdens de evaluatie van de innerlijke uitdrukking. Omdat er alleen definitie kan zijn gekoppeld aan een symbool, is er geen idee van prioriteit zoals hierboven.
Overeenkomende context
Nadat een regel is gekoppeld, zijn er lokaal gebonden definities voor variabelen. Dit gebeurt lexicaal . Dat wil zeggen, het vervangt in de gebonden definities voor variabelen in de uitdrukking, zonder iets anders te evalueren. Pas als alle subsubs hebben plaatsgevonden, begint het de expressie als geheel opnieuw van bovenaf te evalueren. De primaire manier waarop Matched Contexts worden gemaakt, is een regel uit een Set Context of Rule. Bijvoorbeeld in
g[a_]:=a+x;
f[x_]:=x+g[1];
f[x^2]
(*Yields 1+x+x^2 *)
Bij het matchen van de f[x_] regel met f[y] , is het symbool x gebonden aan de waarde x^2 . Het voert de ene vervanging uit, maar omdat het g niet evalueert, geeft het x^2+g[1] . Dit wordt vervolgens geëvalueerd in vlakke Set context opnieuw en wordt 1+x+x^2 . Het significante verschil in evaluatie in een Matched Context is dat de vervanging niet recursief is. Wanneer het x->x^2 vervangt, herhaalt het zelfs niet op zijn eigen resultaten.
Overeenkomende contexten worden met name ook gemaakt met With , Module , Function en Replace . Veel andere functies maken ze intern, bijvoorbeeld Plot gebruikt dit type context bij het evalueren van de uit te zetten uitdrukking.
Vervang Herhaalde context
Er wordt een ReplaceRepeated-context gemaakt wanneer een toepassing van ReplaceRepeated plaatsvindt. Dit onderscheidt zich doordat het elke expressie als regel LHS kan hebben, inclusief die zonder tag, zoals _[_] . In deze zin is het de meest flexibele context. Het kan ook verschillende regels bevatten die tegenstrijdig kunnen zijn, dus het moet een prioriteit behouden. Een ReplaceRepeated Context past de eerste regel in de lijst toe, indien van toepassing. Als het niet overeenkomt, gaat het verder naar de tweede, enzovoort. Als op enig moment een regel overeenkomt, keert deze terug naar de eerste regel en begint opnieuw. Als zich op enig moment een regeltoepassing voordoet en er geen verandering optreedt, wordt deze afgesloten - zelfs als andere regels later in de lijst een wijziging zouden aanbrengen. Dit betekent dat eventuele minder specifieke regels eerder in de lijst voorkomen dat latere regels ooit worden gebruikt. Bovendien, het plaatsen van a_->a aan de voorzijde van de lijst met regels zal leiden tot een onmiddellijke beëindiging van de gehele ReplaceRepeated .
Vervang alle context
Een ReplaceAll-context wordt gemaakt wanneer een toepassing van ReplaceAll plaatsvindt. De werking ervan is vergelijkbaar met die van ReplaceRepeated in die zin dat de prioriteit van de regeltoepassing op orde komt in de lijst wanneer twee beide op hetzelfde niveau van de uitdrukking kunnen worden toegepast. Het is echter als een overeenkomende context omdat de vervangen inhoud niet verder wordt geëvalueerd, zelfs niet door latere regels . Bijvoorbeeld x/.{x->y,y->z} levert y . Het is dus onjuist om te zien dat een toepassing van ReplaceAll elke regel om de beurt toepast. In plaats daarvan doorloopt het de boom, op zoek naar toepasselijke regels. Wanneer het iets vindt dat overeenkomt, voert het de vervanging uit en keert vervolgens de boom terug, zonder de nieuwe boom te passeren. Het is ook vermeldenswaard dat het probeert regels van boven naar beneden toe te passen, waardoor de lijst mogelijk uit de volgorde raakt. Bijvoorbeeld,
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 leveren 5 zonder iets af te drukken. Omdat de Cos[_] overeenkomt met een hoger niveau van de boom, geldt die eerst.
Hold en Evaluate en de uitvoeringsorder
De volgorde van de evaluatie, gegeven een uitdrukking, verloopt als volgt: * Evalueer de kop zo grondig mogelijk * Als de kop een eigenschap Hold heeft ( HoldFirst , HoldRest , HoldAll , HoldAllComplete ), dan * Controleer de relevante argumenten. Tenzij het HoldAllComplete , controleer of de kop Evaluate . Als dit het geval is, strip dan de Evaluate en markeer deze toch om te evalueren. * Controleer argumenten voor instanties van Niet Unevaluated en verwijder ze indien nodig, tenzij de eigenschap HoldAllComplete aanwezig is. * Afvlakken van argumenten uit Sequence s, tenzij SequenceHold wordt toegepast. * Pas de attributen Flat , Listable , Orderless zoals van toepassing. * Pas evaluatie toe geassocieerd met de waarden van het argument (hun tags) * Pas evaluatie toe geassocieerd met het hoofd.
Wanneer de evaluatie van een uitdrukking voltooid is, wordt deze gemarkeerd als volledig geëvalueerd. Volgende evaluaties die die uitdrukking raken, zullen niet proberen het te evalueren. Als een nieuwe regel is gedefinieerd voor een symbool dat binnen voorkomt, wordt de vlag verwijderd en kan deze opnieuw worden geëvalueerd. De opmerkelijke plaats dat dit 'faalt' is met Condition ( \; ): een voorwaardelijke regel kan mogelijk niet van toepassing zijn bij de eerste evaluatie. Als een niet-gerelateerd symbool waarden wijzigt en nu de voorwaarde van toepassing is, wordt de uitdrukking nog steeds als volledig geëvalueerd gemarkeerd en zal als gevolg daarvan niet veranderen. De functie Update is uniek omdat het zijn argument evalueert, ongeacht de al geëvalueerde status of niet, waardoor een soort "cache flush" wordt gedwongen.
Er zijn een aantal andere functies die vaak als uitzonderlijk worden beschouwd, zoals Hold , Defer , ReplacePart , Extract of ReleaseHold . Deze effecten kunnen allemaal worden bereikt door attributen (zoals HoldAll ) en normale functiedefinitie, en hoeven niet uniek te worden behandeld door de beoordelaar.
Toepassing van `ReplaceAll` en` ReplaceRepeated`
Voorbeeld van hoe ReplaceAll slechts één regel maximaal één keer ReplaceRepeated , terwijl ReplaceRepeated dit in een lus doet, maar de toepassing altijd opnieuw start vanaf de eerste regel.
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" *)
Bellen soort
Bellen sorteren met regels en vervangingen:
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}
*)