2010-11-07 3 views
6

तो हम आसानी से मिल जाती है और की तरह कुछ कर रही द्वारा Prolog में एक और परमाणु के साथ एक परमाणु की जगह ले सकता: मुझे यकीन है कि वहाँ भी ऐसा करने के लिए अन्य तरीके हैं रहा हूँगैर तुच्छ Prolog खोज और बदल

replace([],A,B,[]). 
replace([H|T],A,B,[B|Result]) :- 
    H=A, 
    replace(T,A,B,Result),!. 
replace([H|T],A,B,[H|Result]) :- 
    replace(T,A,B,Result). 

हालांकि, मैं कंप्यूटिंग में तर्क में कुछ और जटिल करना चाहता हूं। आप केवल कुछ (x, y) के साथ तार्किक कथन में conj(x,y) जैसे संयोजनों को बदलने की तरह कुछ कैसे करेंगे? तो यह फाइनल की तरह है और प्रतिस्थापित है लेकिन परमाणुओं के साथ नहीं। तो हमारे पास reduce(conj(conj(x,y),z)). जैसा कुछ हो सकता है कि मैं ((x,y),z) को कम करना चाहता हूं।

यह केवल संयोजन के साथ एक साधारण उदाहरण है, लेकिन यह संयोजन के मामले में मैं यही करना चाहता हूं। यदि कोई दिलचस्पी लेता है, तो यह वर्णनात्मक तर्क और झुकाव विधि के बारे में है।

मैं इस बारे में उलझन में हूं कि आप एक खोज करने और बदलने के लिए कैसे जाते हैं जब इनपुट वास्तव में एक सूची नहीं है; यह एक संरचना है। मैं नहीं देखता कि आप रिकर्सन और सूचियों के साथ मानक [H|T] चाल का उपयोग किए बिना इसे कैसे हल कर सकते हैं। क्या किसी के पास कोई विचार है?

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

+0

प्रतिस्थापन/4 के बजाय पहले एच = ए के बाद कट क्यों न रखें? आपका कोड तेजी से चलेगा क्योंकि प्रोलॉग सिस्टम तब पता लगा सकता है कि प्रतिस्थापन/4 निर्धारक है। –

उत्तर

5

यह निम्न प्रकार की एक मेटा-दुभाषिया, लिख कर एक सरल तरीके से किया जाता है:

replace(V, V) :- 
    % pass vars through 
    var(V), !.  
replace(A, A) :- 
    % pass atoms through 
    atomic(A), !. 
replace([], []) :- 
    % pass empty lists through 
    !. 
replace([X|Xs], [Y|Ys]) :- 
    % recursively enter non-empty lists 
    !, 
    replace(X, Y), 
    replace(Xs, Ys). 
replace(conj(X,Y), (NX,NY)) :- 
    % CUSTOM replacement clause for conj/2 
    !, 
    replace(X, NX), 
    replace(Y, NY). 
replace(T, NT) :- 
    % finally, recursively enter any as yet unmatched compound term 
    T =.. [F|AL], 
    replace(AL, NAL), 
    NT =.. [F|NAL]. 

नोट दूसरी अंतिम खंड, जिसके साथ conj/2 की जगह के अपने विशेष मामले के स्थान पर प्रदर्शन करने के लिए कार्य करता है संयोजन, ,/2। आप सामान्य रूप से टर्म प्रतिस्थापन करने के लिए इस तरह के कई अन्य खंडों को जोड़ सकते हैं, क्योंकि शेष परिभाषा (replace/2 के सभी अन्य खंड) यहां किसी भी PROLOG शब्द को पुन: व्यवस्थित कर देंगे, क्योंकि हमने सभी को कवर किया है प्रकार; युद्ध, परमाणु, और यौगिक शब्द (सूचियों सहित स्पष्ट रूप से)।

आपके मामले में यह निष्पादित हमें देता है:

?- replace(conj(conj(x,y),z), NewTerm). 
NewTerm = ((x, y), z). 

