\noindent{}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 on which the program is executed. 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 \parameters{}, what we wish to know, the \variables{}, and the relationships that should exist between them, the \constraints{}. This type of combinatorial problem is typically called a \gls{csp}. The goal of a \gls{csp} is to find values for the \variables{} that satisfy the \constraints{} or prove that no such assignment exists. Many \cmls\ also support the modelling of \gls{cop}, where a \gls{csp} is augmented with a \gls{objective} \(z\). In this case the goal is to find a solution that satisfies all \constraints{} while minimising (or maximising) \(z\). Although a constraint model does not contain any instructions on how to find a suitable solution, these models can generally be given to a dedicated solving program, or \solver{} for short, that can find a solution that fits the requirements of the model.