2016-04-21 6 views
5

में पूर्णांक और अनंत लूप की सूची मान लीजिए कि मैं इस तरह के पूर्णांक का प्रतिनिधित्व करना चाहता हूं: integer:Sign:[FirstDigit,SecondDigit,...]। उदाहरण के लिए, 42 को integer:positive:[4,2] के रूप में दर्शाया जाएगा।प्रोलॉग सीएलपीएफडी

मुझे एक अनुमान की आवश्यकता है जो इस प्रतिनिधित्व के आधार पर पूर्णांक का मान उत्पन्न करता है और इसके विपरीत।

integer_value_('integer':Sign:[H],E) :- 
    H in 0..9, 
    (
     Sign = 'positive', 
     E #= H 
     ; 
     Sign = 'negative', 
     E #= -H 
    ). 
integer_value_('integer':Sign:[H,I|T],E) :- 
    H in 0..9, 
    length([I|T],L), 
    (
     Sign = 'positive', 
     E #= F + H * 10^L 
     ; 
     Sign = 'negative', 
     E #= F - H * 10^L 
    ), 
    integer_value_('integer':Sign:[I|T],F). 

यह काम करता है के रूप में उम्मीद:

यहाँ मैं के साथ आया है। हालांकि, इसमें integer:positive:[0,1] जैसी चीजों को स्वीकार करने की दुर्भाग्यपूर्ण संपत्ति है, जो सूची की शुरुआत में अग्रणी शून्य है। यह विशेष रूप से समस्याग्रस्त है जब मैं integer_value_(I,J), label([J]). का उपयोग कर सभी संभावित पूर्णांकों का आकलन करता हूं: अग्रणी शून्य वाले लोग भी दिखाते हैं।

मैं तो केवल सभी लेकिन पहले अंक के लिए integer_value_ उपयोग कर, और पहले एक के लिए integer_value का उपयोग कर (ध्यान में रखते हुए कि हम केवल 0 युक्त एक सूची के साथ प्रस्तुत किया जा रहा 0 के लिए समायोजित करने के लिए की जरूरत है) करके इसे ठीक करने का प्रयास किया:

integer_value('integer':Sign:[H],E) :- 
    abs(E) #< 10, 
    abs(E) #> -1, 
    integer_value_('integer':Sign:[H],E). 
integer_value('integer':Sign:[H,I|T],E) :- 
    H in 1..9, 
    length([I|T],L), 
    (
     Sign = 'positive', 
     E #= F + H * 10^L 
     ; 
     Sign = 'negative', 
     E #= F - H * 10^L 
    ), 
    integer_value_('integer':Sign:[I|T],F). 

हालांकि अब यह ठीक से व्यवहार नहीं करता है। उदाहरण के लिए, integer_value(I,-19).I = integer:negative:[1, 9] लौटाता है, लेकिन अगर हम एक और जवाब मांगते हैं तो Prolog उन कारणों के लिए अनंत लूप में जाता है जिन्हें मैं समझ नहीं पा रहा हूं (इसे झूठ बोलना चाहिए, या पहले से ही पता है कि कोई अन्य जवाब नहीं है)।

यह समस्या "विपरीत" क्वेरी integer_value(integer:negative:[1,9],Z). जो Z = 19 रिटर्न और फिर झूठे, न ही यह होती है जब दोनों बहस चर रहे हैं के साथ नहीं होती है (यह संख्या ठीक से विश्लेषण करता है, कोई अग्रणी शून्य के साथ), जो मेरे लिए आश्चर्य की बात है।

कोई विचार यह है कि अनंत लूप क्या होता है, और यदि इसे ठीक करने का कोई आसान तरीका है?

+0

