2017-04-21 14 views
5

मेरे पास प्रोलॉग में एक अनुमानित, अद्वितीय_लेमेंट/2 के दो, थोड़ा अलग, कार्यान्वयन हैं। तत्व एक्स और एक सूची एल दिए जाने पर पूर्वानुमान सफल होता है, तत्व एक्स सूची में केवल एक बार दिखाई देता है।(एसडब्ल्यूआई) प्रस्ताव: उप-लक्ष्यों का आदेश

कार्यान्वयन 1:

%%% unique_element/2 
unique_element(Elem, [Elem|T]) :- 
    not(member(Elem, T)). 
unique_element(Elem, [H|T]) :- 
    member(Elem, T), 
    H\==Elem, 
    unique_element(Elem, T), 
    !. 

परिणाम:

?- unique_element(X, [a, a, b, c, c, b]). 
false. 

?- unique_element(X, [a, b, c, c, b, d]). 
X = a ; 
X = d. 

कार्यान्वयन 2:

%%% unique_element/2 
unique_element(Elem, [Elem|T]) :- 
    not(member(Elem, T)). 
unique_element(Elem, [H|T]) :- 
    H\==Elem, 
    member(Elem, T), 
    unique_element(Elem, T), 
    !. 

मामले में आप पहली बार में नोटिस नहीं किया था नीचे कार्यान्वयन और परिणाम हैं दृष्टि: "एच \ == एलेम" और "सदस्य (एलेम, टी)" दूसरे प्रत्यारोपण, नियम 2 पर फिसल गए हैं।

परिणाम:

?- unique_element(X, [a, a, b, c, c, b]). 
X = a. 

?- unique_element(X, [a, b, c, c, b, d]). 
X = a ; 
X = d. 

प्रश्न: कैसे आदेश, इस मामले में, परिणाम प्रभावित करता है? मुझे एहसास है कि नियम/तथ्यों/आदि मामलों का आदेश। यद्यपि फ़्लिप किए गए दो विशिष्ट नियम, "कनेक्ट" नहीं होते हैं या किसी अन्य को किसी भी तरह प्रभावित नहीं करते हैं (उदाहरण के लिए गलत जगह/ऑर्डर में "कट" अनुमानित)।

नोट: हम यहां एसडब्ल्यूआई-प्रोलॉग के बारे में बात कर रहे हैं।

नोट 2: मुझे पता है, शायद अलग और बेहतर कार्यान्वयन। मेरा प्रश्न यहां उप-लक्ष्यों को बदलने के क्रम के बारे में है।

+2

दोनों संस्करण गलत 'अनन्य_लेमेंट (एक्स, [ए, बी, सी]), एक्स = सी। – false

उत्तर

6

टी एल; डॉ: दस्तावेज़ पढ़ें और यह पता लगाने क्यों:

?- X = a, X \== a. 
false. 

?- X \== a, X = a. 
X = a. 

मुझे आश्चर्य है कि तुम क्यों यह अपने आप पता लगाना से इतने करीब रोक ;-)

भी कर रहे हैं Prolog में चीजों की तुलना करने के कई तरीके। कम से कम, आपके पास एकीकरण है, जो कभी-कभी तुलना कर सकता है, और कभी-कभी और भी करता है; आपके पास समानता है, और इसकी अस्वीकृति, जिसे आप उपयोग कर रहे हैं। तो यह क्या क्या करता है:

?- a \== b. % two different ground terms 
true. 

?- a \== a. % the same ground term 
false. 

अब यह हो जाता है दिलचस्प:

?- X \== a. % a free variable and a ground term 
true. 

?- X \== X. % the same free variable 
false. 

?- X \== Y. % two different free variables 
true. 

मैं सुझाव है कि आप निम्न कार्य करें:? यह पता लगाने कैसे member/2 यह एकीकरण का उपयोग करता है अपनी बात (करता तुल्यता कुछ और?) तो जो भी member/2 को ऊपर दिए गए सभी उदाहरणों में उपयोग कर रहा है और देखें कि परिणाम अलग हैं या नहीं।

और चूंकि आप यह सुनिश्चित करने की कोशिश कर रहे हैं कि चीजें अलग हैं, तो dif/2 क्या करें। में के रूप में:

?- dif(a, b). 

या

?- dif(X, X). 

या

?- dif(X, a). 

और इतने पर।

यह भी देखें this question and answers: मुझे लगता है कि उत्तर आपके प्रश्न के लिए प्रासंगिक हैं।

उम्मीद है कि मदद करता है।

7

H\==Elem लक्ष्य निष्पादित होने पर बिंदु पर वाक्य रचनात्मक असमानता के लिए परीक्षण कर रहा है। तो यहाँ हम परीक्षण करता है, तो वे कर रहे हैं (वाक्य रचना) अलग, और फिर वे फिर भी है और इस तरह एकीकृत

?- H\==Elem, H = Elem. 
H = Elem. 

