2010-06-28 7 views
8

संभावित मुद्दों पर मूल्यांकन पर mathematica दस्तावेज में होल्ड भीतर एक स्तर से परे मूल्यांकन का कहना है:मेथेमेटिका

केवल पहले स्तर पर काम करता है मूल्यांकन, सीधे एक आयोजित समारोह

मेथेमेटिका क्यों अंदर क्या यह सीमा है? तो अगर मैं एक से अधिक स्तर के साथ एक अभिव्यक्ति है इस सरल उदाहरण लेते हैं:

होल्ड [प्लस [प्लस [2, 2], 2]]]

अब मान लीजिए कि मैं देखना क्या जवाब देने के लिए है चाहता हूँ दूसरा प्लस, इसके नीचे के स्तर पर कुछ भी मूल्यांकन किए बिना। मैंने अलग-अलग चीजों की कोशिश की है जैसे:

In[290]:= Hold[Plus[Evaluate[Plus[2, 2]], 2]] 
Out[290]= Hold[Evaluate[2+2]+2] 

In[287]:= Hold[Plus[ReleaseHold[Hold[Plus[2, 2]]], 2]] 
Out[287]= Hold[ReleaseHold[Hold[2+2]]+2] 

पहला होल्ड इस मामले में पहले स्तर पर और उसके बाद सबकुछ अनचाहे रखता है। लक्ष्य लगातार होल्ड, ReleaseHold का उपयोग कर बाहरी एक के लिए सबसे भीतरी नेस्टेड समारोह से प्रत्येक चरण में एक अभिव्यक्ति के मूल्यांकन को नियंत्रित करने और कार्यों का मूल्यांकन करें कि प्राप्त करने के लिए है। मुझे लगता है मैं यह देखने के लिए कि क्या एक अभिव्यक्ति में एक स्तर से परे होता है, लेकिन वह अलग है और कभी कभी लंबे समय तक भाव के साथ पढ़ने के लिए जटिल है ट्रेस इस्तेमाल कर सकते हैं पता है।

ऐसा लगता है एक ही रास्ता निकालने के लिए और पूरी तरह से निकालें, भाग या स्तर का उपयोग कर सूचियों में अभिव्यक्ति विघटित है की तरह; अभिव्यक्ति के हिस्से का मूल्यांकन करें जो मैं चाहता हूं; फिर प्रत्येक चरण के लिए एक साथ वापस अभिव्यक्ति का पुनर्निर्माण और पुन: मानचित्रण करें। वहाँ किसी भी अन्य तरीकों या इस मैं विचार कर सकते हैं प्राप्त करने के लिए कार्य करता है?

संपादित करें: यह एक बेहतर उदाहरण पहले पकड़ जारी करने की दृष्टिकोण को देखने के लिए हो सकता है। अभिव्यक्ति के साथ:

Hold[Plus[Plus[2, Plus[2,2]], 2]]] 

आप पहली बार पकड़ जारी है और तीसरे प्लस पर एक अभिव्यक्ति में एक उच्च स्तर पर रोक जगह, इस तरह देखने के लिए हैं:

in = Plus[Plus[2, Hold[Plus[2,2]]], 2]]] 
out = Hold[2+2]+4 

आप पाते हैं कि मेथेमेटिका होगा जब आप वास्तव में प्रतीक्षा करना चाहते हैं तो पृष्ठभूमि में निम्न स्तर का मूल्यांकन करें।

+1

संबंधित प्रश्न: http://stackoverflow.com/questions/1616592/hold-defer-etc – dreeves

उत्तर

3

मैं सही कारण नहीं दे सकता कि क्यों Evaluate "केवल पहले स्तर पर काम करता है, सीधे आयोजित किए गए फ़ंक्शन के अंदर" लेकिन मुझे संदेह है कि यह आंशिक रूप से दक्षता है, इसमें यह धीमा होगा कि मूल्यांकनकर्ता को पूरी अभिव्यक्ति स्कैन करना पड़ा नेस्ट Evaluate भाव के लिए एक Hold* विशेषता के साथ किसी भी कार्य करने के लिए पारित कर दिया आयोजित बहस के पेड़ और उन्हें मूल्यांकन, और फिर recurse और क्या यह सिर्फ का मूल्यांकन में Evaluate subexpressions के लिए देखो, अभिव्यक्ति के बाकी unevaluated रखने यह सब करते हुए, खासकर जब यह हमेशा नहीं हो सकता है वही हो जो आप वैसे भी करना चाहते हैं।

