Prolog Language
डेटा के बारे में तर्क देना
खोज…
टिप्पणियों
डेटा स्ट्रक्चर्स नामक एक नया खंड जीवन के लिए लाया गया था जहाँ कुछ संरचनाओं के स्पष्टीकरण + सृजन के कुछ सरल उदाहरण (उदाहरण) प्रदान किए गए हैं। इसकी सामग्री को संक्षिप्त और अप्रयुक्त रखने के लिए, इसमें डेटा हेरफेर के बारे में कोई दस्तावेज नहीं होना चाहिए।
इसलिए, इस खंड का नाम "डेटा के बारे में तर्क" के रूप में रखा गया था, जिसका उद्देश्य प्रोलॉग में डेटा के बारे में तर्क का सामान्यीकरण था। इसमें 'टॉप-डाउन इनफैक्शन' से लेकर 'ट्रैवर्सल ऑफ लिस्ट' तक के विषय और साथ ही कई अन्य विषय शामिल हो सकते हैं। इसके व्यापक सामान्यीकरण के कारण, स्पष्ट उपधाराएं बनाई जानी चाहिए!
प्रत्यावर्तन
प्रोलॉग में पुनरावृत्ति नहीं होती है, लेकिन पुनरावृत्ति का उपयोग करके सभी पुनरावृत्ति को फिर से लिखा जा सकता है। पुनर्संरचना तब प्रकट होती है जब एक विधेय में एक लक्ष्य होता है जो स्वयं को संदर्भित करता है। प्रोलॉग में ऐसी भविष्यवाणी करते समय, एक मानक पुनरावर्ती पैटर्न में हमेशा कम से कम दो भाग होते हैं:
आधार (गैर-पुनरावर्ती) खंड : आमतौर पर आधार-केस नियम (एस) उस समस्या के सबसे छोटे संभावित उदाहरण (ओं) का प्रतिनिधित्व करेंगे जिन्हें आप हल करने की कोशिश कर रहे हैं - बिना सदस्यों वाली एक सूची, या सिर्फ एक सदस्य, या यदि आप एक पेड़ की संरचना के साथ काम कर रहे हैं, यह एक खाली पेड़ से निपट सकता है, या इसमें केवल एक नोड के साथ एक पेड़, आदि। यह गैर-पुनरावर्ती पुनरावर्ती प्रक्रिया के आधार का वर्णन करता है।
पुनरावर्ती (जारी) खंड : पुनरावर्ती जारी रखने के लिए खुद को एक कॉल सहित किसी भी आवश्यक तर्क को समाहित करता है।
एक उदाहरण के रूप में हम जाने-माने विधेय append/3
को परिभाषित करेंगे। घोषित रूप से देखा गया, append(L1,L2,L3)
रखता है जब L3
सूची L1
और L2
को जोड़ने वाली सूची का परिणाम है। जब हम किसी विधेय के घोषित अर्थ का पता लगाने की कोशिश करते हैं, तो हम उन समाधानों का वर्णन करने का प्रयास करते हैं जिनके लिए विधेय धारण करता है। यहां कठिनाई किसी भी चरण-दर-चरण आवर्ती विवरण से बचने की कोशिश में निहित है जबकि अभी भी प्रक्रियात्मक व्यवहार को ध्यान में रखते हुए विधेय को प्रदर्शित किया जाना चाहिए।
% Base case
append([],L,L).
% Recursive clause
append([X|L1],L2,[X|L3]) :- append(L1,L2,L3).
आधार मामले में घोषणा की गई है कि "खाली सूची में संलग्न कोई भी एल एल है", ध्यान दें कि यह एल के खाली होने के बारे में कुछ भी नहीं कहता है - या यहां तक कि एक सूची होने के नाते (याद रखें, प्रोलॉग में सब कुछ शर्तों पर उबलता है):
?- append(X,some_term(a,b),Z).
X = [],
Z = some_term(a, b).
पुनरावर्ती नियम का वर्णन करने के लिए, हालांकि प्रोलॉग बाएं-से-दाएं नियमों को निष्पादित करता है, हम एक सेकंड के लिए सिर छोड़ते हैं और पहले शरीर को देखते हैं - नियम को दाएं-बाएं पढ़ना:
append([X|L1],L2,[X|L3]):- append(L1,L2,L3).
अब हम कहते हैं कि यदि शरीर धारण करता है: "उस append(L1,L2,L3)
धारण करना"
append([X|L1],L2,[X|L3]) :-append(L1,L2,L3).
फिर ऐसा होता है: "फिर ऐसा करता है append([X|L1],L2,[X|L3])
"
सादा अंग्रेजी में यह केवल अनुवाद करता है:
मान लिया जाए कि L3 L1 और L2 का संघटन है, तो [X का अनुसरण L3] और [L1 के बाद X] और L2 का संघटन भी है।
एक व्यावहारिक उदाहरण में:
"मान लेना [1,2,3] [1] और [2,3] का संघटन है, तो [a, 1,2,3] [[1, 1] और [2,3] का भी संघटन है। "
अब कुछ प्रश्नों पर नजर डालते हैं:
यह हमेशा एक अच्छा विचार है कि किसी विशिष्ट परिदृश्य परीक्षण मामले के साथ प्रदान करने के बजाय सबसे सामान्य क्वेरी के साथ प्रारंभिक रूप से परीक्षण करें। इसके बारे में सोचो: प्रोलॉग के एकीकरण के कारण, हमें परीक्षण डेटा प्रदान करने की आवश्यकता नहीं है, हम सिर्फ इसे मुफ्त चर देते हैं!
?- append(L1,L2,L3).
L1 = [],
L2 = L3 ; % Answer #1
L1 = [_G1162],
L3 = [_G1162|L2] ; % Answer #2
L1 = [_G1162, _G1168],
L3 = [_G1162, _G1168|L2] ; % Answer #3
L1 = [_G1162, _G1168, _G1174],
L3 = [_G1162, _G1168, _G1174|L2] ; % Answer #4
...
आइए एक बेहतर अवलोकन प्राप्त करने के लिए वर्णमाला के अक्षरों के साथ मुक्त चर _G1162
संकेतन को बदलें:
?- append(L1,L2,L3).
L1 = [],
L2 = L3 ; % Answer #1
L1 = [_A],
L3 = [_A|L2] ; % Answer #2
L1 = [_A, _B],
L3 = [_A, _B|L2] ; % Answer #3
L1 = [_A, _B, _C],
L3 = [_A, _B, _C|L2] ; % Answer #4
...
पहले उत्तर में, बेस केस का मिलान किया गया और प्रोलॉग ने L1
को खाली सूची में L2
और L3
L2
और L3
एकीकृत करते हुए यह साबित किया कि L3
खाली सूची और एल 2 का संघटन है।
उत्तर # 2 पर, कालानुक्रमिक बैकट्रैकिंग के माध्यम से, पुनरावर्ती खंड खेल में आता है और प्रोलॉग यह प्रमाणित करने की कोशिश करता है कि L1
साथ L2
L1
के सिर में कुछ तत्व L3
, जिसकी सूची सूची में उसी तत्व के साथ है। ऐसा करने के लिए, L1 के सिर के साथ एक नया मुक्त चर _A
एकीकृत किया गया है और L3 अब साबित हो गया है [_A|L2]
।
एक नया पुनरावर्ती कॉल किया जाता है, अब L1 = [_A]
। एक बार और, प्रोलोग यह प्रमाणित करने की कोशिश करता है कि L1
के सिर में रखा गया कुछ तत्व, L2
साथ L2
है, उसके सिर में उसी तत्व के साथ L2
L3
। ध्यान दें कि _A
पहले से ही L1
का प्रमुख है, जो पूरी तरह से नियम से मेल खाता है, इसलिए अब पुनरावृत्ति के माध्यम से, Prolog एक नए मुक्त चर के सामने _A
डालता है और हमें L1 = [_A,_B]
और L3 = [_A,_B|L2]
हम स्पष्ट रूप से पुनरावर्ती पैटर्न को खुद को दोहराते हुए देखते हैं और आसानी से देख सकते हैं, उदाहरण के लिए, पुनरावृत्ति में 100 वें चरण का परिणाम इस तरह दिखेगा:
L1 = [X1,X2,..,X99],
L3 = [X1,X2,..,X99|L2]
नोट: जैसा कि अच्छे Prolog कोड के लिए विशिष्ट है, append/3
की पुनरावर्ती परिभाषा हमें न केवल यह सत्यापित करने की संभावना प्रदान करती है कि क्या एक सूची दो अन्य सूचियों का संघटन है, यह तार्किक रूप से पूरी तरह से संतुष्ट करने वाले सभी संभावित उत्तरों को भी उत्पन्न करती है। या आंशिक रूप से त्वरित सूची।
पहुंच सूची
सदस्य
member/2
के हस्ताक्षर member(?Elem, ?List)
और true
को निरूपित करता true
यदि Elem
List
सदस्य है। इस विधेयकों का उपयोग किसी सूची में चरों तक पहुँचने के लिए किया जा सकता है, जहाँ विभिन्न समाधानों को पीछे ले जाने के माध्यम से प्राप्त किया जाता है।
उदाहरण के प्रश्न:
?- member(X, [1,2,3]).
X = 1 ;
X = 2 ;
X = 3.
?- member(X,[Y]).
X = Y.
?- member(X,Y).
Y = [X|_G969] ;
Y = [_G968, X|_G972] ;
Y = [_G968, _G971, X|_G975] ;
Y = [_G968, _G971, _G974, X|_G978]
...
पैटर्न मिलान
जब आपको उपयोग करने के लिए आवश्यक सूचक छोटे होते हैं, तो पैटर्न मिलान एक अच्छा समाधान हो सकता है, जैसे:
third([_,_,X|_], X).
fourth([_,_,_,X|_], X).