?- H\==Elem, H = Elem, H\==Elem. 
false. 

अब अलग हैं: लेकिन बाद में एकीकरण चर समान बना सकता है। यह इस प्रकार सिर्फ एक अस्थायी परीक्षण है।

लक्ष्य member(Elem, T) दूसरे ओर यह सच है यदि Elem वास्तव में T का एक तत्व है। पर विचार करें:

?- member(Elem, [X]). 
Elem = X. 

कौन सा

के रूप में पढ़ा जा सकता है (जब) ​​इसे पकड़ है कि Elem सूची [X] का एक तत्व है?

और जवाब

कुछ निश्चित परिस्थितियों में यह रखती है, अर्थात् जब Elem = X है।

यदि आप अब अपने कार्यक्रमों में उन विभिन्न प्रकार के लक्ष्यों को मिलाते हैं तो आपको अजीब परिणाम मिलते हैं जो केवल आपके कार्यक्रम को विस्तार से देखकर समझाया जा सकता है।

शुरुआत के रूप में, केवल प्रोल के शुद्ध भागों से चिपकना सबसे अच्छा है। आपके मामले में: के \==

  • कटौती का उपयोग नहीं करते जगह में

    • उपयोग dif/2 - अपने मामले में यह दो के लिए जवाब की संख्या सीमित करता है। में के रूप में unique_element(X, [a,b,c])

    • not/1 है और न ही (\+)/1 प्रयोग नहीं करते। यह और भी गलतता पैदा करता है। unique_element(a,[a,X]),X=b. पर विचार करें जो गलत तरीके से विफल रहता है जबकि X=b,unique_element(a,[a,X]) सही ढंग से सफल होता है।


    यहाँ अपने कार्यक्रम का एक सीधे शुद्ध संस्करण है। सुधार के लिए अभी भी जगह है!

    non_member(_X, []). 
    non_member(X, [E|Es]) :- 
        dif(X, E), 
        non_member(X, Es). 
    
    unique_element(Elem, [Elem|T]) :- 
        non_member(Elem, T). 
    unique_element(Elem, [H|T]) :- 
        dif(H,Elem), 
        % member(Elem, T),   % makes unique_element(a,[b,a,a|Xs]) loop 
        unique_element(Elem, T). 
    
    ?- unique_element(a,[a,X]). 
        dif(X, a) 
    ; false.    % superfluous 
    
    ?- unique_element(X,[E1,E2,E3]). 
        X = E1, 
        dif(E1, E3), 
        dif(E1, E2) 
    ; X = E2, 
        dif(E2, E3), 
        dif(E1, E2) 
    ; X = E3, 
        dif(E2, E3), 
        dif(E1, E3) 
    ; false. 
    

    नोट करें कि अंतिम क्वेरी कैसे पढ़ती है?

    X[E1,E2,E3] का एक अद्वितीय तत्व कब है?

    उत्तर तीन गुना है।एक के बाद एक तत्व को ध्यान में रखते:

    XE1 है, लेकिन केवल अगर यह E2 को अलग है और E3

    आदि

  • 5

    आप tcount तरह unique_element को परिभाषित नहीं किया जा सकता Prolog - count repetitions in list

    unique_element(X, List):- tcount(=(X),List,1).

    +1

    के लिए गलत तरीके से असफल हो सकते हैं शायद कुछ दिलचस्प उपयोग जोड़ें? – false

    4
    :- use_module(library(apply)). 
    
    unique_element(Y,[X|Xs]) :- 
        if_(Y=X,maplist(dif(Y),Xs),unique_element(Y,Xs)). 
    

    इसके विपरीत करने के लिए @ user27815 बहुत सुरुचिपूर्ण समाधान (+ रों (0)) इस संस्करण clpfd पर निर्माण नहीं करता है (tcount/3 द्वारा प्रयोग किया जाता है:यहाँ एक और संभावना unique_element परिभाषित/2 का उपयोग कर if_/3 और maplist/2 है)। ओपी काम द्वारा दिए गए उदाहरण के प्रश्नों के रूप में उम्मीद:

    ?- unique_element(a,[a, a, b, c, c, b]). 
    no 
        ?- unique_element(X,[a, b, c, c, b, d]). 
    X = a ? ; 
    X = d ? ; 
    no 
    

    अब @false द्वारा प्रदान उदाहरण एक ज़रूरत से ज़्यादा ChoicePoint से बाहर निकले बिना सफल होता है:

    ?- unique_element(a,[a,X]). 
    dif(a,X) 
    

    दूसरे अधिक सामान्य क्वेरी पैदावार ही परिणाम:

    ?- unique_element(X,[E1,E2,E3]). 
    E1 = X, 
    dif(X,E3), 
    dif(X,E2) ? ; 
    E2 = X, 
    dif(X,E3), 
    dif(X,E1) ? ; 
    E3 = X, 
    dif(X,E2), 
    dif(X,E1) ? ; 
    no 
    
    संबंधित मुद्दे