prolog

2009-04-07 11 views
5

से अनूठे परिणाम क्या प्रोलॉग में कोई प्रश्न पूछने का एक आसान तरीका है केवल एक बार प्रत्येक परिणाम लौटाएं?prolog

उदाहरण के लिए

मैं की तरह कुछ कोशिश कर रहा हूँ:

deadly(Xn) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xn)), safe(Xp). 
deadly(Xp) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xp)), safe(Xn). 

deadly(X). 

और नहीं मेरे लिए उपयोगी करने के लिए

X = 5 

X = 5 

X = 5 

X = 5 

.... 

रही।

उत्तर

1

आपके कोड के बिना और कहना मुश्किल है, लेकिन आप शायद कट ऑपरेटर (!) की तलाश में हैं। यदि आप foo पर पोस्ट करना चाहते हैं, तो मैं (या कोई अन्य जो अनुसरण करता है) एक विस्तृत/विशिष्ट उत्तर देने में सक्षम हो सकता है।

+0

हर बार जब मैं का उपयोग किया है! इसने मूल्यांकन को पूरी तरह से रोक दिया है और मैं चाहता हूं कि प्रोलॉग हर मूल्य को ढूंढ रहा हो, लेकिन प्रति मूल्य केवल एक बार। (मैं कोशिश करूँगा और अपना केस घटा दूंगा) – BCS

+1

यह एक बात है कि इसका उपयोग कब और कहाँ किया जाए। "यहां फिर कभी वापस न आएं" का कहना है कि डेटा के पहले कैप्चर से पहले या उसके बाद आने वाला एक जंगली अर्थ है। – MarkusQ

3

यदि मुझे सही ढंग से याद है तो एक अनुमानित समाधान है (या इसी तरह, यह कुछ समय हो गया है क्योंकि मैंने प्रोलॉग प्रोग्राम किया था) जो एक सूची में अद्वितीय समाधान एकत्र करता है।

संपादित करें:setof/3 वह है जिसे मैं सोच रहा था। धन्यवाद, कारल।

+0

findall/3, bagof/3, setof/3 – Kaarel

4

एक चीज जो आप कर सकते हैं setof/3 लागू करने के लिए समाधान उत्पन्न करता है। लेकिन ध्यान दें कि setof/3sort/2 को bagof/3 द्वारा वितरित परिणाम के लिए लागू किया गया है (कम से कम यह एसडब्ल्यूआई-प्रोलॉग में मामला है)। इसलिए, यदि आपका समाधान जनरेटर हमेशा के लिए चला जाता है, तो setof/3 कभी भी लागू नहीं किया जाएगा ...

तो मैं कहूंगा कि प्रोग्राम करने का प्रयास करें ताकि डुप्लीकेट उत्पन्न न हो जाएं, यानी कट (!) का उपयोग करके जहां यह समझ में आता है ।

+0

अगर मुझे सही याद है, तो सेट केवल तभी उपयोगी होगा जब क्वेरी का एक सीमित समाधान आकार हो, और यह जानता है कि यह हो गया है। अन्यथा, यह केवल 5 प्राप्त कर सकता है, कह रहा है, नहीं, पहले से ही मिल गया है, और फिर से देख रहा है, और एक और 5 प्राप्त कर रहा है ... अनंत लूप। –

+0

धन्यवाद। मैंने थोड़ा सा जवाब अपडेट किया है। – Kaarel

3

एक और तरीका समाधान को याद रखना है।

:- dynamic seen/1. 

% Call this always before calling deadly_wrapper/1 
clear_seen :- 
    retractall(seen(_)). 

% This wrapper calls deadly/1 but remembers 
% the solution using assert/1, and fails 
% if the solution has been "seen" before. 
deadly_wrapper(X) :- 
    deadly(X), 
    (
     seen(X) 
    -> 
     fail 
    ; 
     assert(seen(X)) 
    ). 


% This is for testing. 
deadly(1). 
deadly(1). 
deadly(1). 
deadly(5). 
deadly(1). 
deadly(1). 

यदि आपका प्रोलॉग टैबलिंग का समर्थन करता है, तो यह और भी आसान हो जाता है। उदाहरण फ़ाइल:

:- table deadly/1. 

deadly(1). 
deadly(1). 
deadly(5). 
deadly(1). 
deadly(5). 

उदाहरण निष्पादन XSB साथ:

$ xsb 
[xsb_configuration loaded] 
[sysinitrc loaded] 

XSB Version 3.2 (Kopi Lewak) of March 15, 2009 
[x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam; 
scheduling: local; word size: 64] 

| ?- [deadly_tab]. 
[Compiling ./deadly_tab] 
[deadly_tab compiled, cpu time used: 0.0100 seconds] 
[deadly_tab loaded] 

yes 
| ?- deadly(X). 

X = 5; 

X = 1; 

no 
| ?- 
+0

मैं "याद रखना" के बजाए "memoize" कहूंगा। –

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