From 147e6910630b659a01c73802419f7f14be859968 Mon Sep 17 00:00:00 2001 From: "Jip J. Dekker" Date: Tue, 20 Jul 2021 21:22:20 +1000 Subject: [PATCH] Use of floating listings in rewriting chapter --- assets/listing/rew_abs.mzn | 5 ++ assets/listing/rew_elem_safe.mzn | 16 ++++ assets/listing/rew_knapsack.mzn | 16 ++++ assets/listing/rew_opt_plus.mzn | 11 +++ assets/listing/rew_pigeon_mzn.mzn | 8 ++ assets/listing/rew_pigeon_uzn.mzn | 16 ++++ chapters/3_rewriting.tex | 139 +++++++++--------------------- 7 files changed, 113 insertions(+), 98 deletions(-) create mode 100644 assets/listing/rew_abs.mzn create mode 100644 assets/listing/rew_elem_safe.mzn create mode 100644 assets/listing/rew_knapsack.mzn create mode 100644 assets/listing/rew_opt_plus.mzn create mode 100644 assets/listing/rew_pigeon_mzn.mzn create mode 100644 assets/listing/rew_pigeon_uzn.mzn diff --git a/assets/listing/rew_abs.mzn b/assets/listing/rew_abs.mzn new file mode 100644 index 0000000..a011bff --- /dev/null +++ b/assets/listing/rew_abs.mzn @@ -0,0 +1,5 @@ +function var int: abs(var int: x) = + let { + var int: z; + constraint int_abs(x, z); + } in z; diff --git a/assets/listing/rew_elem_safe.mzn b/assets/listing/rew_elem_safe.mzn new file mode 100644 index 0000000..2966536 --- /dev/null +++ b/assets/listing/rew_elem_safe.mzn @@ -0,0 +1,16 @@ +function tuple(var bool, var int): element_safe( + array of int: a, + var int: x +) = + let { + set of int: idx = index_set(x) + var bool: total = x in idx; + var idx: xs; + int: m = min(idx); + % Give xs the value of x when result is total + constraint total -> xs = x; + % Otherwise, give xs the value m instead + constraint not total -> xs = m; + % element constraint that is guaranteed to be total + tuple(var bool, var int): res = (total, element(a, xs)); + } in ret; diff --git a/assets/listing/rew_knapsack.mzn b/assets/listing/rew_knapsack.mzn new file mode 100644 index 0000000..f7da336 --- /dev/null +++ b/assets/listing/rew_knapsack.mzn @@ -0,0 +1,16 @@ +predicate knapsack( + array[int] of int: w, + array[int] of int:p, + array[int] of var int:x, + var int: W, var int: P +) = + assert( + index_set(w) = index_set(p) /\ index_set(w) = index_set(x), + "index set of weights must be equal to index set of profits and index set of items", + ) /\ assert( + lb_array(w) >= 0, + "weights must be non-negative", + ) /\ assert( + lb_array(p) >= 0, + "profits must be non-negative", + ) /\ fzn_knapsack(w, p, x, W, P); diff --git a/assets/listing/rew_opt_plus.mzn b/assets/listing/rew_opt_plus.mzn new file mode 100644 index 0000000..1ec4854 --- /dev/null +++ b/assets/listing/rew_opt_plus.mzn @@ -0,0 +1,11 @@ +function tuple(var bool, var int): int_plus( + tuple(var bool, var int): x, + tuple(var bool, var int): y +) = + let { + (x1, x2) = x; + (y1, y2) = y; + var int: x3 = if_then_else([x1, true], [x2, 0]); + var int: y3 = if_then_else([y1, true], [y2, 0]); + tuple(var bool, var int): res = (bool_and(x1, y1), int_plus(x3, y3)); + } in res; diff --git a/assets/listing/rew_pigeon_mzn.mzn b/assets/listing/rew_pigeon_mzn.mzn new file mode 100644 index 0000000..cd13e1b --- /dev/null +++ b/assets/listing/rew_pigeon_mzn.mzn @@ -0,0 +1,8 @@ +predicate all_different(array[int] of var int: x) = + forall (i,j in 1..length(x) where i xs = x; - % Otherwise, give xs the value m instead - constraint not total -> xs = m; - % element constraint that is guaranteed to be total - tuple(var bool, var int): res = (total, element(a, xs)); - } in ret; - \end{mzn} + \begin{listing} + \mznfile{assets/listing/rew_elem_safe.mzn} + \caption{\label{lst:rew-elem-safe} A total of the \mzninline{element} function in \microzinc{}.} + \end{listing} Similar to the replacement of optional values, all occurrences of the \mzninline{element} function are replaced by \mzninline{element_safe}. The usage of its result should be guarded by the returned totality variable in the surrounding Boolean context. @@ -246,40 +223,23 @@ The translation from \minizinc{} to \microzinc{} involves the following steps. \begin{example} - Consider the following \minizinc{} model, a simple \gls{unsat} ``pigeonhole problem'', trying to assign \(n\) pigeons to \(n-1\) holes. + Consider the \minizinc{} model in \cref{lst:rew-pigeon-mzn}. + It describes a simple \gls{unsat} ``pigeonhole problem'': trying to assign \(n\) pigeons to \(n-1\) holes. - \begin{mzn} - predicate all_different(array[int] of var int: x) = - forall (i,j in 1..length(x) where i= 20) \/ (abs(x)+5 >= 15) @@ -775,31 +731,18 @@ The usage of a \gls{cse} table can be costly. The memory requirement and time spent finding entries can be significant in the overall process. This is aggravated by the fact that \minizinc{} has many places where a function's body only contains a single call to a function that is not used anywhere else. Although this structure offers flexibility when defining \minizinc{} libraries, it results in many \gls{cse} entries that differ only by their function identifier. -For example, the \mzninline{knapsack} \gls{global} is defined in the \minizinc{} standard library as follows. -\begin{mzn} -predicate knapsack( - array[int] of int: w, - array[int] of int:p, - array[int] of var int:x, - var int: W, var int: P -) = - assert( - index_set(w) = index_set(p) /\ index_set(w) = index_set(x), - "index set of weights must be equal to index set of profits and index set of items", - ) /\ assert( - lb_array(w) >= 0, - "weights must be non-negative", - ) /\ assert( - lb_array(p) >= 0, - "profits must be non-negative", - ) /\ fzn_knapsack(w, p, x, W, P); -\end{mzn} - -After checking the \parameter{} arguments, the function merely returns the result of \mzninline{fzn_knapsack}. -This function is implemented in the \solver{} library to provide the implementation of the \mzninline{knapsack} \gls{global}. -The extra function layer ensures that these checks can be performed independently of the \solver{} library and that the \solver{} can make certain assumptions about the function arguments. -But because the modeller will only use \mzninline{knapsack}, it does not make sense to also create \gls{cse} entries for \mzninline{fzn_knapsack}, as it will never be used. +\begin{example} + For example, the definition of the \mzninline{knapsack} \gls{global} in the \minizinc{} standard library is shown in \cref{lst:rew-knapsack}. + After checking the \parameter{} arguments, the function merely returns the result of \mzninline{fzn_knapsack}. + This function is implemented in the \solver{} library to provide the implementation of the \mzninline{knapsack} \gls{global}. + The extra function layer ensures that these checks can be performed independently of the \solver{} library and that the \solver{} can make certain assumptions about the function arguments. + But because the modeller will only use \mzninline{knapsack}, it does not make sense to also create \gls{cse} entries for \mzninline{fzn_knapsack}, as it will never be used. +\end{example} +\begin{listing} + \mznfile{assets/listing/rew_knapsack.mzn} + \caption{\label{lst:rew-knapsack} The definition of \mzninline{knapsack} in the \minizinc{} standard library.} +\end{listing} Therefore, we have added an additional flag to our call instruction. This flag controls whether the call is subject to \gls{cse}.