+1 सीएलपी (एफडी) बाधाओं के एक बहुत ही रोचक और उचित उपयोग मामले के लिए +1! मेरे पास एकल उद्धरणों के बारे में एक छोटी टिप्पणी है: आप उन सभी परमाणुओं के लिए '' 'को छोड़ सकते हैं जिन्हें' पॉजिटिव ',' नकारात्मक ',' पूर्णांक 'आदि जैसे उद्धरणों की आवश्यकता नहीं है। आप इन सभी परमाणुओं को सीधे नीचे लिख सकते हैं , जैसे 'साइन = पॉजिटिव', 'साइन = नकारात्मक' और 'पूर्णांक: साइन: [आई | टी] '। – mat

+0

@mat मुझे पता है, लेकिन चूंकि मैं प्रोलॉग प्रोग्रामर नहीं हूं, इसलिए मुझे इस तरह के परमाणु होने के लिए काफी बदसूरत लगता है: पी – Fatalize

उत्तर

5

समस्या को देखने के लिए, आपके प्रोग्राम के एक छोटे से हिस्से को देखने के लिए पर्याप्त है। वास्तव में निम्नलिखित पर्याप्त है:

 
integer_value('integer':Sign:[H],E) :- false, 
    abs(E) #< 10, 
    abs(E) #> -1, 
    integer_value_('integer':Sign:[H],E). 
integer_value('integer':Sign:[H,I|T],E) :- 
    H in 1..9, 
    length([I|T],L), false, 
    ( Sign = 'positive', 
     E #= F + H * 10^L 
     ; 
     Sign = 'negative', 
     E #= F - H * 10^L 
    ), 
    integer_value_('integer':Sign:[I|T],F). 

L पहली बार के लिए यहां होता है, इसलिए किसी भी लंबाई संभव है। आपको किसी भी तरह के लम्बे लक्ष्य को संशोधित करना होगा।

+1

मुझे यह नहीं मिला। अब इसे हल करने के लिए ... – Fatalize

+2

@Fatalize: संबंधित समस्या के लिए [यह] (http://stackoverflow.com/a/28442760/772868) देखें। – false

3

मैं this other answer @false

पकड़ में से एक अंतिम चरण के रूप संख्या के हस्ताक्षर की तय करने के लिए है से कहा का उपयोग कर अपनी समस्या को हल करने के लिए इतना है कि जब संभव पूर्णांकों के माध्यम से पुनरावृत्ति हम बारी-बारी से जवाब पाने में कामयाब सकारात्मक और नकारात्मक संख्याओं के बीच: 9 (1 अंक) तक पहुंचने के बाद, यह -9, फिर -8, आदि के साथ एकीकृत होगा। -1 के बाद, यह 10, 11, आदि के साथ एकीकृत होगा। 99 के बाद, यह 99 के साथ एकीकृत होगा , -98, आदि आप बिंदु प्राप्त करते हैं।

integer_value('integer':Sign:I,E) :- 
    integer_value('integer':Sign:I,0,E,E). 

integer_value('integer':Sign:[H],N0,N,M) :- 
    H in 0..9, 
    N1 #= H + N0 * 10, 
    abs(M) #>= abs(N1), 
    integer_value_('integer':Sign:[],N1,N,M). 
integer_value('integer':Sign:[H,I|T],N0,N,M) :- 
    H in 1..9, 
    N1 #= H + N0 * 10, 
    abs(M) #>= abs(N1), 
    integer_value_('integer':Sign:[I|T],N1,N,M). 

integer_value_('integer':Sign:[],N0,N,_) :- 
    (
     Sign = 'positive', 
     N #= N0 
     ; 
     Sign = 'negative', 
     N #\= 0, 
     N #= - N0 
    ). 
integer_value_('integer':Sign:[H],N0,N,M) :- 
    H in 0..9, 
    N1 #= H + N0 * 10, 
    abs(M) #>= abs(N1), 
    integer_value_('integer':Sign:[],N1,N,M). 
integer_value_('integer':Sign:[H,I|T],N0,N,M) :- 
    H in 0..9, 
    N1 #= H + N0 * 10, 
    abs(M) #>= abs(N1), 
    integer_value_('integer':Sign:[I|T],N1,N,M).