कर क्या आप चाहते हैं Extract और ReplacePart के संयोजन का उपयोग हालांकि बहुत आसान है:

In[51]:= expr = Hold[Plus[Plus[2, 2], 2]]; 

In[52]:= ReleaseHoldAt[expr_, partspec_] := 
    ReplacePart[expr, partspec -> Extract[expr, partspec]] 

In[53]:= ReleaseHoldAt[expr, {1, 1}] 

Out[53]= Hold[4 + 2] 

यह हमें एक और कारण है कि यह Evaluate के लिए कोई मतलब नहीं पारित कर एक अभिव्यक्ति में किसी भी स्तर पर काम करने के लिए हो सकता है उदाहरण देकर स्पष्ट करने देता है एक Hold* विशेषता के साथ एक समारोह के लिए एक तर्क के रूप, को शामिल i निम्नलिखित अभिव्यक्ति पर विचार:

In[82]:= i = 1; 

In[83]:= ReleaseHoldAt[Hold[i = 2; j = Plus[i, i]], {1, 2}] 

Out[83]= Hold[i = 2; 2] 

ध्यान दें कि 01,236 का मूल्य4 होगा यदि हमने Plus से पहले उस अभिव्यक्ति के पहले भाग का मूल्यांकन किया था, लेकिन परिणाम अलग हैं क्योंकि हम केवल आंशिक मूल्यांकन कर रहे हैं, और i=2 का मूल्यांकन नहीं किया गया था जब हमने subexpression सेटिंग j का मूल्यांकन किया था। कभी-कभी, यह हो सकता है कि आप क्या करना चाहते हैं, लेकिन अक्सर यह बहुत संभावना नहीं है।

ध्यान रखें कि यहां तक ​​कि Evaluate प्रथम स्तर में एक समारोह विशेषता HoldAllComplete है कि या HoldComplete का उपयोग करके हराया जा सकता है:

In[62]:= Hold[Evaluate[Plus[2,2]]] 
Out[62]= Hold[4] 

... बनाम:

In[63]:= HoldComplete[Evaluate[Plus[2,2]]] 
Out[63]= HoldComplete[Evaluate[2+2]] 

अंत में , Trace का उत्पादन थोड़ा घना हो सकता है, लेकिन आप दूसरे तर्क में पैटर्न या रुचि के प्रतीकों का उपयोग करके जो चाहते हैं उसे फ़िल्टर कर सकते हैं:

In[88]:= Trace[Plus[Plus[Plus[1,2],3],4],Plus] 
Out[88]= {{{1+2,3},3+3,6},6+4,10} 

In[93]:= Trace[Plus[Subtract[Plus[1,2],4],8],_Plus] 
Out[93]= {{{1+2}},-1+8} 

एचटीएच!

+0

धन्यवाद कि एक बहुत मदद करता है। उपरोक्त पहला फ़ंक्शन उदाहरण सरल और चालाक है। यह अभिव्यक्ति का हिस्सा निकालता है जिसे आप धारणा के नियंत्रण में अभिव्यक्ति से बाहर करना चाहते हैं; अब यह होल्ड की सीमा से बाहर है इसलिए इसका मूल्यांकन करता है और फिर उस स्थान पर वापस ले जाता है जहां से इसे लिया गया था। मैं कुछ और अधिक जटिल तरीके से कुछ करने की कोशिश कर रहा था। – dbjohn

2

एक तकनीक है जो शामिल नहीं करता है Extract भीतरी Hold रों में Hold अंदर भागों रैप करने के लिए है, और फिर बाहरी Hold जारी:

expr=Hold[(1+2)+3]; 
[email protected][Hold,expr,{2}] 

Out[2]= Hold[3]+Hold[1+2] 

आप इस दिशा में विभिन्न खेल खेल सकते हैं, लेकिन जब से मैं यह कर सकते हैं यह नहीं बताओ कि आप क्या करना चाहते हैं, यह विशिष्ट होना मुश्किल है। कुछ ऐसा जो उपयोगी हो सकता है कि descents लेकिन आप के लिए यह चाहते अपनी खुद की Hold परिभाषित करने के लिए है:

SetAttributes[DescentHold,{HoldAll}] 
DescentHold[a_Plus]:[email protected][DescentHold,Hold[a],{2}] 
DescentHold[a_]:=Hold[a] 

ध्यान दें कि यह एक तक पहुंचता बाहरी Hold रों एक बार अंदर लिपटे रहे हैं, ताकि उदाहरण के लिए Plus किक की समतलता में:

