2015-12-08 13 views
5

की एन-वें पंक्ति वापस लौटें, मैं rowN/3 भविष्यवाणी लिखने की कोशिश कर रहा हूं जो n -th तत्व (इस मामले में पंक्ति) में मैट्रिक्स का लौटाता है। उदाहरण:प्रोलॉग - एक मैट्रिक्स

?- rowN([[1,2],[3,4],[5,6]], 2, R). 
R = [3,4]; 
No 

मैं काउंटर के साथ संघर्ष कर रहा हूँ। मैंने कुछ सुंदर उदाहरणों को खोजने में असफल प्रयास किया है। अब तक मैं इस लिखने के लिए प्रबंधित किया है:

कोड:

rowN(L,[],[]). 
rowN([],X,[]). 
rowN([],[],[]. 
rowN([H|T],X,R) :- 
    A==X, 
    A is A + 1, 
    rowI(T,A,H). 

उत्तर

4

यह पंक्ति बहुत मतलब नहीं है:

rowN(L,[],[]). 

क्योंकि दूसरा तर्क एक पूर्णांक है (अगर मैं सही ढंग से समझ), और आप एक सूची का उपयोग करें। यह आपके सभी तर्कों के साथ मामला है। इसके अलावा आप अपने रिकर्सिव कॉल में RowI का उपयोग करते हैं?

समाधान

एक समाधान पहले निर्दिष्ट करने के लिए है कि पहली पंक्ति (I = 1), मैट्रिक्स के सिर के बराबर है:

rowN([H|_],1,H). 

अगले आप के माध्यम से गणना करने में एक सतत रास्ता खोजने की जरूरत है आपका मैट्रिक्स तो हैडर निश्चित रूप से फार्म के बारे में कुछ है:

rowN([H|T],I,X) :- 
# ... 

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

rowN([_|T],I,X) :- 
    I1 is I-1, 
    rowN(T,I1,X). 

इसलिए हमारे विधेय पढ़ता है:

rowN([H|_],1,H). 
rowN([_|T],I,X) :- 
    I1 is I-1, 
    rowN(T,I1,X). 

अब अगर आप इस विधेय उपयोग करें, यह सही परिणाम दे देंगे:

?- rowN([[1,2],[3,4],[5,6]], 2, R). 
R = [3, 4] ; 
false. 

सवाल क्यों है क्या भविष्यवाणी अन्य परिणाम उत्पन्न नहीं करती है: पहला परिणाम दिखाने के बाद, rowN([[1,2],[3,4],[5,6]], 2, R) :- rowN([[3,4],[5,6]],1,[3,4]). के लिए, यह विकल्प खोजने का प्रयास कर सकता है। यह दूसरे खंड का उपयोग करके ऐसा करता है, लेकिन फिर अंततः यह पंक्तियों से बाहर हो जाएगा और rowN([],_,_) पूर्वानुमान के लिए कॉल करेगा, क्योंकि क्लॉज मैच के नहीं, यह असफल हो जाएगा।

यह समाधान सही नहीं है: यह सभी दिशाओं में सही ढंग से काम नहीं करता है, जो प्रोलॉग में सामान्य रूप से कठिन है। यही कारण है कि अच्छे प्रोलॉग प्रोग्रामर ने पुस्तकालयों को लिखा है।

के builtin nth1/3

इसके बजाय पहिया पुनर्रचना की का उपयोग करके आप SWI-prolog में nth1/3 विधेय का उपयोग कर सकते। हालांकि तर्कों को बदल दिया गया है - आपको इसे nth1(2,[[1,2],[3,4],[5,6]],R). की तरह कॉल करने की आवश्यकता है - इसका लाभ यह है कि यह अधिक दिशाओं में काम करता है कि अधिकतर लोग तेजी से समाधान में आ सकते हैं, यह निश्चित निश्चितता बगफ्री के साथ है (क्योंकि यह अरबों का परीक्षण किया गया है भविष्यवाणी का उपयोग करने वाले सभी प्रोलॉग प्रोग्राम्स द्वारा बार) और इनमें से कुछ अंतर्निहित सी ++ में कभी-कभी तेज़ बनाते हैं।उदाहरण के लिए:

?- nth1(2, [[1,2],[3,4],[5,6]], R). 
R = [3, 4]. 

?- nth1(I, [[1,2],[3,4],[5,6]], [5,6]). 
I = 3. 

?- nth1(I, [[1,2],[3,4],[5,6]], R). 
I = 1, 
R = [1, 2] ; 
I = 2, 
R = [3, 4] ; 
I = 3, 
R = [5, 6]. 

?- nth1(I,M,[2,3]). 
I = 1, 
M = [[2, 3]|_G23] ; 
I = 2, 
M = [_G22, [2, 3]|_G26] ; 
I = 3, 
M = [_G22, _G25, [2, 3]|_G29] ; 
I = 4, 
M = [_G22, _G25, _G28, [2, 3]|_G32] . 

आप इस प्रकार से पूछ सकते हैं कि क्या दूसरी पंक्ति है, पूछना जहां पंक्ति [5,6] स्थित है, सूचकांक I की tuples और पंक्ति R साथ उत्तर देकर क्वेरी अधिक सामान्य बनाने के लिए और के साथ एक मैट्रिक्स उत्पन्न एक पंक्ति [2,3] कहीं।

+2

यह उत्तर इतना अंतर्दृष्टिपूर्ण था! धन्यवाद @ कॉमूसोफ्ट –