this repo has no description
at develop 5.7 kB view raw
1/* 2% FlatZinc built-in redefinitions for linear solvers. 3% 4% AUTHORS 5% Sebastian Brand 6% Gleb Belov 7*/ 8 9%-----------------------------------------------------------------------------% 10% 11% Logic operations 12% Use indicators for reifs (CPLEX)? Seems weak. 13% 14%-----------------------------------------------------------------------------% 15 16predicate bool_not(var bool: p, var bool: q) = 17 bool2int(p) + bool2int(q) = 1; 18 19predicate bool_and(var bool: p, var bool: q, var bool: r) = 20% my_trace(" bool_and: \(p) /\\ \(q) <-> \(r) \n") /\ 21 if false then 22 int_lin_le_reif__IND( [-1, -1], [p, q], -2, r) 23 else 24 array_bool_and( [p, q], r ) 25% bool_and__INT(bool2int(p), bool2int(q), bool2int(r)) 26 endif; 27 28predicate bool_and__INT(var int: x, var int: y, var int: z) = 29 x + y <= z + 1 /\ 30 %% x + y >= z * 2; % weak 31 x >= z /\ y >= z; % strong 32 33 34predicate bool_or(var bool: p, var bool: q, var bool: r) = 35 if false then 36 int_lin_le_reif__IND( [-1, -1], [p, q], -1, r) 37 elseif true then 38 array_bool_or( [p, q], r ) 39 else 40 let { var int: x = bool2int(p), 41 var int: y = bool2int(q), 42 var int: z = bool2int(r) } 43 in 44 x + y >= z /\ 45 % x + y <= z * 2; % weak 46 x <= z /\ y <= z % strong 47 endif; 48 49predicate bool_xor(var bool: p, var bool: q) = 50 1==p+q; 51 52predicate bool_xor(var bool: p, var bool: q, var bool: r) = 53 if false then 54% int_lin_eq_reif__IND( [1, 1], [p, q], 1, r) /\ 55 true 56 else 57 let { var int: x = bool2int(p), 58 var int: y = bool2int(q), 59 var int: z = bool2int(r) } 60 in 61 x <= y + z /\ 62 y <= x + z /\ 63 z <= x + y /\ 64 x + y + z <= 2 65 endif; 66 67 68predicate bool_eq_reif(var bool: p, var bool: q, var bool: r) = 69%% trace(" bool_eq_reif: \(p), \(q), \(r) \n") /\ 70 if is_fixed(r) then % frequent case 71 if fix(r) = true then p = q else bool_not(p,q) endif 72 elseif is_fixed(q) then 73 if fix(q) = true then p = r 74 else bool_not(p,r) endif 75 elseif is_fixed(p) then 76 if fix(p) = true then q = r 77 else bool_not(q,r) endif 78 elseif false then 79% int_lin_eq_reif__IND( [1, -1], [p, q], 0, r) /\ 80 true 81 else 82 let { var int: x = bool2int(p), 83 var int: y = bool2int(q), 84 var int: z = bool2int(r) } 85 in 86 x + y <= z + 1 /\ 87 x + z <= y + 1 /\ 88 y + z <= x + 1 /\ 89 x + y + z >= 1 90 endif; 91 92 93predicate bool_ne_reif(var bool: p, var bool: q, var bool: r) = 94 bool_xor(p, q, r); 95 96 97predicate bool_le(var bool: p, var bool: q) = 98 let { var int: x = bool2int(p), 99 var int: y = bool2int(q) } 100 in 101 x <= y; 102 103 104predicate bool_le_reif(var bool: p, var bool: q, var bool: r) = 105 if false then 106% int_lin_le_reif__IND( [1, -1], [p, q], 0, r) /\ 107 true 108 else 109 let { var int: x = bool2int(p), 110 var int: y = bool2int(q), 111 var int: z = bool2int(r) } 112 in 113 1 - x + y >= z /\ 114 %% /\ 1 - x + y <= z * 2 not needed 115 1 - x <= z /\ y <= z % strong 116 endif; 117 118 119predicate bool_lt(var bool: p, var bool: q) = 120 not p /\ q; 121 122 123predicate bool_lt_reif(var bool: p, var bool: q, var bool: r) = 124 (not p /\ q) <-> r; 125 126%-----------------------------------------------------------------------------% 127 128%% Reified disjunction 129predicate array_bool_or(array[int] of var bool: a, var bool: b) = 130 if exists( i in index_set( a ) )( is_fixed(a[i]) /\ fix(a[i]) ) then 131 b 132 elseif is_fixed(b) then % frequent case 133 if fix(b) = true then 134 sum(i in index_set(a))( bool2int(a[i]) ) >= 1 %% >=1 seems better for MIPDomains... 5.4.19 135 else 136 forall(i in index_set(a))( not a[i] ) 137 endif 138 else 139 let { var int: x = bool2int(b), 140 array[1..length(a)] of var int: c = 141 [ bool2int(a[i]) | i in index_set(a) ] } 142 in 143 sum(c) >= x /\ 144 % sum(c) <= x * length(a) % weak 145 forall (i in index_set(a)) (x >= c[i]) % strong 146 endif; 147 148%% Reified conjunction 149predicate array_bool_and(array[int] of var bool: a, var bool: b) = 150 if exists( i in index_set( a ) )( is_fixed(a[i]) /\ not fix(a[i]) ) then 151 not b 152 elseif is_fixed(b) then % frequent case 153 if fix(b) = false then 154 sum(i in index_set(a))( bool2int(a[i]) ) <= length(a)-1 155 else 156 forall(i in index_set(a))( a[i] ) 157 endif 158 else 159 let { var int: x = bool2int(b), 160 array[1..length(a)] of var int: c = 161 [ bool2int(a[i]) | i in index_set(a) ] } 162 in 163 length(a) - sum(c) >= 1 - x /\ 164 % length(a) - sum(c) <= (1 - x) * length(a); % weak 165 forall (i in index_set(a)) (x <= c[i]) % strong 166 endif; 167 168% predicate array_bool_xor(array[int] of var bool: a) = .. sum(a) is odd .. 169predicate array_bool_xor(array[int] of var bool: a) = 170 let { var 0..(length(a)-1) div 2: m, 171 var 1..((length(a)-1) div 2)*2+1: ss = sum(i in index_set(a))( bool2int(a[i]) ) } 172 in 173 ss == 1 + 2 * m; 174 175predicate bool_clause(array[int] of var bool: p, array[int] of var bool: n) = 176 sum(i in index_set(p))( bool2int(p[i]) ) 177 - sum(i in index_set(n))( bool2int(n[i]) ) 178 + length(n) 179 >= 1; 180 181predicate bool_lin_eq(array[int] of int: c, array[int] of var bool: x, var int: d) :: promise_total = 182 sum(i in index_set(x))( c[i]*bool2int(x[i]) ) == d; 183 184predicate bool_lin_eq_reif(array[int] of int: c, array[int] of var bool: x, 185 int: d, var bool: b) = %% No var int d, sorry 186 aux_int_eq_iff_1(sum(i in index_set(x))( c[i]*bool2int(x[i]) ), d, bool2int(b)); 187 188