कुछ बहुत अच्छे जवाब हैं। मैं चर्चा में योगदान देने का प्रयास करूंगा।
प्रोलॉग में डिक्लेरेटिव, लॉजिक प्रोग्रामिंग के विषय पर रिचर्ड ओ'कीफ की महान पुस्तक "द क्राफ्ट ऑफ प्रोलॉग" है । यह एक प्रोग्रामिंग भाषा का उपयोग करके कुशल प्रोग्राम लिखने के बारे में है जो आपको बहुत ही अक्षम प्रोग्राम लिखने देता है। इस पुस्तक में, कई एल्गोरिदम के कुशल कार्यान्वयन पर चर्चा करते हुए (अध्याय "प्रोग्रामिंग के तरीके") में, लेखक निम्नलिखित दृष्टिकोण लेता है:
- अंग्रेजी में समस्या को परिभाषित करें
- एक कार्यशील समाधान लिखें जो यथासंभव घोषित हो; आमतौर पर, इसका मतलब है कि आपके प्रश्न में वास्तव में बहुत कुछ है, बस प्रोलॉग को सही करें
- वहां से, इसे और तेज करने के लिए कार्यान्वयन को परिष्कृत करने के लिए कदम उठाएं
सबसे अधिक ज्ञानवर्धक (मेरे लिए) अवलोकन मैं इन के माध्यम से अपने तरीके से काम करते हुए बनाने में सक्षम था:
हां, लेखक द्वारा शुरू किए गए "घोषणात्मक" विनिर्देश की तुलना में कार्यान्वयन का अंतिम संस्करण बहुत अधिक कुशल है। यह अभी भी बहुत ही घोषणात्मक, रसीला और समझने में आसान है। बीच में क्या हुआ है कि अंतिम समाधान समस्या के गुणों को कैप्चर करता है जिससे प्रारंभिक समाधान अनजान था।
दूसरे शब्दों में, एक समाधान को लागू करते समय, हमने समस्या के बारे में अपने ज्ञान का उतना ही उपयोग किया है जितना हम कर सकते हैं। की तुलना करें:
किसी सूची का क्रमांकन खोजें जैसे कि सभी तत्व आरोही क्रम में हैं
सेवा मेरे:
दो सॉर्ट की गई सूची को मर्ज करने के परिणामस्वरूप एक सॉर्ट की गई सूची होगी। चूँकि वहाँ पहले से ही सॉर्ट किए जा सकने वाले सब्लिस्ट्स हो सकते हैं, इन्हें 1 के सब्लिस्ट्स के बजाय एक शुरुआती बिंदु के रूप में उपयोग करें।
एक छोटी सी तरफ: आपके द्वारा दी गई एक परिभाषा आकर्षक है क्योंकि यह बहुत सामान्य है। हालाँकि, मैं इस भावना से नहीं बच सकता कि यह उद्देश्यपूर्ण रूप से इस तथ्य की अनदेखी करता है कि क्रमपरिवर्तन एक अच्छी तरह से समस्या है। यह कुछ ऐसा है जो हम पहले से ही जानते हैं ! यह आलोचना नहीं है, सिर्फ एक अवलोकन है।
असली सवाल के रूप में: आगे कैसे बढ़ना है? खैर, एक तरीका यह है कि हम कंप्यूटर को घोषित होने वाली समस्या के बारे में अधिक से अधिक ज्ञान प्रदान करें।
मैं वास्तव में समस्या को हल करने का सबसे अच्छा प्रयास अलेक्जेंडर स्टेपानोव द्वारा लिखित पुस्तकों में प्रस्तुत किया गया है, "प्रोग्रामिंग के तत्व" और "गणित से सामान्य प्रोग्रामिंग के लिए" । मैं दुख की बात है कि इन पुस्तकों में सब कुछ संक्षेप में (या पूरी तरह से समझने के) काम नहीं कर रहा हूं। हालांकि, इस दृष्टिकोण को कुशल (या यहां तक कि इष्टतम) लाइब्रेरी एल्गोरिदम और डेटा संरचनाओं को परिभाषित करने के लिए है, इस प्रावधान के तहत कि इनपुट के सभी प्रासंगिक गुण अग्रिम में ज्ञात हैं। अंतिम परिणाम है:
- प्रत्येक अच्छी तरह से परिभाषित परिवर्तन बाधाओं का एक शोधन है जो पहले से ही मौजूद हैं (गुण जो ज्ञात हैं);
- हमने कंप्यूटर को यह तय करने दिया कि मौजूदा बाधाओं के आधार पर कौन सा परिवर्तन इष्टतम है।
जैसा कि यह काफी हद तक अभी तक नहीं हुआ है, ठीक है, कंप्यूटर विज्ञान वास्तव में एक युवा क्षेत्र है, और हम अभी भी इसमें से अधिकांश की नवीनता की सराहना कर रहे हैं।
पुनश्च
"कार्यान्वयन को निखारने" से मेरा क्या मतलब है, इसका स्वाद आपको देने के लिए: उदाहरण के लिए, सूची में अंतिम तत्व प्राप्त करने की आसान समस्या के लिए प्रोलाग में लें। कहने के लिए विहित घोषणात्मक समाधान है:
last(List, Last) :-
append(_, [Last], List).
यहाँ, का घोषित अर्थ append/3
है:
List1AndList2
का संयोजन है List1
औरList2
चूंकि दूसरे तर्क में append/3
हमारे पास केवल एक तत्व के साथ एक सूची है, और पहले तर्क को अनदेखा किया गया है (अंडरस्कोर), हमें मूल सूची का एक विभाजन मिलता है जो सूची के सामने ( List1
संदर्भ में append/3
) का खुलासा करता है और मांग करता है कि पीछे ( List2
संदर्भ में append/3
) वास्तव में केवल एक तत्व के साथ एक सूची है: इसलिए, यह अंतिम तत्व है।
वास्तविक SWI-Prolog द्वारा प्रदान की कार्यान्वयन , तथापि, का कहना है:
last([X|Xs], Last) :-
last_(Xs, X, Last).
last_([], Last, Last).
last_([X|Xs], _, Last) :-
last_(Xs, X, Last).
यह अभी भी अच्छी तरह से घोषणात्मक है। ऊपर से नीचे तक पढ़ें, यह कहता है:
सूची का अंतिम तत्व केवल कम से कम एक तत्व की सूची के लिए समझ में आता है। पूंछ और एक सूची के प्रमुख की जोड़ी के लिए अंतिम तत्व, तब है: सिर, जब पूंछ खाली होती है, या गैर-खाली पूंछ के अंतिम।
इस कार्यान्वयन को प्रदान करने का कारण प्रोलॉग के निष्पादन मॉडल के आसपास के व्यावहारिक मुद्दों पर काम करना है । आदर्श रूप से, यह अंतर नहीं होना चाहिए कि किस कार्यान्वयन का उपयोग किया जाता है। इसी तरह, हम कह सकते थे:
last(List, Last) :-
reverse(List, [Last|_]).
किसी सूची का अंतिम तत्व प्रत्यावर्तित सूची का पहला तत्व है।
यदि आप अच्छी, घोषणात्मक प्रस्तावना के बारे में अनिर्णायक चर्चाओं को भरना चाहते हैं, तो स्टैक ओवरफ्लो पर प्रोलॉग टैग में कुछ प्रश्नों और उत्तरों के माध्यम से जाएं ।