DescentHold[2*3+(4+5)] 
Out[4]= Hold[4]+Hold[5]+Hold[2*3] 
3

जैसा कि अक्सर मामला है जब आप कुछ मेथेमेटिका में मुश्किल करना चाहते हैं, पैटर्न मिलान और नियम प्रतिस्थापन बचाव के लिए आते हैं। हालांकि, इस उदाहरण में, आपको something weird करना है, और आपको ReplaceAll (/. ऑपरेटर) के बजाय Replace का उपयोग करना होगा ताकि आप इसे एक मानक विनिर्देश देने के लिए अपने वैकल्पिक तीसरे तर्क का लाभ उठा सकें।उदाहरण आप की पेशकश का उपयोग करना:

In[1]:= Replace[ 
     Hold[Plus[Plus[2, 2], 2]], 
     expr_Plus :> With[{eval = expr}, eval /; True], 
     {2}] 
Out[1]= Hold[4 + 2] 

बेकार दिखने

expr_Plus :> With[{eval = expr}, eval /; True] 

नियम वास्तव में टेस्ट मैच और With structre के शरीर के बीच स्थानीय चर साझा करने के लिए a documented way है; यहां आप स्थानीय चर के साथ कुछ भी नहीं करते हैं लेकिन इसके मूल्यांकन को चौराहे के रास्ते में मजबूर करते हैं --- क्योंकि कम चौराहे के तरीके काम नहीं करेंगे!

जोड़ने के लिए संपादित करें: मुझे लगता है कि आप Level के परिणाम का गलत व्याख्या कर रहे हैं; इस अभिव्यक्ति के स्तर {2} पर दो अभिव्यक्ति 2 और Plus[2, 2] हैं; आप स्तर के लिए वैकल्पिक तीसरा तर्क है, जो Extract की वैकल्पिक तीसरा तर्क को कुछ ऐसा ही का उपयोग करके यह देख सकते हैं:

In[2]:= Level[Hold[Plus[Plus[2, 2], 2]], {2}, Hold] 
Out[2]= Hold[2 + 2, 2] 
{2} स्तर कल्पना के साथ

, Replace से मेल खाते हैं और बदलने का प्रयास करेगा के खिलाफ नियम इन दो अभिव्यक्तियों, और यह दूसरे पर काम करेगा।

+0

@dbjohn: मुझे आशा है कि मेरे संपादन ने प्रश्न का उत्तर दिया है; यदि नहीं, तो मुझे लगता है कि यह शायद अपने आप के सवाल के लायक है। – Pillsy

+0

मैं देख सकता हूं कि यह स्तर 2 के लिए कैसे काम कर सकता है। क्या पैटर्न 3 स्तर पर समान पैटर्न नहीं होना चाहिए? जहां मिलान करने और प्रतिस्थापित करने के लिए प्लस का एक प्रमुख है या फ़ंक्शन प्लस इस स्तर पर "सक्रिय" नहीं है? – dbjohn

+0

@ डीबीजोह्न: नहीं। 'प्लस' स्तर 3 पर पॉप अप करने का कारण है 'हेड -> ट्रू' सेटिंग के कारण; आप * प्रतीक * 'प्लस' देख रहे हैं, जो 'प्लस [2, 2]' रूप का मुखिया है और स्तर 3 पर है (बस दो 2s की तरह), लेकिन 'expr_Plus' केवल सिर के साथ अभिव्यक्तियों से मेल खाता है 'प्लस', 'प्लस' नहीं! – Pillsy

2

विचार का उपयोग के बारे में ReplacePart और Michael Pilat द्वारा answer से Extract काम करता है, एक HoldAndEvaluate समारोह है, जो उसे अपनी स्थिति की गणना की आवश्यकता के बिना अभिव्यक्ति का एक वांछित हिस्सा मूल्यांकन करने के लिए अनुमति देता है लिख सकते हैं (यह "MyEvaluate के साथ चिह्नित किया जा सकता है ")।

In[1]:= expr = Hold[MyEvaluate[2 + 2] + 2]; 

In[2]:= HoldAndEvaluate[expr_] := 
    ReplacePart[expr, 
    # -> Evaluate @@ Extract[expr, #] & /@ 
    Position[expr, MyEvaluate[_]] ]; 

In[3]:= HoldAndEvaluate[expr] 

Out[3]= Hold[4 + 2] 
संबंधित मुद्दे