Error: Registry: Constraint float_log2 not found

29 views
Skip to first unread message

Andrew Gill

unread,
Dec 12, 2024, 6:17:39 PM12/12/24
to MiniZinc
Hi - Hoping there is an obvious (although not to me :-() fix. 

int: K=5;

set of int: K_set=1..K;

array[K_set] of var int: N;

constraint ceil(log2(int2float(N[K]))+0.001)=4;


I thought int2float would coerce N[K] to a float, which log2 takes and returns a float, which I could add to the float 0.001 (yielding a float), which ceil takes and returns an int, which I could constrain to equal an int?


Andrew

Jip Dekker

unread,
Dec 12, 2024, 6:32:59 PM12/12/24
to MiniZinc
Hi Andrew,

The problem seems to be that Gecode does not implement the "float_log2" predicate, which is used when compiling your model. I think the simplest fix is to stick to integers, and use the fact that constraints are relational to use "pow" instead.

You could replace your constraint by:
constraint pow(2, 4) = N[K];

Or you could even define an integer log2 function and use that:
function var int: int_log2(var int: x) = let {
var 0..ub(x) div 2: y;
constraint pow(2, y) = x;
} in y;
constraint int_log2(N[K]) = 4;

Note that this might quickly lead to integer overflow, so you will have to put some bound on 'N'. For example, the bounds '0..50' would work.

Andrew Gill

unread,
Dec 12, 2024, 11:11:31 PM12/12/24
to MiniZinc
Hi Jip - Thanks for the suggestion, but I maybe should have provided a bit more context. The constraint I was after was to set "the smallest power of 2 strictly greater than N[K]" to a given integer, for which I thought  pow(2,ceil(log2(N[K])+0.001))=16
would work, i.e., N[K]=15 makes LHS=16 but N[K]=16 makes LHS=32 (which I why I add the 0.001 to the ceil() argument). I can't see how I can achieve this without using the float version of log2().

Andrew
Reply all
Reply to author
Forward
0 new messages