/* Global constraint same_interval in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Csame_interval.html """ same_interval​(VARIABLES1,​VARIABLES2,​SIZE_INTERVAL)​ Purpose Let Ni (respectively Mi) denote the number of variables of the collection VARIABLES1 (respectively VARIABLES2) that take a value in the interval [SIZE_INTERVAL*i, SIZE_INTERVAL*i+SIZE_INTERVAL-1. For all integer i we have Ni=Mi. Example ( <1, 7, 6, 0, 1, 7>, <8, 8, 8, 0, 1, 2>, 3 ) In the example, the third argument SIZE_INTERVAL=3 defines the following family of intervals [3*k, 3*k+2], where k is an integer. Consequently the values of the collection <1, 7, 6, 0, 1, 7> are respectively located within intervals [0, 2], [6, 8], [6, 8], [0, 2], [0, 2], [6, 8]. Therefore intervals [0, 2] and [6, 8] are respectively used 3 and 3 times. Similarly, the values of the collection <8, 8, 8, 0, 1, 2> are respectively located within intervals [6, 8], [6, 8], [6, 8], [0, 2], [0, 2], [0, 2]. As before intervals [0, 2] and [6, 8] are respectively used 3 and 3 times. Consequently the same_interval constraint holds. Figure 4.244.1 illustrates this correspondence. [See the figure at http://www.emn.fr/x-info/sdemasse/gccat/Csame_interval.html] Figure 4.244.1. Correspondence between the intervals associated with collection <1, 7, 6, 0, 1, 7> and with collection <8, 8, 8, 0, 1, 2> """ 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, Variables1 = new_list(N), Variables1 :: 0..8, Variables2 = new_list(N), Variables2 :: 0..8, SizeInterval :: 1..N, % = 3 Variables1 = [1,7,6,0,1,7], Variables2 = [8,8,8,0,1,2], SizeInterval = 3, same_interval(Variables1, Variables2,SizeInterval), Vars = Variables1 ++ Variables2 ++ [SizeInterval], solve(Vars), println(variables1=Variables1), println(variables2=Variables2), println(size_interval=SizeInterval), nl, fail, nl. same_interval(Variables1,Variables2,SizeInterval) => Ub = fd_max(SizeInterval), foreach(I in 0..Ub) sum([Variables1[K] #>= I*SizeInterval #/\ Variables1[K] #<= I*SizeInterval+SizeInterval-1 : K in 1..Variables1.len ]) #= sum([Variables2[K] #>= I*SizeInterval #/\ Variables2[K] #<= I*SizeInterval+SizeInterval-1 : K in 1..Variables2.len ]) end.