मैं निम्नलिखित प्रोलॉग कोड के साथ समस्याओं का सामना कर रहा हूँ:

valid(X, Y) :-
    append([E1 | T2], [E1 | T3], X1), append([E1|T1], X1, X),
    append([E2 | T2], [E2 | T3], Y1), append([E2|T1], Y1, Y),
    E2 is E1 + 1.

मैं जो करने की कोशिश कर रहा हूं वह है: किसी दी गई सूची X के लिए, जांचें कि क्या यह पैटर्न [E1, ..., E1, ..., E1, ...] से मेल खाता है; अगर ऐसा होता है, तो सभी E1 को E1+1 से बदल दें। ... भागों में कितनी भी संख्या में तत्व हो सकते हैं, यानी T1, T2 और T3 किसी भी लम्बाई के हो सकते हैं।

उदाहरण के लिए, मेरा इच्छित आउटपुट है:

?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.

?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.

?- valid([1,5,6,7,8], Y).
false.

लेकिन अब मुझे जो वास्तविक आउटपुट मिला है वह है:

?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
ERROR: Out of global stack

?- valid([1,5,6,7,8], Y).
ERROR: Out of global stack

समस्या यह है कि, प्रोलॉग T1, T2 और T3 की असीमित कई लंबाई को आज़माने का प्रयास करेगा, और इसलिए कभी भी रुकता नहीं है। इसलिए जब मेरी इनपुट सूची X पैटर्न से मेल नहीं खाती, तो यह मेमोरी स्पेस खत्म होने तक चलती रहती है।

क्या मेरे कोड को ठीक करने का कोई तरीका है ताकि यह तब रुक जाए जब सभी संभावित उत्तर मिल जाएं (एक से अधिक हो सकते हैं) या जब X पैटर्न से मेल नहीं खाता है?

धन्यवाद!

1
yixiaoyx 26 मार्च 2017, 10:46

1 उत्तर

सबसे बढ़िया उत्तर

Append/3 विधेय स्थिर नहीं है, इसलिए यह शुरुआत में इसके मापदंडों का मूल्यांकन करता है। तो आपको उस नियम को स्थानांतरित करने की आवश्यकता है जो एक्स का मूल्यांकन सामने की तरह करता है:

valid(X, Y) :-
    append([E1|T1], X1, X),append([E1 | T2], [E1 | T3], X1),
    append([E2|T1], Y1, Y),append([E2 | T2], [E2 | T3], Y1),
    E2 is E1 + 1.

चूंकि एक्स का मूल्यांकन पहले परिशिष्ट से किया जाता है, इसलिए असीम रूप से कई लंबाई और इसी तरह दूसरे परिशिष्ट की कोशिश नहीं की जाएगी।

कुछ उदाहरण:

?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.

?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.

?- valid([1,5,6,7,8], Y).
false. 

मैं कुछ सरल रिकर्सन और ई 1 (और आउटपुट सूची में ई 2 के साथ प्रतिस्थापित) की उपस्थिति की गिनती के साथ समस्या को हल करना पसंद करूंगा क्योंकि परिशिष्ट थोड़ा मुश्किल हो सकता है ...

तो उदाहरण के लिए:

:- use_module(library(clpfd)).

valid([H|T], [H2|T2]):-  H2 #= H+1 ,valid(H,T,T2,1).

valid(_,[],[],3).
valid(H,[H|T1],[H2|T2],Count):- H2 #= H+1, Count1 #= Count+1,valid(H,T1,T2,Count1).  
valid(H,[H1|T1],[H1|T2],Count):- dif(H1,H), valid(H,T1,T2,Count).  

और कुछ उदाहरण:

?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.

?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.

?- valid([1,5,6,7,8], Y).
false.

?- valid(X, [2, 5, 2, 6, 7, 2, 8]).
X = [1, 5, 1, 6, 7, 1, 8] ;
false.

CLPFD लाइब्रेरी का उपयोग विधेय को अधिक संबंधपरक बनाता है, इसलिए जैसा कि आप ऊपर दिए गए अंतिम उदाहरण में देख सकते हैं, आप इस तरह के प्रश्न कर सकते हैं: valid(X, [2, 5, 2, 6, 7, 2, 8]). जबकि इससे पहले आप (पिछले समाधान के साथ) नहीं कर सकते थे।

यहाँ एक और वैकल्पिक तरीका है:

new(H,H,R):- R is H+1.
new(H,N,N):- dif(N,H). 

valid([H|T], Y):- findall(X1, (member(X1,[H|T]),X1 = H) , L), 
                  length(L,3), maplist(new(H),[H|T],Y).
2
coder 26 मार्च 2017, 12:05
मदद करने में खुशी हुई !!!, मैंने पहले से ही रिकर्सन के साथ हल करने की कोशिश की और अपना जवाब संपादित किया, उम्मीद है कि यह मदद करता है !!।
 – 
coder
26 मार्च 2017, 12:06