/* Global constraint common_modulo in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Ccommon_modulo.html """ Constraint common_modulo (NCOMMON1, NCOMMON2, VARIABLES1, VARIABLES2, M) Purpose NCOMMON1 is the number of variables of the collection of variables VARIABLES1 taking a value situated in an equivalence class (congruence modulo a fixed number M) derived from the values assigned to the variables of VARIABLES2 and from M. NCOMMON2 is the number of variables of the collection of variables VARIABLES2 taking a value situated in an equivalence class (congruence modulo a fixed number M) derived from the values assigned to the variables of VARIABLES1 and from M. Example ( 3, 4, <0, 4, 0, 8>, <7, 5, 4, 9, 2, 4>, 5 ) In the example, the last argument M=5 defines the equivalence classes a=0 (mod 5), a=1 (mod 5), a=2 (mod 5), a=3 (mod 5), and a=4 (mod 5) where a is an integer. As a consequence the items of collection <0, 4, 0, 8> respectively correspond to the equivalence classes a=0 (mod 5), a=4 (mod 5), a=0 (mod 5), and a=3 (mod 5). Similarly the items of collection <7, 5, 4, 9, 2, 4> respectively correspond to the equivalence classes a=2 (mod 5), a=0 (mod 5), a=4 (mod 5), a=4 (mod 5), a=2 (mod 5), and a=4 (mod 5). The common_modulo constraint holds since: * Its first argument NCOMMON1=3 is the number of equivalence classes associated with the items of collection <0, 4, 0, 8> that also correspond to equivalence classes associated with <7, 5, 4, 9, 2, 4>. * Its second argument NCOMMON2=4 is the number of equivalence classes associated with the items of collection <7, 5, 4, 9, 2, 4> that also correspond to equivalence classes associated with <0, 4, 0, 8>. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> X = new_list(4), X :: 0..9, Y = new_list(6), Y :: 0..9, M = 5, % modulo A :: 0..10, B :: 0..10, X = [0,4,0,8], Y = [7,5,4,9,2,4], common_modulo(A, B, X, Y, M), % A #= 3, % B #= 4, Vars = X ++ Y ++ [A,B], solve(Vars), println(x=X), println(y=Y), println(a=A), println(b=B), println(m=M), nl, fail, nl. go => true. % % common_modulo(a, b, x, y, m) % - a is the number of values of (x mod m) that are in (y mod m) % - b is the number of values of (y mod m) that are in (x mod m) % common_modulo(A, B, X, Y, M) => A #= sum([ sum([(X[I] mod M) #= (Y[J] mod M) : J in 1..Y.len]) #>= 1 : I in 1..X.len]), B #= sum([ sum([(Y[J] mod M) #= (X[I] mod M) : I in 1..X.len]) #>= 1 : J in 1..Y.len]).