This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
dekker-phd-thesis/chapters/2_background.tex

181 lines
8.0 KiB
TeX

%************************************************
\chapter{Review of Literature}\label{ch:background}
%************************************************
A goal shared between all programming languages is to provide a certain level of
abstraction: an assembly language allows you to abstract from the binary
instructions and memory positions; Low-level imperial languages, like FORTRAN,
were the first to allow you to abstract from the processor architecture of the
target machine; and nowadays writing a program requires little knowledge of the
actual workings of the hardware.
Freuder states that the ``Holy Grail'' of programming languages would be where
the user merely states the problem, and the computer solves it and that
\gls{constraint-modelling} is one of the biggest steps towards this goal to this
day \autocite*{freuder-1997-holygrail}. Different from imperative (and even
other declarative) languages, in a \cml\ the modeller does not describe how to
solve the problem, but rather provides the problem requirements. You could say
that a constraint model actually describes the solution to the problem.
In a constraint model, instead of specifying the manner in which we can find the
solution, we give a concise description of the problem. We describe what we
already know, the \glspl{parameter}, what we wish to know, the \glspl{variable},
and the relationships that should exists between them, the \glspl{constraint}.
This type of combinatorial problem is typically called a \gls{csp}. Many \cmls
also support the modelling of \gls{cop}, where a \gls{csp} is augmented with an
\gls{objective} \(z\). In this case the goal is to find an solution that
satisfies all \glspl{constraint} while minimising (or maximising) \(z\).
Although a constraint model does not contain any instructions to find a suitable
solution, dedicated solving programs exist
these models can generally be given to a dedicated solving program, or
\gls{solver} for short, that can find a solution that fits the requirements of
the model.
\begin{listing}
\pyfile{assets/py/2_dyn_knapsack.py}
\caption{\label{lst:2-dyn-knapsack} A Python program that solves a 0-1 knapsack
problem using dynamic programming}
\end{listing}
\begin{example}
Let us consider the following scenario: Packing for a weekend trip, I have to
decide which toys to bring for my dog, Audrey. We only have a small amount of
space left in the car, so we cannot bring all the toys. Since Audrey gets
enjoys playing with some toys more than others, we can now try and pick the
toys that bring Audrey the most amount of joy, but still fit in the car.
One way to solve this problem is to try all combinations of toys, but this is
a time intensive task that quickly grows with the number of toys considered
(which one would quickly realise trying to pack a car \(2^{|\text{toys}|}\)
different ways).
An educated reader in optimisation problems might recognise that this is a
variation on the widely known \gls{knapsack}, more specifically a \textit{0-1
knapsack problem} \autocite[13--67]{silvano-1990-knapsack}. A commonly used
solution to this problem is based on dynamic programming. An implementation of
this approach is shown in \cref{lst:2-dyn-knapsack}. The use of dynamic
programming avoid the exponential growth of the problem when increasing the
number of toys.
Although expert knowledge can sometimes bring you an efficient solution to a
known problem, it should be noted that not all problems will easily map to
well known (and studied) problems. Even when part of a problem finds an
equivalent in a well studied problem, the overall problem might still contain
requirements that impair you from using known algorithms to solve the problem.
For example, if wanted to bring toys with different colours, then the
algorithm in \cref{lst:2-dyn-knapsack} would have to be drastically changed.
\Gls{constraint-modelling} can offer a more flexible alternative that requires
less expert knowledge.
The following set of equations describe this knapsack problem as a \gls{cop}:
\begin{equation}
\text{maximise} z \text{subject to}
\begin{cases}
S \subset toys
z = \sum_{i \in S} joy(i) \\
\sum_{i \in S} space(i) < C
\end{cases}
\end{equation}
In these equations \(S\) is set \gls{variable}. It contains the selection of
toys that will be packed for the trip. The \(joy\) and \(space\) functions are
\glspl{parameter} used to map toys to a value depicting the amount of
enjoyment and space required respectively. \(C\) is the \gls{parameter} that
depicts the total space that is left in the car before packing the toys.
Finally, \(z\) is the objective \gls{variable} that is maximised to find the
optimal selections of toys to pack.
This constraint model gives a concise definition of the problem that would be
easy to adjust to changes in the requirements.
\end{example}
In the remainder of this chapter we will first, in \cref{sec:back-minizinc}
introduce \minizinc\ as the leading \cml\ used within this thesis.
\cref{sec:back-mzn-interpreter} explains the process that the current \minizinc\
interpreter uses to translate a \minizinc\ model into a solver-level constraint
model. Then, \cref{sec:back-other-languages} introduces alternative \cmls\ and
compares their functionality to \minizinc{}. Finally, \cref{sec:back-term} and
\cref{sec:back} survey the closely related fields of
\section{\glsentrytext{minizinc}}%
\label{sec:back-minizinc}
\minizinc\ is a high-level, solver- and data-independent modelling language for
discrete satisfiability and optimisation problems
\autocite{nethercote-2007-minizinc}. Its expressive language and extensive
library of constraints allow users to easily model complex problems.
Let us introduce the language by modelling the well-known \emph{Latin squares}
problem \autocite{wallis-2011-combinatorics}: Given an integer \(n\), find an
\(n \times n\) matrix, such that each row and column is a permutation of values
\(1 \ldots n\). A \minizinc\ model encoding this problem could look as follows:
\begin{listing}
\mznfile{assets/mzn/2_knapsack.mzn}
\caption{\label{lst:2-mzn-knapsack} A \minizinc\ model describing a 0-1 knapsack
problem}
\end{listing}
\begin{mzn}
int: n;
array [1..n, 1..n] of var 1..n: x;
constraint forall (r in 1..n) (
all_different([x[r, c] | c in 1..n])
);
constraint forall (c in 1..n) (
all_different([x[r, c] | r in 1..n])
);
\end{mzn}
The model introduces a \gls{parameter} \mzninline{n}, and a two-dimensional
array of \glspl{variable} (marked by the \mzninline{var} keyword) \mzninline{x}.
Each variable in \mzninline{x} is restricted to the set of integers
\mzninline{1..n}, which is called the variable's \gls{domain}. The constraints
specify the requirements of the problem: for each row \mzninline{r}, the
\mzninline{x} variables of all columns must take pairwise different values (and
the same for each column \mzninline{c}). This is modelled using the
\mzninline{all_different} function, one of hundreds of pre-defined constraints
in \minizinc's library.
Given ground assignments to input \glspl{parameter}, a \minizinc\ model is
translated (via a process called \emph{flattening}) into a set of variables and
primitive constraints. Here is the result of flattening for \mzninline{n=2}:
\begin{mzn}
var 1..2: x_1_1;
var 1..2: x_1_2;
var 1..2: x_2_1;
var 1..2: x_2_2;
constraint all_different([x_1_1, x_1_2]);
constraint all_different([x_2_1, x_2_2]);
constraint all_different([x_1_1, x_2_1]);
constraint all_different([x_1_2, x_2_2]);
\end{mzn}
This \emph{flat} problem will be passed to some \gls{solver}, which will attempt
to determine an assignment to each decision variable \verb|x_i_j| that satisfies
all constraints, or report that there is no such assignment.
\section{The current \glsentrytext{minizinc} interpreter}%
\label{sec:back-mzn-interpreter}
\section{Other Constraint Modelling Languages}%
\label{sec:back-other-languages}
\section{ACD Term Rewriting}%
\label{sec:back-term}
\section{Constraint Logic Programming}%
\label{sec:back-clp}