2011-05-12 16 views
5

मैं "सात सप्ताह में सात भाषाओं" एटीएम पढ़ रहा हूं, और मैं कुछ प्रोलॉग क्वेरी पर फंस गया हूं कि मुझे 'नहीं' प्रतिक्रिया नहीं है।चर के साथ प्रोलॉग प्रश्नों में ` +` के साथ समस्या

friends.pl फ़ाइल इस तरह दिखता है:

| ?- ['friends']. 
compiling /home/marc/btlang-code/code/prolog/friends.pl for byte code... 
/home/marc/btlang-code/code/prolog/friends.pl compiled, 12 lines read - 994 bytes written, 8 ms 

yes 
| ?- friend(wallace,grommit). 

yes 
| ?- friend(wallace,wendolene). 

no 

यह सभी के रूप में की उम्मीद है:

likes(wallace, cheese). 
likes(grommit, cheese). 
likes(wendolene, sheep). 

friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z). 

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

| ?- trace. 
The debugger will first creep -- showing everything (trace) 

yes 
{trace} 
| ?- friend(wallace,X). 
     1 1 Call: friend(wallace,_16) ? 
     2 2 Call: \+wallace=_16 ? 
     3 3 Call: wallace=_16 ? 
     3 3 Exit: wallace=wallace ? 
     2 2 Fail: \+wallace=_16 ? 
     1 1 Fail: friend(wallace,_16) ? 

no 
{trace} 

यह भी X (_16) grommit साथ एकजुट करने के लिए कोशिश नहीं करता। क्यूं कर?

उत्तर

4

यह दोस्त की परिभाषा है

\+ Goal :- Goal,!,fail 

ध्यान दें कि इसका मतलब यह है लक्ष्य सफल होता है कि, आप असफल होने के लिए निश्चित हैं। नि: शुल्क चर (जिन्हें आवंटित किया गया है) हमेशा एकजुट होंगे, और इस प्रकार बराबर होंगे, इसलिए आप हमेशा एक मुक्त चर के साथ असफल रहेंगे। इस प्रकार यह एक्स या वाई के लिए कभी भी मूल्य निर्दिष्ट नहीं करेगा यदि उसके पास पहले से कोई नहीं है।

इसके बजाय

friend(X, Y) :- likes(X, Z), likes(Y, Z), \+(X = Y) 

आपकी अपेक्षा के अनुसार अधिक व्यवहार करेगा।

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

3

friend/2 का पहला सबगोल \+(X = Y) है। इसे पहले X = Y के लिए समाधान खोजने का प्रयास करके निष्पादित किया जाता है, फिर उस परिणाम को अस्वीकार कर दिया जाता है। अनुमान =/2 लगभग unify/2 के बराबर है, यह है कि यह दाएं ऑपरेंड के साथ बाएं ऑपरेंड को एकीकृत करने का प्रयास करता है। अब, जब आप क्वेरी का उपयोग कर पूछ रहे हैं friend(wallace, gromit), दो परमाणु wallace और gromit एकजुट नहीं हैं; लेकिन जब मिश्रण में एक फ्री वैरिएबल फेंक दिया जाता है, तो यह हमेशा जो भी शब्द दिया जाता है, उसके साथ एकीकृत होता है, इसलिए X = Y हमेशा सफल होता है, इसलिए \+(X = Y) हमेशा विफल रहता है, और निष्पादन उस पहले सबगोल से पहले कभी नहीं मिलता है।

friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z). 

यहां महत्वपूर्ण बात यह है कि आप \+(X = Y) के साथ शुरू जो आम तौर पर के रूप में परिभाषित किया गया है है::

+0

ठीक है, समझा। आप 'दोस्त/2' को कैसे सुधारेंगे ताकि यह चर के साथ एक क्वेरी के साथ काम करे? –

+1

पहली नज़र में, मैंने समानता ऑपरेटर '==/2' का उपयोग किया होगा और इसे' मित्र (एक्स, वाई) के रूप में लिखा होगा: - \ + (एक्स == वाई), पसंद (एक्स, जेड), पसंद (वाई , जेड)। 'लेकिन इस संस्करण में आपके दोस्तों के भीतर स्वयं को शामिल करने का दोष है, उदाहरण के लिए 'मित्र (दीवार, एक्स)' समाधान के रूप में 'दीवारों' की सूची देगा। तो फिलिप जेएफ सुझाव देता है कि फिलिप जेएफ सुझाव देता है कि भले ही वह एकीकरण ऑपरेटर का उपयोग कर रहा है, अंत में चेक डालने के लिए: 'दोस्त (एक्स, वाई): - पसंद (एक्स, जेड), पसंद (वाई, जेड), एक्स \ == वाई'। (ध्यान दें कि '\ ==/2'' ==/2' को अस्वीकार करने के बराबर है, लेकिन स्पष्ट, बस अधिक प्रत्यक्ष।) –

4

ऊपर फिलिप जेएफ की टिप्पणी के बारे में:

यह प्रकार की कमी एक तरीका है कि इन समस्याओं का उत्पादन नहीं करता में "विफलता के रूप में निषेध" व्यक्त करने के लिए संभव हो जाना चाहिए।

यह संभव है: ऐसी समस्याओं के लिए आधुनिक समाधान बाधाएं हैं। इस मामले में, उदाहरण के लिए dif/2, सभी गंभीर प्रोलॉग सिस्टम में उपलब्ध है।

+0

'gprolog' (v1.3): 'अपूर्ण अपवाद: त्रुटि (अस्तित्व_error (प्रक्रिया, भिन्न/2), दोस्त/2) ' –

+2

उदाहरण के लिए एसडब्ल्यूआई, याप, एसआईसीस्टस, बी-प्रोलॉग, और कई अन्य प्रयास करें। – mat

1

असमानता बाधा रखने वाला एक और मुद्दा यह है: अनबाउंड X (इस पल के लिए grommit के साथ इसे एकीकृत करने के मामूली मामले को छोड़कर) के लिए बाध्यकारी खोजने के लिए यह अनुपयोगी है। Prolog unbound चर को एकीकृत करने की कोशिश कर, अपने डेटाबेस के माध्यम से चलकर बाइंडिंग पाता है। यही कारण है कि likes(grommit, Z)Z के लिए कुछ बाध्यकारी पाएगा, जिसे आगे संसाधित किया जा सकता है, क्योंकि likes डेटाबेस में खंड हैं। लेकिन कुछ के साथ grommit की असमानता के लिए इस तरह के कोई खंड नहीं हैं, तो Prolog किसी भी बाइंडिंग का उत्पादन नहीं कर सकते हैं। जैसे-जैसे चीजें खड़ी होती हैं, friend भविष्यवाणी यह ​​सुनिश्चित करने के लिए होती है कि असमानता का परीक्षण करने से पहले सभी चर बाध्य हो जाएं।

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