/* Global constraint in_same_partition in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Cin_same_parition.html """ in_same_partition​(VAR1,​VAR2,​PARTITIONS) Purpose Enforce VAR1 and VAR2 to be respectively assigned to values v1 and v2 that both belong to a same partition of the collection PARTITIONS. Example ( 6, 2, < p-<1, 3>, p-<4>, p-<2, 6> > ) The in_same_partition constraint holds since its first and second arguments VAR1=6 and VAR2=2 both belong to the third partition <2, 6> of its third argument PARTITIONS. """ 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, % range M = 3, % num partitions % As a boolean matrix instead of var set S = new_array(M,N), S :: 0..1, Var1 :: 1..N, Var2 :: 1..N, S = {{1,0,1,0,0,0}, % 1,3 {0,0,0,1,0,0}, % 4 {0,1,0,0,0,1} % 2,6 }, % foreach(I in 1..M) % sum(S[I]) #> 0 % end, % Var1 = 6, % Var2 = 2, all_disjoint(S), in_same_partition(Var1,Var2,S), Vars = [Var1,Var2] ++ S, solve(Vars), println(var1=Var1), println(var2=Var2), println("S:"), foreach(P in S) println([I : I in 1..N, P[I] == 1]) end, nl, fail, nl. in_same_partition(V1,V2,Partitions) => N = Partitions[1].len, sum([ V1 #!= V2 #/\ sum([V1 #= Partitions[P,J]*J : J in 1..N]) #=1 #/\ sum([V2 #= Partitions[P,J]*J : J in 1..N]) #=1 : P in 1..Partitions.len]) #> 0. % % Ensure that all values are disjoint % in the boolean matrix S. % all_disjoint(S) => foreach(J in 1..S[1].len) sum([S[I,J] : I in 1..S.len]) #<= 1 end.