2015-05-22 13 views
5

प्रोलॉग में कुछ अनुभव के साथ कोई भी प्रोग्रामर संख्याओं के लिए असामान्य नोटेशन का उपयोग करने के फायदे जानता है। उदाहरण, अगर हम 1 की सूची के रूप में एक संख्या का प्रतिनिधित्व करते हैं "(" 4 "सूची है" [1,1,1,1] "और इतने पर), हम परिभाषित कर सकते हैं:प्रोलॉग: गायब सुविधा?

unary_succ(X,[1|X]). 

निम्नलिखित प्रश्नों करता है क्या उम्मीद है:

?- X=[1,1],unary_succ(X,Y). 
X = [1, 1], 
Y = [1, 1, 1]. 

?- unary_succ(X,Y),X=[1,1]. 
X = [1, 1], 
Y = [1, 1, 1]. 

?- unary_succ(X,Y),Y=[1,1]. 
X = [1], 
Y = [1, 1]. 

इस तरह, बयान unary_succ (एक्स, वाई) एक्स और वाई "बांधता है" एक तरह से है कि, अगर बाद तथ्य कहा गया है, इन में से एक चर एक मूल्य के लिए बाध्य है, दूसरा एक करता है।

हालांकि, यदि हम आंतरिक संख्या का प्रतिनिधित्व करते हैं तो यह व्यवहार संभव नहीं है:

?- X=2,succ(X,Y). 
X = 2, 
Y = 3. 

?- succ(X,Y),X=2. 
ERROR: succ/2: Arguments are not sufficiently instantiated 

?- succ(X,Y),Y=2. 
ERROR: succ/2: Arguments are not sufficiently instantiated 

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

मेरे प्रश्न हैं:

क) कुछ आसान करने के लिए कि Prolog में जिस तरह से।

बी) यदि संभव नहीं है, तो इस सुविधा का समर्थन करने वाली कोई अन्य प्रोग्रामिंग भाषा?

कोई टिप्पणी स्वागत है।

सभी को धन्यवाद।

* परिशिष्ट मैं *

एक और उदाहरण है:

user_id(john,1234). 
user_id(tom,5678). 

और प्रश्नों:

X=john,user_id(X,Y). 
user_id(X,Y),X=john 

वर्तमान में उलटे पांव लौटने द्वारा हल कर रहे हैं।

+3

एसडब्ल्यूआई प्रोलॉग में, मुझे लगता है कि आप clpfd लाइब्रेरी के साथ कर सकते हैं। आप यह देखने के लिए अपने स्रोत कोड को देखना चाहेंगे कि इसे कैसे कार्यान्वित किया जाता है। – nhahtdh

+0

हाय। आपके सहयोग के लिए धन्यवाद। प्रश्न में जोड़ा गया स्पष्ट करने के लिए एक और उदाहरण। –

+4

मैं @nhahtdh द्वारा सीएलपी (एफडी) सुझाव दूसरा सेकेंड करता हूं: कम से कम पूर्णांक के लिए, सीएलपी (एफडी) बाधाओं का उपयोग करके निश्चित रूप से एक रिलेशनल समाधान है जिसे आप ढूंढ रहे हैं, और सभी प्रमुख प्रोलॉग कार्यान्वयन द्वारा प्रदान किया जाता है। बस 'एक्स # = 2, वाई # = एक्स + 1' या समकक्ष' वाई # = एक्स + 1, एक्स # = 2' लिखें। – mat

उत्तर

3

यह विषय coroutining के रूप में जाना जाता है, और इसे सामान्य रूप से हल करने के लिए - afaik - मूल Prolog गणना मॉडल के विस्तार की आवश्यकता है। सौभाग्य से, सबसे Prologs है इस तरह के विस्तार ... तो चलिए in SWISH अपनी खुद की 'प्रतिक्रियाशील' एक्सटेंशन का निर्माण करने की कोशिश करते हैं:

my_succ(X, Y) :- when((nonvar(X);nonvar(Y)), succ(X, Y)). 

