1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker f2a1c4e389 Squashed 'software/mza/' content from commit f970a59b17
git-subtree-dir: software/mza
git-subtree-split: f970a59b177c13ca3dd8aaef8cc6681d83b7e813
2021-07-11 16:34:30 +10:00

58 lines
2.1 KiB
MiniZinc

%-----------------------------------------------------------------------------%
% Domain encodings
%-----------------------------------------------------------------------------%
% Linear equality encoding
% Single variable: x = d <-> x_eq_d[d]
predicate equality_encoding(var int: x, array[int] of var 0..1: x_eq_d) =
x in index_set(x_eq_d)
/\
sum(d in dom(x))( x_eq_d[d] ) = 1
/\
sum(d in dom(x))( d * x_eq_d[d] ) = x;
% Array of variables: x[i] = d <-> x_eq_d[i,d]
predicate equality_encoding(array[int] of var int: x,
array[int, int] of var 0..1: x_eq_d) =
forall(i in index_set(x))(
x[i] in index_set_2of2(x_eq_d)
/\
sum(d in index_set_2of2(x_eq_d))( x_eq_d[i,d] ) = 1
/\
sum(d in index_set_2of2(x_eq_d))( d * x_eq_d[i,d] ) = x[i]
);
function var int: eq_new_var(var int: x, int: i) =
if i in dom(x) then
let {
var 0..1: xi;
} in xi
else 0 endif;
function array[int] of var 0..1: eq_encode(var int: x) ::promise_total =
let {
array[int] of var 0..1: y = array1d(lb(x)..ub(x),[eq_new_var(x,i) | i in lb(x)..ub(x)]);
constraint equality_encoding(x,y);
} in y;
function array[int] of int: eq_encode(int: x) ::promise_total =
array1d(lb(x)..ub(x),[ if i=x then 1 else 0 endif | i in lb(x)..ub(x)]);
function array[int,int] of var int: eq_encode(array[int] of var int: x) ::promise_total =
let {
array[index_set(x),lb_array(x)..ub_array(x)] of var 0..1: y =
array2d(index_set(x),lb_array(x)..ub_array(x),
[ let {
array[int] of var int: xi = eq_encode(x[i])
} in if j in index_set(xi) then xi[j] else 0 endif
| i in index_set(x), j in lb_array(x)..ub_array(x)]
)
} in y;
function array[int,int] of int: eq_encode(array[int] of int: x) ::promise_total =
array2d(index_set(x),lb_array(x)..ub_array(x),[ if j=x[i] then 1 else 0 endif | i in index_set(x), j in lb_array(x)..ub_array(x)]);
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%