Search code examples
minizinc

is there a way to provide search annotation in minizinc predicate?


I am wondering if I could provide search order in a minizinc predicate. For instance I have code like this

predicate numbers_falling_within_range (var int:a, var int:b)=
      let {
         var 213233..4535553: num;
       } in 
       (a+b<num*64+64) /\ (a+b>num*64);  %% pick a and b such that their sum fall within a range

Here I would prefer when it executes the predicate, it solves for num first, before a or b. Is there a way to do it? I am looking for something similar to solve order annotation we provide at end of model.


Solution

  • The only place where you can devise a search strategy is in you solve item, but you might also ask: "Can I devise a search strategy over (to a predicate) local variables?"

    Since MiniZinc is a scoped language, you can't really access these variables outside of the predicate, but you can elevate them to the global scope:

    int num_num = ???;
    array[1..num_num] of var 213233..4535553: nums;
    predicate numbers_falling_within_range (var int: a, var int: b, var int: num) =
      (a+b<num*64+64) /\ (a+b>num*64);
    
    % a call to the predicate
    constraint numbers_falling_within_range(x, y, nums[1]);
    
    solve ::int_search(nums, input_order, indomain_min) minimize cost;
    

    Note that this kind of approach is only possible if the can (over-)estimate the number of calls to the predicate and give each call a different (now global) variable. Unless your predicate is recursive, this should be relatively straightforward.