/* Decomposition of twin global constraint in Picat. From Global catalog: """ Pairs of variables related by hiden element constraints sharing the same table. twin(PAIRS) Purpose Enforce the condition PAIRS[i].x = u /\ PAIRS[i].y = v (i in [1, |PAIRS|]) => forall j in [1, |PAIRS|] : PAIRS[j].x = u <=> PAIRS[j].y = v. Example x-1 y-8 x−9 y−6 x−1 y−8, x−5 y−0, x−6 y−7, x−9 y−6 The twin constraint holds since 1 is paired with 8, 9 is paired with 6, 5 is paired with 0, 6 is paired with 7. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => N = 6, Pairs = new_array(N,2), Pairs :: 1..9, % Original problem: % Pairs = {{1,8}, % {9,6}, % {1,8}, % {5,0}, % {6,7}, % {9,6}}, % The pairs (1,8) and (9,6) should be restored % Pairs = {{1,_}, % {9,6}, % {1,8}, % {5,0}, % {6,7}, % {9,_}}, % Here we also let (5,_) free -> 7 solutions ( 5 <-> 6,7, and 8 are not possible) Pairs = {{_,8}, {9,6}, {1,8}, {5,_}, {6,7}, {9,_}}, twin(Pairs), solve(Pairs), % println(Pairs), foreach(Pair in Pairs) println(Pair.to_list) end, nl, fail, nl. go => true. twin(Pairs) => N = Pairs.len, foreach(I in 1..N) foreach(J in 1..N) Pairs[I,1] #= Pairs[J,1] #<=> Pairs[I,2] #= Pairs[J,2] end end.