/* Global constraint count_ctr in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Ccount_ctr.html """ Let N be the number of variables of the VARIABLES collection assigned to value VALUE; Enforce condition N RELOP NVAR to hold. Example (5, <4, 5, 5, 4,5>, >=,2) The count constraint holds since value VALUE=5 occurs 3 times within the items of the collection VARIABLES=<4, 5, 5, 4, 5>, which is greater than or equal to (RELOP is set to >=) NVAR=2. """ 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 = 5, X = new_list(N), X :: 1..5, NVar :: 1..5, Val :: 1..N, X = [4,5,5,4,5], Val #= 5, % NVar #= 2, count_ctr(Val, X, #>=, NVar), Vars = X ++ [NVar,Val], solve(Vars), println(x=X), println(nvar=NVar), println(val=Val), nl, fail, nl. go => true. % % count_ctr % The global constraint catalogue calls this predicate count, but there are % already a count in globals.mzn, without the relop stuff. % % % Note: The following (using call/3) works when X is fixed, but not for free X. % % count_ctr(Val, X, Relop, NVar) => % sum([ 1 % : I in 1..X.len, call(Relop, X[I], Val)]) #>= NVar. % % % Reversible versions % count_ctr(Val, X, #<, NVar) => sum([ X[I] #< Val : I in 1..X.len]) #>= NVar. count_ctr(Val, X, #=<, NVar) => sum([ X[I] #=< Val : I in 1..X.len]) #>= NVar. count_ctr(Val, X, #=, NVar) => sum([ X[I] #= Val : I in 1..X.len]) #>= NVar. count_ctr(Val, X, #!=, NVar) => sum([ X[I] #!= Val : I in 1..X.len]) #>= NVar. count_ctr(Val, X, #>=, NVar) => sum([ X[I] #>= Val : I in 1..X.len]) #>= NVar. count_ctr(Val, X, #>, NVar) => sum([ X[I] #> Val : I in 1..X.len]) #>= NVar.