2013-10-17 8 views
6

मैं एक Prolog के बारे में सोच रहा था कि शामिल हो सकते हैं एक अंतर्निहित कॉल इस तरह:क्या प्रोलॉग का कोई संस्करण accumulators के उच्च आदेश abstraction का समर्थन करता है?

accum(generator, filter, accumulator) 
Calculates all solutions to generator. 
For each one, if filter can be proved, accumulator is proved. 
Backtracks to find all solutions to filter and generator. 
Accumulator may backtrack internally, but multiple proofs of accumulator are 
    conjoined, not backtracked. 

तो, उदाहरण के लिए, आप लिख सकते हैं प्रत्यावर्तन का उपयोग किए बिना एक सूची योग करने के लिए:

X is 0, accum(member(Val,List), True, X is X + Val). 

है इस निर्माण या समकक्ष के साथ कोई प्रस्ताव है? ध्यान रखें कि मैं प्रोलॉग में एक नौसिखिया हूं और कुछ स्पष्ट याद आ रही है।

+0

बुध में कोई व्यक्ति केवल एक अनुमानित नाम लिखता है जो यह करता है।हालांकि आप लक्ष्य का उपयोग पैरामीटर के रूप में नहीं कर सकते हैं (जैसा कि आपने प्रश्न में किया है) आपको इसके बजाय लैम्ब्डा का उपयोग करना होगा। –

+0

@PaulBone परिणाम जेनरेटर के सभी समाधानों की गणना करने पर निर्भर करता है। इसलिए, आखिरकार, बुध के 'समाधान' मॉड्यूल से कुछ कॉल करना अभी भी आवश्यक होगा, जब तक कि आप गैर-लॉजिकल विशेषताओं का उपयोग नहीं करना चाहते (जिस स्थिति में adverb "बस" लागू नहीं होता है))। –

उत्तर

3

मुझे लगता है कि स्पष्ट रिकर्सन के बिना मेरा मतलब है? यदि ऐसा है, तो आप एक सहायक भविष्य की आवश्यकता से बचने के लिए एक लैम्ब्डा अभिव्यक्ति के साथ, उच्च-आदेश अनुमानित सूची गुना बाएं के कार्यान्वयन का उपयोग कर सकते हैं। Logtalk एक उदाहरण के रूप का उपयोग करके आप लिख सकते हैं:

?- Sum0 is 0, meta::fold_left([X,Y,Z]>>(Z is Y+X), Sum0, [1,2,3], Sum). 
Sum0 = 0, 
Sum = 6. 

Logtalk सबसे Prolog कार्यान्वयन एक बैकएंड संकलक के रूप में उपयोग कर सकते हैं (http://logtalk.org/)। आप एक प्रोलॉग लाइब्रेरी के साथ एक समर्थित प्रोलॉग कंपाइलर के साथ Ulrich की lambda लाइब्रेरी (http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord.html) का भी उपयोग कर सकते हैं, जो एक ही परिणाम के लिए गुना बाएं पूर्वानुमान प्रदान करता है। एक उदाहरण के रूप अब YAP का उपयोग करना:

$ yap 
... 
?- use_module(library(lambda)). 
... 
?- use_module(library(maplist)). 
... 
?- Sum0 is 0, foldl(\X^Y^Z^(Z is Y+X), [1,2,3], Sum0, Sum). 
Sum = 6, 
Sum0 = 0. 

संक्षेप में, एक सूची से अधिक गुना छोड़ दिया विधेय दोहराता, रिकर्सिवली एक सूची तत्व और संचायक के लिए अपनी पहली बहस में बंद को लागू करने, अंतिम संचायक मूल्य लौटने।

+0

सवाल बैकट्रैकिंग द्वारा उत्पन्न किए जाने वाले समाधानों के लिए पूछ रहा था। आपकी प्रतिक्रिया पहले से उत्पन्न समाधान [1,2,3] 'समाधान से शुरू होती है, इसलिए यह प्रश्न का उत्तर नहीं देती है। –

+0

'1,2,3]' ** ** ** ** समाधान की सूची नहीं है, यह ** इनपुट ** सूची है, वही है कि आप 'सदस्य (वैल, सूची)' बिट में गुजरेंगे प्रश्न उदाहरण –

+0

आपने केवल सामान्य मामला नहीं बल्कि उदाहरण हल किया है। सवाल स्पष्ट रूप से था, मैं दोहराना, बैकट्रैकिंग द्वारा उत्पन्न किए जाने वाले समाधानों के लिए पूछना। –

5

SWI-Prolog library(aggregate)

aggregate_all(sum(Val), member(Val,List), Sum) 

(जाहिरा तौर पर साधारण) एकत्रीकरण और पीढ़ी के बीच चर के बंटवारे विधेय के साथ प्राप्त किया जाता है, foreach/2, जो आपके लिए रुचिकर सकता है उदाहरण के लिए

, एक शक्तिशाली इंटरफ़ेस है।

SWI-Prolog में आप क्या कर सकते हैं ?- edit(library(aggregate)). आंतरिक अध्ययन करने के लिए ...

पुस्तकालय (कुल) अपेक्षाकृत अक्षम है, लेकिन SWI-Prolog nb_ (गैर backtrackable) डेटा संरचनाओं के साथ मिलकर कर रहा है बहुत अच्छी तरह से अपना काम करना चाहिए ...

गैर बैकट्रैक करने योग्य डेटा संरचनाओं के बारे में: herenb_setarg/3 के माध्यम से लागू मेरे 'स्वयं निर्मित' संचयक का एक उदाहरण है।

2

बुध की मानक लाइब्रेरी में "समाधान" मॉड्यूल इस तरह की कार्यक्षमता प्रदान करता है।

ध्यान दें कि X is X + Val एक्स के लिए एक नया मान निर्दिष्ट नहीं करता है। यह एक कथन है जो वैध है यदि वैल शून्य है, और झूठी है यदि यह कोई अन्य नंबर है, जो शायद आपका मतलब नहीं है। इस तरह के जमाकर्ताओं को आम तौर पर प्रारंभिक और अंतिम मूल्य के बीच संबंध के रूप में व्यक्त किया जाता है।

:- import_module solutions. 
... 
sumlist(List, Sum) :- 
    Generator = (pred(Val::out) is nondet :- member(Val, List), true), 
    Accumulator = (pred(X::in, Y::in, Z::out) is det :- Z = X + Y), 
    aggregate(Generator, Accumulator, 0, Sum). 

एक अलग फिल्टर तर्क के लिए कोई जरूरत नहीं है, के रूप में यह जनरेटर के हिस्से के रूप में शामिल किया जा सकता है:

पारा में, अपने उदाहरण के रूप में लिखा जा सकता है।

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