2012-12-22 34 views
11

मैं एक प्रोलॉग (सीएलपी) भविष्यवाणी लिखने की कोशिश कर रहा हूं जो दो सूचियों की असमानता को बाधित करने में बाधा उत्पन्न करेगी।सूची असमानता बाधा

अधिक औपचारिक रूप से, दो सूचियां A=[A1,...,AN], B=[B1,...,BN] होने पर बाधा (A1 #\= B1) #\/ (A2 #\= B2) #\/ ... #\/ (AN #\= BN) के रूप में परिभाषित की गई है।

मुझे यकीन है कि इस बाधा को कैसे मनमाने ढंग से लम्बाई की दो सूचियां दी गई हैं। यह मेरा प्रयास है। मैं समझता हूं कि यह क्यों काम नहीं करता है, लेकिन इसे ठीक नहीं कर सकता।

any_different([], []). 
any_different([H1|T1], [H2|T2]):- 
    H1 #\= H2 #\/ any_different(T1, T2). 

उत्तर

9

आप अलगाव का निर्माण और एक तीसरा तर्क के माध्यम से वापस जाने के लिए चाहता हूँ:

any_different([], [], V) :- 
    V #= 0. % no differences between [] and [] 
any_different([H1|T1], [H2|T2], Disj) :- 
    any_different(T1, T2, Disj0), 
    Disj #<==> (H1 #\= H2) #\/ Disj0. 

अब, बुला any_different(List1, List2, AnyDiff) contrains एक चर AnyDiff है कि आप के साथ लेबलिंग विधेय को पारित कर सकते हैं अपने अन्य चर AnyDiff #= 0 बताकर आप List1 और List2 को बराबर होने के लिए बाध्य कर सकते हैं, जबकि AnyDiff #= 1 उन्हें असमान बना देगा।

+1

धन्यवाद। यह वह मूर्खता है जिसे मैं ढूंढ रहा था। – mscavnicky

4

मुझे लगता है कि, कम से कम SWI-Prolog, विधेय dif/2 और पुस्तकालय (clpfd) में reification के लिए एक विकल्प हो सकता है:

?- L=[X,Y,Z], L ins 1..3, dif(L,[1,2,3]), label(L). 
L = [1, 1, 1], 
X = Y, Y = Z, Z = 1 ; 
L = [1, 1, 2], 
X = Y, Y = 1, 
Z = 2 ; 
... 
4

यहाँ एक कार्यान्वयन sum/3 और clpfd reification (#<==>)/2 पर आधारित है :

not_equals_reified(X, Y, B) :- 
    X #\= Y #<==> B. 

any_different(Xs, Ys) :- 
    maplist(not_equals_reified, Xs, Ys, Bs), 
    sum(Bs, #>, 0). 

maplist/4 का उपयोग करके हम भी पुनरावर्ती कोड लिखने की जरूरत नहीं है!