प्रोलॉग के साथ एक समस्या को हल करने के लिए, किसी भी प्रोग्रामिंग भाषा के साथ, यह घोषणात्मक या अनिवार्य है, आपको समाधान और इनपुट के प्रतिनिधित्व के बारे में सोचना होगा।
चूँकि यह एक प्रोग्रामिंग प्रश्न है, यह StackOverflow.com पर लोकप्रिय होगा जहाँ प्रोग्रामर प्रोग्रामिंग की समस्याओं को हल करते हैं। यहाँ मैं और अधिक वैज्ञानिक बनने का प्रयास करूँगा।
ओपी में समस्या को हल करने के लिए इनपुट में निर्भरताओं द्वारा परिभाषित संबंध को उल्टा करना पड़ता है। फार्म के क्लाज उल्टा करने के लिए आसान है। खंड एक टी टी ई एन डी ( ए डी ) ∧ एक टी टी ई एन डी (A t t e n d( एक्स)) → ए टी टी ई एन डी( य) ∧ एक टी टी ई एन डी( Z)) जैसेA t t e n d( ए डी ) ∧ एक टी टी ई एन डी( बी एम) → ए टी टी ई एन डी( D D )
डेज़ी डोडरिज ने कहा कि अगर अल्बस डंबलडोर और बर्डॉक मुलदून दोनों आए तो वह आएगी
इलाज करना ज्यादा मुश्किल है।
प्रोलॉग के साथ पहला सरल दृष्टिकोण संबंध के पूर्ण उलट से बचने और इसके बजाय निर्देशित लक्ष्य होना है।
मेहमानों की सूची पर एक आदेश मान लें और एक नियम का उपयोग करें
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪ए ( एक्स)) ∧ एक ( Y)ए ( डब्ल्यू))ए ( डब्ल्यू))एक्सY→ ए ( जेड)) ,→ ए ( एक्स)) ,→ ए ( वाई) ,< जेड,< जेड⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⊢ए ( डब्ल्यू)) → ए ( जेड))
(हम का उपयोग के बजाय एक टी टी ई एन डी ( एक्स ) यह कम रखने के लिए)ए ( एक्स))A t t e n d( एक्स))
इस नियम को लागू करना आसान है।
बल्कि भोली दृष्टिकोण
पठनीयता के लिए follows
एक इनपुट के रूप में दिए गए संबंध brings
हो , और इसके विपरीत हो।
फिर इनपुट के द्वारा दिया जाता है
follows(bm,[ad]).
follows(cp,[ad]).
follows(ad,[cp]).
follows(dd,[cp]).
follows(ad,[ec]).
follows(bm,[ec]).
follows(cp,[ec]).
follows(cp,[fa]).
follows(dd,[fa]).
follows(bm,[cp,dd]).
follows(ec,[cp,dd]).
follows(fa,[cp,dd]).
follows(dd,[ad,bm]).
और brings
निम्नानुसार परिभाषित किया जा सकता है:
brings(X,S):-brings(X,S,[]).
brings(_X,[],_S).
brings(X,[X|L],S):-brings(X,L,[X|S]).
brings(X,[Y|L],S):-follows(Y,[X]),brings(X,L,[Y|S]).
brings(X,[Y|L],S):-follows(Y,[A,B]),
member(A,S),member(B,S),brings(X,L,[Y|S]).
brings/3(X,L,S)
एक्स
अगर हम परिभाषित करते हैं
partymaker(X):-Guests=[ad,bm,cp,dd,ec,fa],member(X,Guests),brings(X,Guests).
हम निम्नलिखित अद्वितीय समाधान प्राप्त करते हैं:
[ad,ec]
यह पूरी सूची नहीं है, क्योंकि वर्णमाला के तहत खंड का आदेश दिया गया है
follows(bm,[cp,dd]).
काम नहीं कर रहा।
मूल पहेली के बजाय एक शामिल समाधान
समस्या को पूरी तरह से हल करने के लिए आपको वास्तव में सिस्टम को बाद के मेहमानों के लिए उपस्थिति साबित करने की कोशिश करनी चाहिए ताकि खोज के पेड़ पर अनंत छोरों की शुरुआत न हो। इस लक्ष्य को पूरा करने के कई तरीके हैं। प्रत्येक के अपने फायदे और नुकसान है।
एक तरीका brings/2
इस प्रकार परिभाषित करना है:
brings(X,S):-brings(X,S,[],[]).
% brings(X,RemainsToBring,AlreadyTaken,AlreadyTried).
%
% Problem solved
brings(_X,[],_S,_N).
% Self
brings(X,[X|L],S,N):-brings(X,L,[X|S],N).
% Follower
brings(X,[Y|L],S,N):-follows(Y,[X]),brings(X,L,[Y|S],N).
% Y is not a follower, but X can bring 2
brings(X,[Y|L],S,N):- \+member(Y,N),\+follows(Y,[X]),
follows(Y,[A,B]),
try_bring(X,A,L,S,[Y|N]),
try_bring(X,B,L,S,[Y|N]),brings(X,L,[Y|S],N).
% Y is not a follower, but X can bring 1
brings(X,[Y|L],S,N):- \+member(Y,N),\+follows(Y,[X]),\+follows(Y,[_A,_B]),
follows(Y,[C]),
try_bring(X,C,L,S,[Y|N]),brings(X,L,[Y|S],N).
try_bring(_X,A,_L,S,_N):-member(A,S).
try_bring(X,A,L,S,N):- \+member(A,S),sort([A|L],Y),brings(X,Y,S,N).
में brings/4
एक अनंत लूप से बचने के लिए अंतिम तर्क आवश्यक है try_bring
।
यह निम्नलिखित उत्तर देता है: एल्बस, कार्लोटा, एल्फ्रिडा और फाल्को। हालांकि यह समाधान सबसे कुशल नहीं है क्योंकि बैकट्रैकिंग को पेश किया जाता है जहां इसे कभी-कभी टाला जा सकता है।
एक सामान्य उपाय
आर ( एक्स), एस) : वी→ वी'
एस⊆ वीवी'= वी∪ { एक्स}
वीयूवी
add_element(X,V,U):- ( var(V) -> % set difference that works in both modes
member(X,U),subtract(U,[X],V);
\+member(X,V),sort([X|V],U) ).
support(V,U):- guests(G), % rule application
member(X,G),
add_element(X,V,U),
follows(X,S),
subset(S,V).
set_support(U,V):- support(V1,U), % sort of a minimal set
( support(_V2,V1) ->
set_support(V1,V) ;
V = V1).
is_duplicate(X,[Y|L]):- ( subset(Y,X) ; is_duplicate(X,L) ).
% purging solutions that are not truly minimal
minimal_support(U,L):-minimal_support(U,[],L).
minimal_support([],L,L).
minimal_support([X|L],L1,L2):-( append(L,L1,U),is_duplicate(X,U) ->
minimal_support(L,L1,L2);
minimal_support(L,[X|L1],L2) ).
solution(L):- guests(G),setof(X,set_support(G,X),S),
minimal_support(S,L).
अब अगर उदाहरण के लिए डाटासेट # 2 के रूप में दिया जाता है
follows(fa,[dd,ec]).
follows(cp,[ad,bm]).
guests([ad,bm,cp,dd,ec,fa]).
हमें उत्तर L = [[ad, bm, dd, ec]] मिलता है। जिसका अर्थ है कि सभी मेहमानों को लेकिन कारलोट और फाल्को को आमंत्रित किया जाना चाहिए।
इस समाधान ने मुझे जो जवाब दिए, वे दुष्ट चुड़ैल लेख में दिए गए डेटासेट # 6 के अपवाद के साथ दिए गए समाधान से मेल खाते हैं, जहां अधिक समाधान का उत्पादन किया गया था। यह सही समाधान प्रतीत होता है।
अंत में, मुझे Prolog की CLP (FD) लाइब्रेरी का उल्लेख करना चाहिए जो इस प्रकार की समस्याओं के लिए विशेष रूप से उपयुक्त है।
attend(BM) :- attend(AD).
बिल्कुल वैसा ही हैattend(X) :- attend(Y).