2016-04-24 11 views
7

में भविष्यवाणियों को कैसे पढ़ा जाए, मैं प्रस्तावनात्मक और भविष्यवाणी तर्क सीखने के बाद प्रोलॉग पर गया।प्रोलॉग

मैं सोच रहा था कि कोई मेरे लिए सिंटैक्स को स्पष्ट कर सकता है क्योंकि मुझे इसे पढ़ने में परेशानी हो रही है।

मैं नीचे आसानी से कुछ पढ़ सकता हूं। तो यह कह रहा है

एक्स वाई के पतित है अगर एक्स वाई के बच्चे है

फिर

यह कहना

एक्स यदि Y का उतर है पर चला जाता है एक्स जेड और जेड के बच्चे वाई

descend(X,Y) :- 
    child(X,Y). 
descend(X,Y) :- 
    child(X,Z), 
    descend(Z,Y). 

के उतर जाता है लेकिन एक बार मैं देख चढ़ गया सूची प्रोग्रामिंग में मैं भविष्यवाणियों के वाक्यविन्यास को पढ़ने के लिए संघर्ष कर रहा हूं। उदाहरण नीचे

remove([], _, []). 
remove([X | Xs], X, Ys) :- remove(Xs, X, Ys). 
remove([Y | Xs], X, [Y | Ys]) :- X \== Y, remove(Xs, X, Ys). 

परीक्षण से के लिए, यह, दूसरे मद को हटा तो उदाहरण के लिए अगर मैं

remove([a,b,c], b, Ys). 

में टाइप मैं Ys = [a,c].

मिलेगा लेकिन मैं कैसे करने के लिए पता नहीं है वाक्यविन्यास पढ़ें, अगर कोई मेरे लिए इसे तोड़ सकता है, तो यह बहुत अच्छा होगा।

उत्तर

2

तथ्य यह है कि आपको यह देखने के लिए केवल यह जांचने की आवश्यकता है कि remove/3 शायद यह अच्छी तरह से नामित नहीं है। remove बहुत सामान्य है और प्रश्न "क्या हटाएं?" खोलता है। इसके अलावा, यह अनिवार्य है, और Prolog संबंध होना चाहता है। शायद एक बेहतर नाम list_without/3 होगा जो कहता है कि तीसरे तर्क में सूची पहले तर्क में सूची है, लेकिन दूसरे तर्क के बिना।

जैसा भी हो सकता है, चलिए आपके पास क्या पढ़ते हैं। इस प्रकार

पढ़ना अपने remove/3 विधेय किया जा सकता है:

remove([], _, []). 

खाली सूची अभी भी खाली सूची है अगर मैं किसी भी तत्व को हटा दें।

remove([X | Xs], X, Ys) :- remove(Xs, X, Ys). 

सूची Ys अगरYs सूची Xs से सभी X तत्वों को निकालने के बाद मैं मिलता है हटाया X तत्वों के साथ सूची [X|Xs] है।

remove([Y | Xs], X, [Y | Ys]) :- X \== Y, remove(Xs, X, Ys). 

[Y|Ys] अगरXY और Ys के समान नहीं है सूची मैं Xs से सभी X तत्वों हटाने के बाद मिलता है हटाया X तत्वों के साथ सूची [Y|Xs] है।

एक अभ्यास के रूप में, आपको इन्हें फिर से पढ़ने की कोशिश करनी चाहिए, लेकिन एक अधिक रिलेशनशिप नाम का उपयोग करना चाहिए, जैसे मैंने प्रदान किया गया उदाहरण नामकरण।

+0

सही धन्यवाद, वाक्य रचना वास्तव में मुझे भ्रमित किया गया है और कैसे मैं सामान्य रूप से पढ़ता था से इतना अलग प्रतीत हो रहा है विधेय। – user6248190

+0

@ user6248190 मैं एक अनुमानित खंड के बारे में सोचकर शुरू करता हूं, * ऐसा और सच है ** यदि ** .... * शर्तों के अनुक्रम के बाद। – lurker

+0

क्षमा करें एक और बात, क्या निकालने की भविष्यवाणी करने के लिए एक छोटा रास्ता है? हटाने की 3 लाइनें क्यों हैं? – user6248190

4

जैसा कि आपके पास तर्क में कुछ पृष्ठभूमि है, आपको तर्क सूत्रों के रूप में नियमों को पढ़ने में मदद मिल सकती है। के/2 dif द्वारा की जगह (\ ==)/2 तब हटाने के रूप में निम्नानुसार/3 पढ़ता है:

remove([], _, [])true

remove([X | Xs], X, Ys)remove(Xs, X, Ys)

remove([Y | Xs], X, [Y | Ys])dif(X,Y)remove(Xs, X, Ys)

