Search code examples
constraintsminizinc

How to use predicate exactly in MiniZinc


New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:

predicate exactly(int: n, array[int] of var int: x, int: v)

"Requires exactly n variables in x to take the value v."

I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.

If i declare my array as

array[1..10,1..30] of var 0..3: s;

how can I use predicate exactly to populate it as I need? Thanks!


Solution

  • Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:

    include "globals.mzn"; 
    array[1..10,1..30] of var 0..3: s;
    solve satisfy;
    constraint
      forall(j in 1..30) (
         forall(c in 1..3) (
            count([s[i,j] | i in 1..10],c) >= 1
         )
      )
    ;
    
    output [
      if j = 1 then "\n" else " " endif ++
        show(s[i,j])
      | i in 1..10, j in 1..30 
    ];
    

    You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.

    Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .

    If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.