Update HR chapter
This commit is contained in:
parent
73d7c2cded
commit
873d277fe7
@ -8,8 +8,6 @@
|
|||||||
\newcommand{\cml}{\gls{constraint-modelling} language\xspace{}}
|
\newcommand{\cml}{\gls{constraint-modelling} language\xspace{}}
|
||||||
\newcommand{\cmls}{\gls{constraint-modelling} languages\xspace{}}
|
\newcommand{\cmls}{\gls{constraint-modelling} languages\xspace{}}
|
||||||
|
|
||||||
\newcommand{\vari}{\mzninline{var}}
|
|
||||||
\newcommand{\pari}{\mzninline{par}}
|
|
||||||
\renewcommand{\phi}{\varphi}
|
\renewcommand{\phi}{\varphi}
|
||||||
\newcommand{\tuple}[1]{\ensuremath{\langle #1 \rangle}}
|
\newcommand{\tuple}[1]{\ensuremath{\langle #1 \rangle}}
|
||||||
\newcommand{\Prog}{\ensuremath{\mathcal{P}}}
|
\newcommand{\Prog}{\ensuremath{\mathcal{P}}}
|
||||||
@ -17,17 +15,11 @@
|
|||||||
\newcommand{\Env}{\ensuremath{\sigma}}
|
\newcommand{\Env}{\ensuremath{\sigma}}
|
||||||
\newcommand{\Sem}[2]{\ptinline{[\!\![#1]\!\!]\tuple{#2}}}
|
\newcommand{\Sem}[2]{\ptinline{[\!\![#1]\!\!]\tuple{#2}}}
|
||||||
\newcommand{\Cbind}{\ensuremath{\wedge}}
|
\newcommand{\Cbind}{\ensuremath{\wedge}}
|
||||||
\newcommand{\true}{\mzninline{true}}
|
|
||||||
\newcommand{\false}{\mzninline{false}}
|
|
||||||
|
|
||||||
\newcommand{\mdiv}{\mzninline{div}}
|
|
||||||
\newcommand{\element}{\mzninline{element}}
|
|
||||||
\newcommand{\alldiff}{\mzninline{all_different}}
|
|
||||||
|
|
||||||
% Half-reification math things
|
% Half-reification math things
|
||||||
|
|
||||||
\newcommand{\VV}{{\cal V}}
|
\newcommand{\VV}{{\cal\ V}}
|
||||||
\newcommand{\PP}{{\cal P}}
|
\newcommand{\PP}{{\cal\ P}}
|
||||||
\newcommand{\range}[2]{\left[\,#1\,..\,#2\,\right]}
|
\newcommand{\range}[2]{\left[\,#1\,..\,#2\,\right]}
|
||||||
\newcommand{\gfp}{\textup{gfp}}
|
\newcommand{\gfp}{\textup{gfp}}
|
||||||
\newcommand{\lfp}{\textup{lfp}}
|
\newcommand{\lfp}{\textup{lfp}}
|
||||||
|
@ -134,7 +134,7 @@ have omitted the definitions of \syntax{<type-inst>} and \syntax{<ident>}, which
|
|||||||
you can assume to be the same as in the definition of \minizinc. While we omit
|
you can assume to be the same as in the definition of \minizinc. While we omit
|
||||||
the typing rules here for space reasons, we will assume that in well-typed
|
the typing rules here for space reasons, we will assume that in well-typed
|
||||||
\microzinc\ programs, the conditions \syntax{<exp>} in if-then-else and where
|
\microzinc\ programs, the conditions \syntax{<exp>} in if-then-else and where
|
||||||
expressions have \pari\ type.
|
expressions have \mzninline{par} type.
|
||||||
|
|
||||||
\begin{figure}
|
\begin{figure}
|
||||||
\begin{grammar}
|
\begin{grammar}
|
||||||
@ -353,13 +353,14 @@ that introduces the variable.
|
|||||||
A \nanozinc\ model (\cref{fig:4-nzn-syntax}) consists of a topologically-ordered
|
A \nanozinc\ model (\cref{fig:4-nzn-syntax}) consists of a topologically-ordered
|
||||||
list of definitions. Each definition binds a variable to the result of a call or
|
list of definitions. Each definition binds a variable to the result of a call or
|
||||||
another variable, and it is associated with a list of identifiers of auxiliary
|
another variable, and it is associated with a list of identifiers of auxiliary
|
||||||
constraints. The \nanozinc\ model contains a special definition $\true$,
|
constraints. The \nanozinc\ model contains a special definition
|
||||||
containing all ``root-context'' constraints of the model, i.e., those that have
|
\mzninline{true}, containing all ``root-context'' constraints of the model,
|
||||||
to hold globally and are not just used to define an auxiliary variable. Only
|
i.e., those that have to hold globally and are not just used to define an
|
||||||
root-context constraints (attached to $\true$) can effectively constrain the
|
auxiliary variable. Only root-context constraints (attached to \mzninline{true})
|
||||||
overall problem. Constraints attached to definitions originate from function
|
can effectively constrain the overall problem. Constraints attached to
|
||||||
calls, and since all functions are guaranteed to be total, attached constraints
|
definitions originate from function calls, and since all functions are
|
||||||
can only define the function result.
|
guaranteed to be total, attached constraints can only define the function
|
||||||
|
result.
|
||||||
|
|
||||||
\begin{example}\label{ex:4-absnzn}
|
\begin{example}\label{ex:4-absnzn}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ formulated. Modelling languages map the more expressive formulations to
|
|||||||
existentially quantified conjunction through a combination of loop unrolling,
|
existentially quantified conjunction through a combination of loop unrolling,
|
||||||
and flattening using reification.
|
and flattening using reification.
|
||||||
|
|
||||||
\begin{example}\label{ex:cons}
|
\begin{example}\label{ex:hr-cons}
|
||||||
Consider the following ``complex constraint'' written in \minizinc\ syntax
|
Consider the following ``complex constraint'' written in \minizinc\ syntax
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
@ -74,7 +74,7 @@ This is known as the \emph{strict} semantics
|
|||||||
The usual choice for modeling partial functions in modelling languages is the
|
The usual choice for modeling partial functions in modelling languages is the
|
||||||
\emph{relational} semantics \autocite{frisch-2009-undefinedness}. In the
|
\emph{relational} semantics \autocite{frisch-2009-undefinedness}. In the
|
||||||
relational semantics the value $\bot$ percolates up through the term until it
|
relational semantics the value $\bot$ percolates up through the term until it
|
||||||
reaches a Boolean subterm where it becomes $\false$. For the example
|
reaches a Boolean subterm where it becomes $\mzninline{false}$. For the example
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
/* t1 @\(\equiv\)@ */ a[7] = ⊥;
|
/* t1 @\(\equiv\)@ */ a[7] = ⊥;
|
||||||
@ -91,7 +91,7 @@ original complex constraint needs to be far more complex.
|
|||||||
The \minizinc\ compiler unrolls, flattens, and reifies \minizinc\ models
|
The \minizinc\ compiler unrolls, flattens, and reifies \minizinc\ models
|
||||||
implementing the relational semantics. Assuming \texttt{i} takes values in the
|
implementing the relational semantics. Assuming \texttt{i} takes values in the
|
||||||
set \mzninline{1..8}, and \texttt{a} has an index set \mzninline{1..5}, its
|
set \mzninline{1..8}, and \texttt{a} has an index set \mzninline{1..5}, its
|
||||||
translation of the constraint in \cref{ex:cons} is
|
translation of the constraint in \cref{ex:hr-cons} is
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
constraint b1 <-> i <= 4; % b1 holds iff i <= 4
|
constraint b1 <-> i <= 4; % b1 holds iff i <= 4
|
||||||
@ -120,7 +120,7 @@ functions, is that each reified version of a constraint requires further
|
|||||||
implementation to create, and indeed most solvers do not provide any reified
|
implementation to create, and indeed most solvers do not provide any reified
|
||||||
versions of their global constraints.
|
versions of their global constraints.
|
||||||
|
|
||||||
\begin{example}\label{ex:alldiff}
|
\begin{example}\label{ex:hr-alldiff}
|
||||||
Consider the complex constraint
|
Consider the complex constraint
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
@ -201,19 +201,22 @@ expressiveness in using global constraints.
|
|||||||
|
|
||||||
\section{Propagation Based Constraint Solving}
|
\section{Propagation Based Constraint Solving}
|
||||||
|
|
||||||
|
\jip{This section looks like background and should probably be moved}
|
||||||
|
|
||||||
We consider a typed set of variables $\VV = \VV_I \cup \VV_B$ made up of
|
We consider a typed set of variables $\VV = \VV_I \cup \VV_B$ made up of
|
||||||
\emph{integer} variables, $\VV_I$, and \emph{Boolean} variables, $\VV_b$. We use
|
\emph{integer} variables, $\VV_I$, and \emph{Boolean} variables, $\VV_b$. We use
|
||||||
lower case letters such as $x$ and $y$ for integer variables and letters such as
|
lower case letters such as $x$ and $y$ for integer variables and letters such as
|
||||||
$b$ for Booleans.
|
$b$ for Booleans.
|
||||||
%
|
%
|
||||||
A \emph{domain} $D$ is a complete mapping from $\VV$ to finite sets of integers
|
A \gls{domain} $D$ is a complete mapping from $\VV$ to finite sets of integers
|
||||||
(for the variables in $\VV_I$) and to subsets of $\{\true,\false\}$ (for the
|
(for the variables in $\VV_I$) and to subsets of
|
||||||
variables in $\VV_b$).
|
$\{\mzninline{true},\mzninline{false}\}$ (for the variables in $\VV_b$).
|
||||||
%
|
%
|
||||||
We can understand a domain $D$ as a formula $\wedge_{v \in \VV} (v \in D(v))$
|
We can understand a \gls{domain} $D$ as a formula
|
||||||
stating for each variable $v$ that its value is in its domain. A \emph{false
|
$\wedge_{v \in \VV} (v \in D(v))$ stating for each variable $v$ that its value
|
||||||
domain} $D$ is a domain where $\exists_{v \in \VV} D(v) = \emptyset$, and
|
is in its domain. A \emph{false domain} $D$ is a domain where
|
||||||
corresponds to an unsatisfiable formula.
|
$\exists_{v \in \VV} D(v) = \emptyset$, and corresponds to an unsatisfiable
|
||||||
|
formula.
|
||||||
|
|
||||||
Let $D_1$ and $D_2$ be domains and $V\subseteq\VV$. We say that $D_1$ is
|
Let $D_1$ and $D_2$ be domains and $V\subseteq\VV$. We say that $D_1$ is
|
||||||
\emph{stronger} than $D_2$, written $D_1 \sqsubseteq D_2$, if
|
\emph{stronger} than $D_2$, written $D_1 \sqsubseteq D_2$, if
|
||||||
@ -281,7 +284,7 @@ $\theta \in solns(c) \cap D$ s.t. $\theta(v_i) = \min D(v_i)$ and
|
|||||||
$\min D(v_j) \leq \theta(v_j) \leq \max D(v_j), 1 \leq j \neq i \leq n$, and
|
$\min D(v_j) \leq \theta(v_j) \leq \max D(v_j), 1 \leq j \neq i \leq n$, and
|
||||||
similarly exists $\theta \in solns(c) \cap D$ s.t. $\theta(v_i) = \max D(v_i)$
|
similarly exists $\theta \in solns(c) \cap D$ s.t. $\theta(v_i) = \max D(v_i)$
|
||||||
and $\min D(v_j) \leq \theta(v_j) \leq \max D(v_j), 1 \leq j \neq i \leq n$. For
|
and $\min D(v_j) \leq \theta(v_j) \leq \max D(v_j), 1 \leq j \neq i \leq n$. For
|
||||||
Boolean variables $v$ we assume $\false < \true$.
|
Boolean variables $v$ we assume $\mzninline{false} < \mzninline{true}$.
|
||||||
|
|
||||||
% A domain $D$ is \emph{bounds(R) consistent} for constraint $c$ if the same
|
% A domain $D$ is \emph{bounds(R) consistent} for constraint $c$ if the same
|
||||||
% conditions as for bounds(Z) consistency hold except $\theta \in solns(c')$ where
|
% conditions as for bounds(Z) consistency hold except $\theta \in solns(c')$ where
|
||||||
@ -323,7 +326,10 @@ fixpoint w.r.t $\sqsubseteq$ lifted to functions.
|
|||||||
% not going up from an empty one.)
|
% not going up from an empty one.)
|
||||||
|
|
||||||
|
|
||||||
\subsection{A Language of Constraints}\label{sec:syntax}
|
\subsection{A Language of Constraints}\label{sec:hr-syntax}
|
||||||
|
|
||||||
|
\jip{This introduces a subset of \minizinc, but we can probably use \microzinc\
|
||||||
|
instead.}
|
||||||
|
|
||||||
\newcommand{\nonterm}[1]{\textsc{#1}}
|
\newcommand{\nonterm}[1]{\textsc{#1}}
|
||||||
\newcommand{\subs}[1]{[\![ #1 ]\!] }
|
\newcommand{\subs}[1]{[\![ #1 ]\!] }
|
||||||
@ -414,13 +420,13 @@ Given a \syntax{<cons>} term defining the constraints of the model we can split
|
|||||||
its \syntax{<cons>} subterms as occurring in different kinds of places: root
|
its \syntax{<cons>} subterms as occurring in different kinds of places: root
|
||||||
contexts, positive contexts, negative contexts, and mixed contexts. A Boolean
|
contexts, positive contexts, negative contexts, and mixed contexts. A Boolean
|
||||||
subterm $t$ of constraint $c$ is in a \emph{root context} iff there is no
|
subterm $t$ of constraint $c$ is in a \emph{root context} iff there is no
|
||||||
solution of $c\subs{t/\false}$, that is $c$ with subterm $t$ replaced by
|
solution of $c\subs{t/\mzninline{false}}$, that is $c$ with subterm $t$ replaced by
|
||||||
$\false$.\footnote{For the definitions of context we assume that the subterm $t$
|
$\mzninline{false}$.\footnote{For the definitions of context we assume that the subterm $t$
|
||||||
is uniquely defined by its position in $c$, so the replacement is of exactly
|
is uniquely defined by its position in $c$, so the replacement is of exactly
|
||||||
one subterm.} Similarly, a subterm $t$ of constraint $c$ is in a
|
one subterm.} Similarly, a subterm $t$ of constraint $c$ is in a
|
||||||
\emph{positive context} iff for any solution $\theta$ of $c$ then $\theta$ is
|
\emph{positive context} iff for any solution $\theta$ of $c$ then $\theta$ is
|
||||||
also a solution of $c\subs{t/\true}$; and a \emph{negative context} iff for any
|
also a solution of $c\subs{t/\mzninline{true}}$; and a \emph{negative context} iff for any
|
||||||
solution $\theta$ of $c$ then $\theta$ is also a solution of $c\subs{t/\false}$.
|
solution $\theta$ of $c$ then $\theta$ is also a solution of $c\subs{t/\mzninline{false}}$.
|
||||||
The remaining Boolean subterms of $c$ are in \emph{mixed} contexts. While
|
The remaining Boolean subterms of $c$ are in \emph{mixed} contexts. While
|
||||||
determining contexts according to these definitions is hard, there are simple
|
determining contexts according to these definitions is hard, there are simple
|
||||||
syntactic rules which can determine the correct context for most terms, and the
|
syntactic rules which can determine the correct context for most terms, and the
|
||||||
@ -432,7 +438,7 @@ Consider the constraint expression
|
|||||||
constraint x > 0 /\ (i <= 4 -> x + bool2int(b) = 5);
|
constraint x > 0 /\ (i <= 4 -> x + bool2int(b) = 5);
|
||||||
\end{mzn}
|
\end{mzn}
|
||||||
|
|
||||||
then $x > 0$ is in the root context, $i \leq 4$ is in a negative context,
|
then \mzninline{x > 0} is in the root context, $i \leq 4$ is in a negative context,
|
||||||
$x + \texttt{bool2int}(b) = 5$ is in a positive context, and $b$ is in a mixed
|
$x + \texttt{bool2int}(b) = 5$ is in a positive context, and $b$ is in a mixed
|
||||||
context. If the last equality were $x + \texttt{bool2int}(b) \geq 5$ then $b$
|
context. If the last equality were $x + \texttt{bool2int}(b) \geq 5$ then $b$
|
||||||
would be in a positive context.
|
would be in a positive context.
|
||||||
@ -452,10 +458,10 @@ for each subterm bottom up using approximation.
|
|||||||
% \cons{} subterms as occurring in kinds of places: positive contexts, negative
|
% \cons{} subterms as occurring in kinds of places: positive contexts, negative
|
||||||
% contexts, and mixed contexts. A Boolean subterm $t$ of constraint $c$, written
|
% contexts, and mixed contexts. A Boolean subterm $t$ of constraint $c$, written
|
||||||
% $c[t]$, is in a \emph{positive context} iff for any solution $\theta$ of $c$
|
% $c[t]$, is in a \emph{positive context} iff for any solution $\theta$ of $c$
|
||||||
% then $\theta$ is also a solution of $c[\true]$, that is $c$ with subterm $t$
|
% then $\theta$ is also a solution of $c[\mzninline{true}]$, that is $c$ with subterm $t$
|
||||||
% replaced by $\true$. Similarly, a subterm $t$ of constraint $c$ is in a
|
% replaced by $\mzninline{true}$. Similarly, a subterm $t$ of constraint $c$ is in a
|
||||||
% \emph{negative context} iff for any solution $\theta$ of $c$ then $\theta$ is
|
% \emph{negative context} iff for any solution $\theta$ of $c$ then $\theta$ is
|
||||||
% also a solution of $c[\false]$. The remaining Boolean subterms of $c$ are in
|
% also a solution of $c[\mzninline{false}]$. The remaining Boolean subterms of $c$ are in
|
||||||
% mixed contexts.
|
% mixed contexts.
|
||||||
|
|
||||||
% \begin{example}
|
% \begin{example}
|
||||||
@ -486,7 +492,7 @@ set of possible values of $t$ are included in the domain of $a$,
|
|||||||
$poss(t) \subseteq \dom(a)$.
|
$poss(t) \subseteq \dom(a)$.
|
||||||
|
|
||||||
\section{Flattening with Full Reification}
|
\section{Flattening with Full Reification}
|
||||||
\label{sec:translation}
|
\label{sec:hr-translation}
|
||||||
|
|
||||||
Constraint problems formulated in \minizinc\ are solved by translating them to a
|
Constraint problems formulated in \minizinc\ are solved by translating them to a
|
||||||
simpler, solver-specific subset of \minizinc, called \flatzinc. \flatzinc
|
simpler, solver-specific subset of \minizinc, called \flatzinc. \flatzinc
|
||||||
@ -534,13 +540,13 @@ detailed discussion) but makes the pseudo-code much longer.
|
|||||||
|
|
||||||
The complex part of flattening arises in flattening the constraints, we shall
|
The complex part of flattening arises in flattening the constraints, we shall
|
||||||
ignore the declarations part for flattening and assume that any objective
|
ignore the declarations part for flattening and assume that any objective
|
||||||
function term $e$ is replaced by a new variable $obj$ and a constraint item
|
function term \mzninline{e} is replaced by a new variable \mzninline{obj} and a
|
||||||
$\texttt{constraint}~obj = e$ which will then be flattened as part of the
|
constraint item \mzninline{constraint obj = e} which will then be flattened as
|
||||||
model.
|
part of the model.
|
||||||
|
|
||||||
\subsection{Flattening Constraints}
|
\subsection{Flattening Constraints}
|
||||||
|
|
||||||
Flattening a constraint $c$ in context $\ctxt$, $\flatc(c,\ctxt)$, returns a
|
Flattening a constraint $c$ in context \ctxt, $\flatc(c,\ctxt)$, returns a
|
||||||
Boolean literal $b$ representing the constraint and as a side effect adds a set
|
Boolean literal $b$ representing the constraint and as a side effect adds a set
|
||||||
of constraints (the flattening) $S$ to the store such that
|
of constraints (the flattening) $S$ to the store such that
|
||||||
$S \models b \full c$.
|
$S \models b \full c$.
|
||||||
@ -616,7 +622,7 @@ actual flattening rules only differentiate between $\rootc$ and other contexts.
|
|||||||
The importance of the $\pos$ context is that \texttt{let} expressions within a
|
The importance of the $\pos$ context is that \texttt{let} expressions within a
|
||||||
$\pos$ context can declare new variables. The important of the $\negc$ context
|
$\pos$ context can declare new variables. The important of the $\negc$ context
|
||||||
is to track $\pos$ context arising under double negations. Note that flattening
|
is to track $\pos$ context arising under double negations. Note that flattening
|
||||||
in the root context always returns a Boolean $b$ made equivalent to $\true$ by
|
in the root context always returns a Boolean $b$ made equivalent to $\mzninline{true}$ by
|
||||||
the constraints in $S$. For succinctness we use the notation $\new b$ ($\new v$)
|
the constraints in $S$. For succinctness we use the notation $\new b$ ($\new v$)
|
||||||
to introduce a fresh Boolean (resp.\ integer) variable and return the name of
|
to introduce a fresh Boolean (resp.\ integer) variable and return the name of
|
||||||
the variable.
|
the variable.
|
||||||
@ -628,7 +634,7 @@ again. We retrieve the result of the previous flattening $h$ and the previous
|
|||||||
context $prev$. If the expression previously appeared at the root then we simply
|
context $prev$. If the expression previously appeared at the root then we simply
|
||||||
reuse the old value, since regardless of the new context the expression must
|
reuse the old value, since regardless of the new context the expression must
|
||||||
hold. If the new context is $\rootc$ we reuse the old value but require it to be
|
hold. If the new context is $\rootc$ we reuse the old value but require it to be
|
||||||
$\true$ in $S$, and modify the hash table to record the expression appears at
|
$\mzninline{true}$ in $S$, and modify the hash table to record the expression appears at
|
||||||
the root. If the expression appeared in a mixed context we simply reuse the old
|
the root. If the expression appeared in a mixed context we simply reuse the old
|
||||||
result since this is the most constrained context. Similarly if the previous
|
result since this is the most constrained context. Similarly if the previous
|
||||||
context is the same as the current one we reuse the old result. In the remaining
|
context is the same as the current one we reuse the old result. In the remaining
|
||||||
@ -683,7 +689,7 @@ expression using function \textsf{flatlet} which returns the extracted
|
|||||||
constraint and a rewritten term (not used in this case, but used in \flatt{}).
|
constraint and a rewritten term (not used in this case, but used in \flatt{}).
|
||||||
The constraints returned by function \textsf{flatlet} are then flattened.
|
The constraints returned by function \textsf{flatlet} are then flattened.
|
||||||
Finally if we are in the root context, we ensure that the Boolean $b$ returned
|
Finally if we are in the root context, we ensure that the Boolean $b$ returned
|
||||||
must be $\true$ by adding $b$ to $S$.
|
must be $\mzninline{true}$ by adding $b$ to $S$.
|
||||||
|
|
||||||
{
|
{
|
||||||
\begin{tabbing}
|
\begin{tabbing}
|
||||||
@ -701,8 +707,8 @@ $\tuple{h,\rootc}$; \textbf{return} $h$
|
|||||||
\> \textbf{if} ($\fixed(c)$) $b$ := $\eval(c)$ \\
|
\> \textbf{if} ($\fixed(c)$) $b$ := $\eval(c)$ \\
|
||||||
\> \textbf{else} \\
|
\> \textbf{else} \\
|
||||||
\> \> \textbf{switch} $c$ \\
|
\> \> \textbf{switch} $c$ \\
|
||||||
%\> \> \textbf{case} \texttt{true}: $b$ := $\true$;\\
|
%\> \> \textbf{case} \texttt{true}: $b$ := $\mzninline{true}$;\\
|
||||||
%\> \> \textbf{case} \texttt{false}: $b$ := $\false$;\\
|
%\> \> \textbf{case} \texttt{false}: $b$ := $\mzninline{false}$;\\
|
||||||
\> \> \textbf{case} $b'$ (\syntax{<bvar>}): $b$ := $b'$; \\
|
\> \> \textbf{case} $b'$ (\syntax{<bvar>}): $b$ := $b'$; \\
|
||||||
\> \> \textbf{case} $t_1$ $r$ $t_2$ (\syntax{<relop>}): \\
|
\> \> \textbf{case} $t_1$ $r$ $t_2$ (\syntax{<relop>}): \\
|
||||||
\>\>\> $\tuple{v_1, b_1}$ := $\flatt(t_1,\ctxt)$;
|
\>\>\> $\tuple{v_1, b_1}$ := $\flatt(t_1,\ctxt)$;
|
||||||
@ -739,7 +745,7 @@ $S$ \cupp $\{ \new b \full (\flatc(c_1,\mix) \full
|
|||||||
%\mathit{safeelement}(v, [b_1, \ldots, b_n], b'),
|
%\mathit{safeelement}(v, [b_1, \ldots, b_n], b'),
|
||||||
%b'' \full v \in \{1,..,n\} \} $ \\
|
%b'' \full v \in \{1,..,n\} \} $ \\
|
||||||
\>\>\> \textbf{if} ($\ctxt = \rootc$) $S$ \cupp $\{\texttt{element}(v', [b_1, \ldots, b_n],
|
\>\>\> \textbf{if} ($\ctxt = \rootc$) $S$ \cupp $\{\texttt{element}(v', [b_1, \ldots, b_n],
|
||||||
\true)\}$; $b$ := $\true$ \\
|
\mzninline{true})\}$; $b$ := $\mzninline{true}$ \\
|
||||||
\>\>\> \textbf{else} \\
|
\>\>\> \textbf{else} \\
|
||||||
\>\>\>\> $S$ \cupp
|
\>\>\>\> $S$ \cupp
|
||||||
$\{ \new b \full (b_{n+1} \wedge \new b' \wedge \new b''), \new v' \in \{1,
|
$\{ \new b \full (b_{n+1} \wedge \new b' \wedge \new b''), \new v' \in \{1,
|
||||||
@ -755,7 +761,7 @@ b'' \full v = v', b'' \full v \in \{1,\ldots,n\} \} $
|
|||||||
\> \> \> \> \textbf{else} $S$ \cupp $\{ p\_reif(v_1,\ldots,v_n,\new b'),
|
\> \> \> \> \textbf{else} $S$ \cupp $\{ p\_reif(v_1,\ldots,v_n,\new b'),
|
||||||
\new b \Leftrightarrow b' \wedge \bigwedge_{j=1}^n b_j\}$ \\
|
\new b \Leftrightarrow b' \wedge \bigwedge_{j=1}^n b_j\}$ \\
|
||||||
\> \> \> \textbf{else} \\
|
\> \> \> \textbf{else} \\
|
||||||
\>\> \> \> $b$ := $\true$; $S$ \cupp $\{ p(v_1, \ldots, v_n) %, \bigwedge_{j=1}^n b_j
|
\>\> \> \> $b$ := $\mzninline{true}$; $S$ \cupp $\{ p(v_1, \ldots, v_n) %, \bigwedge_{j=1}^n b_j
|
||||||
\}$
|
\}$
|
||||||
\\
|
\\
|
||||||
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): user-defined predicate \\
|
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): user-defined predicate \\
|
||||||
@ -771,7 +777,7 @@ b_j\}$
|
|||||||
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}) built-in predicate: \\
|
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}) built-in predicate: \\
|
||||||
\> \> \> \textbf{if} ($\ctxt \neq \rootc$) \textbf{abort} \\
|
\> \> \> \textbf{if} ($\ctxt \neq \rootc$) \textbf{abort} \\
|
||||||
\> \> \> \textbf{foreach}($j \in 1..n$) $\tuple{v_j, \_}$ := $\flatt(t_j,\rootc)$; \\
|
\> \> \> \textbf{foreach}($j \in 1..n$) $\tuple{v_j, \_}$ := $\flatt(t_j,\rootc)$; \\
|
||||||
\>\> \> $b$ := $\true$; $S$ \cupp $\{ p(v_1, \ldots, v_n)\}$
|
\>\> \> $b$ := $\mzninline{true}$; $S$ \cupp $\{ p(v_1, \ldots, v_n)\}$
|
||||||
\\
|
\\
|
||||||
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): user-defined predicate \\
|
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): user-defined predicate \\
|
||||||
\>\> \> \textbf{let} $p(x_1, \ldots, x_n) = c_0$ be defn of $p$ \\
|
\>\> \> \textbf{let} $p(x_1, \ldots, x_n) = c_0$ be defn of $p$ \\
|
||||||
@ -886,7 +892,7 @@ $\flatt(t,\ctxt)$ flattens an integer term $t$ in context $\ctxt$. It returns a
|
|||||||
tuple $\tuple{v,b}$ of an integer variable/value $v$ and a Boolean literal $b$,
|
tuple $\tuple{v,b}$ of an integer variable/value $v$ and a Boolean literal $b$,
|
||||||
and as a side effect adds constraints to $S$ so that
|
and as a side effect adds constraints to $S$ so that
|
||||||
$S \models b \full (v = t)$. Note that again flattening in the root context
|
$S \models b \full (v = t)$. Note that again flattening in the root context
|
||||||
always returns a Boolean $b$ made equivalent to $\true$ by the constraints in
|
always returns a Boolean $b$ made equivalent to $\mzninline{true}$ by the constraints in
|
||||||
$S$.
|
$S$.
|
||||||
|
|
||||||
Flattening first checks if the same expression has been flattened previously and
|
Flattening first checks if the same expression has been flattened previously and
|
||||||
@ -936,13 +942,13 @@ $\tuple{h,b',\rootc}$; \textbf{return} $\tuple{h,b'}$
|
|||||||
\>\> \textbf{if} ($prev = \mix \vee prev = \ctxt$)
|
\>\> \textbf{if} ($prev = \mix \vee prev = \ctxt$)
|
||||||
\textbf{return} $\tuple{h,b'}$ \\
|
\textbf{return} $\tuple{h,b'}$ \\
|
||||||
\>\> $\ctxt$ := $\mix$ \\
|
\>\> $\ctxt$ := $\mix$ \\
|
||||||
\> \textbf{if} ($\fixed(t)$) $v$ := $\eval(t)$; $b$ := $\true$ \\
|
\> \textbf{if} ($\fixed(t)$) $v$ := $\eval(t)$; $b$ := $\mzninline{true}$ \\
|
||||||
\> \textbf{else} %\\
|
\> \textbf{else} %\\
|
||||||
%% \> \> \textbf{if} ($t$ is marked \emph{total}) $\ctxt$ := $\rootc$ \\
|
%% \> \> \textbf{if} ($t$ is marked \emph{total}) $\ctxt$ := $\rootc$ \\
|
||||||
%\> \>
|
%\> \>
|
||||||
\textbf{switch} $t$ \\
|
\textbf{switch} $t$ \\
|
||||||
%\> \> \textbf{case} $i$ (\intc): $v$ := $i$; $b$ := $\true$ \\
|
%\> \> \textbf{case} $i$ (\intc): $v$ := $i$; $b$ := $\mzninline{true}$ \\
|
||||||
\> \> \textbf{case} $v'$ (\syntax{<ivar>}): $v$ := $v'$; $b$ := $\true$\\
|
\> \> \textbf{case} $v'$ (\syntax{<ivar>}): $v$ := $v'$; $b$ := $\mzninline{true}$\\
|
||||||
\> \> \textbf{case} $t_1$ $a$ $t_2$ (\syntax{<arithop>}): \\
|
\> \> \textbf{case} $t_1$ $a$ $t_2$ (\syntax{<arithop>}): \\
|
||||||
\> \> \>
|
\> \> \>
|
||||||
$\tuple{v_1,b_1}$ := $\flatt(t_1,\ctxt)$;
|
$\tuple{v_1,b_1}$ := $\flatt(t_1,\ctxt)$;
|
||||||
@ -1035,14 +1041,16 @@ $S$ \cupp $\{ \new b \full (b_1 \wedge b_2)\}$
|
|||||||
\> \textbf{return} $\tuple{v,b}$
|
\> \textbf{return} $\tuple{v,b}$
|
||||||
\end{tabbing}
|
\end{tabbing}
|
||||||
|
|
||||||
\begin{example}\label{ex:flat}
|
\begin{example}\label{ex:hr-flat}
|
||||||
Consider the flattening of the expression
|
Consider the flattening of the expression
|
||||||
$$
|
$$
|
||||||
a[x] + bool2int(x > y) - bool2int(x > z) \geq 4 \vee
|
a[x] + bool2int(x > y) - bool2int(x > z) \geq 4 \vee
|
||||||
(a[x] \leq 2 \wedge x > y \wedge (x > z \rightarrow b))
|
(a[x] \leq 2 \wedge x > y \wedge (x > z \rightarrow b))
|
||||||
$$
|
$$
|
||||||
The different terms and subterms of the expression are
|
|
||||||
illustrated and numbered in Figure~\ref{fig:tree}.
|
The different terms and subterms of the expression are illustrated and
|
||||||
|
numbered in \cref{fig:hr-tree}.
|
||||||
|
|
||||||
\begin{figure}[t]
|
\begin{figure}[t]
|
||||||
$$
|
$$
|
||||||
\xymatrix@R=1em@C=0.6em{
|
\xymatrix@R=1em@C=0.6em{
|
||||||
@ -1060,7 +1068,7 @@ $S$ \cupp $\{ \new b \full (b_1 \wedge b_2)\}$
|
|||||||
}
|
}
|
||||||
$$
|
$$
|
||||||
\caption{An expression to be flattened with non-leaf (sub-)terms
|
\caption{An expression to be flattened with non-leaf (sub-)terms
|
||||||
numbered.\label{fig:tree}}
|
numbered.\label{fig:hr-tree}}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
Note that positions 0 is in the $\rootc$ context, while position 10 is in a
|
Note that positions 0 is in the $\rootc$ context, while position 10 is in a
|
||||||
$\negc$ context, positions 13 and 15 are in a $\mix$ context, and the rest are
|
$\negc$ context, positions 13 and 15 are in a $\mix$ context, and the rest are
|
||||||
@ -1171,7 +1179,7 @@ $S$ \cupp $\{ \new b \full (b_1 \wedge b_2)\}$
|
|||||||
|
|
||||||
% The pseudo-code for \flatc($b$,$c$) flattens a constraint expression $c$ to be
|
% The pseudo-code for \flatc($b$,$c$) flattens a constraint expression $c$ to be
|
||||||
% equal to $b$, returning a set of constraints implementing $b \full c$. We
|
% equal to $b$, returning a set of constraints implementing $b \full c$. We
|
||||||
% flatten a whole model $c$ using $\flatc(\true, c)$. In the pseudo-code the
|
% flatten a whole model $c$ using $\flatc(\mzninline{true}, c)$. In the pseudo-code the
|
||||||
% expressions $\new b$ and $\new v$ create a new Boolean and integer variable
|
% expressions $\new b$ and $\new v$ create a new Boolean and integer variable
|
||||||
% respectively.
|
% respectively.
|
||||||
|
|
||||||
@ -1193,8 +1201,8 @@ $S$ \cupp $\{ \new b \full (b_1 \wedge b_2)\}$
|
|||||||
% \> \textbf{case} \texttt{not} $c_1$:
|
% \> \textbf{case} \texttt{not} $c_1$:
|
||||||
% \textbf{return} $\flatc(\new b_1, c_1) \cup \{ b \full \neg b_1 \}$ \\
|
% \textbf{return} $\flatc(\new b_1, c_1) \cup \{ b \full \neg b_1 \}$ \\
|
||||||
% \> \textbf{case} $c_1$ \verb+/\+ $c_2$: \=
|
% \> \textbf{case} $c_1$ \verb+/\+ $c_2$: \=
|
||||||
% \textbf{if} ($b \equiv \true$) \textbf{return} $\flatc(\true, c_1) \cup
|
% \textbf{if} ($b \equiv \mzninline{true}$) \textbf{return} $\flatc(\mzninline{true}, c_1) \cup
|
||||||
% \flatc(\true, c_2)$ \\
|
% \flatc(\mzninline{true}, c_2)$ \\
|
||||||
% \> \> \textbf{else} \textbf{return} $\flatc(\new b_1, c_1) \cup
|
% \> \> \textbf{else} \textbf{return} $\flatc(\new b_1, c_1) \cup
|
||||||
% \flatc(\new b_2, c_2) \cup \{ b \full (b_1 \wedge b_2)\}$ \\
|
% \flatc(\new b_2, c_2) \cup \{ b \full (b_1 \wedge b_2)\}$ \\
|
||||||
% xx\=xx\=xx\=xx\=xx\=xx\=xx\= \kill
|
% xx\=xx\=xx\=xx\=xx\=xx\=xx\= \kill
|
||||||
@ -1208,7 +1216,7 @@ $S$ \cupp $\{ \new b \full (b_1 \wedge b_2)\}$
|
|||||||
% \flatc(\new b_2, c_2) \cup \{ b \full (b_1 \full
|
% \flatc(\new b_2, c_2) \cup \{ b \full (b_1 \full
|
||||||
% b_2)\}$ \\
|
% b_2)\}$ \\
|
||||||
% \> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): \\
|
% \> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): \\
|
||||||
% \> \> \textbf{if} ($b \equiv \true$) \textbf{return} $\safen(b,
|
% \> \> \textbf{if} ($b \equiv \mzninline{true}$) \textbf{return} $\safen(b,
|
||||||
% \cup_{j=1}^n \flatt(\new v_j, t_j)) \cup \{ p(v_1, \ldots, v_n) \}$ \\
|
% \cup_{j=1}^n \flatt(\new v_j, t_j)) \cup \{ p(v_1, \ldots, v_n) \}$ \\
|
||||||
% \> \> \textbf{else} \textbf{abort}
|
% \> \> \textbf{else} \textbf{abort}
|
||||||
% \end{tabbing}
|
% \end{tabbing}
|
||||||
@ -1237,21 +1245,22 @@ The procedure \safen($b, C$) enforces the relational semantics for unsafe
|
|||||||
expressions, by ensuring that the unsafe relational versions of partial
|
expressions, by ensuring that the unsafe relational versions of partial
|
||||||
functions are made safe. Note that to implement the \emph{strict semantics} as
|
functions are made safe. Note that to implement the \emph{strict semantics} as
|
||||||
opposed to the relational semantics we just need to define $\safen(b,C) = C$. If
|
opposed to the relational semantics we just need to define $\safen(b,C) = C$. If
|
||||||
$b \equiv \true$ then the relational semantics and the strict semantics
|
$b \equiv \mzninline{true}$ then the relational semantics and the strict semantics
|
||||||
coincide, so nothing needs to be done. The same is true if the set of
|
coincide, so nothing needs to be done. The same is true if the set of
|
||||||
constraints $C$ is safe. For $div(x,y,z)$, the translation introduces a new
|
constraints $C$ is safe. For $div(x,y,z)$, the translation introduces a new
|
||||||
variable $y'$ which cannot be 0, and equates it to $y$ if $y \neq 0$. The
|
variable $y'$ which cannot be 0, and equates it to $y$ if $y \neq 0$. The
|
||||||
constraint $div(x,y',z)$ never reflects a partial function application. The new
|
constraint $div(x,y',z)$ never reflects a partial function application. The new
|
||||||
variable $b'$ captures whether the partial function application returns a non
|
variable $b'$ captures whether the partial function application returns a non
|
||||||
$\bot$ value. For $\element(v,a,x)$, it introduces a new variable $v'$ which
|
$\bot$ value. For \mzninline{element(v, a, x)}, it introduces a new variable $v'$
|
||||||
only takes values in $\dom(a)$ and forces it to equal $v$ if $v \in \dom(a)$. A
|
which only takes values in $\dom(a)$ and forces it to equal $v$ if
|
||||||
partial function application forces $b = \false$ since it is the conjunction of
|
$v \in \dom(a)$. A partial function application forces $b = \mzninline{false}$ since it is
|
||||||
the new variables $b'$. The \%HALF\% comments will be explained later.
|
the conjunction of the new variables $b'$. The \%HALF\% comments will be
|
||||||
|
explained later.
|
||||||
|
|
||||||
\begin{tabbing}
|
\begin{tabbing}
|
||||||
xx\=xx\=xx\=xx\=xx\=xx\=xx\= \kill
|
xx\=xx\=xx\=xx\=xx\=xx\=xx\= \kill
|
||||||
\safen($b$,$C$) \\
|
\safen($b$,$C$) \\
|
||||||
\> \textbf{if} ($b \equiv \true$) \textbf{return} $C$ \\
|
\> \textbf{if} ($b \equiv \mzninline{true}$) \textbf{return} $C$ \\
|
||||||
\> \textbf{if} ($C$ is a set of safe constraints) \textbf{return} $C$ \\
|
\> \textbf{if} ($C$ is a set of safe constraints) \textbf{return} $C$ \\
|
||||||
\> $B$ := $\emptyset$; $S$ := $\emptyset$ \\
|
\> $B$ := $\emptyset$; $S$ := $\emptyset$ \\
|
||||||
\> \textbf{foreach} $c \in C$ \\
|
\> \textbf{foreach} $c \in C$ \\
|
||||||
@ -1261,13 +1270,13 @@ xx\=xx\=xx\=xx\=xx\=xx\=xx\= \kill
|
|||||||
= y', div(x,y',z) \}$ \\
|
= y', div(x,y',z) \}$ \\
|
||||||
\> \> \> \%HALF\% $S$ := $S \cup \{ b' \full y \neq 0, b' \half
|
\> \> \> \%HALF\% $S$ := $S \cup \{ b' \full y \neq 0, b' \half
|
||||||
div(x,y,z)\}$ \\
|
div(x,y,z)\}$ \\
|
||||||
\> \> \textbf{else if} $c \equiv \element(v,a,x)$ and $v$ can take a value outside the domain of $a$) \\
|
\> \> \textbf{else if} \(c \equiv \mzninline{element(v, a, x)}\) and $v$ can take a value outside the domain of $a$) \\
|
||||||
\> \> \> $B$ := $B \cup \{ \new b' \}$ \\
|
\> \> \> $B$ := $B \cup \{ \new b' \}$ \\
|
||||||
\> \> \> $S$ := $S \cup \{ \new v' \in \dom(a),
|
\> \> \> $S$ := $S \cup \{ \new v' \in \dom(a),
|
||||||
b' \full v \in \dom(a), b' \full v = v',
|
b' \full v \in \dom(a), b' \full v = v',
|
||||||
\element(v',a,x)\}$ \\
|
\mzninline{element(v', a, x)}\}$ \\
|
||||||
\> \> \> \%HALF\% $S$ := $S \cup \{ b' \full v \in \dom(a), b' \half
|
\> \> \> \%HALF\% $S$ := $S \cup \{ b' \full v \in \dom(a), b' \half
|
||||||
\element(v,a,x)\}$ \\
|
\mzninline{element(v, a, x)}\}$ \\
|
||||||
\> \> \textbf{else} $S$ := $S \cup \{c\}$ \\
|
\> \> \textbf{else} $S$ := $S \cup \{c\}$ \\
|
||||||
\> \> \textbf{return} $S \cup \{b \full \wedge_{b' \in B} b'
|
\> \> \textbf{return} $S \cup \{b \full \wedge_{b' \in B} b'
|
||||||
\})$
|
\})$
|
||||||
@ -1279,7 +1288,7 @@ renamed-apart copies of already-generated constraints, but for simplicity of
|
|||||||
presentation, we omit the algorithms we use to do this.
|
presentation, we omit the algorithms we use to do this.
|
||||||
|
|
||||||
\section{Half Reification}
|
\section{Half Reification}
|
||||||
\label{sec:halfreif}
|
\label{sec:hr-halfreif}
|
||||||
|
|
||||||
Given a constraint $c$, the \emph{half-reified version} of $c$ is a constraint
|
Given a constraint $c$, the \emph{half-reified version} of $c$ is a constraint
|
||||||
of the form $b \half c$ where $b \not\in vars(c)$ is a Boolean variable.
|
of the form $b \half c$ where $b \not\in vars(c)$ is a Boolean variable.
|
||||||
@ -1288,11 +1297,11 @@ We can construct a propagator $f_{b \half c}$ for the half-reified version of
|
|||||||
$c$, $b \half c$, using the propagator $f_c$ for $c$.
|
$c$, $b \half c$, using the propagator $f_c$ for $c$.
|
||||||
$$
|
$$
|
||||||
\begin{array}{rcll}
|
\begin{array}{rcll}
|
||||||
f_{b \half c}(D)(b) & = & \{ \false \} \cap D(b) & \text{if~} f_c(D) \text{~is a false domain} \\
|
f_{b \half c}(D)(b) & = & \{ \mzninline{false} \} \cap D(b) & \text{if~} f_c(D) \text{~is a false domain} \\
|
||||||
f_{b \half c}(D)(b) & = & D(b) & \text{otherwise} \\
|
f_{b \half c}(D)(b) & = & D(b) & \text{otherwise} \\
|
||||||
f_{b \half c}(D)(v) & = & D(v) & \text{if~} v \in vars(c) \text{~and~} \false \in D(b) \\
|
f_{b \half c}(D)(v) & = & D(v) & \text{if~} v \in vars(c) \text{~and~} \mzninline{false} \in D(b) \\
|
||||||
f_{b \half c}(D)(v) & = & f_c(D)(v) & \text{if~} v \in vars(c)
|
f_{b \half c}(D)(v) & = & f_c(D)(v) & \text{if~} v \in vars(c)
|
||||||
\text{~and~} \false \not\in D(b)
|
\text{~and~} \mzninline{false} \not\in D(b)
|
||||||
\end{array}
|
\end{array}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
@ -1325,27 +1334,28 @@ $$
|
|||||||
% Given this separation we can improve the definition of $f_{b \half c}$ above by
|
% Given this separation we can improve the definition of $f_{b \half c}$ above by
|
||||||
% replacing the check ``$f_c(D)$ is a false domain'' by ``$f_{check(c)}(D)$ is a
|
% replacing the check ``$f_c(D)$ is a false domain'' by ``$f_{check(c)}(D)$ is a
|
||||||
% false domain''. In practice it means that the half-reified propagator can be
|
% false domain''. In practice it means that the half-reified propagator can be
|
||||||
% implemented to only perform the checking part until $D(b) = \{\true\}$, when it
|
% implemented to only perform the checking part until $D(b) = \{\mzninline{true}\}$, when it
|
||||||
% needs to perform both.
|
% needs to perform both.
|
||||||
|
|
||||||
In practice most propagator implementations for $c$ first check whether $c$ is
|
In practice most propagator implementations for \mzninline{c} first check
|
||||||
satisfiable, before continuing to propagate. For example,
|
whether \mzninline{c} is satisfiable, before continuing to propagate. For
|
||||||
$\sum_i a_i x_i \leq a_0$ determines $L = \sum_i min_D(a_i x_i) - a_0$ and fails
|
example, \mzninline{sum(i in N)(a[i] * x[i]) <= C} determines \mzninline{L =
|
||||||
if $L > 0$ before propagating; Regin's domain propagator for
|
sum(i in N)(lb(a[i] * x[i])) - C} and fails if \mzninline{L > 0} before
|
||||||
\alldiff$([x_1, \ldots, x_n]$) determines a maximum matching between variables
|
propagating; Regin's domain propagator for \mzninline{all_different(X)}
|
||||||
and values first, if this is not of size $n$ it fails before propagating; the
|
determines a maximum matching between variables and values first, if this is not
|
||||||
timetable \texttt{cumulative} constraint determines a profile of necessary
|
of size \mzninline{length(X)} it fails before propagating; the timetable
|
||||||
resource usage, and fails if this breaks the resource limit, before considering
|
\texttt{cumulative} constraint determines a profile of necessary resource usage,
|
||||||
propagation. We can implement the propagator for $f_{b \half c}$ by only
|
and fails if this breaks the resource limit, before considering propagation. We
|
||||||
performing the checking part until $D(b) = \{\true\}$.
|
can implement the propagator for $f_{\mzninline{b -> c}}$ by only performing the
|
||||||
|
checking part until $D(\texttt{b}) = \{\mzninline{true}\}$.
|
||||||
|
|
||||||
Half reification naturally encodes the relational semantics for partial function
|
Half reification naturally encodes the relational semantics for partial function
|
||||||
applications in positive contexts. We associate a Boolean variable $b$ with each
|
applications in positive contexts. We associate a Boolean variable \texttt{b} with each
|
||||||
Boolean term in an expression, and we ensure that all unsafe constraints are
|
Boolean term in an expression, and we ensure that all unsafe constraints are
|
||||||
half-reified using the variable of the nearest enclosing Boolean term.
|
half-reified using the variable of the nearest enclosing Boolean term.
|
||||||
|
|
||||||
\begin{example}
|
\begin{example}
|
||||||
Consider flattening of the constraint of \cref{ex:cons}. First we will convert
|
Consider flattening of the constraint of \cref{ex:hr-cons}. First we will convert
|
||||||
it to an equivalent expression with only positive contexts
|
it to an equivalent expression with only positive contexts
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
@ -1364,10 +1374,10 @@ half-reified using the variable of the nearest enclosing Boolean term.
|
|||||||
constraint b1 \/ b2;
|
constraint b1 \/ b2;
|
||||||
\end{mzn}
|
\end{mzn}
|
||||||
|
|
||||||
The unsafe $\element$ constraint is half reified with the name of its nearest
|
The unsafe \mzninline{element} constraint is half reified with the name of its nearest
|
||||||
enclosing Boolean term. Note that if $i = 7$ then the second constraint makes
|
enclosing Boolean term. Note that if $i = 7$ then the second constraint makes
|
||||||
$b2 = \false$. Given this, the final constraint requires $b1 = \true$, which
|
$b2 = \mzninline{false}$. Given this, the final constraint requires $b1 = \mzninline{true}$, which
|
||||||
in turn requires $i > 4$. Since this holds, the whole constraint is $\true$
|
in turn requires $i > 4$. Since this holds, the whole constraint is $\mzninline{true}$
|
||||||
with no restrictions on $x$.
|
with no restrictions on $x$.
|
||||||
\end{example}
|
\end{example}
|
||||||
|
|
||||||
@ -1376,7 +1386,7 @@ assume that each global constraint predicate $p$ is available in half-reified
|
|||||||
form. Recall that this places no new burden on the solver implementer.
|
form. Recall that this places no new burden on the solver implementer.
|
||||||
|
|
||||||
\begin{example}
|
\begin{example}
|
||||||
Consider the constraint of \cref{ex:alldiff}. Half reification results in
|
Consider the constraint of \cref{ex:hr-alldiff}. Half reification results in
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
constraint b1 -> i > 4;
|
constraint b1 -> i > 4;
|
||||||
@ -1385,14 +1395,15 @@ form. Recall that this places no new burden on the solver implementer.
|
|||||||
constraint b1 \/ b2 % b1 or b2
|
constraint b1 \/ b2 % b1 or b2
|
||||||
\end{mzn}
|
\end{mzn}
|
||||||
|
|
||||||
We can easily modify any existing propagator for \alldiff to support the
|
We can easily modify any existing propagator for \mzninline{all_different} to
|
||||||
half-reified form, hence this model is executable by our constraint solver.
|
support the half-reified form, hence this model is executable by our
|
||||||
|
constraint solver.
|
||||||
\end{example}
|
\end{example}
|
||||||
|
|
||||||
Half reification can lead to more efficient constraint solving, since it does
|
Half reification can lead to more efficient constraint solving, since it does
|
||||||
not propagate unnecessarily.
|
not propagate unnecessarily.
|
||||||
|
|
||||||
\begin{example}\label{ex:cumul}
|
\begin{example}\label{ex:hr-cumul}
|
||||||
Consider the task decomposition of a \texttt{cumulative} constraint (see \eg\
|
Consider the task decomposition of a \texttt{cumulative} constraint (see \eg\
|
||||||
\autocite{schutt-2009-cumulative}) which includes constraints of the form
|
\autocite{schutt-2009-cumulative}) which includes constraints of the form
|
||||||
|
|
||||||
@ -1415,7 +1426,7 @@ not propagate unnecessarily.
|
|||||||
\end{mzn}
|
\end{mzn}
|
||||||
|
|
||||||
Whenever the start time of task $i$ is constrained so that it does not overlap
|
Whenever the start time of task $i$ is constrained so that it does not overlap
|
||||||
time $s[j]$, then $b3[i]$ is fixed to $\false$ and $a[i]$ to 0, and the long
|
time $s[j]$, then $b3[i]$ is fixed to $\mzninline{false}$ and $a[i]$ to 0, and the long
|
||||||
linear sum is awoken. But this is useless, since it cannot cause failure.
|
linear sum is awoken. But this is useless, since it cannot cause failure.
|
||||||
|
|
||||||
% Half-reification of this expression which appears in a negative context produces
|
% Half-reification of this expression which appears in a negative context produces
|
||||||
@ -1442,7 +1453,7 @@ not propagate unnecessarily.
|
|||||||
\pjs{Add linearization example here!}
|
\pjs{Add linearization example here!}
|
||||||
|
|
||||||
Half reification can cause propagators to wake up less frequently, since
|
Half reification can cause propagators to wake up less frequently, since
|
||||||
variables that are fixed to $\true$ by full reification will never be fixed by
|
variables that are fixed to $\mzninline{true}$ by full reification will never be fixed by
|
||||||
half reification. This is advantageous, but a corresponding disadvantage is that
|
half reification. This is advantageous, but a corresponding disadvantage is that
|
||||||
variables that are fixed can allow the simplification of the propagator, and
|
variables that are fixed can allow the simplification of the propagator, and
|
||||||
hence make its propagation faster. We can reduce this disadvantage by fully
|
hence make its propagation faster. We can reduce this disadvantage by fully
|
||||||
@ -1463,7 +1474,7 @@ rewriting used with full reification.
|
|||||||
|
|
||||||
The procedure $\halfc(b,c)$ defined below returns a set of constraints
|
The procedure $\halfc(b,c)$ defined below returns a set of constraints
|
||||||
implementing the half-reification $b \half c$. We flatten a constraint item
|
implementing the half-reification $b \half c$. We flatten a constraint item
|
||||||
$\texttt{constraint}~c$ using $\halfc(\true, c)$. The half-reification
|
$\texttt{constraint}~c$ using $\halfc(\mzninline{true}, c)$. The half-reification
|
||||||
flattening transformation uses half reification whenever it is in a positive
|
flattening transformation uses half reification whenever it is in a positive
|
||||||
context. If it encounters a constraint $c_1$ in a negative context, it negates
|
context. If it encounters a constraint $c_1$ in a negative context, it negates
|
||||||
the constraint if it is safe, thus creating a new positive context. If this is
|
the constraint if it is safe, thus creating a new positive context. If this is
|
||||||
@ -1541,8 +1552,8 @@ $\tuple{h,\rootc}$; \textbf{return} $h$
|
|||||||
\> \textbf{if} ($\fixed(c)$) $b$ := $\eval(c)$ \\
|
\> \textbf{if} ($\fixed(c)$) $b$ := $\eval(c)$ \\
|
||||||
\> \textbf{else} \\
|
\> \textbf{else} \\
|
||||||
\> \> \textbf{switch} $c$ \\
|
\> \> \textbf{switch} $c$ \\
|
||||||
%\> \> \textbf{case} \texttt{true}: $b$ := $\true$;\\
|
%\> \> \textbf{case} \texttt{true}: $b$ := $\mzninline{true}$;\\
|
||||||
%\> \> \textbf{case} \texttt{false}: $b$ := $\false$;\\
|
%\> \> \textbf{case} \texttt{false}: $b$ := $\mzninline{false}$;\\
|
||||||
\> \> \textbf{case} $b'$ (\syntax{<bvar>}): $b$ := $b'$; \\
|
\> \> \textbf{case} $b'$ (\syntax{<bvar>}): $b$ := $b'$; \\
|
||||||
\> \> \textbf{case} $t_1$ $r$ $t_2$ (\syntax{<relop>}): \\
|
\> \> \textbf{case} $t_1$ $r$ $t_2$ (\syntax{<relop>}): \\
|
||||||
\> \> \> \textbf{switch} $r$ \\
|
\> \> \> \textbf{switch} $r$ \\
|
||||||
@ -1586,7 +1597,7 @@ $S$ \cupp $\{ \new b \half (\flatc(c_1,\mix) \full
|
|||||||
%\mathit{safeelement}(v, [b_1, \ldots, b_n], b'),
|
%\mathit{safeelement}(v, [b_1, \ldots, b_n], b'),
|
||||||
%b'' \full v \in \{1,..,n\} \} $ \\
|
%b'' \full v \in \{1,..,n\} \} $ \\
|
||||||
\>\>\> \textbf{if} ($\ctxt = \rootc$)
|
\>\>\> \textbf{if} ($\ctxt = \rootc$)
|
||||||
$S$ \cupp $\{\texttt{element}(v, [b_1, \ldots, b_n], \true), \new b\}$ \\
|
$S$ \cupp $\{\texttt{element}(v, [b_1, \ldots, b_n], \mzninline{true}), \new b\}$ \\
|
||||||
\>\>\> \textbf{else}
|
\>\>\> \textbf{else}
|
||||||
$S$ \cupp $\{ \new b \half (b_{n+1} \wedge \new b'), b \half
|
$S$ \cupp $\{ \new b \half (b_{n+1} \wedge \new b'), b \half
|
||||||
\texttt{element}(v, [b_1, \ldots, b_n], b') \}$ \\
|
\texttt{element}(v, [b_1, \ldots, b_n], b') \}$ \\
|
||||||
@ -1601,7 +1612,7 @@ $S$ \cupp $\{ \new b \half (b_{n+1} \wedge \new b'), b \half
|
|||||||
\> \> \> \textbf{foreach}($j \in 1..n$) $\tuple{v_j, b_j}$ :=
|
\> \> \> \textbf{foreach}($j \in 1..n$) $\tuple{v_j, b_j}$ :=
|
||||||
$\halft(t_j,\ctxt,\iboth)$; \\
|
$\halft(t_j,\ctxt,\iboth)$; \\
|
||||||
\> \> \> \textbf{if} ($\ctxt = \rootc$)
|
\> \> \> \textbf{if} ($\ctxt = \rootc$)
|
||||||
$b$ := $\true$; $S$ \cupp $\{ p(v_1, \ldots, v_n) %, \bigwedge_{j=1}^n b_j
|
$b$ := $\mzninline{true}$; $S$ \cupp $\{ p(v_1, \ldots, v_n) %, \bigwedge_{j=1}^n b_j
|
||||||
\}$
|
\}$
|
||||||
\\
|
\\
|
||||||
\>\>\> \textbf{else} %($\ctxt = \pos$) \\ \> \> \> \>
|
\>\>\> \textbf{else} %($\ctxt = \pos$) \\ \> \> \> \>
|
||||||
@ -1626,7 +1637,7 @@ b_j\}$
|
|||||||
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}) built-in predicate: \\
|
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}) built-in predicate: \\
|
||||||
\> \> \> \textbf{if} ($\ctxt \neq \rootc$) \textbf{abort} \\
|
\> \> \> \textbf{if} ($\ctxt \neq \rootc$) \textbf{abort} \\
|
||||||
\> \> \> \textbf{foreach}($j \in 1..n$) $\tuple{v_j, \_}$ := $\flatt(t_j,\rootc)$; \\
|
\> \> \> \textbf{foreach}($j \in 1..n$) $\tuple{v_j, \_}$ := $\flatt(t_j,\rootc)$; \\
|
||||||
\>\> \> $b$ := $\true$; $S$ \cupp $\{ p(v_1, \ldots, v_n)\}$
|
\>\> \> $b$ := $\mzninline{true}$; $S$ \cupp $\{ p(v_1, \ldots, v_n)\}$
|
||||||
\\
|
\\
|
||||||
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): user-defined predicate \\
|
\>\> \textbf{case} $p$ ($t_1, \ldots, t_n$) (\syntax{<pred>}): user-defined predicate \\
|
||||||
\>\> \> \textbf{let} $p(x_1, \ldots, x_n) = c_0$ be defn of $p$ \\
|
\>\> \> \textbf{let} $p(x_1, \ldots, x_n) = c_0$ be defn of $p$ \\
|
||||||
@ -1689,8 +1700,8 @@ $\tuple{h,\rootc}$; \textbf{return} $h$\\
|
|||||||
\> \textbf{if} ($\fixed(c)$) $b$ := $\neg \eval(c)$ \\
|
\> \textbf{if} ($\fixed(c)$) $b$ := $\neg \eval(c)$ \\
|
||||||
\> \textbf{else} \\
|
\> \textbf{else} \\
|
||||||
\> \> \textbf{switch} $c$ \\
|
\> \> \textbf{switch} $c$ \\
|
||||||
%\> \> \textbf{case} \texttt{true}: $b$ := $\true$;\\
|
%\> \> \textbf{case} \texttt{true}: $b$ := $\mzninline{true}$;\\
|
||||||
%\> \> \textbf{case} \texttt{false}: $b$ := $\false$;\\
|
%\> \> \textbf{case} \texttt{false}: $b$ := $\mzninline{false}$;\\
|
||||||
\> \> \textbf{case} $b'$ (\syntax{<bvar>}): $S$ \cupp $\{\new b \half \neg b'\}$; \\
|
\> \> \textbf{case} $b'$ (\syntax{<bvar>}): $S$ \cupp $\{\new b \half \neg b'\}$; \\
|
||||||
\> \> \textbf{case} $t_1$ $r$ $t_2$ (\syntax{<relop>}): \\
|
\> \> \textbf{case} $t_1$ $r$ $t_2$ (\syntax{<relop>}): \\
|
||||||
\> \> \> \textbf{if} ($t_1$ and $t_2$ are safe) \\
|
\> \> \> \textbf{if} ($t_1$ and $t_2$ are safe) \\
|
||||||
@ -1786,7 +1797,7 @@ bounds. If the previous context was root or the context are the same we examine
|
|||||||
the bounds. If they are the same we reuse the result, otherwise we set the
|
the bounds. If they are the same we reuse the result, otherwise we set the
|
||||||
$\bnds$ to $\iboth$ and reflatten since we require both bounds (perhaps in
|
$\bnds$ to $\iboth$ and reflatten since we require both bounds (perhaps in
|
||||||
different situations). Otherwise the new context is $\rootc$ and the previous
|
different situations). Otherwise the new context is $\rootc$ and the previous
|
||||||
$\pos$, we force $b'$ to be $\true$ in $S$, and then reuse the result if the
|
$\pos$, we force $b'$ to be $\mzninline{true}$ in $S$, and then reuse the result if the
|
||||||
bounds are the same, or set $\bnds$ to $\iboth$ and reflatten. We store the
|
bounds are the same, or set $\bnds$ to $\iboth$ and reflatten. We store the
|
||||||
result found at the end of flattening, note that we only need one entry: context
|
result found at the end of flattening, note that we only need one entry: context
|
||||||
can move from $\pos$ to $\rootc$ and bounds can move from one of $\iabove$ or
|
can move from $\pos$ to $\rootc$ and bounds can move from one of $\iabove$ or
|
||||||
@ -1853,13 +1864,13 @@ xx\=xx\=xx\=xx\=xx\=xx\=xx\= \kill
|
|||||||
\> \> \> \textbf{if} ($pbnds = \bnds$) hhash[$t$] := $\tuple{h,b',\rootc,\bnds}$; \textbf{return} $\tuple{h,b'}$
|
\> \> \> \textbf{if} ($pbnds = \bnds$) hhash[$t$] := $\tuple{h,b',\rootc,\bnds}$; \textbf{return} $\tuple{h,b'}$
|
||||||
\\
|
\\
|
||||||
\> \> \> \textbf{else} $\bnds$ := $\iboth$ \\
|
\> \> \> \textbf{else} $\bnds$ := $\iboth$ \\
|
||||||
\> \textbf{if} ($\fixed(t)$) $v$ := $\eval(t)$; $b$ := $\true$ \\
|
\> \textbf{if} ($\fixed(t)$) $v$ := $\eval(t)$; $b$ := $\mzninline{true}$ \\
|
||||||
\> \textbf{else} %\\
|
\> \textbf{else} %\\
|
||||||
%% \> \> \textbf{if} ($t$ is marked \emph{total}) $\ctxt$ := $\rootc$ \\
|
%% \> \> \textbf{if} ($t$ is marked \emph{total}) $\ctxt$ := $\rootc$ \\
|
||||||
%\> \>
|
%\> \>
|
||||||
\textbf{switch} $t$ \\
|
\textbf{switch} $t$ \\
|
||||||
%\> \> \textbf{case} $i$ (\intc): $v$ := $i$; $b$ := $\true$ \\
|
%\> \> \textbf{case} $i$ (\intc): $v$ := $i$; $b$ := $\mzninline{true}$ \\
|
||||||
\> \> \textbf{case} $v'$ (\syntax{<ivar>}): $v$ := $v'$; $b$ := $\true$\\
|
\> \> \textbf{case} $v'$ (\syntax{<ivar>}): $v$ := $v'$; $b$ := $\mzninline{true}$\\
|
||||||
\> \> \textbf{case} $t_1$ $a$ $t_2$ (\syntax{<arithop>}): \\
|
\> \> \textbf{case} $t_1$ $a$ $t_2$ (\syntax{<arithop>}): \\
|
||||||
\> \> \> \textbf{switch} $a$ \\
|
\> \> \> \textbf{switch} $a$ \\
|
||||||
\> \> \> \textbf{case} $+$:
|
\> \> \> \textbf{case} $+$:
|
||||||
@ -1957,8 +1968,8 @@ $S$ \cupp $\{ \new b \half (b_1 \wedge b_2)\}$
|
|||||||
% context, negates $c_1$ and half-reifies the result if $c_1$ is safe and in a
|
% context, negates $c_1$ and half-reifies the result if $c_1$ is safe and in a
|
||||||
% negative context, and uses full flattening otherwise.
|
% negative context, and uses full flattening otherwise.
|
||||||
|
|
||||||
\begin{example}\label{ex:half}
|
\begin{example}\label{ex:hr-half}
|
||||||
Now lets consider half reifying the expression of \cref{ex:flat}.
|
Now lets consider half reifying the expression of \cref{ex:hr-flat}.
|
||||||
|
|
||||||
The result of flattening with half reification is:
|
The result of flattening with half reification is:
|
||||||
|
|
||||||
@ -2029,7 +2040,7 @@ $S$ \cupp $\{ \new b \half (b_1 \wedge b_2)\}$
|
|||||||
transformation will construct many implications of the form $b \half b'$, note
|
transformation will construct many implications of the form $b \half b'$, note
|
||||||
that the constraint $b \half b_1 \wedge \cdots \wedge b_n$ is equivalent to
|
that the constraint $b \half b_1 \wedge \cdots \wedge b_n$ is equivalent to
|
||||||
$b \half b_1, b \half b_2, \ldots, b \half b_n$. Just as in
|
$b \half b_1, b \half b_2, \ldots, b \half b_n$. Just as in
|
||||||
Example~\ref{ex:half} above we can simplify the result of half reification. For
|
\cref{ex:hr-half} above we can simplify the result of half reification. For
|
||||||
each $b'$ which appears only on the right of one constraint of the form
|
each $b'$ which appears only on the right of one constraint of the form
|
||||||
$b \half b'$ and other constraints of the form $b' \half c_i$ we remove the
|
$b \half b'$ and other constraints of the form $b' \half c_i$ we remove the
|
||||||
first constraint and replace the others by $b \half c_i$.
|
first constraint and replace the others by $b \half c_i$.
|
||||||
@ -2047,17 +2058,17 @@ To do so independent of propagation strength, we define the behaviour of the
|
|||||||
propagators of the half-reified forms in terms of the full reified propagator.
|
propagators of the half-reified forms in terms of the full reified propagator.
|
||||||
$$
|
$$
|
||||||
\begin{array}{rcll}
|
\begin{array}{rcll}
|
||||||
f_{b \half c}(D)(b) & = & D(b) \cap ( \{ \false \} \cup f_{b \full c}(D)(b)) \\
|
f_{b \half c}(D)(b) & = & D(b) \cap ( \{ \mzninline{false} \} \cup f_{b \full c}(D)(b)) \\
|
||||||
f_{b \half c}(D)(v) & = & D(v) & \texttt{if}~v \in vars(c),~\false \in D(b) \\
|
f_{b \half c}(D)(v) & = & D(v) & \texttt{if}~v \in vars(c),~\mzninline{false} \in D(b) \\
|
||||||
f_{b \half c}(D)(v) & = & f_{b \full c}(D)(v) & \texttt{if}~v \in vars(c),~\text{otherwise}
|
f_{b \half c}(D)(v) & = & f_{b \full c}(D)(v) & \texttt{if}~v \in vars(c),~\text{otherwise}
|
||||||
\end{array}
|
\end{array}
|
||||||
$$
|
$$
|
||||||
and
|
and
|
||||||
$$
|
$$
|
||||||
\begin{array}{rcll}
|
\begin{array}{rcll}
|
||||||
f_{b' \half \neg c}(D)(b') & = & D(b') & \texttt{if}~\{ \false \} \in f_{b \full c}(D)(b) \\
|
f_{b' \half \neg c}(D)(b') & = & D(b') & \texttt{if}~\{ \mzninline{false} \} \in f_{b \full c}(D)(b) \\
|
||||||
f_{b' \half \neg c}(D)(b') & = & D(b') \cap \{ \false\} & \text{otherwise}\\
|
f_{b' \half \neg c}(D)(b') & = & D(b') \cap \{ \mzninline{false}\} & \text{otherwise}\\
|
||||||
f_{b' \half \neg c}(D)(v) & = & D(v) & \texttt{if}~v \in vars(c),~\false \in D(b') \\
|
f_{b' \half \neg c}(D)(v) & = & D(v) & \texttt{if}~v \in vars(c),~\mzninline{false} \in D(b') \\
|
||||||
f_{b' \half \neg c}(D)(v) & = & f_{b \full c}(D)(v) & \texttt{if}~v \in vars(c),~\text{otherwise}
|
f_{b' \half \neg c}(D)(v) & = & f_{b \full c}(D)(v) & \texttt{if}~v \in vars(c),~\text{otherwise}
|
||||||
\end{array}
|
\end{array}
|
||||||
$$
|
$$
|
||||||
@ -2067,7 +2078,7 @@ half reified split versions of the propagator should act.
|
|||||||
In order to prove the same behaviour of the split reification versions we must
|
In order to prove the same behaviour of the split reification versions we must
|
||||||
assume that $f_{b \full c}$ is \emph{reified-consistent} which is defined as
|
assume that $f_{b \full c}$ is \emph{reified-consistent} which is defined as
|
||||||
follows: suppose $f_{b \full c}(D)(v) \neq D(v), v \not\equiv b$, then
|
follows: suppose $f_{b \full c}(D)(v) \neq D(v), v \not\equiv b$, then
|
||||||
$f_{b \full c}(D)(b) \neq \{ \false, \true\}$. That is if the propagator ever
|
$f_{b \full c}(D)(b) \neq \{ \mzninline{false}, \mzninline{true}\}$. That is if the propagator ever
|
||||||
reduces the domain of some variable, then it must also fix the Boolean variable
|
reduces the domain of some variable, then it must also fix the Boolean variable
|
||||||
$b$. This is sensible since if $b$ is not fixed then every possible value of $v$
|
$b$. This is sensible since if $b$ is not fixed then every possible value of $v$
|
||||||
is consistent with constraint $b \full c$ regardless of the domain $D$. This is
|
is consistent with constraint $b \full c$ regardless of the domain $D$. This is
|
||||||
@ -2105,14 +2116,14 @@ the usual case for such a trivial propagator.
|
|||||||
% $D'' = \solv(\{ f_{b \half c}, f_{b' \half \neg c}, f_{b' \full \neg b}\}, D)$.
|
% $D'' = \solv(\{ f_{b \half c}, f_{b' \half \neg c}, f_{b' \full \neg b}\}, D)$.
|
||||||
% The proof is by cases of $D$.
|
% The proof is by cases of $D$.
|
||||||
|
|
||||||
% \textbf{(a)} Suppose $D(b) = \{\true,\false\}$. \textbf{(a-i)} Suppose
|
% \textbf{(a)} Suppose $D(b) = \{\mzninline{true},\mzninline{false}\}$. \textbf{(a-i)} Suppose
|
||||||
% $f_{b \full c}(D) = D$. Then clearly $f_{b \half c}(D) = D$ by definition, and
|
% $f_{b \full c}(D) = D$. Then clearly $f_{b \half c}(D) = D$ by definition, and
|
||||||
% similarly $f_{b' \half \neg c}(D) = D$. Hence $D_1 = D_2 = D$. Note that since
|
% similarly $f_{b' \half \neg c}(D) = D$. Hence $D_1 = D_2 = D$. Note that since
|
||||||
% $f_{b \full c}$ is reified consistent, then $f_{b \full c}(D) \neq D$ implies
|
% $f_{b \full c}$ is reified consistent, then $f_{b \full c}(D) \neq D$ implies
|
||||||
% that $f_{b \full c}(D)(b) \neq \{ \false, \true \}$. \textbf{(a-ii)} Suppose
|
% that $f_{b \full c}(D)(b) \neq \{ \mzninline{false}, \mzninline{true} \}$. \textbf{(a-ii)} Suppose
|
||||||
% $f_{b \full c}(D)(b) = \{ \true \}$. Let $D_1 = f_{b' \half \neg c}(D)$, then
|
% $f_{b \full c}(D)(b) = \{ \mzninline{true} \}$. Let $D_1 = f_{b' \half \neg c}(D)$, then
|
||||||
% $D_1(b') = \{ \false \}$ by definition and $D_1(v) = D(v), v \not\equiv b'$.
|
% $D_1(b') = \{ \mzninline{false} \}$ by definition and $D_1(v) = D(v), v \not\equiv b'$.
|
||||||
% Let $D_2 = f_{b' \full \neg b}(D_1)$ then $D_2(b)= \{ \true \}$ and
|
% Let $D_2 = f_{b' \full \neg b}(D_1)$ then $D_2(b)= \{ \mzninline{true} \}$ and
|
||||||
% $D_2(v) = D(v), v \not\in \{b,b'\}$. Then
|
% $D_2(v) = D(v), v \not\in \{b,b'\}$. Then
|
||||||
% $D_3 = f_{b \half c}(D_2) = f_{b \full c}(D_2)$ by definition, and by
|
% $D_3 = f_{b \half c}(D_2) = f_{b \full c}(D_2)$ by definition, and by
|
||||||
% idempotence of $f_{b \full c}$ and since $D_2$ and $D$ differ only on $b$ and
|
% idempotence of $f_{b \full c}$ and since $D_2$ and $D$ differ only on $b$ and
|
||||||
@ -2121,9 +2132,9 @@ the usual case for such a trivial propagator.
|
|||||||
% $f_{b \half c}$, $f_{b' \full \neg b}$ and $f_{b' \half \neg c}$ and hence
|
% $f_{b \half c}$, $f_{b' \full \neg b}$ and $f_{b' \half \neg c}$ and hence
|
||||||
% $D'' = D_3$. But also $D' = f_{b' \full \neg b}(f_{b \full c}(D)) = D_3$ since
|
% $D'' = D_3$. But also $D' = f_{b' \full \neg b}(f_{b \full c}(D)) = D_3$ since
|
||||||
% $D_3$ and $f_{b \full c}(D)$ only differ on $b'$. \textbf{(a-iii)} Suppose
|
% $D_3$ and $f_{b \full c}(D)$ only differ on $b'$. \textbf{(a-iii)} Suppose
|
||||||
% $f_{b \full c}(D)(b) = \{ \false \}$. Let $D_1 = f_{b \half c}(D)$, then
|
% $f_{b \full c}(D)(b) = \{ \mzninline{false} \}$. Let $D_1 = f_{b \half c}(D)$, then
|
||||||
% $D_1(b) = \{ \false \}$ by definition and $D_1(v) = D(v), v \not\equiv b$. Let
|
% $D_1(b) = \{ \mzninline{false} \}$ by definition and $D_1(v) = D(v), v \not\equiv b$. Let
|
||||||
% $D_2 = f_{b' \full \neg b}(D_1)$ then $D_2(b')= \{ \true \}$ and
|
% $D_2 = f_{b' \full \neg b}(D_1)$ then $D_2(b')= \{ \mzninline{true} \}$ and
|
||||||
% $D_2(v) = D(v), v \not\in \{b,b'\}$. Then
|
% $D_2(v) = D(v), v \not\in \{b,b'\}$. Then
|
||||||
% $D_3 = f_{b' \half \neg c}(D_2) = f_{b \full c}(D_2)$ by definition, and by
|
% $D_3 = f_{b' \half \neg c}(D_2) = f_{b \full c}(D_2)$ by definition, and by
|
||||||
% idempotence of $f_{b \full c}$ and since $D_2$ and $D$ differ only on $b$ and
|
% idempotence of $f_{b \full c}$ and since $D_2$ and $D$ differ only on $b$ and
|
||||||
@ -2132,10 +2143,10 @@ the usual case for such a trivial propagator.
|
|||||||
% $D' = f_{b' \full \neg b}(f_{b \full c}(D)) = D_3$ since $D_3$ and
|
% $D' = f_{b' \full \neg b}(f_{b \full c}(D)) = D_3$ since $D_3$ and
|
||||||
% $f_{b \full c}(D)$ only differ on $b'$.
|
% $f_{b \full c}(D)$ only differ on $b'$.
|
||||||
|
|
||||||
% \textbf{(b)} If $D(b) = \{\true\}$ then clearly $f_{b \full c}$ and
|
% \textbf{(b)} If $D(b) = \{\mzninline{true}\}$ then clearly $f_{b \full c}$ and
|
||||||
% $f_{b \half c}$ act identically on variables in $vars(c)$.
|
% $f_{b \half c}$ act identically on variables in $vars(c)$.
|
||||||
|
|
||||||
% \textbf{(c)} If $D(b) = \{\false\}$ then $D(b') = \{\true\}$ and clearly
|
% \textbf{(c)} If $D(b) = \{\mzninline{false}\}$ then $D(b') = \{\mzninline{true}\}$ and clearly
|
||||||
% $f_{b \full c}$ and $f_{b' \half \neg c}$ act identically on variables in
|
% $f_{b \full c}$ and $f_{b' \half \neg c}$ act identically on variables in
|
||||||
% $vars(c)$. \qed
|
% $vars(c)$. \qed
|
||||||
% \end{proof}
|
% \end{proof}
|
||||||
@ -2181,7 +2192,7 @@ still fixed at the same time, but there is less overhead.
|
|||||||
|
|
||||||
Implementing half-reification within the \minizinc\ distribution consists of two
|
Implementing half-reification within the \minizinc\ distribution consists of two
|
||||||
parts: the \minizinc\ compiler needs to be extended with an implementation of
|
parts: the \minizinc\ compiler needs to be extended with an implementation of
|
||||||
the half-reification flattening algorithm as described in \cref{sec:halfreif}
|
the half-reification flattening algorithm as described in \cref{sec:hr-halfreif}
|
||||||
and for any target solver that supports half-reification its library needs to be
|
and for any target solver that supports half-reification its library needs to be
|
||||||
appended with definitions for the predicates that are half-reified. Because the
|
appended with definitions for the predicates that are half-reified. Because the
|
||||||
\minizinc\ language allows for the definition of new predicates, we allow any
|
\minizinc\ language allows for the definition of new predicates, we allow any
|
||||||
@ -2220,35 +2231,34 @@ has propagators for half-reified constraints we have declared the corresponding
|
|||||||
predicates as solver builtins. Gecode provides half-reified propagators for
|
predicates as solver builtins. Gecode provides half-reified propagators for
|
||||||
almost all \flatzinc\ builtins. The other targeted solvers use the linear
|
almost all \flatzinc\ builtins. The other targeted solvers use the linear
|
||||||
library. The linear library \jip{,as seen before + reference???,} already has
|
library. The linear library \jip{,as seen before + reference???,} already has
|
||||||
redefinition for their fully reified predicates, \(b \full c\). These generally
|
redefinition for their fully reified predicates, \mzninline{b <-> c}. These
|
||||||
consist of two parts which are equivalent to the implications
|
generally consist of two parts which are equivalent to the implications
|
||||||
\(b \half c \land \lnot b \half \lnot c \). Because of this, the implementations
|
\mzninline{b -> c /\ not b -> not c}. Because of this, the implementations of
|
||||||
of the half-reified version of the same predicates usually consist of using only
|
the half-reified version of the same predicates usually consist of using only
|
||||||
one of these two parts, which will eliminate the need of many constraints. We
|
one of these two parts, which will eliminate the need of many constraints. We
|
||||||
added half-reified versions for all predicates for which a full reification was
|
added half-reified versions for all predicates for which a full reification was
|
||||||
provided.
|
provided.
|
||||||
|
|
||||||
\subsection{Implication Chain Compression}
|
\subsection{Implication Chain Compression}
|
||||||
|
|
||||||
As shown in \cref{ex:half}, flattening with half reification will in many cases
|
As shown in \cref{ex:hr-half}, flattening with half reification will in many
|
||||||
result in implication chains: \((b \half b') \land (b' \half c)\), where \(b'\)
|
cases result in implication chains: \mzninline{b1 -> b2 /\ b2 -> c}, where
|
||||||
has no other occurrences. In this case the conjunction can be replaced by
|
\texttt{b2} has no other occurrences. In this case the conjunction can be
|
||||||
\(b \half c\) and \(b'\) can be removed from the model. The case shown in the
|
replaced by \mzninline{b1 -> c} and \texttt{b2} can be removed from the model.
|
||||||
example can be generalised to
|
The case shown in the example can be generalised to \mzninline{b1 -> b2 /\
|
||||||
\((b \half b') \land \left(\forall_{i \in N} b' \half c_i \right)\), which, if
|
forall(i in N)(b2 -> c[i])}, which, if \texttt{b2} has no other usage in the
|
||||||
\(b'\) has no other usage in the instance, can be resolved to
|
instance, can be resolved to \mzninline{forall(i in N)(b1 -> c[i])} after which
|
||||||
\(\forall_{i \in N} b \half c_i\) after which \(b'\) can be removed from the
|
\texttt{b1} can be removed from the model.
|
||||||
model.
|
|
||||||
|
|
||||||
An algorithm to remove these chains of implications is best visualised through
|
An algorithm to remove these chains of implications is best visualised through
|
||||||
the use of an implication graph. An implication graph \(\tuple{V,E}\) is a
|
the use of an implication graph. An implication graph \(\tuple{V,E}\) is a
|
||||||
directed graph where the vertices \(V\) represent the variables in the instance
|
directed graph where the vertices \(V\) represent the variables in the instance
|
||||||
and an edge \(\tuple{x,y} \in E\) represents the presence of an implication
|
and an edge \(\tuple{x,y} \in E\) represents the presence of an implication
|
||||||
\(x \half y\) in the instance. Additionally, for the benefit of the algorithm, a
|
\mzninline{x -> y} in the instance. Additionally, for the benefit of the
|
||||||
vertex is marked when it is used in other constraints in the constraint model.
|
algorithm, a vertex is marked when it is used in other constraints in the
|
||||||
The goal of the algorithm is now to identify and remove vertices that are not
|
constraint model. The goal of the algorithm is now to identify and remove
|
||||||
marked and have only one incoming edge. The following pseudo code provides a
|
vertices that are not marked and have only one incoming edge. The following
|
||||||
formal specification for this algorithm.
|
pseudo code provides a formal specification for this algorithm.
|
||||||
|
|
||||||
\newcommand{\setminusp}{\ensuremath{\setminus}\text{:=}~}
|
\newcommand{\setminusp}{\ensuremath{\setminus}\text{:=}~}
|
||||||
\begin{tabbing}
|
\begin{tabbing}
|
||||||
@ -2266,12 +2276,12 @@ formal specification for this algorithm.
|
|||||||
\jip{Here we could actually show an example using a drawn graph}
|
\jip{Here we could actually show an example using a drawn graph}
|
||||||
|
|
||||||
The algorithm can be further improved by considering implied conjunctions. These
|
The algorithm can be further improved by considering implied conjunctions. These
|
||||||
can be split up into multiple implications: \(b' \half \forall_{i \in N} b_i\)
|
can be split up into multiple implications: \mzninline{b -> forall(i in
|
||||||
is equivalent to \(\forall_{i \in N} (b' \half b_i)\). This transformation both
|
N)(bs[i])} is equivalent to \mzninline{forall(i in N)(b -> bs[i])}. This
|
||||||
simplifies a complicated constraint and possibly allows for the further
|
transformation both simplifies a complicated constraint and possibly allows for
|
||||||
compression of implication chains. It should however be noted that although this
|
the further compression of implication chains. It should however be noted that
|
||||||
transformation can result in an increase in the number of constraints, it
|
although this transformation can result in an increase in the number of
|
||||||
generally increases the propagation efficiency.
|
constraints, it generally increases the propagation efficiency.
|
||||||
|
|
||||||
To adjust the algorithm to simplify implied conjunctions more introspection from
|
To adjust the algorithm to simplify implied conjunctions more introspection from
|
||||||
the \minizinc\ compiler is required. The compiler must be able to tell if a
|
the \minizinc\ compiler is required. The compiler must be able to tell if a
|
||||||
@ -2289,8 +2299,8 @@ available \jip{Insert new link} has our experimental \minizinc\ instances and
|
|||||||
the infrastructure that performs the benchmarks.
|
the infrastructure that performs the benchmarks.
|
||||||
|
|
||||||
The first experiment considers ``QCP-max'' problems which are defined as
|
The first experiment considers ``QCP-max'' problems which are defined as
|
||||||
quasi-group completion problems where the \alldiff constraints are soft, and the
|
quasi-group completion problems where the \mzninline{all_different} constraints
|
||||||
aim is to satisfy as many of them as possible.
|
are soft, and the aim is to satisfy as many of them as possible.
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
int: n; % size
|
int: n; % size
|
||||||
@ -2308,20 +2318,21 @@ predicate all_different(array[int] of var int: x) =
|
|||||||
forall(i,j in index_set(x) where i < j)(x[i] != x[j]);
|
forall(i,j in index_set(x) where i < j)(x[i] != x[j]);
|
||||||
\end{mzn}
|
\end{mzn}
|
||||||
|
|
||||||
Note that this is not the same as requiring the maximum number of
|
Note that this is not the same as requiring the maximum number of disequality
|
||||||
disequality constraints to be satisfied. The \alldiff constraints, while
|
constraints to be satisfied. The \mzninline{all_different} constraints, while
|
||||||
apparently in a mixed context, are actually in a positive context, since the
|
apparently in a mixed context, are actually in a positive context, since the
|
||||||
maximization in fact is implemented by inequalities forcing at least some number
|
maximisation in fact is implemented by inequalities forcing at least some number
|
||||||
to be true.
|
to be true.
|
||||||
|
|
||||||
In Table~\ref{tab:qcp} we compare three different resulting programs on QCP-max
|
In \cref{tab:hr-qcp} we compare three different resulting programs on QCP-max
|
||||||
problems: full reification of the model above, using the \alldiff decomposition
|
problems: full reification of the model above, using the
|
||||||
defined by the predicate shown (\textsf{full}), half reification of the model
|
\mzninline{all_different} decomposition defined by the predicate shown
|
||||||
using the \alldiff decomposition (\textsf{half}), and half reification using a
|
(\textsf{full}), half reification of the model using the
|
||||||
half-reified global \alldiff (\textsf{half-g}) implementing arc consistency
|
\mzninline{all_different} decomposition (\textsf{half}), and half reification
|
||||||
(thus having the same propagation strength as the decomposition). \jip{is this
|
using a half-reified global \mzninline{all_different} (\textsf{half-g})
|
||||||
still correct??} We use standard QCP examples from the literature, and group
|
implementing arc consistency (thus having the same propagation strength as the
|
||||||
them by size.
|
decomposition). \jip{is this still correct??} We use standard QCP examples from
|
||||||
|
the literature, and group them by size.
|
||||||
% and whether they are satisfiable or unsatisfiable as QCP problems.
|
% and whether they are satisfiable or unsatisfiable as QCP problems.
|
||||||
We compare both a standard finite domain solver (FD) and a learning lazy clause
|
We compare both a standard finite domain solver (FD) and a learning lazy clause
|
||||||
generation solver (FD + Explanations). We use the same fixed search strategy of
|
generation solver (FD + Explanations). We use the same fixed search strategy of
|
||||||
@ -2329,7 +2340,7 @@ labeling the matrix in order left-to-right from highest to lowest value for all
|
|||||||
approaches to minimize differences in search.
|
approaches to minimize differences in search.
|
||||||
|
|
||||||
\begin{table} [tb] \begin{center}
|
\begin{table} [tb] \begin{center}
|
||||||
\caption{\label{tab:qcp} QCP-max problems:
|
\caption{\label{tab:hr-qcp} QCP-max problems:
|
||||||
Average time (in seconds), number of solved instances (300s timeout).}
|
Average time (in seconds), number of solved instances (300s timeout).}
|
||||||
\begin{tabular}{|l||rr|rr|rr|}
|
\begin{tabular}{|l||rr|rr|rr|}
|
||||||
\hline
|
\hline
|
||||||
@ -2359,7 +2370,7 @@ The second experiment shows how half reification can reduce the overhead of
|
|||||||
handling partial functions correctly. Consider the following model for
|
handling partial functions correctly. Consider the following model for
|
||||||
determining a prize collecting path, a simplified form of prize collecting
|
determining a prize collecting path, a simplified form of prize collecting
|
||||||
travelling salesman problem
|
travelling salesman problem
|
||||||
\autocite{balas-1989-pctsp}, %shown in Figure~\ref{fig:pct}
|
\autocite{balas-1989-pctsp}, %shown in \cref{fig:hr-pct}
|
||||||
where the aim is define an acyclic path from node 1 along weighted edges to
|
where the aim is define an acyclic path from node 1 along weighted edges to
|
||||||
collect the most weight. Not every node needs to be visited ($pos[i] = 0$).
|
collect the most weight. Not every node needs to be visited ($pos[i] = 0$).
|
||||||
|
|
||||||
@ -2382,12 +2393,12 @@ constraint alldifferent_except_0(next) /\ pos[1] = 1;
|
|||||||
solve minimize sum(i in 1..n)(prize[i]);
|
solve minimize sum(i in 1..n)(prize[i]);
|
||||||
\end{mzn}
|
\end{mzn}
|
||||||
|
|
||||||
It uses the global constraint \texttt{alldifferent\_except\_0} which constrains
|
It uses the global constraint \mzninline{alldifferent_except_0} which constrains
|
||||||
each element in the $next$ array to be different or equal 0. The model has one
|
each element in the \mzninline{next} array to be different or equal 0. The model
|
||||||
unsafe array lookup $pos[next[i]]$. We compare using full reification
|
has one unsafe array lookup \mzninline{pos[next[i]]}. We compare using full
|
||||||
(\textsf{full}) and half reification (\textsf{half}) to model this problem. Note
|
reification (\textsf{full}) and half reification (\textsf{half}) to model this
|
||||||
that if we extend the $pos$ array to have domain $0..n$ then the model becomes
|
problem. Note that if we extend the $pos$ array to have domain $0..n$ then the
|
||||||
safe, by replacing its definition with the following two lines
|
model becomes safe, by replacing its definition with the following two lines
|
||||||
|
|
||||||
\begin{mzn}
|
\begin{mzn}
|
||||||
array[0..n] of var 0..n: pos; % posn on node i in path, 0=notin
|
array[0..n] of var 0..n: pos; % posn on node i in path, 0=notin
|
||||||
@ -2397,18 +2408,18 @@ safe, by replacing its definition with the following two lines
|
|||||||
We also compare against this model (\textsf{extended}).
|
We also compare against this model (\textsf{extended}).
|
||||||
|
|
||||||
We use graphs with both positive and negative weights for the tests. The search
|
We use graphs with both positive and negative weights for the tests. The search
|
||||||
strategy fixes the $next$ variables in order of their maximum value. First we
|
strategy fixes the \mzninline{next} variables in order of their maximum value.
|
||||||
note that \textsf{extended} is slightly better than \textsf{full} because of the
|
First we note that \textsf{extended} is slightly better than \textsf{full}
|
||||||
simpler translation, while \textsf{half} is substantially better than
|
because of the simpler translation, while \textsf{half} is substantially better
|
||||||
\textsf{extended} since most of the half reified \texttt{element} constraints
|
than \textsf{extended} since most of the half reified \texttt{element}
|
||||||
become redundant. Learning increases the advantage because the half reified
|
constraints become redundant. Learning increases the advantage because the half
|
||||||
formulation focusses on propagation which leads to failure which creates more
|
reified formulation focuses on propagation which leads to failure which creates
|
||||||
reusable nogoods.
|
more reusable nogoods.
|
||||||
|
|
||||||
\begin{table} [tb] \begin{center}
|
\begin{table} [tb] \begin{center}
|
||||||
\caption{\label{tab:pctsp} Prize collecting paths:
|
\caption{\label{tab:hr-pctsp} Prize collecting paths: Average time (in seconds)
|
||||||
Average time (in seconds) and number of solved
|
and number of solved instances with a 300s timeout for various number of
|
||||||
instances with a 300s timeout for various number of nodes.}
|
nodes.}
|
||||||
\begin{tabular}{|l||rr|rr|rr||rr|rr|rr|}
|
\begin{tabular}{|l||rr|rr|rr||rr|rr|rr|}
|
||||||
\hline
|
\hline
|
||||||
& \multicolumn{6}{|c||}{FD} & \multicolumn{6}{|c|}{FD + Explanations} \\
|
& \multicolumn{6}{|c||}{FD} & \multicolumn{6}{|c|}{FD + Explanations} \\
|
||||||
@ -2457,11 +2468,11 @@ Nodes &
|
|||||||
|
|
||||||
In the final experiment we compare resource constrained project scheduling
|
In the final experiment we compare resource constrained project scheduling
|
||||||
problems (RCPSP) where the \texttt{cumulative} constraint is defined by the task
|
problems (RCPSP) where the \texttt{cumulative} constraint is defined by the task
|
||||||
decomposition as in \cref{ex:cumul} above, using both full reification and
|
decomposition as in \cref{ex:hr-cumul} above, using both full reification and
|
||||||
half-reification. We use standard benchmark examples from PSPlib
|
half-reification. We use standard benchmark examples from PSPlib
|
||||||
\autocite{kolisch-1997-psplib}. \Cref{tab:rcpsp} compares RCPSP instances using
|
\autocite{kolisch-1997-psplib}. \Cref{tab:hr-rcpsp} compares RCPSP instances
|
||||||
\textsf{full} reification and \textsf{half} reification. We compare using J30
|
using \textsf{full} reification and \textsf{half} reification. We compare using
|
||||||
instances (\textsf{J30} ) and instances due to Baptiste and Le Pape
|
J30 instances (\textsf{J30} ) and instances due to Baptiste and Le Pape
|
||||||
(\textsf{BL}). Each line in the table shows the average run time and number of
|
(\textsf{BL}). Each line in the table shows the average run time and number of
|
||||||
solved instances. The search strategy tries to schedule the task with the
|
solved instances. The search strategy tries to schedule the task with the
|
||||||
earliest possible start time. We find a small and uniform speedup for
|
earliest possible start time. We find a small and uniform speedup for
|
||||||
@ -2469,7 +2480,7 @@ earliest possible start time. We find a small and uniform speedup for
|
|||||||
learning, again because learning is not confused by propagations that do not
|
learning, again because learning is not confused by propagations that do not
|
||||||
lead to failure.
|
lead to failure.
|
||||||
|
|
||||||
\begin{table} [tb] \caption{\label{tab:rcpsp} RCPSP:
|
\begin{table} [tb] \caption{\label{tab:hr-rcpsp} RCPSP:
|
||||||
Average time (in seconds) and number of solved instances with a 300s timeout.}
|
Average time (in seconds) and number of solved instances with a 300s timeout.}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|l||rr|rr||rr|rr|}
|
\begin{tabular}{|l||rr|rr||rr|rr|}
|
||||||
@ -2494,15 +2505,13 @@ To verify the effectiveness of the half reification implementation within the
|
|||||||
\minizinc{} translator (rev. \jip{add revision}) against the equivalent version
|
\minizinc{} translator (rev. \jip{add revision}) against the equivalent version
|
||||||
for which we have implemented half reification. We use the model instances used
|
for which we have implemented half reification. We use the model instances used
|
||||||
by the \minizinc{} challenges
|
by the \minizinc{} challenges
|
||||||
\autocite{stuckey-2010-challenge,stuckey-2014-challenge} from 2012 until 2017.
|
\autocite{stuckey-2010-challenge,stuckey-2014-challenge} from 2019 and 2020. The
|
||||||
Note that the instances that the instances without any reifications have been
|
|
||||||
excluded from the experiment as they would not experience any change. The
|
|
||||||
performance of the generated \flatzinc{} models will be tested using Gecode,
|
performance of the generated \flatzinc{} models will be tested using Gecode,
|
||||||
flattened with its own library, and Gurobi and CBC, flattened with the linear
|
flattened with its own library, and Gurobi and CBC, flattened with the linear
|
||||||
library.
|
library.
|
||||||
|
|
||||||
\begin{table} [tb]
|
\begin{table} [tb]
|
||||||
\caption{\label{tab:flat_results} Flattening results: Average changes in the
|
\caption{\label{tab:hr-flat-results} Flattening results: Average changes in the
|
||||||
generated the \flatzinc{} models}
|
generated the \flatzinc{} models}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tabular}{|l|r||r|r|r||r|}
|
\begin{tabular}{|l|r||r|r|r||r|}
|
||||||
@ -2517,9 +2526,9 @@ library.
|
|||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
\end{table}
|
\end{table}
|
||||||
\jip{Better headers for \cref{tab:flat_results} and update with current results}
|
\jip{Better headers for \cref{tab:hr-flat-results} and update with current results}
|
||||||
|
|
||||||
\Cref{tab:flat_results} shows the average change on the number of full
|
\Cref{tab:hr-flat-results} shows the average change on the number of full
|
||||||
reification, constraints, and variables between the \flatzinc\ models generated
|
reification, constraints, and variables between the \flatzinc\ models generated
|
||||||
by the different versions of the translator using the different libraries. We
|
by the different versions of the translator using the different libraries. We
|
||||||
find that the number full reifications is reduced by a significant amount.
|
find that the number full reifications is reduced by a significant amount.
|
||||||
@ -2535,8 +2544,7 @@ of memory running the Ubuntu 16.04.3 LTS operating system.
|
|||||||
\jip{Scatter plot of the runtimes + discussion!}
|
\jip{Scatter plot of the runtimes + discussion!}
|
||||||
|
|
||||||
%=============================================================================%
|
%=============================================================================%
|
||||||
\section{Related Work and Conclusion}
|
\section{Related Work and Conclusion}\label{sec:hr-conclusion}
|
||||||
\label{conclusion}
|
|
||||||
%=============================================================================%
|
%=============================================================================%
|
||||||
|
|
||||||
Half reification on purely Boolean constraints is well understood, this is the
|
Half reification on purely Boolean constraints is well understood, this is the
|
||||||
@ -2546,33 +2554,28 @@ clausal representation of the circuit (see \eg\
|
|||||||
total) and the calculation of polarity for Booleans terms inside
|
total) and the calculation of polarity for Booleans terms inside
|
||||||
\texttt{bool2int} do not arise in pure Boolean constraints.
|
\texttt{bool2int} do not arise in pure Boolean constraints.
|
||||||
|
|
||||||
Half reified constraints have been used in constraint modeling but are typically
|
Half reified constraints have been used in constraint modelling but are
|
||||||
not visible as primitive constraints to users, or produced through flattening.
|
typically not visible as primitive constraints to users, or produced through
|
||||||
Indexicals \autocite{van-hentenryck-1992-indexicals} can be used to implement
|
flattening. Indexicals \autocite{van-hentenryck-1992-indexicals} can be used to
|
||||||
reified constraints by specifying how to propagate a constraint
|
implement reified constraints by specifying how to propagate a constraint,
|
||||||
$c$, %($prop(c)$),
|
propagate its negation, check disentailment, and check entailment, and this is
|
||||||
propagate its negation,
|
implemented in SICstus Prolog \autocite{carlsson-1997-sicstus}. A half reified
|
||||||
%$prop(\neg c)$,
|
propagator simply omits entailment and propagating the negation.
|
||||||
check disentailment, % $check(c)$,
|
|
||||||
and check entailment, %$check(\neg c)$,
|
|
||||||
and this is implemented in SICstus Prolog \autocite{carlsson-1997-sicstus}. A
|
|
||||||
half reified propagator simply omits entailment and propagating the negation.
|
|
||||||
% $prop(\neg c)$ and $check(\neg c)$. Half reification was briefly discussed in
|
|
||||||
% our earlier work \autocite{cp2009d}, in terms of its ability to reduce
|
|
||||||
% propagation.
|
|
||||||
Half reified constraints appear in some constraint systems, for example SCIP
|
Half reified constraints appear in some constraint systems, for example SCIP
|
||||||
\autocite{gamrath-2020-scip} supports half-reified real linear constraints of
|
\autocite{gamrath-2020-scip} supports half-reified real linear constraints of
|
||||||
the form $b \half \sum_i a_i x_i \leq a_0$ exactly because the negation of the
|
the form \mzninline{b -> sum(i in N)(a[i] * x[i]) <= C} exactly because the
|
||||||
linear constraint $\sum_i a_i x_i > a_0$ is not representable in an LP solver so
|
negation of the linear constraint \mzninline{sum(i in N)(a[i] * x[i]) > C} is
|
||||||
full reification is not possible.
|
not representable in an LP solver so full reification is not possible.
|
||||||
|
|
||||||
While flattening is the standard approach to handle complex formula involving
|
While flattening is the standard approach to handle complex formula involving
|
||||||
constraints, there are a number of other approaches which propagate more
|
constraints, there are a number of other approaches which propagate more
|
||||||
strongly. Schulte proposes a generic implementation of $b \full c$ propagating
|
strongly. Schulte proposes a generic implementation of \mzninline{b <-> c}
|
||||||
(the flattened form of) $c$ in a separate constraint space which does not affect
|
propagating (the flattened form of) \mzninline{c} in a separate constraint space
|
||||||
the original variables \autocite*{schulte-2000-deep}; entailment and
|
which does not affect the original variables \autocite*{schulte-2000-deep};
|
||||||
disentailment of $c$ fix the $b$ variable appropriately, although when $b$ is
|
entailment and disentailment of \mzninline{c} fix the \mzninline{b} variable
|
||||||
made $\false$ the implementation does not propagate $\neg c$. This can also be
|
appropriately, although when \mzninline{b} is made \mzninline{false} the
|
||||||
|
implementation does not propagate \mzninline{not c}. This can also be
|
||||||
implemented using propagator groups \autocite{lagerkvist-2009-groups}. Brand and
|
implemented using propagator groups \autocite{lagerkvist-2009-groups}. Brand and
|
||||||
Yap define an approach to propagating complex constraint formulae called
|
Yap define an approach to propagating complex constraint formulae called
|
||||||
controlled propagation which ensures that propagators that cannot affect the
|
controlled propagation which ensures that propagators that cannot affect the
|
||||||
|
Reference in New Issue
Block a user