नोट कैसे निहितार्थ तीर नियम के सिर को इंगित करता है। इसका मतलब है कि नियम का शरीर पूर्ववर्ती है और नियम का मुखिया परिणामस्वरूप है। तो आप इस नियम को पढ़ते हैं: यदि नियम का शरीर सत्य है तो नियम का मुखिया सत्य है। नियमों में लक्ष्य संयोजन के साथ जुड़े हुए हैं। ध्यान दें कि तथ्य true पूर्ववर्ती के रूप में है, जिसका अर्थ है कि remove([], _, []) हमेशा सत्य है। दूसरी तरफ, यदि नियम का शरीर गलत है कि नियम विफल रहता है लेकिन भविष्यवाणी अभी भी सफल हो सकती है यदि किसी अन्य नियम का शरीर सत्य है। यदि अन्य सभी नियमों के निकाय भी झूठे हैं तो भविष्यवाणी विफल हो जाती है। इसलिए भविष्यवाणी के लिए कई नियम तार्किक होते हैं या: नियम 1 या नियम 2 या नियम 3 सफल होने पर पूर्वानुमान निकालें/3 सफल होता है।

जैसा कि आपने विशेष रूप से वाक्यविन्यास के लिए कहा था, यह सूचियों के लिए सिर और पूंछ नोटेशन से परिचित होने का भी उपयुक्त है। यही कारण है, आप एक सूची के पहले तत्व (रों) स्पष्ट रूप से तो एक सूची निर्माता | और सूची के बाकी लिख सकते हैं:

[1|Xs] ... सूची 1 साथ शुरू होता है और फिर वहाँ एक आराम

है [1,2|Xs] ... सूची 1 और 2 द्वारा एक आराम

[X|Xs] ... सूची का पालन किया कम से कम एक तत्व से एक आराम

नोट का पालन कैसे सूची तत्वों 012,360 से अलग होते हैं के साथ शुरू होता हैजबकि शेष सूची | से अलग है। | के बाद शब्द वास्तव में एक सूची है और यह एक खाली सूची भी हो सकती है।यहाँ बराबर सूचियों के लिए कुछ उदाहरण हैं:

:

[1] रूप [1|[]]

[1,2] = [1|[2]] = [1|[2|[]]] = [1,2|[]]

निम्न सूची के लिए वहाँ पहले से ही कर रहे हैं यह लिखने के लिए 8 तरीके एक ही है [1,2,3] = [1,2|[3]] = [1|[2,3]] = [1|[2|[3|[]]]] = ...

उपर्युक्त अवलोकनों के साथ आप एक समय में नियमों की जांच करेंगे। जैसा कि @ लर्कर ने पहले से ही अपने जवाब में किया था, मैं विस्तार से नहीं जाऊंगा। हालांकि, मैं जोड़ना होगा कि यदि कोई नियम कई लक्ष्यों, अपने उदाहरण में 3 नियम की तरह है, मैं इसे उपयोगी एक समय में लक्ष्यों को एक के माध्यम से चलने के लिए लगता है:

remove([Y | Xs], X, [Y | Ys]) :- 

तत्व मूल सूची के Y है भी

remove([Y | Xs], X, [Y | Ys]) :- 
    dif(X,Y), 

X यदि बिना सूची ... में ... XY और से अलग है ...

remove([Y | Xs], X, [Y | Ys]) :- 
    dif(X,Y), 
    remove(Xs, X, Ys). 

... संबंध Xs, X और Ys के लिए भी है।

तो प्रतिस्थापन क्यों? अंतर्निहित भविष्यवाणी (\ ==)/2 एकीकरण या दुष्प्रभाव के बिना बस सफल या विफल हो जाती है। किसी दिए गए समय पर टर्म असमानता परीक्षण करने के लिए यह अच्छा है लेकिन बाद में इसका कोई प्रभाव नहीं पड़ता है। निम्नलिखित प्रश्नों पर विचार करें:

?- X=Y, X\==Y. 
no 

प्रथम चर X और Y एकीकृत कर रहे हैं और बाद में असमानता के लिए परीक्षण विफल रहता है। लेकिन:

?- X\==Y, X=Y. 
X = Y 

पहले असमानता के लिए परीक्षण सफल होता है, अन्यथा Prolog दूसरे लक्ष्य पर भी विचार नहीं करेगा। फिर X और Y सफलतापूर्वक एकीकृत हैं। द्वारा इसका मतलब यह है कि बाद में पर कोई प्रभाव नहीं पड़ा। तो भविष्यवाणी पढ़ने पर मैंने जो कुछ भी लिखा है वह वास्तव में अर्थपूर्ण नहीं है (\ ==)/2।

मैं टोपी में निम्नलिखित, if_/3 और =/3 का उपयोग कर फेंक एक छोटा संस्करण के रूप में:

list_without_element([],[],_E). 
list_without_element([X|Xs],L,E) :- 
    if_(X=E,L=Ys,L=[X|Ys]), 
    list_without_element(Xs,Ys,E). 
+2

या, 'dif/3':' list_without_element (Es, Xs, E) के साथ 'tfilter/3' का उपयोग करके इसे और अधिक संक्षेप में बताएं: - tfilter (dif (E), Es, Xs)। – repeat