संपादित मुद्दे पर पूरी तरह से नहीं है, लेकिन जनवरी SWI-Prolog मेलिंग सूची एक सरल पर पोस्ट coroutining आवेदन के उदाहरण:

?- freeze(X, writeln(X)), findall(X, between(1,3,X), Xs). 
1 
2 
3 
Xs = [1, 2, 3], 
freeze(X, writeln(X)). 
+0

बहुत बहुत धन्यवाद, मुझे नहीं पता था कि यह कथन मौजूद है। –

+2

'जब/2' एसआईसीस्टस (मूल), वाईएपी, और एसडब्ल्यूआई में मौजूद है। सामान्य रूप से coroutining का उल्लेख करने के लिए – false

+3

+1। हालांकि, यह विशेष उदाहरण मेरे विचार में बहुत भाग्यशाली नहीं है, क्योंकि 'वाई # = एक्स + 1' अधिक सुविधाजनक और सीएलपी (एफडी) बाधाओं के साथ अधिक उपयुक्त ढंग से हल किया गया है। मेरा सुझाव है कि आप वर्तमान के बजाय 'कब/2' के लिए एक व्यावहारिक रूप से अधिक मूल्यवान उदाहरण दें। – mat

4

समस्या आप का वर्णन रूप में लंबे समय के रूप में एक Prolog प्रणाली द्वारा जवाब (वाक्यात्मक) जवाब प्रतिस्थापन तक ही सीमित हैं मौजूद है। आपके उदाहरण में, लक्ष्य succ(X, Y) को समाधान के पूरे सेट का वर्णन करने के लिए असीमित कई उत्तरों की आवश्यकता होगी। इस कारण से, instantiation_error इसके बजाए जारी किया गया है।

इस समस्या को हल करने के लिए हमें जवाबों को विस्तारित करने की आवश्यकता है। तो जवाब न केवल उत्तर प्रतिस्थापन शामिल हैं बल्कि कुछ सेटों का वर्णन करने के लिए कुछ और विस्तृत तरीका हैं।

जेड से अधिक

library(clpfd) भेंट की कमी (और सबसे प्रमुखता से परिमित डोमेन)।

?- use_module(library(clpfd)). 
?- Y #= X+1. 
X+1#=Y. 

ध्यान दें कि इस तरह के समाधानकर्ताओं सामान्य स्थिति के लिए बहुत मजबूत नहीं कर रहे हैं:

?- Y #= X+1, X #= Y+1. 
Y+1#=X, 
X+1#=Y. 

आप प्रणाली विफल अपेक्षा कर सकते हैं लेकिन यह एक जवाब जो अनिवार्य रूप से क्वेरी फिर से बताने से पैदा करता है। कम से कम उत्तर गलत नहीं है, क्योंकि यह केवल कहता है: हां, एक समाधान प्रदान किया गया है यह संबंध रखता है (जो यह नहीं है, बीमा अनुबंधों में गारंटी के समान प्रिंट या गारंटी प्रमाण पत्र के समान नहीं है)।

when/2 भी coroutining रूप में जाना जाता है और आप क्या clpfd साथ मिल की तुलना में कमजोर कई मामलों में है। लेकिन, कुछ मामलों में यह clpfd के कुछ कार्यान्वयन के लिए मजबूत है। dif/2 जो when(?=(X,Y), X \== Y) के रूप में व्यक्त किया जा सकता है और

| ?- dif(X, Y), X = Y. 
no 

पर विचार करें ... जबकि (SICStus में)

| ?- X #\= Y, X #= Y. 
Y #= X, 
Y #\= X, 
Y in inf..sup, 
X in inf..sup ? ; 
no 

library(clpq) एक solver कि कई स्थितियों में मजबूत है, लेकिन mod/2 तरह पूर्णांक विशिष्ट बाधाओं का अभाव है प्रदान करता है । कई परिस्थितियों में यह अभी भी दिलचस्प है, जैसा कि यहां SICStus में है:

| ?- use_module(library(clpq)). 
yes 
| ?- {Y=X+1}. 
{X = -1+Y} ? 
yes 
| ?- {Y=X+1}, {X=Y+1}. 
no