sql >> データベース >  >> Database Tools >> MySQL Workbench

Mathematicaの割り当てにおける不要な評価:なぜそれが起こるのか、そしてパッケージのロード中にそれをデバッグする方法は?

    WB(質問に答えるのに実際には必要ありません)は別として、問題は、割り当て中に式がどのように評価されるかにのみ基づいて、簡単な答えを持っているようです。次に例を示します:

    In[1505]:= 
    notGoodQ[x_]:=True;
    Clear[g];
    g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])
    
    In[1509]:= g/:cccQ[g[x0_]]:=True
    
    During evaluation of In[1509]:= g::nogood: -- Message text not found -- (x0_)
    Out[1509]= $Aborted
    

    それを機能させるために、私は意図的にnotGoodQの定義を作成しました 常にTrueを返す 。さて、なぜg[x0_] TagSetDelayedによる割り当て中に評価されます ?答えは、TagSetDelayed (およびSetDelayed )割り当てh/:f[h[elem1,...,elemn]]:=... fのルールは適用されません 持っている可能性がありますが、h[elem1,...,elem2]を評価します 、およびf 。次に例を示します:

    In[1513]:= 
    ClearAll[h,f];
    h[___]:=Print["Evaluated"];
    
    In[1515]:= h/:f[h[1,2]]:=3
    
    During evaluation of In[1515]:= Evaluated
    During evaluation of In[1515]:= TagSetDelayed::tagnf: Tag h not found in f[Null]. >>
    Out[1515]= $Failed  
    

    TagSetDelayedという事実 HoldAllです 引数を評価しないという意味ではありません。引数が未評価で到着することを意味するだけであり、評価されるかどうかはTagSetDelayedのセマンティクスに依存します。 (これについては上記で簡単に説明しました)。 SetDelayedについても同じことが言えます したがって、「引数を評価しない」という一般的に使用されるステートメントは、文字通り正しくありません。より正しいステートメントは、評価されていない引数を受け取り、特別な方法でそれらを評価することです-r.h.sを評価しませんが、l.h.s。の場合、ヘッドと要素を評価しますが、ヘッドのルールは適用しません。これを回避するには、HoldPatternでラップすることができます。 、このように:

    Clear[g,notGoodQ];
    notGoodQ[x_]:=EvenQ[x];
    g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])
    g/:cccQ[HoldPattern[g[x0_]]]:=True;
    

    これは通過します。使用法は次のとおりです:

    In[1527]:= cccQ[g[1]]
    Out[1527]= True
    
    In[1528]:= cccQ[g[2]]
    During evaluation of In[1528]:= g::nogood: -- Message text not found -- (2)
    Out[1528]= $Aborted
    

    ただし、HoldPatternの必要性に注意してください 定義を作成するときの左側の内側は、多くの場合、関数呼び出し中に頭の中の式も評価される可能性があり、コードが破損する可能性があることを示しています。これが私の言いたいことの例です:

    In[1532]:= 
    ClearAll[f,h];
    f[x_]:=x^2;
    f/:h[HoldPattern[f[y_]]]:=y^4;
    

    このコードは、h[f[something]]のようなケースをキャッチしようとします 、ただし、f[something]なので、明らかに失敗します。 評価がhになる前に評価します :

    In[1535]:= h[f[5]]
    Out[1535]= h[25]
    

    私にとって、HoldPatternの必要性 l.h.s.自分のデザインを再考する必要がある兆候です。

    編集

    WBでのロード中のデバッグに関して、実行できることの1つ(IIRC、現在チェックできません)は、古き良き印刷ステートメントを使用することです。その出力はWBのコンソールに表示されます。個人的には、この目的のためにデバッガーの必要性を感じることはめったにありません(ロード時にパッケージをデバッグする)

    編集2

    質問の編集に応じて:

    定義の順序について:はい、これを行うことができ、この特定の問題を解決します。しかし、一般的に、これは堅牢ではなく、私はそれを良い一般的な方法とは見なしません。状況から少し外れているため、当面のケースについて明確なアドバイスを与えることは困難ですが、UpValuesの使用は私には思えます ここは不当です。これがエラー処理のために行われる場合、その他の方法 UpValuesを使用せずにそれを行うには 。

    通常、UpValues オーバーロードされる関数にルールを追加せずに、安全な方法で一部の関数をオーバーロードするために最も一般的に使用されます。 1つのアドバイスは、UpValuesの関連付けを避けることです。 DownValuesもあるヘッドを使用 そして、評価するかもしれません-これを行うことによって、あなたは評価者とゲームを始め、最終的には負けます。最も安全なのは、UpValuesを添付することです 不活性なシンボル(ヘッド、コンテナ)に変換します。これは、特定の関数をオーバーロードするオブジェクトの「タイプ」を表すことがよくあります。

    HoldPatternの存在に関する私のコメントについて 悪いデザインを示しています。確かに HoldPatternの正当な使用法 、このような(やや人工的な)もの:

    In[25]:= 
    Clear[ff,a,b,c];
    ff[HoldPattern[Plus[x__]]]:={x};
    ff[a+b+c]
    
    Out[27]= {a,b,c} 
    

    多くの場合、Plusであるため、ここでは正当化されます。 未評価のままであり、未評価の形式で役立ちます-合計を表すと推測できるためです。 HoldPatternが必要です Plusの方法のためにここに は単一の引数で定義され、パターンは定義中にたまたま単一の引数であるため(通常、複数の引数を記述している場合でも)。したがって、HoldPatternを使用します ここでは、パターンが通常の引数として扱われないようにしますが、これはPlusの使用目的とはほとんど異なります。 。これが当てはまる場合はいつでも(定義は意図されたユースケースで問題なく機能すると確信しています)、HoldPattern 結構です。この例も壊れやすいことに注意してください:

    In[28]:= ff[Plus[a]]
    Out[28]= ff[a]
    

    それでもほとんど問題ない理由は、通常はPlusを使用しないためです。 単一の引数で。

    ただし、通常提供される引数の構造が定義に使用されるパターンの構造と同じである場合の2番目のグループがあります。この場合、割り当て中のパターン評価は、関数呼び出し中に実際の引数で同じ評価が行われることを示しています。あなたの使用法はこのカテゴリーに分類されます。設計上の欠陥についての私のコメントは、そのような場合でした。パターンが評価されないようにすることはできますが、これを機能させるには、引数も評価されないようにする必要があります。また、完全に評価されていない表現に対するパターンマッチングは脆弱です。また、関数は、引数に対して(型チェックできる範囲を超えて)いくつかの追加の条件を想定してはなりません。




    1. MySql-InnoDBをデータベースのMyISAMストレージエンジンに変換します

    2. phpmyadminのユーザー名とパスワードを設定する方法

    3. LINQtoSQLの実行時間はSSMSSQLの50倍です

    4. mbstring拡張機能がありません。 PHP構成を確認してください