2012-12-22 15 views
11

İki listenin eşitsizliğini kısıtlayan bir kısıtlama oluşturacak bir Prolog (CLP) yüklemesi yazmaya çalışıyorum.Eşitsizlik kısıtlamasını listeleme

Daha resmi olarak, iki listeye sahip olmak A=[A1,...,AN], B=[B1,...,BN] kısıtlaması (A1 #\= B1) #\/ (A2 #\= B2) #\/ ... #\/ (AN #\= BN) olarak tanımlanmıştır.

İki kısıtlı uzunluk listesi verildiğinde bu kısıtlamanın nasıl oluşturulacağından emin değilim. Bu benim girişim. Neden işe yaramadığını anlıyorum ama düzeltemiyorum.

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

cevap

9

Sen disjunction kurmak ve üçüncü bir argüman yoluyla geri istersiniz: any_different(List1, List2, AnyDiff) contrains Eğer birlikte etiketleme yüklemi için geçebileceği bir değişken AnyDiff arayarak Şimdi

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. 

, senin diğer değişkenler. AnyDiff #= 0 belirtilerek, ve List2'u eşit olarak sınırlayabilirsiniz, AnyDiff #= 1 ise bunların eşit olmamasına neden olur.

+1

Teşekkür ederiz. Aradığım deyim bu. – mscavnicky

4

Ben en azından SWI-Prolog, yüklem dif/2 ve kütüphane (clpfd) şeyleştirmeye bir alternatif olabilir düşünüyorum: Burada

?- 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 ve clpfd şeyleşme (#<==>)/2 dayalı bir uygulama var : maplist/4 kullanarak

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

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

biz bile özyinelemeli kod yazmak gerekmez!