Initial syntax swtich for MicroZinc and NanoZinc
This commit is contained in:
parent
79f115597d
commit
4c54084bf6
@ -173,7 +173,7 @@ outputdir=build,
|
||||
]{minizinc}}{\end{minted}}
|
||||
|
||||
% TODO: Fix the nanozinc sytax highlighting/formatting
|
||||
\newcommand{\nzninline}[1]{\mintinline[fontsize=\small,escapeinside=@@]{markdown}{#1}}
|
||||
\newcommand{\nzninline}[1]{\mintinline[fontsize=\small,escapeinside=@@]{minizinc}{#1}}
|
||||
\newenvironment{nzn}{\VerbatimEnvironment{}\begin{minted}[
|
||||
autogobble=true,
|
||||
breaklines,
|
||||
@ -181,4 +181,4 @@ outputdir=build,
|
||||
numbers=none,
|
||||
escapeinside=@@,
|
||||
fontsize=\scriptsize,
|
||||
]{markdown}}{\end{minted}}
|
||||
]{minizinc}}{\end{minted}}
|
||||
|
@ -121,66 +121,73 @@ presents our conclusions.
|
||||
This section introduces the two sub-languages of \minizinc\ at the core of the
|
||||
new abstract machine model we have developed.
|
||||
|
||||
MicroZinc (\microzinc) is a simplified subset of \minizinc\ that only contains
|
||||
function declarations and a restricted expression language. Models written in
|
||||
different \cmls\ can be translated into \microzinc. NanoZinc (\nanozinc) is
|
||||
similar to \flatzinc\ in that it contains only simple variable declarations and
|
||||
flat constraints. However, while all function calls in \flatzinc\ need to be
|
||||
solver-level primitives, \nanozinc\ calls can refer to functions implemented in
|
||||
\microzinc.
|
||||
\microzinc\ is generally a simplified subset of \minizinc\ that only contains
|
||||
function declarations and a restricted expression language, but extends
|
||||
\minizinc{}'s type system with tuples. Models written in \minizinc\ can be
|
||||
translated into \microzinc. \nanozinc\ is similar to \flatzinc\ in that it
|
||||
contains only simple variable declarations and flat constraints. However, while
|
||||
all function calls in \flatzinc\ need to be solver-level primitives, \nanozinc\
|
||||
calls can refer to functions implemented in \microzinc.
|
||||
|
||||
The core of the syntax of \microzinc\ is defined in \cref{fig:4-uzn-syntax}. We
|
||||
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
|
||||
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
|
||||
expressions have \mzninline{par} type.
|
||||
have omitted the definitions of \syntax{<mzn-type-inst>} and \syntax{<ident>},
|
||||
which you can assume to be the same as the definition of \syntax{<type-inst>}
|
||||
and \syntax{<ident>} in the \minizinc\ grammar, see \cref{ch:minizinc-grammar}.
|
||||
While we omit 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 expressions have \mzninline{par} type.
|
||||
|
||||
\begin{figure}
|
||||
\begin{grammar}
|
||||
<model> ::= <fun-decl>*
|
||||
<model> ::= <fun-decl>*
|
||||
|
||||
<fun-decl> ::= function <type-inst>: <ident>([<type-inst>: <ident>]*) [ = <exp> ];
|
||||
<fun-decl> ::= "function" <type-inst>":" <ident>"(" <param> ["," <param>]* ")" [ "=" <exp> ]";"
|
||||
|
||||
<literal> ::= <constant> | <ident>
|
||||
<literal> ::= <constant> | <ident>
|
||||
|
||||
<exp> ::= <literal>
|
||||
\alt <ident>( <literal>* )
|
||||
\alt let { <item>* } in <exp>
|
||||
\alt if <exp> then <exp> else <exp> endif
|
||||
\alt [ <exp> | <gen-exp> where <exp> ]
|
||||
<exp> ::= <literal>
|
||||
\alt <ident>"(" <literal> ["," <literal>]* ")"
|
||||
\alt "let" "{" <item>* "}" "in" <exp>
|
||||
\alt "if" <exp> "then" <exp> "else" <exp> "endif"
|
||||
\alt "[" <exp> "|" <gen-exp> "where" <exp> "]"
|
||||
\alt "(" <exp> ["," <exp>]* ")"
|
||||
|
||||
<item> ::= <type-inst>: <ident> [ = <exp> ];
|
||||
\alt constraint <exp>;
|
||||
<item> ::= <param> [ "=" <exp> ]";"
|
||||
\alt "(" <param> ["," <param>]* ")" "=" <exp> ";"
|
||||
\alt "constraint" <exp>";"
|
||||
|
||||
<gen-exp> ::= <ident> in <exp> [ , <ident> in <exp> ]*
|
||||
<param> ::= <type-inst>":" <ident>
|
||||
|
||||
<type-inst> ::= <mzn-type-inst> | "tuple(" <mzn-type-inst> ["," <mzn-type-inst>]* ")"
|
||||
|
||||
<gen-exp> ::= <ident> "in" <exp> ["," <ident> "in" <exp> ]*
|
||||
\end{grammar}
|
||||
\caption{\label{fig:4-uzn-syntax} Syntax of \microzinc.}
|
||||
\caption{\label{fig:4-uzn-syntax}Syntax of \microzinc.}
|
||||
\end{figure}
|
||||
|
||||
\newcommand{\sep}{\rhd}
|
||||
|
||||
A \nanozinc\ program, defined in \cref{fig:4-nzn-syntax}, is simply a list of
|
||||
calls, where the result of each call is bound to either an identifier or the
|
||||
constant true. The \syntax{\(\sep\) <ident>*} will be used to track dependent
|
||||
constraints (this will be explained in detail in \cref{sec:4-nanozinc}, for now
|
||||
you can assume it is empty).
|
||||
variable declaration and constraints in the form of calls. The syntax
|
||||
``\texttt{└──}'' will be used to track dependent constraints (this will be
|
||||
explained in detail in \cref{sec:4-nanozinc}, for now you can ignore them).
|
||||
|
||||
\begin{figure}
|
||||
\begin{grammar}
|
||||
<nzn> ::= <nzn-def>*
|
||||
<nzn> ::= <nzn-item>*
|
||||
|
||||
<nzn-def> ::= <nzn-result> \(\mapsto\) <nzn-bind> \(\sep\) <ident>*
|
||||
<nzn-item> ::= <nzn-def> | <nzn-con>
|
||||
|
||||
<nzn-bind> ::= <ident> | <nzn-call>
|
||||
<nzn-con> ::= "constraint" <ident>"(" <literal> ["," <literal>]* ")"";"
|
||||
|
||||
<nzn-result> ::= <ident> | true
|
||||
<nzn-var> ::= "var" <nzn-dom> ":" <ident> ";" <nzn-bind>*
|
||||
|
||||
<nzn-call> ::= <ident>( <literal>* )
|
||||
<nzn-dom> ::= <constant> ".." <constant> | <constant>
|
||||
\alt "bool" | "int" | "float" | "set of int"
|
||||
|
||||
<nzn-bind> ::= "└──" <nzn-con>
|
||||
\end{grammar}
|
||||
\caption{\label{fig:4-nzn-syntax}
|
||||
Syntax of \nanozinc.
|
||||
}
|
||||
\caption{\label{fig:4-nzn-syntax}Syntax of \nanozinc.}
|
||||
\end{figure}
|
||||
|
||||
\subsection{\glsentrytext{minizinc} to
|
||||
@ -206,50 +213,6 @@ The translation from \minizinc\ to \microzinc\ involves the following steps:
|
||||
arguments are the parameters of the model.
|
||||
\end{enumerate}
|
||||
|
||||
% \begin{algorithm}[H]
|
||||
% \KwData{A \minizinc\ model \(M = \langle{}V, C, F\rangle{}\), where \(V\) is a set of declaration
|
||||
% items, \(C\) is a set of constraint items, and \(F\) are the definitions for all
|
||||
% functions used in \(M\).}
|
||||
% \KwResult{A list of \microzinc\ defintions \(\mu\) and a \nanozinc\ program \(n\).}
|
||||
|
||||
% \While{not at end of this document}{
|
||||
% read current\;
|
||||
% \eIf{understand}{
|
||||
% go to next section\;
|
||||
% current section becomes this one\;
|
||||
% }{
|
||||
% go back to the beginning of current section\;
|
||||
% }
|
||||
% }
|
||||
% \caption{MicrowaveModel}
|
||||
% \end{algorithm}
|
||||
|
||||
|
||||
% \begin{algorithm}[H]
|
||||
% \KwData{A \minizinc\ expression \(e\) and \(rn\) a function to rename identifiers}
|
||||
% \KwResult{A \microzinc\ expression \(e'\).}
|
||||
|
||||
% \Switch{\(e\)} {
|
||||
% \Case{\textup{\texttt{if \(c\) then \(e_{1}\) else \(e_{2}\) endif}}}{
|
||||
% \eIf{\(type(c) \in \textup{\texttt{var}}\)}{
|
||||
% \(e' \longleftarrow \texttt{MicroExpr}(\texttt{slv\_if\_then\_else(\(c\), \(e_{1}\), \(e_{2}\))}, rn)\)
|
||||
% }{
|
||||
% \(c' \longleftarrow \texttt{MicroExpr(\(c, rn\))}\)\;
|
||||
% \(e_{1}' \longleftarrow \texttt{MicroExpr(\(e_{1}, rn\))}\)\;
|
||||
% \(e_{2}' \longleftarrow \texttt{MicroExpr(\(e_{2}\), rn)}\)\;
|
||||
% \(e' \longleftarrow \texttt{if \(c'\) then \(e_{1}'\) else \(e_{2}'\) endif}\)
|
||||
% }
|
||||
% }
|
||||
% \Case{\textup{(call)} \(n(e_{1}, ..., e_{n})\)}{
|
||||
|
||||
% }
|
||||
% \lCase{\textup{(ident)} \(id\)} {\(e' \longleftarrow rn(id)\)}
|
||||
% \lOther{\(e' \longleftarrow e\)}
|
||||
% }
|
||||
% \Return{\(e'\)}
|
||||
% \caption{MicroExpr}
|
||||
% \end{algorithm}
|
||||
|
||||
\begin{example}
|
||||
Consider the following \minizinc\ model, a simple unsatisfiable ``pigeonhole
|
||||
problem'', trying to assign \(n\) pigeons to \(n-1\) holes:
|
||||
@ -292,7 +255,11 @@ The translation from \minizinc\ to \microzinc\ involves the following steps:
|
||||
|
||||
For a concrete instance of the model, we can then create a simple \nanozinc\
|
||||
program that calls \mzninline{main}, for example for \(n=10\):
|
||||
\nzninline{true @\(\mapsto\)@ main(10) @\(\sep\)@ []}.
|
||||
|
||||
\begin{nzn}
|
||||
constraint main(10);
|
||||
\end{nzn}
|
||||
|
||||
\end{example}
|
||||
|
||||
\subsection{Partial Evaluation of \glsentrytext{nanozinc}}\label{sub:4-partial}
|
||||
@ -364,20 +331,25 @@ result.
|
||||
|
||||
\begin{example}\label{ex:4-absnzn}
|
||||
|
||||
Consider the \minizinc\ fragment\\\mzninline{constraint abs(x) > y;}\\ where
|
||||
\mzninline{x} and \mzninline{y} have domain \([-10, 10]\). After rewriting all
|
||||
definitions, the resulting \nanozinc\ program could look like this:
|
||||
Consider the \minizinc\ fragment
|
||||
|
||||
\begin{mzn}
|
||||
constraint abs(x) > y;
|
||||
\end{mzn}
|
||||
|
||||
where \mzninline{x} and \mzninline{y} have domain \mzninline{-10..10}. After
|
||||
rewriting all definitions, the resulting \nanozinc\ program could look like
|
||||
this:
|
||||
|
||||
\begin{nzn}
|
||||
x @\(\mapsto\)@ mkvar(-10..10) @\(\sep\)@ []
|
||||
y @\(\mapsto\)@ mkvar(-10..10) @\(\sep\)@ []
|
||||
z @\(\mapsto\)@ mkvar(-infinity,infinity) @\(\sep\)@ []
|
||||
b0 @\(\mapsto\)@ int_abs(x, z) @\(\sep\)@ []
|
||||
t @\(\mapsto\)@ z @\(\sep\)@ [b0]
|
||||
b1 @\(\mapsto\)@ int_gt(t,y) @\(\sep\)@ []
|
||||
true @\(\mapsto\)@ true @\(\sep\)@ [b1]
|
||||
var -10..10: x;
|
||||
var -10..10: y;
|
||||
var int: z;
|
||||
└── constraint int_abs(x, z);
|
||||
constraint int_gt(z, y);
|
||||
\end{nzn}
|
||||
|
||||
\jip{Adjust text to match the new \nanozinc\ formatting.}
|
||||
The variables \mzninline{x} and \mzninline{y} result in identifiers bound to
|
||||
the special built-in \mzninline{mkvar}, which records the variable's domain in
|
||||
its arguments. Evaluating the call \mzninline{abs(x)} introduces a new
|
||||
@ -652,7 +624,8 @@ constraint, we can pick any value for it. The model without the variable is
|
||||
therefore equisatisfiable with the original model.
|
||||
|
||||
Consider now the case where a variable in \nanozinc\ is only used in its own
|
||||
auxiliary definitions (the \mzninline{@\(\sep\phi\)@} part).
|
||||
auxiliary definitions (the constraints directly succeeding the declaration
|
||||
prepended by \texttt{└── }).
|
||||
|
||||
\begin{example}\label{ex:4-absreif}
|
||||
The following is a slight variation on the \minizinc\ fragment in
|
||||
@ -673,15 +646,14 @@ auxiliary definitions (the \mzninline{@\(\sep\phi\)@} part).
|
||||
was introduced for \mzninline{abs(x) > y}:
|
||||
|
||||
\begin{nzn}
|
||||
c @\(\mapsto\)@ true @\(\sep\)@ []
|
||||
x @\(\mapsto\)@ mkvar(-10..10) @\(\sep\)@ []
|
||||
y @\(\mapsto\)@ mkvar(-10..10) @\(\sep\)@ []
|
||||
b0 @\(\mapsto\)@ int_abs(x, z) @\(\sep\)@ []
|
||||
b1 @\(\mapsto\)@ int_gt(t,y) @\(\sep\)@ []
|
||||
z @\(\mapsto\)@ mkvar(-infinity,infinity) @\(\sep\)@ []
|
||||
t @\(\mapsto\)@ z @\(\sep\)@ [b0]
|
||||
b2 @\(\mapsto\)@ bool_or(b1,c) @\(\sep\)@ []
|
||||
true @\(\mapsto\)@ true @\(\sep\)@ [b2,c]
|
||||
var true: c;
|
||||
var -10..10: x;
|
||||
var -10..10: y;
|
||||
var int: z;
|
||||
└── constraint int_abs(x, z);
|
||||
var bool: b1;
|
||||
└── constraint int_gt(z, y);
|
||||
constraint bool_or(b1, c);
|
||||
\end{nzn}
|
||||
|
||||
Since \mzninline{c} is bound to \mzninline{true}, the disjunction
|
||||
@ -700,17 +672,16 @@ auxiliary definitions (the \mzninline{@\(\sep\phi\)@} part).
|
||||
is much more compact:
|
||||
|
||||
\begin{nzn}
|
||||
c @\(\mapsto\)@ true @\(\sep\)@ []
|
||||
x @\(\mapsto\)@ mkvar(-10..10) @\(\sep\)@ []
|
||||
y @\(\mapsto\)@ mkvar(-10..10) @\(\sep\)@ []
|
||||
true @\(\mapsto\)@ true @\(\sep\)@ []
|
||||
var true: c;
|
||||
var -10..10: x;
|
||||
var -10..10: y;
|
||||
\end{nzn}
|
||||
|
||||
We assume here that \mzninline{c}, \mzninline{x} and \mzninline{y} are used
|
||||
in other parts of the model not shown here and therefore not removed.
|
||||
|
||||
We assume here that \mzninline{c}, \mzninline{x} and \mzninline{y} are used in
|
||||
other parts of the model not shown here and therefore not removed.
|
||||
\end{example}
|
||||
|
||||
\jip{adjust text to match the new \nanozinc\ syntax}
|
||||
Note how \mzninline{t} acts as a unique name for the result of the let
|
||||
expression (and thus the function call) --- we could not simply have used
|
||||
\mzninline{z}, because then \mzninline{b0} would have kept \mzninline{z} alive.
|
||||
@ -830,34 +801,29 @@ as \mzninline{constraint f(a)=g(b)}. Let us assume that part of the
|
||||
corresponding \nanozinc\ code looks like this:
|
||||
|
||||
\begin{nzn}
|
||||
x @\(\mapsto\)@ mkvar() @\(\sep\)@ [];
|
||||
y @\(\mapsto\)@ mkvar() @\(\sep\)@ [];
|
||||
b0 @\(\mapsto\)@ f_rel(a,x) @\(\sep\)@ [];
|
||||
b1 @\(\mapsto\)@ g_rel(b,y) @\(\sep\)@ [];
|
||||
t0 @\(\mapsto\)@ x @\(\sep\)@ [b0];
|
||||
t1 @\(\mapsto\)@ y @\(\sep\)@ [b1];
|
||||
b2 @\(\mapsto\)@ int_eq(t0,t1) @\(\sep\)@ [];
|
||||
true @\(\mapsto\)@ true @\(\sep\)@ [b2];
|
||||
var int: x;
|
||||
└── constraint f_rel(a, x);
|
||||
var int: y;
|
||||
└── constraint g_rel(b, y);
|
||||
constraint int_eq(x, y);
|
||||
\end{nzn}
|
||||
|
||||
In this case, simply removing either \mzninline{t0} or \mzninline{t1} would not
|
||||
be correct, since that would trigger the removal of the corresponding definition
|
||||
\mzninline{b0} or \mzninline{b1}, leaving nothing to be substituted. Rather, the
|
||||
interpreter needs to pick one of the two definitions and \emph{promote} it to
|
||||
top-level status. Let us assume that the interpreter decides to replace
|
||||
\mzninline{t1} by \mzninline{t0}. It follows the definition of \mzninline{t1} to
|
||||
find \mzninline{y}, which is then globally replaced by \mzninline{t0}, and its
|
||||
definition is removed. The interpreter moves all auxiliary constraints from
|
||||
\mzninline{t1} into the list of auxiliary constraints of the top-level
|
||||
\mzninline{true} item, and then removes the \mzninline{int_eq} constraint and
|
||||
\mzninline{t1}. The resulting \nanozinc\ looks like this:
|
||||
In this case, simply removing either \mzninline{x} or \mzninline{y} would not be
|
||||
correct, since that would trigger the removal of the corresponding definition
|
||||
\mzninline{f_rel(a, x)} or \mzninline{g_rel(b, y)}, leaving nothing to be
|
||||
substituted. Rather, the interpreter needs to pick one of the two definitions
|
||||
and \emph{promote} it to top-level status. Let us assume that the interpreter
|
||||
decides to replace \mzninline{y} by \mzninline{x}. \mzninline{y} is then
|
||||
globally replaced by \mzninline{x}, and its declaration is removed. The
|
||||
interpreter moves all auxiliary constraints from \mzninline{y} into the list of
|
||||
top-level constraints, and then removes the \mzninline{int_eq} constraint. The
|
||||
resulting \nanozinc\ looks like this:
|
||||
|
||||
\begin{nzn}
|
||||
x @\(\mapsto\)@ mkvar() @\(\sep\)@ [];
|
||||
b0 @\(\mapsto\)@ f_rel(a,x) @\(\sep\)@ [];
|
||||
b1 @\(\mapsto\)@ g_rel(b,t0) @\(\sep\)@ [];
|
||||
t0 @\(\mapsto\)@ x @\(\sep\)@ [b0];
|
||||
true @\(\mapsto\)@ true @\(\sep\)@ [b1];
|
||||
var int: x;
|
||||
└── constraint f_rel(a, x);
|
||||
constraint g_rel(x, y);
|
||||
constraint int_eq(x, y);
|
||||
\end{nzn}
|
||||
|
||||
The process of equality propagation is similar to unification in logic
|
||||
|
@ -36,7 +36,7 @@ the rules for identifiers and annotations.
|
||||
\alt <function-item>
|
||||
\alt <annotation-item>
|
||||
|
||||
<ti-expr-and-id> ::= <ti-expr> ":" <ident>
|
||||
<ti-expr-and-id> ::= <type-inst> ":" <ident>
|
||||
|
||||
% Include items
|
||||
<include-item> ::= "include" <string-literal>
|
||||
@ -75,7 +75,7 @@ the rules for identifiers and annotations.
|
||||
|
||||
<test-item> ::= "test" <operation-item-tail>
|
||||
|
||||
<function-item> ::= "function" <ti-expr> ":" <operation-item-tail>
|
||||
<function-item> ::= "function" <type-inst> ":" <operation-item-tail>
|
||||
|
||||
<operation-item-tail> ::= <ident> <params> <annotations> [ "=" <expr> ]
|
||||
|
||||
@ -88,7 +88,7 @@ the rules for identifiers and annotations.
|
||||
|
||||
\begin{grammar}
|
||||
% Type-inst expressions
|
||||
<ti-expr> ::= <base-ti-expr>
|
||||
<type-inst> ::= <base-ti-expr>
|
||||
\alt <array-ti-expr>
|
||||
|
||||
<base-ti-expr> ::= <var-par> <opt-ti> <set-ti> <base-ti-expr-tail>
|
||||
@ -115,7 +115,7 @@ the rules for identifiers and annotations.
|
||||
<ti-variable-expr-tail> ::= \(regexp\left(\texttt{\$[A-Za-z][A-Za-z0-9\_]*}\right)\)
|
||||
|
||||
% Array type-inst expressions
|
||||
<array-ti-expr> ::= "array" [ <ti-expr> "," ... ] "of" <base-ti-expr>
|
||||
<array-ti-expr> ::= "array" [ <type-inst> "," ... ] "of" <base-ti-expr>
|
||||
\alt "list" "of" <base-ti-expr>
|
||||
\end{grammar}
|
||||
|
||||
@ -191,16 +191,16 @@ the rules for identifiers and annotations.
|
||||
<bool-literal> ::= "false" \alt "true"
|
||||
|
||||
% Integer literals
|
||||
<int-literal> ::= \(regexp\left(\texttt{[0-9]+}\right)\)
|
||||
\alt \(regexp\left(\texttt{0x[0-9A-Fa-f]+}\right)\)
|
||||
\alt \(regexp\left(\texttt{0o[0-7]+}\right)\)
|
||||
<int-literal> ::= \(regexp\left(\texttt{\textbackslash{}d+}\right)\)
|
||||
\alt \(regexp\left(\texttt{0x\textbackslash{}x+}\right)\)
|
||||
\alt \(regexp\left(\texttt{0o\textbackslash{}O+}\right)\)
|
||||
|
||||
% Float literals
|
||||
<float-literal> ::= \(regexp\left(\verb=[0-9]+\.[0-9]+=\right)\)
|
||||
\alt \(regexp\left(\verb=[0-9]+\.[0-9]+[Ee][-+]?[0-9]+=\right)\)
|
||||
\alt \(regexp\left(\verb=[0-9]+[Ee][-+]?[0-9]+=\right)\)
|
||||
\alt \(regexp\left(\verb=0[xX]([0-9a-fA-F]*"."[0-9a-fA-F]+|[0-9a-fA-F]+".")([pP][+-]?[0-9]+)=\right)\)
|
||||
\alt \(regexp\left(\verb=(0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+)=\right)\)
|
||||
<float-literal> ::= \(regexp\left(\verb=\d+\.\d+=\right)\)
|
||||
\alt \(regexp\left(\verb=\d+\.\d+[Ee][-+]?\d+=\right)\)
|
||||
\alt \(regexp\left(\verb=\d+[Ee][-+]?\d+=\right)\)
|
||||
\alt \(regexp\left(\verb=0[xX](\x*\.\x+|\x+\.)([pP][+-]?\d+)=\right)\)
|
||||
\alt \(regexp\left(\verb=(0[xX]\x+[pP][+-]?\d+)=\right)\)
|
||||
|
||||
% String literals
|
||||
<string-contents> ::= \(regexp\left(\verb=([^"\n\] | \[^\n(])*=\right)\)
|
||||
|
Reference in New Issue
Block a user