/* Global constraint global_cardinality_low_up in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Copen_global_cardinality_low_up.html """ Constraint open_global_cardinality_low_up(S,VARIABLES,VALUES) Purpose Each value VALUES[i].val(1<=i<=|VALUES|)should be taken by at least VALUES[i].omin and at most VALUES[i].omax variables of the VARIABLES collection for which the corresponding position belongs to the set S. Example ( {2,3,4}, <3,3,8,6>, < val-3 omin-1 omax-3, val-5 omin-0 omax-1, val-6 omin-1 omax-2 > ) The open_global_cardinality_low_up constraint holds since: * Values 3, 5 and 6 are respectively used 1 (1<=1<=3), 0 (0<=0<=1) and 1 (1<=1<=2) times within the collection <3,3,8,6> (the first item 3 of <3,3,8,6> is ignored since value 1 does not belong to the first argument S={2,3,4} of the open_global_cardinality_low_up constraint). * No constraint was specified for value 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 ?=> N = 4, M = 3, Variables = new_list(N), Variables :: 1..8, S = new_list(N), S :: 0..1, Values = new_array(M, 3), Values :: 0..6, Variables = [3,3,8,6], S = [0,1,1,1], % the set {2,3,4} Values = {{3,1,3}, {5,0,1}, {6,1,2}}, % Values = {{3,1,_}, % {5,0,_}, % {6,1,_}}, open_global_cardinality_low_up(S, Variables, Values), Vars = Variables ++ S ++ Values.vars, solve(Vars), println(variables=Variables), println(s=[I : I in 1..S.len, S[I]==1]), println(variables_selected=[Variables[I] : I in 1..S.len, S[I] == 1]), foreach(Row in Values) println(Row) end, nl, fail, nl. go => true. open_global_cardinality_low_up(S,Variables,Values) => foreach(I in 1..Values.len) SSum :: 0..Variables.len, SSum #= sum([S[J]#= 1 #/\ Variables[J] #= Values[I,1] : J in 1..Variables.len]), SSum #>= Values[I,2], SSum #<= Values[I,3], % sanify if Values are free Values[I,2] #<= Values[I,3] end.