wolfram-mathematica
評価オーダー
サーチ…
備考
これは、評価の順序を可能な限り明白に説明することになっています。おそらくMathematicaの実行の紹介として理想的ではない。 Mathematicaのtutorial/Evaluationページには、異なるルールが適用される順序を説明し、評価エンジンによって特別に扱われる関数を説明することによって構築されています。
評価コンテキスト
どの時点でも、コードはコンテキスト内で実行されています。コンテキストは、置換規則のセット(その辞書)とそれらを評価すべき優先順位とからなる。 * Contextの設定* Block Context * Matched Context * ReplaceAll Context * ReplaceRepeated Contextの5種類のコンテキストをグループ化します。
コンテキストを設定する
Set Contextは、Set []オペレーションのいくつかのセット(より一般的に書かれた関数= )によって定義されるものです。主な例は、プライマリ実行環境です。その辞書は、他のスコープではない変数に対してSet []が実行されるたびに変更されます。 Set Contextの他のインスタンスはパッケージから発生します。パッケージコンテキストは、その親コンテキストに関連しており、パッケージ内のパターンも親コンテキスト内のパターンになり、適切な接頭辞を持ちます(定義foo[x_]=3*xはInnerPackageName\ foo [x _] = 3 * x `)。
Set Contextsには、ルールの適用性をより迅速に識別するために、頭に関連付けられた文字列である関連する「Tag」を持つルールのみが含まれます。 Set[yyy_,zzz_]のアプリケーションは、 yyyがシンボルであるかどうかをチェックしてタグを決定します。そうであれば、それはタグです。それ以外の場合は、 yyy[[0]] 、次にyyy[[0,0]]などをチェックします。ある時点でこれがシンボルであると判断された場合、それがタグとみなされます。代わりに非記号アトム(String、Integer、Real ...など)の場合、エラーをスローし、ルールは作成されません。
関数UpSet(書かれた^= )とTagSet(書かれた/: / = )(とその同僚のUpSetDelayedとTagSetDelayed)は、ルールを別のタグに関連付けることができます。タグはシンボルでなければならないという依然の制約があります。 UpSetは式の中の各引数にそれを関連づけ、それらがheadのシンボルを持つ関数であればその頭に関連付けます。たとえば、 f[a,b,c+d,e[f,g],5,h[i][j][k],p_] UpSetを呼び出すと、作成されたルールはa 、 b 、 e 、 h 。 c+d 、 5 、およびp_引数には何も関連付けられておらず、エラーメッセージが表示されます。割り当ては引き続き各引数で成功し、(評価順の後半で明らかになるように)ほぼすべての目的で機能します。 TagSetはUpSetに似ていますが、タグには1つのシンボルしか指定できません。シンボルは、SetまたはUpSet(先頭または引数の最上位シンボル)で設定できるものでなければなりません。例えば、 TagSet[f, f[a,b[c]], 2]は受け入れられ、定義をfと関連付けます。 TagSet[a, f[a,b[c]], 2]とTagSet[b, f[a,b[c]], 2] TagSet[c, f[a,b[c]], 2]はそうではない。
コンテキスト内のルールには、アプリケーションの優先順位が必要です。これは、指定された式に適用されるルールが多数ある可能性があるためです。 (これはReplaceAllとReplaceRepeated Contextsでも当てはまりますが、処理は非常に異なります)。優先順位は一般にパターンの特異性に対応することを意図している。頭と引数がすべて完全に評価されて評価される式a[q][b[c,d],e[f,g]]与えられたら、タグ付きのルールbが適用されます。 eタグ付けされたルール。 aタグ付けされaルール。ルールの各セット内では、与えられたシンボルに関連付けられたルールが維持されます。ブランクのないルール( f[a,b]=3 )は、自動的に一番上に配置され、正規の順序(ソート順)でソートされます。新しいルールが追加されるたびに、カーネルはリストを通過します。一部のルールが完全に同じLHSを持つ場合、そのルールはインプレースで置き換えられます。それ以外の場合は、特異性の比較を行います。既にリストにあるルールXが新しいルールYよりも「あまり具体的」でないと判定された場合、YはXの直前に置かれ、そうでなければリストを通って継続する。ルールの特定性が低い場合、ルールはリストの最後に配置されます。特異性チェックはより複雑で、以下のセクションで詳しく説明します。
ルールの特殊性
* 2つの式がBlankSequence(のインスタンスがない場合は__ )、BlankNullSequence( ___ )、オプション( : )、代替( | )を繰り返し、( .. )、RepeatedNull( ... )、またはオプションの引数を( _.その後、彼らは構造的に比較することができます。 2つの同等な式ツリーXとYが与えられ、Yのすべての空白もXの空白ですが、Xは空白があり、Yが空白でない場合、Yはより具体的です。 * _一部のインスタンスが他の式で__で置き換えられていること、または__が___で置き換えられていることを除いて、2つの式が同等である場合、前者はより具体的です。 (剥離もう一つのオプション場合* : )(またはオプション_. )の用語は、他の式を与え、次いで、後者は、より特異的です。 * Alternativesの選択肢のあるセットが他の式を与える場合、後者はより具体的です。すべてのインスタンス交換する場合* RepeatedNull[foo]持つRepeated[foo]またはRepeated[foo]てfoo 、他の式を与え、その後、後者は、これらの規則の一部combationsを一度に適用することができます*より具体的であるが、それは現在ありませんこれがどのような場合であるかを知る。 * _Listや{___}ような表現の組み合わせは、理論的にはそれらを同じように扱うべきですが、比較は状況に依存しているように見えます。
ブロックコンテキスト
ブロックコンテキストは、ブロック内のルールのLHSがシンボルにしかならないという点で、より制限的です。つまり、 f[x_]=2+xではなく、 f=2+xという形式の定義のみです。 (実用的な観点からは、関数は `Set [ブロックはその親コンテキストに関連しているため、ブロックの評価中に新しい定義は囲まれたコンテキストに通常どおり転送されますが、周囲のコンテキストの定義を隠すことができる定義を提供する変数の一部を「シャドー」するだろう。上記の優先順位。
一致するコンテキスト
ルールがマッチした後、変数にローカルにバインドされた定義があります。これは字句的に発生します。言い換えれば、それは他の何かを評価することなく、式の中の変数の束縛された定義を中に入れます。一度すべてのサブシェイションが発生した場合にのみ、式全体を再び上から評価し始めます。一致したコンテキストが作成される主要な方法は、Set ContextまたはRuleのルールです。例えば、
g[a_]:=a+x;
f[x_]:=x+g[1];
f[x^2]
(*Yields 1+x+x^2 *)
f[x_]ルールをf[y]にマッチさせると、シンボルxは値x^2束縛される。 1回の置換を実行しますが、 g評価しないため、 x^2+g[1]返します。これは、周囲のSet Contextで再び評価され、 1+x+x^2ます。一致したコンテキストでの評価の重要な違いは、置換が再帰的でないことです。 x->x^2代入すると、それ自身の結果でさえも繰り返されません。
一致したコンテキストは、 With 、 Module 、 Function 、およびReplaceによっても作成されます。他の多くの関数はそれらを内部的に作成します。例えば、 PlotはPlotする式を評価する際にこのタイプのコンテキストを使用します。
ReplaceRepeated Context
ReplaceRepeatedコンテキストは、 ReplaceRepeatedいずれかのアプリケーションが発生したときに作成されます。これは、 _[_]ように、タグを持たないものを含めて、ルールLHSとしての任意の式を持つことができる点で独特です。この意味では、最も柔軟なコンテキストです。競合する可能性があるいくつかのルールも含めることができるため、優先順位を維持する必要があります。 ReplaceRepeated Contextは、適用可能な場合は最初にリストの最初のルールを適用します。一致しない場合は2番目に進みます。ルールが一致すると、最初のルールに戻り、再び開始されます。どの時点でもルールアプリケーションが発生し、変更が発生しなければ、リストの後の他のルールが変更されたとしても終了します。これは、リストの前のあまり具体的でないルールは、それ以降のルールが使用されないようにすることを意味します。さらに、 a_->aルールリストの先頭に置くとa_->a ReplaceRepeated全体が即座に終了します。
ReplaceAllコンテキスト
任意のアプリケーションときでReplaceAllコンテキストが作成されるReplaceAll発生します。その機能はReplaceRepeatedの機能と似ていますが、ルールアプリケーションの優先順位が2つの両方が同じレベルの式に当てはまる場合はリスト内で順番に並んでいます。しかし、置き換えられた内容は後の規則でさえも評価されないという点でMatched Contextのようなものです。例えば、 x/.{x->y,y->z}はyます。したがって、ReplaceAllのアプリケーションで各ルールを順番に適用していることを確認するのは間違いです。代わりに、ツリーを走査し、適用可能なルールを探します。一致するものが見つかると、それは置換を実行し、新しいツリーを横断することなくツリーを返します。また、トップダウンからルールを適用しようとし、結果としてリストの順序が崩れる可能性があることにも注意してください。例えば、
Cos[1 + 2 Sqrt[Sin[x]]] /. {Cos[_] -> 5, Sin[_] :> (Print[1]; 10)}
Cos[1 + 2 Sqrt[Sin[x]]] /. {Sin[_] :> (Print[1]; 10), Cos[_] -> 5}
どちらも印刷せずに5を得ます。 Cos[_]はツリーの上位レベルと一致するため、最初に適用されます。
HoldとEvaluateと実行順序
*頭部にHoldプロパティ( HoldFirst 、 HoldRest 、 HoldAll 、 HoldAllComplete )がある場合は、関連する引数をチェックします。それがHoldAllComplete 、頭部がEvaluateであるかどうか確認してください。そうであれば、 Evaluateを取り除いてEvaluateします。 * Unevaluatedインスタンスの引数をチェックし、プロパティHoldAllCompleteが存在しない限り、必要に応じてそれらを削除します。 *からの引数を平らにSequenceがない限り、SをSequenceHold適用されます。 *属性を適用Flat 、 Listable 、 Orderless該当します。 *引数のupvalues(そのタグ)に関連付けられた評価を適用する*頭に関連付けられた評価を適用する。
式の評価が完了すると、完全に評価されたものとしてマークされます。その式にヒットした後続の評価は評価することを試みません。内部で発生するシンボルに新しいルールが定義されている場合、フラグは削除され、再度評価されます。これが「失敗する」という注目すべき場所は、 Condition ( \; )です:条件付きルールは、最初の評価に適用されない可能性があります。無関係な記号が値を変更し、条件が適用可能な場合、式はまだ完全に評価されているとマークされ、結果として変更されません。関数Updateは、既に評価された状態にかかわらず引数を評価し、ソートの「キャッシュ・フラッシュ」を強制するという点で一意です。
多くの場合、例外、同様のものとみなされている他の多くの機能がありHold 、 Defer 、 ReplacePart 、 Extract 、またはReleaseHold 。これらの影響はすべて、属性( HoldAllなど)と通常の関数定義によって実現でき、評価者が一意に扱う必要はありません。
`ReplaceAll`と` ReplaceRepeated`の適用
ReplaceAllはルールを1回だけ適用する方法の例ですが、 ReplaceRepeatedはループ内でこれを行いますが、常に最初のルールからアプリケーションを再起動します。
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" *)
バブルソート
ルールと置換えによるバブルソート:
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}
*)