2016-02-25 4 views
6

मैं एक सूची के तत्वों की संख्या की गणना में शामिल Prolog समस्या पर काम कर रहा था:एक सूची में तत्वों की संख्या गिनती: कैसे दिखावा काम करता है

count([], 0). 
count([H|T], N) :- 
    count(T, X), 
    N is X+1, 
    N > 0. 

मैं समझ सकता क्यों यह है कि लेकिन मैं की तरह लिखा है समझ में नहीं आ रहा है कि हम एक्स को प्रतिस्थापित नहीं कर सकते हैं एक्स + 1 एक्स एन -1 है?

बहुत बहुत धन्यवाद!

+0

मामूली नाइट: प्रभाव का मतलब असाइनमेंट है। – false

उत्तर

5

आपका प्रश्न बहुत वैध है, +1।

इस प्रतीत होता है कि मनमाने ढंग से पसंद का कारण यह है कि (is)/2 तुलनात्मक रूप से निम्न स्तर की भविष्यवाणी है और केवल बहुत ही विशिष्ट मामलों में काम करता है जिसे केवल प्रक्रियात्मक रूप से समझा जा सकता है, न कि घोषणात्मक रूप से। इसलिए, (is)/2 शुरुआती लोगों के लिए समझना बेहद मुश्किल है और बेहतर से बचा जाना चाहिए क्योंकि यह प्रोलॉग का उपयोग करते समय कई रिलेशनल गुणों का आनंद लेना चाहता है।

घोषणात्मक समाधान बाधाओं का उपयोग करना है, जहां आप वही कर सकते हैं जो आप कहते हैं। पूर्णांक पर संबंधों के लिए, कृपया को (#=)/2 द्वारा प्रतिस्थापित करने वाले रिलेशनल गुणों का आनंद लेने के लिए प्रतिस्थापित करें।

उदाहरण के लिए, जीएनयू   Prolog का उपयोग कर: SICStus Prolog और SWI की तरह अन्य प्रणालियों में

 
count([], 0). 
count([_|Ls], N) :- 
     count(Ls, X), 
     X #= N - 1, 
     N #> 0. 

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

 
:- use_module(library(clpfd)). 

list_length([], 0). 
list_length([_|Ls], N) :- 
     list_length(Ls, X), 
     X #= N - 1, 
     N #> 0. 

नमूना प्रश्न:

 
?- list_length([_,_,_], N). 
N = 3. 

?- list_length(Ls, 2). 
Ls = [_G602, _G605] . 

मैं एक आसान के रूप में इस विधेय की समाप्ति गुणों में सुधार छोड़ व्यायाम।

+1

आपके विस्तृत उत्तर चटाई के लिए धन्यवाद! आपके उत्तर की शुरुआत में, आपने कहा कि (है)/2 बहुत विशिष्ट मामलों में काम करता है। क्या आप जानते हैं कि मुझे इसके बारे में और जानकारी कहाँ मिल सकती है? एसडब्ल्यूआई-प्रोलॉग वेबसाइट में, यह कहता है कि इसका उपयोग अनबाउंड बाएं ऑपरेंड के साथ किया जाना चाहिए, लेकिन यह मेरे लिए बहुत स्पष्ट नहीं है (मेरे पाठों में, यह कहता है "कॉल के समय दाएं हाथ की अवधि पूरी तरह से तत्काल होनी चाहिए। ")। – azekirel555

+1

इसमें कोई आश्चर्य की बात नहीं है कि यह आपके लिए बहुत स्पष्ट नहीं है: विशेष रूप से शुरुआत करने वाले के रूप में, आपको यह समझने का लगभग कोई मौका नहीं है कि '(is)/2' का उपयोग कैसे किया जाना चाहिए। बाद के संदर्भ के लिए, मैं केवल आपको यह बताना चाहता हूं कि इसके दाएं हाथ की तरफ पूरी तरह से तत्काल होना चाहिए, और जब लक्ष्य को कॉल किया जाता है तो उसका बाएं हाथ एक चर * होना चाहिए * (उह!)। लेकिन लॉजिक * प्रोग्रामिंग * के बजाय इस तर्क * हैकिंग * से भी परेशान क्यों? '(# =)/2' और' (#>)/2' का उपयोग करें, और इन भविष्यवाणियों की रिलेशनशिप प्रकृति का आनंद लें, जो ** सभी ** दिशाओं में प्रयोग योग्य हैं। मैंने इसके जवाब में इसके बारे में और स्पष्टीकरण जोड़े हैं। – mat

+0

आपकी आखिरी टिप्पणी थोड़ा अप्रत्यक्ष हो सकती है ... – false

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