2010-11-06 15 views
9

में पूर्वानुमान नियंत्रण प्रोलॉग अनुमान नियंत्रण से संबंधित जिज्ञासा है।प्रोलॉग

माना जाता है कि मेरे पास एक अनुमानित एफ (ए, एक्स) और जी (बी) है।

f(A,X):- a,b,c, g(X). 
g(B):- true. 

a - returns true 
b - returns true. 
c - returns false. 
where a,b and c are random predicates. 

मैं विधेय f(A,X) अगर सी झूठी रिटर्न में g(X) मूल्यांकन करने के लिए कैसे जारी रख सकते हैं?

उत्तर

8

अपने इरादे को परिभाषित करने के f(A,X) ऐसी है कि g(X) मूल्यांकन किया जाना चाहिए या नहीं, c, विफल रहता है तो या तो:

  1. आप इस का उपयोग कर सांकेतिक शब्दों में बदलना कर सकता है निहितार्थ (->) और/या अलगाव (;), या
  2. f(A,X)कोc के संदर्भ में परिभाषित करने की आवश्यकता नहीं है। यह मानता है कि c में साइड इफेक्ट्स (उदाहरण के लिए, assert का उपयोग करके डेटाबेस तथ्यों का दावा करना, या स्ट्रीम में आईओ प्रिंट करना) जो पर्यावरण को बदलता है और जिसे c की विफलता पर पूर्ववत नहीं किया जा सकता है, इस मामले में पहला विकल्प बेहतर है।

    f(A,X) :- ((a, b, c) ; (a, b)), g(X). 
    

    (ऊपर) इस परिभाषा a के रूप में बिल्कुल c पर निर्भर नहीं करता है, लेकिन यह हमेशा c निष्पादित कर दी जाएगी (और:

जैसे अलगाव प्रयोग करने के लिए कई विकल्प हैं, कर रहे हैं b सफल)। संयोजन (;) a, bफिर से निष्पादित करने का प्रयास करने के लिए PROLOG को बैकट्रैक करने की अनुमति देता है यदि c असफल रहा, और g(X) पर जारी रहा। ध्यान दें कि यह के बराबर है:

f(A,X) :- a, b, c, g(X). 
f(A,X) :- a, b, g(X). 

PROLOG के लिए आदेश हर मूल्यांकन के लिए दो बार दूसरे (समान) सिर विधेय f(A,X) की वजह से f(A,X) का मूल्यांकन करने के पीछे नहीं है, तो आप एक कट (!) जगह चुन सकते हैं, यदि आपका कार्यान्वयन इसका समर्थन करता है, के बाद तुरंत पहले खंड में c सबगोल।c के बाद रखा गया है क्योंकि हम नहीं चाहते हैं कि क्लॉज c क्लॉज की पसंद के लिए दुभाषिया को प्रतिबद्ध करे, इसके बजाय, हम चाहते हैं कि दुभाषिया इस खंड से विफल हो और प्रभावी रूप से प्रभावी हो c को अनदेखा करें और g(X) को संसाधित करना जारी रखें।

भी ध्यान रखें कि इस समाधान a और b कोई दुष्प्रभाव होने पर निर्भर करता है, क्योंकि जब c विफल रहता है, a और b फिर से क्रियान्वित कर रहे हैं। सभी a, b, और c है साइड इफेक्ट हैं, तो आप निहितार्थ उपयोग करने का प्रयास कर सकते हैं:

f(A,X) :- a, b, (c -> g(X) ; g(X)). 

यह भी प्रभावी ढंग से हमेशा निष्पादित करेंगे g(X) कि क्या c विफल रहता है या नहीं, और a और b फिर से अमल नहीं होगा अगर c विफल रहता है। यह सिंगल-क्लॉज परिभाषा पिछले सुझाव की तरह एक विकल्प-बिंदु भी नहीं छोड़ेगी।

3

मुझे लगता है कि आप cignore/1 में लपेट सकते हैं। उदाहरण पर विचार करें

?- false, writeln('Hello World!'). 
false. 

?- ignore(false), writeln('Hello World!'). 
Hello World! 
true. 

लेकिन यदि आप c विफल हो जाते हैं तो आप क्यों जारी रखना चाहते हैं? उपयोग का मामला क्या है?

मैंने एसडब्ल्यूआई-प्रोलॉग में इस कोड का परीक्षण किया, मुझे यकीन नहीं है कि अन्य प्रोलॉग्स false/0 और ignore/1 हैं। बाद हालांकि इस तरह परिभाषित किया जा सकता:

ignore(Goal) :- Goal, !. 
ignore(_). 
+0

+1 यह पूछने के लिए कि यह उपयोगी क्यों होगा। पोर्टेबल विफलता भविष्यवाणी 'विफल' है, बीटीडब्ल्यू। (जो कार्यान्वित करने के लिए तुच्छ है: 'असफल: - 0 = 1.') –

+0

एक परिदृश्य जहां आप जारी रखना चाहते हैं यदि 'c' विफल रहता है तो' c' _side-effect_ है; अधिक जानकारी के लिए इस प्रश्न का मेरा जवाब देखें। – sharky

संबंधित मुद्दे