ध्यान दें कि यह परिभाषा एक और शब्द भीतर मनमाना गहराई तक नेस्टेड किसी भी मामले की सही प्रतिस्थापन प्रदर्शन करेंगे।

+0

इस शार्क के लिए धन्यवाद। चालाक सामान लेकिन ... बहुत चालाक, क्या आप मेटा दुभाषियों के बारे में जानने के लिए किसी भी संसाधन की सिफारिश करते हैं? धन्यवाद। – ale

+0

बहुत चालाक? एक पोलॉग प्रोग्रामर के रूप में, यह एक उपयोगिता भविष्यवाणी है जिसे मैं नियमित रूप से टर्म मैनिपुलेशन करने के लिए उपयोग करता हूं, और किसी भी पेशेवर पोलॉग प्रोग्रामर के बैग-ऑफ-ट्रिक्स में होगा;) मेटा-दुभाषियों पर संसाधनों के लिए, आप "प्रोग्रामिंग इन प्रोलॉग" देख सकते हैं क्लॉक्सिन और मेलिश, और लियो स्टर्लिंग और एहूद शापिरो द्वारा "प्रोल की कला"। 'मेटा-दुभाषिया' द्वारा, मेरा मतलब है पोलॉग कोड जो PROLOG कोड को समझ/समझ सकता है, जो आपके प्रश्न के लिए विशेष रूप से अनुकूल है। – sharky

1

आप =.. का उपयोग करके एक सामान्य शब्द को एक सूची में बदल सकते हैं, उदा।

?- conj(conj(x,y),z) =.. List. 
List = [conj, conj(x, y), z]. 

इसे बार-बार करना, आप पूरी अवधि को बाहर कर सकते हैं।

एक सामान्य विधेय है कि इनपुट अवधि में कुछ नोड्स में परिवर्तन कुछ इस तरह दिखेगा:

change_term(NodeChanger, Term1, Term3) :- 
    call(NodeChanger, Term1, Term2), 
    change_term(NodeChanger, Term2, Term3), 
    !. 

change_term(NodeChanger, Term1, Term2) :- 
    Term1 =.. [Functor | SubTerms1], 
    change_termlist(NodeChanger, SubTerms1, SubTerms2), 
    Term2 =.. [Functor | SubTerms2]. 


change_termlist(_, [], []). 

change_termlist(NodeChanger, [Term1 | Terms1], [Term2 | Terms2]) :- 
    change_term(NodeChanger, Term1, Term2), 
    change_termlist(NodeChanger, Terms1, Terms2). 

अब आपके द्वारा निर्धारित हैं:

conj_changer(conj(X, Y), (X, Y)). 

तो आप के द्वारा अपने को कम-विधेय को परिभाषित कर सकते हैं:

reduce(Term1, Term2) :- 
    change_term(conj_changer, Term1, Term2). 

उपयोग:

?- reduce(conj(conj(x,y),z), ReducedTerm). 
ReducedTerm = ((x, y), z). 

आपको सावधान रहना होगा कि आप NodeChanger को कैसे परिभाषित करते हैं, कुछ परिभाषाएं change_term/3 पाश बना सकती हैं। शायद कोई उस पर सुधार कर सकता है।

3

याद रखें कि एक सूची सिर्फ एक निश्चित प्रकार की संरचना है, ताकि आप आसानी से किसी भी अन्य संरचना से मेल खाने के लिए अपने कोड का अनुवाद कर सकें। यह आप अपने डेटा के लिए एक क्लीनर प्रतिनिधित्व उपयोग करने के लिए मदद मिल सकती है: आप संयोजक का उपयोग बस के रूप में/2 संयोजक निरूपित करने के लिए, आप एक functor वर 1 चर निरूपित करने के लिए दे सकते हैं /:

reduce(conj(X0,Y0), (X,Y)) :- 
     reduce(X0, X), 
     reduce(Y0, Y). 
reduce(var(X), X). 

उदाहरण:

?- reduce(conj(conj(var(x),var(y)), var(z)), R). 
R = ((x, y), z).