Search code examples
minizinc

How to create an equivalent for a function in Minizinc to simplify a predicate


I am very new to constraint programming and I am learning MiniZinc. I have large predicates and I would like to create an equivalent of a function (in a classical programming language) to simplify the predicates

For example, I have:

% INPUTS
int: nodes;
float: T;
%OUTPUT
array [1..nodes, 1..nodes] of var 0..1000: rates_matrix;

predicate column_summ(int: to_dc) =
sum(from_dc in 1..nodes) (rates_matrix[from_dc, to_dc]) * sum(from_dc in 1..nodes) (rates_matrix[from_dc, to_dc]) * 2 < T; 

constraint forall(n in 1..nodes) (column_summ(n));
solve satisfy;

The column_summ predicate simply computes an equivalent of a function f(x) 2x^2 < T but in its current form it takes a lot of space and it is hard to follow the code. I would like to be able to rewrite the code in the following way:

function f_polynomial(x) = 2*x*x;
function f_sum(y, m) = sum(from_dc in 1..nodes) (m[from_dc, y])

predicate column_summ(int: to_dc) =
    f_polynomial(f_sum(to_dc, rates_matrix)) < T;

What is the correct syntax in MiniZinc to express the above code? Thanks!


Solution

  • Here is one variant using functions. I added some initial values (for "nodes" and "T") to be able to play with the model.

    % INPUTS
    int: nodes = 5; 
    float: T = 100.0;
    %OUTPUT
    array [1..nodes, 1..nodes] of var 0..1000: rates_matrix;
    
    function var int: f_polynomial(var int: x) = 2*x*x;
    function var int: f_sum(var int: y, array[int,int] of var int: m) = sum(from_dc in 1..nodes) (m[from_dc, y]);
    
    predicate column_summ(int: to_dc) = f_polynomial(f_sum(to_dc, rates_matrix)) < T;
    
    constraint forall(n in 1..nodes) (column_summ(n));
    solve satisfy;
    

    I recommend that you read the MiniZinc Tutorial, especially the section 4.3 about predicates and functions.