2012-12-22 4 views
11

두 목록의 제약 불균형 부등식을 작성하는 프롤로그 (CLP) 조건자를 작성하려고합니다.목록 불균등 제약 조건

더 많은 공식적으로, 두 개의리스트를 갖는 제약은 (A1 #\= B1) #\/ (A2 #\= B2) #\/ ... #\/ (AN #\= BN)으로 정의됩니다.

임의 길이의 두 목록이 주어진이 제약 조건을 구성하는 방법을 잘 모르겠습니다. 이것은 나의 시도이다. 나는 그것이 효과가 없지만 그것을 고칠 수없는 이유를 이해합니다.

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

답변

9

당신은 분리를 구축하고 세 번째 인수를 통해 반환 할 수 있습니다 : any_different(List1, List2, AnyDiff) contrains 당신과 함께 라벨 술어에 전달할 수있는 변수 AnyDiff에게 전화 이제

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. 

, 당신의 다른 변수들. AnyDiff #= 0이라고 말하면 List1List2을 동일하게 유지할 수 있으며 AnyDiff #= 1은 불균등하게 만듭니다.

+1

감사합니다. 이것이 제가 찾고 있던 관용구입니다. – mscavnicky

4

나는 적어도 SWI - 프롤로그, 술어 DIF/2 및 라이브러리 (clpfd)에서 구체화에 대한 대안이 될 수 있다고 생각 : 여기

?- 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 구체화 (#<==>)/2을 기반으로 구현이다 : maplist/4를 사용하여

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

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

우리는 심지어 재귀 코드를 작성할 필요가 없습니다!