A global grammar check
This commit is contained in:
parent
ac4dfb75d7
commit
47265d441d
2
.vscode/ltex.dictionary.en-GB.txt
vendored
2
.vscode/ltex.dictionary.en-GB.txt
vendored
@ -36,3 +36,5 @@ GBAC
|
||||
RCPSP
|
||||
Reifications
|
||||
SCIP
|
||||
Sictus
|
||||
QCP-Max
|
||||
|
1
.vscode/ltex.disabledRules.en-GB.txt
vendored
1
.vscode/ltex.disabledRules.en-GB.txt
vendored
@ -1 +1,2 @@
|
||||
ARROWS
|
||||
PASSIVE_VOICE
|
||||
|
43
.vscode/ltex.hiddenFalsePositives.en-GB.txt
vendored
43
.vscode/ltex.hiddenFalsePositives.en-GB.txt
vendored
@ -261,6 +261,49 @@
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qtrs name=term rewriting system, description=A computational model that expresses computation through the application of rewriting rules.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qunsat name=unsatisfiable, description=An \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, or a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, is unsatisfiable when a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q cannot exist.\\E$"}
|
||||
{"rule":"UPPERCASE_SENTENCE_START","sentence":"^\\Qvariable-assignment name=variable assignment, description=see \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.,\\E$"}
|
||||
{"rule":"IE_NO_COMMA","sentence":"^\\QThe second component of our \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q definition is the “restarting strategy”, defining how much effort the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q should put into each \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q (i.e. \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q), and when to stop the overall search.\\E$"}
|
||||
{"rule":"ACTUAL","sentence":"^\\QHowever, since functions returning Boolean Dummies are equivalent to a predicate, it is actually the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q of \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q that gets used.\\E$"}
|
||||
{"rule":"THREE_NN","sentence":"^\\QOur first model is based on a problem of planning cancer radiation therapy treatment using multi-leaf collimators \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.\\E$"}
|
||||
{"rule":"METRIC_UNITS_EN_IMPERIAL","sentence":"^\\Q=15pt =1em\\E$"}
|
||||
{"rule":"ACTUAL","sentence":"^\\QIt could be said that a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q actually describes the answer to the problem.\\E$"}
|
||||
{"rule":"MEANING","sentence":"^\\QThe problem classes can be restrictive: the input to the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, can only contain \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q Dummies and Dummies, meaning those that are directly supported by the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QAn \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q model of the open shop problem.\\E$"}
|
||||
{"rule":"MEANING","sentence":"^\\QThe \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q model provides a clear definition of the problem class, but it can be argued that its meaning is hard to decipher.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qgls-ampl name=AMPL: A Mathematical Programming Language, description=AMPL is a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q originally designed to serve as a common input language for mathematical Dummies (e.g., \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q).\\E$"}
|
||||
{"rule":"UPPERCASE_SENTENCE_START","sentence":"^\\Qbacktrack name=backtrack, description=A \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q is said to backtrack when it revisits a search decision (e.g., a value assumed during search).\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qboundsr-con name=bounds(\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q) consistent, description=A \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q is bounds(\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q) consistent when it tightens the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q such that they could satisfy the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q if it where using rational arithmetic.,\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qboundsz-con name=bounds(\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q) consistent, description=A \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q is bounds(\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q) consistent when it tightens the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q such that they can satisfy the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.,\\E$"}
|
||||
{"rule":"MAP","sentence":"^\\Qeqsat name=equisatisfiable, description=Two Dummies are equisatisfiable when a bijective function can be defined to map the Dummies of one \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q onto the Dummies of the other.,\\E$"}
|
||||
{"rule":"UPPERCASE_SENTENCE_START","sentence":"^\\Qkleene-sem name=Kleene semantics, description= A semantic model for treating undefined behaviour in Dummies.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QIt is defined in terms of formalized decision, Dummies of different kinds (e.g., Boolean, integers, or even sets), and Dummies, Boolean logic formulas which are forced to hold in any \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, and, in case of an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.\\E$"}
|
||||
{"rule":"UPPERCASE_SENTENCE_START","sentence":"^\\Qstrict-sem name=strict semantics, description= A semantic model for treating undefined behaviour in Dummies.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qrel-sem name=relational semantics, description= A semantic model for treating undefined behaviour in Dummies.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QA specific problem is captured by an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, the combination of a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q with a complete \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q (i.e., a mapping from all Dummies to a value).\\E$"}
|
||||
{"rule":"MAP","sentence":"^\\QThe \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q functions are Dummies used to map toys, \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, to a numeric value describing the amount of enjoyment and space required respectively.\\E$"}
|
||||
{"rule":"MAP","sentence":"^\\QDummies declare the Dummies \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, that map toys to integer values.\\E$"}
|
||||
{"rule":"EN_GB_SIMPLE_REPLACE","sentence":"^\\QA \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q model describing a 0-1 knapsack problem.\\E$"}
|
||||
{"rule":"MEANING","sentence":"^\\QThe term “variable” has two overlapping, and slightly confusing meanings.\\E$"}
|
||||
{"rule":"TOO_LONG_SENTENCE","sentence":"^\\Q[\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q] The \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q expression which assigns the values of collections to identifiers, [\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q] an optional filtering condition, which has to evaluate to true for the iteration to be included in the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, [\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q] and the expression that is evaluated for each iteration when the filtering condition succeeds.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QFor many problems the use of \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q Dummies, such as \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and RC2 \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, offers a very successful method to find an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q to a problem.\\E$"}
|
||||
{"rule":"MEANING","sentence":"^\\QThis makes it harder in \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q to write the correct \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and its meaning is less clear.\\E$"}
|
||||
{"rule":"TOO_LONG_SENTENCE","sentence":"^\\Q[\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q] The \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q expression which assigns the values of collections to identifiers, [\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q] an optional filtering condition, which decided whether the iteration to be included in the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, [\\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q] and the expression that is evaluated for each iteration when the filtering condition succeeds.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QTo solve the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q problem, the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q has to find an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q for the Dummies where at least one literal takes the value \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q in every clause.\\E$"}
|
||||
{"rule":"MEANING","sentence":"^\\QThis means that, depending on the target \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q will not be able to understand the meaning of all Dummies.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QThese are said to be the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q-context Dummies of the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, i.e., those that have to hold globally and are not just used to define an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\QThe (WhereT) rule evaluates the guard of a where \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and if \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q returns the resulting expression in a list.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\QThe (WhereF) rule evaluates the guard and when \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q returns an empty list.\\E$"}
|
||||
{"rule":"ACTUAL","sentence":"^\\QActually make source available\\E$"}
|
||||
{"rule":"MEANING","sentence":"^\\QIts meaning is now completely captured by the Dummies of the Dummies.\\E$"}
|
||||
{"rule":"TOO_LONG_SENTENCE","sentence":"^\\QTo simplify presentation, we assume that all rules that introduce new identifiers into the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q program do so in a way that ensures those identifiers are fresh (i.e., not used in the rest of the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q program), by suitable alpha renaming.\\E$"}
|
||||
{"rule":"THREE_NN","sentence":"^\\QWe also present our rules using a call by name evaluation strategy, i.e., the arguments to function calls are substituted into function body.\\E$"}
|
||||
{"rule":"THREE_NN","sentence":"^\\QAlthough pure \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q behaves the same under any call evaluation strategy, in implementation a call by value strategy might provide more predictable behaviour with debugging functions in the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q language, such as \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.\\E$"}
|
||||
{"rule":"THREE_NN","sentence":"^\\QIn \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q we introduce our new context analysis algorithm: a way to determine where \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q can be used in \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, and by extension \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\QDefinition of the “argCtx” function for \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q operators.\\E$"}
|
||||
{"rule":"UPPERCASE_SENTENCE_START","sentence":"^\\Qjoin A table showing the result of joining two contexts, considering the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q context.\\E$"}
|
||||
{"rule":"PUNCTUATION_PARAGRAPH_END","sentence":"^\\QThe case shown in the example can be generalized to\\E$"}
|
||||
{"rule":"PUNCTUATION_PARAGRAPH_END","sentence":"^\\QThe \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q reports\\E$"}
|
||||
{"rule":"TOO_LONG_SENTENCE","sentence":"^\\Q[Unsatisfiable] when it proves the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q does not have a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q, [Optimal solution] when it has found a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and has proven the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q to be optimal, [Satisfied] when it has found a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q for the problem, [Unknown] when it does not find a \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q is found within the time limit, and [Error] when the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q program crashes.\\E$"}
|
||||
{"rule":"EN_A_VS_AN","sentence":"^\\QFor this comparison, we analyse the time that is required to (repeatedly) rewrite an \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q and the time required by the \\E(?:Dummy|Ina|Jimmy-)[0-9]+\\Q by different methods.\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qaccap amaze code-generator fox-geese-corn groupsplitter hrc kidney-exchange liner-sf-repositioning lot-sizing median-string multi-knapsack nside ptv rcpsp-wet-diverse rotating-workforce stack-cuttingstock steelmillslab stochastic-vrp triangular zephyrus\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qbnn-planner cabletreewiring code-generator collaborative-construction gbac hoist-benchmark is lot-sizing minimal-decision-sets p1f-pjs pentominoes pillars-and-planks racp radiation sdn-change skill-allocation soccer-computational stable-goods towerchallenge whirlpool\\E$"}
|
||||
{"rule":"MORFOLOGIK_RULE_EN_GB","sentence":"^\\Qgbac radiation steelmillslab rcpsp-wet\\E$"}
|
||||
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -73,7 +73,9 @@
|
||||
"\\minisearch": "dummy",
|
||||
"\\mznfile{}": "ignore",
|
||||
"\\plainfile{}": "ignore",
|
||||
"\\amplfile{}": "ignore"
|
||||
"\\amplfile{}": "ignore",
|
||||
"\\true{}": "dummy",
|
||||
"\\false{}": "dummy"
|
||||
},
|
||||
"ltex.latex.environments": {
|
||||
"mzn": "ignore",
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
\newglossaryentry{gls-ampl}{
|
||||
name={AMPL:\ A Mathematical Programming Language},
|
||||
description={AMPL is a \gls{cml} originally designed to serve as a common input language for mathematical \glspl{solver} (\eg{} \gls{lp} and \gls{mip}). It has later been extended for other types of \glspl{solver}. See \cref{sub:back-ampl}.},
|
||||
description={AMPL is a \gls{cml} originally designed to serve as a common input language for mathematical \glspl{solver} (e.g., \gls{lp} and \gls{mip}). It has later been extended for other types of \glspl{solver}. See \cref{sub:back-ampl}.},
|
||||
}
|
||||
|
||||
\newglossaryentry{gls-api}{
|
||||
@ -58,7 +58,7 @@
|
||||
|
||||
\newglossaryentry{backtrack}{
|
||||
name={backtrack},
|
||||
description={A \gls{solver} is said to backtrack when it revisits a search decision (\eg{} a value assumed during search). Notably the action of backtracking generally involves invalidating all effects of the revisited and subsequent search decisions.},
|
||||
description={A \gls{solver} is said to backtrack when it revisits a search decision (e.g., a value assumed during search). Notably the action of backtracking generally involves invalidating all effects of the revisited and subsequent search decisions.},
|
||||
}
|
||||
|
||||
\newglossaryentry{binding}{
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
\newglossaryentry{byte-code}{
|
||||
name={byte-code},
|
||||
description={A set of instructions designed to be efficiently executed by an \gls{interpreter}. Distinctive from other computer languages a byte code has a very compact representation, \eg{} using only numbers, and can not be directly read by humans.},
|
||||
description={A set of instructions designed to be efficiently executed by an \gls{interpreter}. Distinctive from other computer languages a byte code has a very compact representation, e.g., using only numbers, and can not be directly read by humans.},
|
||||
}
|
||||
|
||||
\newglossaryentry{booleanization}{
|
||||
@ -83,7 +83,7 @@
|
||||
|
||||
\newglossaryentry{bounds}{
|
||||
name={bounds},
|
||||
description={The minimal and maximum value in the \domain{} of a \variable{}, \ie{} the boundaries of the \domain{}.},
|
||||
description={The minimal and maximum value in the \domain{} of a \variable{}, i.e., the boundaries of the \domain{}.},
|
||||
}
|
||||
|
||||
\newglossaryentry{boundsr-con}{
|
||||
@ -371,7 +371,7 @@
|
||||
name={constraint model},
|
||||
description={
|
||||
A formalization of a \gls{dec-prb} or an \gls{opt-prb}.
|
||||
It is defined in terms of formalized decision, \glspl{variable} of different kinds (\eg{} Boolean, integers, or even sets), and \glspl{constraint}, Boolean logic formulas which are forced to hold in any \gls{sol}, and, in case of an \gls{opt-prb}, an \gls{objective}.
|
||||
It is defined in terms of formalized decision, \glspl{variable} of different kinds (e.g., Boolean, integers, or even sets), and \glspl{constraint}, Boolean logic formulas which are forced to hold in any \gls{sol}, and, in case of an \gls{opt-prb}, an \gls{objective}.
|
||||
Any external data required to formulate the \glspl{constraint} is said to be the \glspl{prb-par}.
|
||||
The combination of a constraint model and \gls{assignment}s for its \glspl{prb-par} is said to be an \gls{instance} of the constraint model.
|
||||
}
|
||||
@ -579,7 +579,7 @@
|
||||
name={relational semantics},
|
||||
description={
|
||||
A semantic model for treating undefined behaviour in \glspl{cml}.
|
||||
Under relational semantics an occurrence of undefined behaviour will cause its closest surrounding Boolean expression to be false.
|
||||
Under relational semantics an occurrence of undefined behaviour will cause its closest surrounding Boolean expression to become \false{}.
|
||||
}
|
||||
}
|
||||
|
||||
@ -624,7 +624,7 @@
|
||||
|
||||
\newglossaryentry{trail}{
|
||||
name={trail},
|
||||
description={A chronological account of changes to data structures with as goal to possibly reverse these changes. The usage of a trail is a common way for \gls{solver} to revisit search decisions (\ie{} \gls{backtrack}).},
|
||||
description={A chronological account of changes to data structures with as goal to possibly reverse these changes. The usage of a trail is a common way for \gls{solver} to revisit search decisions (i.e., \gls{backtrack}).},
|
||||
}
|
||||
|
||||
\newglossaryentry{trs}{
|
||||
@ -654,7 +654,7 @@
|
||||
|
||||
\newglossaryentry{violated}{
|
||||
name={violated},
|
||||
description={A \gls{constraint} is said to be violated when its logical expression is known to be false.},
|
||||
description={A \gls{constraint} is said to be violated when it is known that it cannot become \gls{satisfied}.},
|
||||
}
|
||||
|
||||
\newglossaryentry{zinc}{
|
||||
|
@ -1,10 +1,8 @@
|
||||
% General math overrides
|
||||
\renewcommand*{\implies}{\rightarrow}
|
||||
|
||||
% Academic writing
|
||||
\newcommand*{\eg}{e.g.,\xspace}
|
||||
\newcommand*{\ie}{i.e.,\xspace}
|
||||
\newcommand*{\wrt}{w.r.t.\xspace}
|
||||
\newcommand{\true}{\texttt{true}\xspace}
|
||||
\newcommand{\false}{\texttt{false}\xspace}
|
||||
|
||||
% Glossary entries
|
||||
\newcommand*{\Cmls}{\Glspl{cml}}
|
||||
|
@ -11,7 +11,7 @@ The \gls{rewriting} required to translate an \instance{} of a \cmodel{} into a \
|
||||
However, \cmls{} have evolved to include functionality that is not directly supported by the target \solvers{}.
|
||||
As such, the \gls{rewriting} process has become more important and complex.
|
||||
|
||||
\minizinc{}, one such language, was originally designed for constraint programming \solvers{}, whose \glspl{slv-mod} contain a small number of highly complex \constraints{}.
|
||||
\minizinc{}, one such language, was originally designed for constraint programming \solvers{}, whose \glspl{slv-mod} contain a few highly complex \constraints{}.
|
||||
The same \minizinc{} models can now target mixed integer programming and Boolean satisfiability \solvers{}, resulting in numerous very simple \constraints{}.
|
||||
Distinctively, the \minizinc{}'s \gls{rewriting} process is founded on its functional language.
|
||||
It generates \glspl{slv-mod} through the application of increasingly complex \minizinc{} functions from \solver{}-specific libraries.
|
||||
|
@ -23,7 +23,7 @@ It could be said that a \cmodel{} actually describes the answer to the problem.
|
||||
In a \cmodel{}, instead of specifying the manner in which we find a \gls{sol}, we give a concise description of the problem.
|
||||
The elements of a \cmodel{} include \prbpars{}, what we already know; \variables{}, what we wish to know; and \constraints{}, the relations that should exist between them.
|
||||
Through the variation of \prbpars{}, a \cmodel{} describes a full class of problems.
|
||||
A specific problem is captured by an \instance{}, the combination of a \cmodel{} with a complete \gls{parameter-assignment} (\ie{} a mapping from all \prbpars{} to a value).
|
||||
A specific problem is captured by an \instance{}, the combination of a \cmodel{} with a complete \gls{parameter-assignment} (i.e., a mapping from all \prbpars{} to a value).
|
||||
|
||||
The type of problem described by a \cmodel{} is called a \gls{dec-prb}.
|
||||
The goal of a \gls{dec-prb} is to find a \gls{sol}: a complete \gls{variable-assignment} that satisfies the \constraints{}.
|
||||
@ -358,7 +358,7 @@ The generation of new \gls{array} structures allows modellers adjust, combine, f
|
||||
|
||||
\begin{description}
|
||||
\item[\(G\)] The \gls{generator} expression which assigns the values of collections to identifiers,
|
||||
\item[\(F\)] an optional filtering condition, which has to evaluate to true for the iteration to be included in the \gls{array},
|
||||
\item[\(F\)] an optional filtering condition, which decided whether the iteration to be included in the \gls{array},
|
||||
\item[\(E\)] and the expression that is evaluated for each iteration when the filtering condition succeeds.
|
||||
\end{description}
|
||||
|
||||
@ -441,10 +441,10 @@ The \gls{reif} of a \constraint{} \(c\) creates a Boolean \gls{avar} \mzninline{
|
||||
|
||||
This model maximizes the number of even numbers taken by the elements of the \gls{array} \mzninline{x}.
|
||||
In this model the expression \mzninline{x[i] mod 2 == 0} has to be \gls{reified}.
|
||||
This means that for each \mzninline{i}, a \gls{cvar} \mzninline{b_i} is added, together with a constraint that makes \mzninline{b_i} true if-and-only-if \mzninline{x[i] mod 2 = 0}.
|
||||
This means that for each \mzninline{i}, a \gls{cvar} \mzninline{b_i} is added, together with a constraint that makes \mzninline{b_i} take the value \true{} if-and-only-if \mzninline{x[i] mod 2 = 0}.
|
||||
We can then add up the values of all these \mzninline{b_i}, as required by the maximization.
|
||||
Since the elements have a domain from 1 to 15 and are constrained to take different values, not all elements of \mzninline{x} can take even values.
|
||||
Instead, the \solver{} is tasked to maximize the number of reified variables it sets to true.
|
||||
Instead, the \solver{} is tasked to maximize the number of \glspl{cvar} it sets to \true{}.
|
||||
\end{example}
|
||||
|
||||
When an expression occurs in a position where it can be directly enforced, we say it occurs in \rootc{} context.
|
||||
@ -472,7 +472,7 @@ Part of the semantics of a \cml{} is the choice as to how to treat these \gls{pa
|
||||
Suppose the \gls{array} \texttt{a} has index set \mzninline{1..5}, but \mzninline{i} takes the value seven.
|
||||
This means the expression \mzninline{a[i]} is undefined.
|
||||
If \minizinc{} did not implement any special handling for \gls{partial} functions, then the whole expression would have to be marked as undefined and a \gls{sol} cannot be found.
|
||||
However, intuitively if \mzninline{i = 7} the \constraint{} should be trivially true.
|
||||
However, intuitively if \mzninline{i = 7} the \constraint{} should be trivially \gls{satisfied}.
|
||||
\end{example}
|
||||
|
||||
Other examples of \gls{partial} functions in \minizinc{} are:
|
||||
@ -512,14 +512,14 @@ There is both the question of what happens when an undefined expression is evalu
|
||||
\item[Kleene] The \Gls{kleene-sem} treat undefined expressions as expressions for which not enough information is available.
|
||||
If an expression contains an undefined sub-expression, then it is only marked as undefined if the value of the sub-expression is required to compute its result.
|
||||
Take for example the expression \mzninline{false -> @\(E\)@}.
|
||||
When \(E\) is undefined the result of the expression is still be said to be true, since the value of \(E\) does not influence the result of the expression.
|
||||
When \(E\) is undefined the result of the expression is still be said to be \true{}, since the value of \(E\) does not influence the result of the expression.
|
||||
However, if we take the expression \mzninline{true /\ @\(E\)@}, then when \(E\) is undefined the overall expression is also undefined since the value of the expression cannot be determined.
|
||||
|
||||
\item[Relational] The \gls{rel-sem} follow from all expressions in a \cml{} eventually becoming part of a relational \constraint{}.
|
||||
So even though a (functional) expression does not have a well-defined result, we can still decide whether its surrounding relation holds.
|
||||
For example, the expression \mzninline{x div 0} is undefined, but the relation \mzninline{int_div(x, 0, y)} is said to be false.
|
||||
For example, the expression \mzninline{x div 0} is undefined, but the relation \mzninline{int_div(x, 0, y)} is \false{}.
|
||||
Values for \mzninline{x} and \mzninline{y} such that the relation holds do not exist.
|
||||
It can be said that the relational semantic makes the closest relational expression that contains an undefined expression false.
|
||||
It can be said that \gls{rel-sem} make the closest relational expression that contains an undefined expression \false{}.
|
||||
|
||||
\end{description}
|
||||
|
||||
@ -529,9 +529,9 @@ This is why \minizinc{} uses \gls{rel-sem} during its evaluation.
|
||||
|
||||
If we, for example, reconsider the \constraint{} from \cref{ex:back-undef}, we will find that \gls{rel-sem} will correspond to the intuitive expectation.
|
||||
When \mzninline{i} takes the value seven, the expression \mzninline{a[i]} is undefined.
|
||||
Its closest Boolean context will take the value false.
|
||||
In this case, that means the right-hand side of the implication becomes false.
|
||||
However, since the left-hand side of the implication is also false, the \constraint{} is \gls{satisfied}.
|
||||
Its closest Boolean context will take the value \false{}.
|
||||
In this case, that means the right-hand side of the implication becomes \false{}.
|
||||
However, since the left-hand side of the implication is also \false{}, the \constraint{} is \gls{satisfied}.
|
||||
|
||||
\textcite{frisch-2009-undefinedness} also show that different \solvers{} often employ different semantics.
|
||||
\minizinc{} therefore implements the \gls{rel-sem} by translating any potentially undefined expression into an expression that is always defined, by introducing appropriate \glspl{avar} and \gls{reified} \constraints{}.
|
||||
@ -599,7 +599,7 @@ Therefore, if the \solver{} needs to reconsider a search decision, then it must
|
||||
The most common method in \gls{cp} \solvers{} to keep track of \gls{domain} changes uses a \gls{trail} data structure \autocite{warren-1983-wam}.
|
||||
Every \domain{} change that is made during \gls{propagation}, after the first search decision, is stored in a list.
|
||||
Whenever a new search decision is made, the current position of the list is tagged.
|
||||
If the \solver{} now needs to undo a search decision (\ie\ \gls{backtrack}), it reverses all changes until it reaches the change that is tagged with the search decision.
|
||||
If the \solver{} now needs to undo a search decision (i.e., \gls{backtrack}), it reverses all changes until it reaches the change that is tagged with the search decision.
|
||||
Because all changes before the tagged point on the \gls{trail} were made before the search decision was made, it is guaranteed that these \domain{} changes do not depend on the search decision.
|
||||
Furthermore, because \gls{propagation} is performed to a \gls{fixpoint}, \gls{propagation} is never duplicated.
|
||||
|
||||
@ -800,7 +800,7 @@ In this field a \gls{sat} problem is generally standardized to be in \gls{cnf}.
|
||||
A \gls{cnf} is formulated in terms of literals.
|
||||
These are Boolean \variables{} \(x\) or their negations \(\neg x\).
|
||||
These literals are then used in a conjunction of disjunctive clauses: a Boolean formula in the form \(\forall \exists b_{i}\).
|
||||
To solve the \gls{sat} problem, the \solver{} has to find an \gls{assignment} for the \variables{} where at least one literal is true in every clause.
|
||||
To solve the \gls{sat} problem, the \solver{} has to find an \gls{assignment} for the \variables{} where at least one literal takes the value \true{} in every clause.
|
||||
|
||||
Even though the problem is proven to be hard to solve, much progress has been made towards solving even very complex \gls{sat} problems.
|
||||
Modern day \gls{sat} solvers, like Clasp \autocite{gebser-2012-clasp}, Kissat \autocite{biere-2021-kissat} and MiniSAT \autocite{een-2003-minisat}, solve instances of the problem with thousands of \variables{} and clauses.
|
||||
@ -1006,7 +1006,7 @@ Take, for example, the following \gls{opl} search definition:
|
||||
\end{plain}
|
||||
|
||||
This search strategy ensures that we first try to find a \gls{sol} where the \variable{} \mzninline{x} takes a value smaller than \mzninline{y}.
|
||||
If it does not find a \gls{sol}, then it tries finding a \gls{sol} where the opposite is true.
|
||||
If it does not find a \gls{sol}, then it tries finding a \gls{sol} by making the opposite assumption.
|
||||
This search specification, like many others imaginable, cannot be enforced using \minizinc{}'s \gls{search-heuristic} \glspl{annotation}.
|
||||
|
||||
To support \gls{opl}'s dedicated search language, the language is tightly integrated with its supported \solvers{}.
|
||||
@ -1092,7 +1092,7 @@ Although the modeller is able to decide on representation, Conjure has been exte
|
||||
|
||||
\paragraph{Essence'}
|
||||
|
||||
Once a \cmodel{} is turned into \gls{ess-prime} it is at a very similar level to a \minizinc{} model.
|
||||
Once a \cmodel{} is turned into \gls{ess-prime}, it is at a very similar level to a \minizinc{} model.
|
||||
This can be illustrated using the N-Queens problem introduced in \cref{ex:back-nqueens}.
|
||||
The same problem is modelled in \gls{ess-prime} is shown in \cref{lst:back-ep-nqueens}.
|
||||
Apart from the syntax used, both languages use the exact same concepts to model the problem.
|
||||
@ -1144,7 +1144,7 @@ In a term rewriting rule, a term can also contain a term variable, which capture
|
||||
\end{example}
|
||||
|
||||
Two properties of a \gls{trs} that are often studied are \gls{termination} and \gls{confluence}.
|
||||
A \gls{trs} is said to be terminating if, no-matter what order the term rewriting rules are applied, it always arrives at a \gls{normal-form} (\ie{} a set of \glspl{term} for which none of the rules apply).
|
||||
A \gls{trs} is said to be terminating if, no-matter what order the term rewriting rules are applied, it always arrives at a \gls{normal-form} (i.e., a set of \glspl{term} for which none of the rules apply).
|
||||
A \gls{trs} is confluent if, no-matter what order the term rewriting rules are applied, it always arrives at the same \gls{normal-form} (if it arrives at a \gls{normal-form}).
|
||||
|
||||
It is trivial to see that our previous example is non-terminating, since rule \(r_{3}\) can be repeated an infinite amount of times.
|
||||
@ -1192,7 +1192,8 @@ This can discover all possible correct ways to rewrite the program.
|
||||
|
||||
To implement this mechanism there is a tight integration between the \solver{}, referred to as the constraint store, and the evaluator of the constraint logic program.
|
||||
In addition to just adding \constraints{}, the program also inspects the status of the constraint store and retracts \constraints{} from the constraint store.
|
||||
This allows the program to detect when the constraint store has become inconsistent and then \gls{backtrack} the constraint store to the last decision (\ie\ restore the constraint store to its state before the last decision was made) and try the next rewriting rule.
|
||||
This allows the program to detect when the constraint store has become inconsistent.
|
||||
It can then \gls{backtrack} the constraint store to the last decision (i.e., restore the constraint store to its state before the last decision was made) and try the next rewriting rule.
|
||||
|
||||
The strength of the constraint store affects the correctness of a constraint logic program.
|
||||
Some \solvers{} are incomplete; they are unable to tell if some of their \constraints{} are \gls{satisfied} or not.
|
||||
@ -1229,7 +1230,7 @@ This means that, for some rules, multiple terms must match, to apply the rule.
|
||||
\begin{itemize}
|
||||
\item The first rule states that if \texttt{X = Y}, then \texttt{X -> Y} is logically true.
|
||||
This rule removes the term \texttt{X -> Y}.
|
||||
Since the \constraint{} is said to be logically true, nothing gets added.
|
||||
Since the \constraint{} is already \gls{satisfied}, nothing gets added.
|
||||
\texttt{X = Y} functions as a guard.
|
||||
This \solver{} \gls{native} \constraint{} is required for the rewriting rule to apply.
|
||||
|
||||
@ -1310,7 +1311,7 @@ For instance, in a call each argument is rewritten before the call itself is rew
|
||||
An exception to this bottom-up approach is the \gls{rewriting} of \glspl{comprehension} \mzninline{[@\(E\)@ | @\(i\)@ in @\(S\)@ where @\(F\)@]}.
|
||||
\Gls{rewriting} \(E\) requires instantiating the identifier \(i\) with the values from the set \(S\), and evaluating the condition \(W\).
|
||||
The \compiler{} therefore iterates through all values in \(S\), binds the values to the specified identifier(s), and rewrites the condition \(F\).
|
||||
If \(F\) is true, it rewrites the expression \(E\) and collects the result.
|
||||
If \(F\) is \true{}, it rewrites the expression \(E\) and collects the result.
|
||||
Once the \gls{generator} is exhausted, the compiler rewrites its surrounding expression using the collected values.
|
||||
|
||||
The \gls{decomp} system in \minizinc{} is defined in terms of function declarations.
|
||||
@ -1331,7 +1332,7 @@ The creation of this \gls{avar} and defining \constraints{} happens in one of tw
|
||||
To constrain this \gls{avar}, the \compiler{} then adds the \gls{reif} of the \constraint{}.
|
||||
This \constraint{} contains a variation of the call that would have been generated for the expression in \rootc{} context.
|
||||
The name of the function is appended with \mzninline{_reif} and an extra Boolean \variable{} argument is added to the call.
|
||||
The definition of this \constraint{} should implement the \gls{reif} of the original expression: setting the additional argument to true if the \constraint{} is \gls{satisfied}, and false otherwise.
|
||||
The definition of this \constraint{} should implement the \gls{reif} of the original expression: setting the additional argument to \true{} if the \constraint{} is \gls{satisfied}, and \false{} otherwise.
|
||||
For example, consider the following \minizinc{} \constraint{}.
|
||||
|
||||
\begin{mzn}
|
||||
@ -1424,13 +1425,13 @@ However, the expression defining \mzninline{y}, \mzninline{pow(i, 2)}, is then f
|
||||
In either case, it can be very beneficial for the efficiency of the solving process if we detect that a \gls{reified} \constraint{} is in fact not required.
|
||||
|
||||
If a \constraint{} is present in the \rootc{} context, it means that it must hold globally.
|
||||
If the same \constraint{} is used in a non-\rootc{} context, \gls{cse} can then replace them with the constant true, avoiding the need for \gls{reif} (or in fact any evaluation).
|
||||
If the same \constraint{} is used in a non-\rootc{} context, \gls{cse} can then replace them with the constant \true{}, avoiding the need for \gls{reif} (or in fact any evaluation).
|
||||
|
||||
We harness \gls{cse} to store the evaluation context when a \constraint{} is added, and detect when the same \constraint{} is used in both contexts.
|
||||
Whenever a lookup in the \gls{cse} table is successful, action is taken depending on both the current and stored evaluation context.
|
||||
If the stored expression was in \rootc{} context, then the constant true is used, independent of the current context.
|
||||
If the stored expression was in \rootc{} context, then the constant \true{} is used, independent of the current context.
|
||||
Otherwise, if the stored expression was in non-\rootc{} context and the current context is non-\rootc{}, then the stored result variable is used.
|
||||
Finally, if the stored expression was in non-\rootc{} context and the current context is \rootc{} context, then the previous result is replaced by the constant true and the evaluation proceeds as normal with the \rootc{} context \constraint{}.
|
||||
Finally, if the stored expression was in non-\rootc{} context and the current context is \rootc{} context, then the previous result is replaced by the constant \true{} and the evaluation proceeds as normal with the \rootc{} context \constraint{}.
|
||||
|
||||
\begin{example}
|
||||
Consider the following \minizinc{} fragment.
|
||||
@ -1443,15 +1444,15 @@ Finally, if the stored expression was in non-\rootc{} context and the current co
|
||||
\end{mzn}
|
||||
|
||||
If we process the \constraints{} in order, we create a \gls{reified} call to \mzninline{q(x)} when \gls{rewriting} the first \constraint{}.
|
||||
Suppose when we rewrite the second \constraint{}, we discover \mzninline{t(x,y)} is true, fixing \mzninline{b1}.
|
||||
Suppose when we rewrite the second \constraint{}, we discover \mzninline{t(x,y)} is \true{}, fixing \mzninline{b1}.
|
||||
When we then process \mzninline{q(x)} in instantiation of the call \mzninline{p(x,y)}, it is in the \rootc{} context.
|
||||
So \gls{cse} needs to set \mzninline{b0} to true.
|
||||
So \gls{cse} needs to set \mzninline{b0} to \true{}.
|
||||
\end{example}
|
||||
|
||||
\subsection{Constraint Propagation}%
|
||||
\label{subsec:back-adjusting-dom}
|
||||
|
||||
Sometimes a \constraint{} can be detected to be true based on its semantics, and the known \glspl{domain} of \variables{}.
|
||||
Sometimes a \constraint{} can be detected \gls{satisfied} based on its semantics, and the known \glspl{domain} of \variables{}.
|
||||
For example, consider the \constraint{} \mzninline{3*x + 7*y > 8}, and assume that both \mzninline{x} and \mzninline{y} cannot be smaller than one.
|
||||
In this case, we can determine that the \constraint{} is always \gls{satisfied}, and remove it from the model without changing satisfiability.
|
||||
This is a simple form of \gls{propagation}, which, as discussed in \cref{subsec:back-cp}, also tightens the \glspl{domain} of \variables{} in the presence of a \constraint{}.
|
||||
@ -1479,11 +1480,11 @@ Finally, it can also be helpful for \solvers{} as they may need to decide on a r
|
||||
|
||||
If we however consider the first \constraint{}, then we deduce that \mzninline{a} must always take a value that is 4 or lower.
|
||||
When the compiler adjusts the domain of \mzninline{a} while \gls{rewriting} the first \constraint{}, then the second \constraint{} can be simplified.
|
||||
The expression \mzninline{a > 5} is known to be false, which means that the \constraint{} is simplified to true.
|
||||
The expression \mzninline{a > 5} cannot hold, which means that the \constraint{} is already \gls{satisfied} and can be removed.
|
||||
\end{example}
|
||||
|
||||
During \gls{rewriting}, the \minizinc{} compiler actively removes values from the \domain{} when it encounters \constraints{} that trivially reduce it.
|
||||
For example, it detects \constraints{} with a single comparison expression between a \variable{} and a \parameter{} (\eg\ \mzninline{x != 5}), \constraints{} with a single comparison between two \variables{} (\eg\ \mzninline{x >= y}), \constraints{} that directly change the domain (\eg\ \mzninline{x in 3..5}).
|
||||
For example, it detects \constraints{} with a single comparison expression between a \variable{} and a \parameter{} (e.g., \mzninline{x != 5}), \constraints{} with a single comparison between two \variables{} (e.g., \mzninline{x >= y}), \constraints{} that directly change the domain (e.g., \mzninline{x in 3..5}).
|
||||
It even performs more complex \gls{propagation} for some known \constraints{}.
|
||||
For example, it will reduce the \domains{} for \mzninline{int_times} and \mzninline{int_div}, and we will see in the next subsection how \gls{aggregation} will help simplify certain \constraints{}.
|
||||
|
||||
@ -1522,7 +1523,7 @@ It is therefore important that equalities are found early in the \gls{rewriting}
|
||||
\label{subsec:back-aggregation}
|
||||
|
||||
Complex \minizinc{} expressions sometimes result in the creation of many \glspl{avar} to represent intermediate results.
|
||||
This is in particular true for linear and Boolean equations that are generally written using \minizinc{} operators.
|
||||
This is in particular \true{} for linear and Boolean equations that are generally written using \minizinc{} operators.
|
||||
|
||||
\begin{example}%
|
||||
\label{ex:back-agg}
|
||||
@ -1561,7 +1562,7 @@ The \gls{rewriting} process continues by \gls{rewriting} this aggregated \constr
|
||||
\subsection{Delayed Rewriting}%
|
||||
\label{subsec:back-delayed-rew}
|
||||
|
||||
Adding \gls{propagation} during \gls{rewriting} means that the system becomes non-confluent, and some orders of execution may produce ``better'', \ie{} more compact or more efficient, \flatzinc{}.
|
||||
Adding \gls{propagation} during \gls{rewriting} means that the system becomes non-confluent, and some orders of execution may produce ``better'', i.e., more compact or more efficient, \flatzinc{}.
|
||||
|
||||
\begin{example}
|
||||
The following example is similar to code found in the \minizinc{} libraries of \gls{mip} \solvers{}.
|
||||
@ -1572,7 +1573,7 @@ Adding \gls{propagation} during \gls{rewriting} means that the system becomes no
|
||||
\end{mzn}
|
||||
|
||||
This predicate expresses the \constraint{} \mzninline{b -> x<=0}, using a well-known technique called the ``Big M method''.
|
||||
The expression \mzninline{ub(x)} returns a valid upper bound for \mzninline{x}, \ie{} a fixed value known to be greater than or equal to \mzninline{x}.
|
||||
The expression \mzninline{ub(x)} returns a valid upper bound for \mzninline{x}, i.e., a fixed value known to be greater than or equal to \mzninline{x}.
|
||||
This could be the initial upper bound \mzninline{x} was declared with, or the current value adjusted by the \minizinc{} \compiler{}.
|
||||
If \mzninline{b} takes the value 0, the expression \mzninline{ub(x)*(1-b)} is equal to \mzninline{ub(x)}, and the \constraint{} \mzninline{x <= ub(x)} holds trivially.
|
||||
If \mzninline{b} takes the value 1, \mzninline{ub(x)*(1-b)} is equal to 0, enforcing the \constraint{} \mzninline{x <= 0}.
|
||||
@ -1614,7 +1615,7 @@ After the \compiler{} has finished \gls{rewriting} the \minizinc{} instance, it
|
||||
The primary role of this phase is to further perform \gls{propagation} until \gls{fixpoint}.
|
||||
However, this phase operates at the level of the \gls{slv-mod}, where all \constraints{} are now \gls{native} \constraints{} of the target \solver{}.
|
||||
This means that, depending on the target \solver{}, the \compiler{} will not be able to understand the meaning of all \constraints{}.
|
||||
It only understands the meaning of the standard \flatzinc{} \constraints{}, but not any of the \solver{} specific \gls{native} \constraints{}.
|
||||
It only recognizes the standard \flatzinc{} \constraints{}, but not any of the \solver{} specific \gls{native} \constraints{}.
|
||||
For the standard \flatzinc{} \constraints{}, it employs \gls{propagation} methods, as discussed in \cref{subsec:back-cp}, are used to eliminate values from \domains{} and simplify \constraints{}.
|
||||
|
||||
In the current implementation, the \minizinc{} \compiler{} propagates mostly Boolean \constraints{} in this phase.
|
||||
|
@ -168,7 +168,7 @@ The translation from \minizinc{} to \microzinc{} involves the following steps.
|
||||
In contrast to \minizinc{}, a \microzinc{} expression must be total.
|
||||
\textcite{stuckey-2013-functions} have extensively examined these problems and describe how to transform any partial function into a total function while maintaining the relational semantics of the original \cmodel{}.
|
||||
A general approach for describing the partiality in \microzinc{} functions is to make the function return an additional Boolean \variable{}.
|
||||
This \variable{} indicates whether the result of the function call is defined \wrt{} the function arguments.
|
||||
This \variable{} indicates whether the result of the function call is defined w.r.t. the function arguments.
|
||||
The resulting value of the function is then adjusted to return a predefined value when it would normally be undefined.
|
||||
For example, the \mzninline{element} function in \minizinc{} is declared as follows.
|
||||
|
||||
@ -251,7 +251,7 @@ The translation from \minizinc{} to \microzinc{} involves the following steps.
|
||||
\subsection{Partial Evaluation of \glsentrytext{nanozinc}}\label{sub:rew-partial}
|
||||
|
||||
Each call in a \nanozinc{} program is either a call to a \gls{native} \constraint{}, or it has a corresponding \microzinc{} function definition.
|
||||
The goal of partial evaluation is to rewrite the \nanozinc{} program into a \gls{slv-mod}, \ie{} a program where all calls are calls to \gls{native} \constraints{}.
|
||||
The goal of partial evaluation is to rewrite the \nanozinc{} program into a \gls{slv-mod}, i.e., a program where all calls are calls to \gls{native} \constraints{}.
|
||||
|
||||
To achieve this, we define the semantics of \microzinc{} as a \gls{rewriting} system that produces \nanozinc{} calls.
|
||||
Each non-\gls{native} call in a \nanozinc{} program can then be replaced with the result of evaluating the corresponding \microzinc{} function.
|
||||
@ -284,7 +284,7 @@ In order to track these dependencies, \nanozinc{} attaches \constraints{} that d
|
||||
A \nanozinc{} program (\cref{fig:rew-nzn-syntax}) consists of a topologically-ordered list of declarations of \variables{} and \constraints{}.
|
||||
\Variables{} are declared with an identifier, a domain, and are associated with a list of attached \constraints{}.
|
||||
\Constraints{} can also occur at the top-level of the \nanozinc{} program.
|
||||
These are said to be the ``root-context'' \constraints{} of the \cmodel{}, \ie{} those that have to hold globally and are not just used to define an \gls{avar}.
|
||||
These are said to be the \rootc{}-context \constraints{} of the \cmodel{}, i.e., those that have to hold globally and are not just used to define an \gls{avar}.
|
||||
Only root-context \constraints{} can effectively constrain the overall problem.
|
||||
\Constraints{} attached to \variables{} originate from function calls, and since all functions are guaranteed to be total, attached \constraints{} can only define the function result.
|
||||
|
||||
@ -316,10 +316,10 @@ The core of the proposed \minizinc{} architecture is an abstract machine that re
|
||||
We can now formally define the rewriting rules for this abstract machine.
|
||||
|
||||
The full set of rules appears in \cref{fig:rew-rewrite-to-nzn-calls,fig:rew-rewrite-to-nzn-let,fig:rew-rewrite-to-nzn-other}.
|
||||
To simplify presentation, we assume that all rules that introduce new identifiers into the \nanozinc{} program do so in a way that ensures those identifiers are fresh (\ie{} not used in the rest of the \nanozinc{} program), by suitable alpha renaming.
|
||||
We also present our rules using a call by name evaluation strategy, \ie{} the arguments to function calls are substituted into function body.
|
||||
To simplify presentation, we assume that all rules that introduce new identifiers into the \nanozinc{} program do so in a way that ensures those identifiers are fresh (i.e., not used in the rest of the \nanozinc{} program), by suitable alpha renaming.
|
||||
We also present our rules using a \emph{call by name} evaluation strategy, i.e., the arguments to function calls are substituted into function body.
|
||||
As such, they are only evaluated when required for the result of the function.
|
||||
Although pure \microzinc{} behaves the same under any call evaluation strategy, in implementation a call by value strategy might provide more predictable behaviour with debugging functions in the \minizinc{} language, such as \mzninline{trace} and \mzninline{assert}.
|
||||
Although pure \microzinc{} behaves the same under any call evaluation strategy, in implementation a \emph{call by value} strategy might provide more predictable behaviour with debugging functions in the \minizinc{} language, such as \mzninline{trace} and \mzninline{assert}.
|
||||
|
||||
\begin{figure*}[p]
|
||||
\centering
|
||||
@ -454,15 +454,15 @@ We use the notation \(x_{\langle{}i\rangle}\) to mark the \(i^{\text{th}}\) memb
|
||||
\caption{\label{fig:rew-rewrite-to-nzn-other} Rewriting rules for partial evaluation of other \microzinc{} expressions to \nanozinc{}.}
|
||||
\end{figure*}
|
||||
|
||||
Finally, the rules in \cref{fig:rew-rewrite-to-nzn-other} handle the evaluation of \variables{}, constants, \glspl{conditional} and \glspl{comprehension}.
|
||||
Finally, the rules in \cref{fig:rew-rewrite-to-nzn-other} handle the evaluation of \variables{}, constants, \glspl{conditional}, and \glspl{comprehension}.
|
||||
The (Ident) rule looks up a \variable{} in the environment and returns the \variable{} itself to be used in any \constraints{}.
|
||||
The (Const) rule simply returns the constant.
|
||||
The (Acess) rule evaluates the \gls{array} expression \(x\) and the index \(i\).
|
||||
It then returns the element from the evaluated \gls{array} chosen by the evaluated index.
|
||||
Note that, in well-defined \microzinc{}, the index \(i\) must evaluate to a value within the index range of the evaluated \gls{array} \(x\).
|
||||
The (If\(_T\)) and (If\(_F\)) rules evaluate the if condition and then return the result of the then or else branch appropriately.
|
||||
The (WhereT) rule evaluates the guard of a where \gls{comprehension} and if true returns the resulting expression in a list.
|
||||
The (WhereF) rule evaluates the guard and when false returns an empty list.
|
||||
The (WhereT) rule evaluates the guard of a where \gls{comprehension} and if \true{} returns the resulting expression in a list.
|
||||
The (WhereF) rule evaluates the guard and when \false{} returns an empty list.
|
||||
The (ListG) rule evaluates the iteration set \(PE\) to get its value \(S\), which must be fixed.
|
||||
It then evaluates the expression \(E\) with all the different possible values \(v \in S\) of the generator \(x\), collecting the additional \nanozinc{} definitions \(\Env_v\).
|
||||
It returns the concatenation of the resulting lists with all the additional \nanozinc{} items.
|
||||
@ -528,10 +528,10 @@ The \constraints{} directly succeeding the declaration prepended by \texttt{↳}
|
||||
constraint bool_or(b, c);
|
||||
\end{nzn}
|
||||
|
||||
Evaluating \mzninline{constraint c} has resulted in the domain of \mzninline{c} to be bound to true.
|
||||
Evaluating \mzninline{constraint c} has resulted in the domain of \mzninline{c} to be \gls{fixed} to \true{}.
|
||||
The disjunction now trivially holds, independent of the value of \mzninline{b}.
|
||||
The \gls{reif} of \mzninline{abs(x) > y} is therefore not required.
|
||||
However, the \gls{rewriting} has to choose a particular order in which arguments are evaluated, so it is always possible that it already evaluated the left-hand side before ``noticing'' that the disjunction is true.
|
||||
However, the \gls{rewriting} has to choose a particular order in which arguments are evaluated, so it is always possible that it already evaluated the left-hand side before ``noticing'' that the disjunction is \gls{satisfied}.
|
||||
|
||||
If the system now simplifies the \constraint{} \mzninline{bool_or(b, c)} to true, then the identifier \mzninline{b} will become unused outside its attached \constraints{}.
|
||||
It was only referenced from the \mzninline{bool_or} call.
|
||||
@ -654,7 +654,7 @@ However, since equations in \minizinc{} always concern scalar variables rather t
|
||||
|
||||
\Gls{rewriting} a function call that has a \microzinc{} definition and \gls{rewriting} a \constraint{} due to \gls{propagation} are very similar.
|
||||
The \interpreter{} therefore simply interleaves both forms of \gls{rewriting}.
|
||||
Efficient \gls{propagation} engines ``wake up'' a \gls{propagator} only when one of its \variables{} has received an update (\ie{} when its \domain{} has been shrunk).
|
||||
Efficient \gls{propagation} engines ``wake up'' a \gls{propagator} only when one of its \variables{} has received an update (i.e., when its \domain{} has been shrunk).
|
||||
To enable this, the \interpreter{} needs to keep a data structure linking \variables{} to the \constraints{} where they appear (in addition to the reverse links from calls to the \variables{} in their arguments).
|
||||
These links do not take part in the reference counting.
|
||||
|
||||
@ -722,7 +722,7 @@ It is clear that when an expression is reused by returning it from the \gls{cse}
|
||||
However, the entries in the \gls{cse} table should not keep the corresponding variables alive.
|
||||
Otherwise, none of the \variables{} would ever become unused.
|
||||
Therefore, we treat \gls{cse} entries as weak references.
|
||||
They reference a \variable{}, but do not affect its liveness (\ie{} increase its reference count).
|
||||
They reference a \variable{}, but do not affect its liveness (i.e., increase its reference count).
|
||||
If an entry is found in the \gls{cse} table with a reference count of zero, it is removed from the table and its contents are not used.
|
||||
|
||||
The usage of a \gls{cse} table can be costly.
|
||||
@ -794,8 +794,8 @@ In the following we present experimental results on basic \gls{rewriting} perfor
|
||||
A description of the used computational environment, \minizinc{} instances, and versioned software has been included in \cref{ch:benchmarks}.
|
||||
|
||||
For our first experiment, we selected 17 models from the annual \minizinc{} challenge and compiled 5 instances of each model to \flatzinc{}, using the current \minizinc{} release version 2.5.5 and the new prototype system.
|
||||
In both cases we use the standard \minizinc{} library of \glspl{global} (\ie{} we decompose those \constraints{} rather than using \solver{} \gls{native} \constraints{}, in order to stress-test the \gls{rewriting}).
|
||||
We measured pure \gls{rewriting} time, \ie{} without time required to parse and type check in version 2.5.5, and without time required for compilation to \microzinc{} in the new system (compilation is usually very fast).
|
||||
In both cases we use the standard \minizinc{} library of \glspl{global} (i.e., we decompose those \constraints{} rather than using \solver{} \gls{native} \constraints{}, in order to stress-test the \gls{rewriting}).
|
||||
We measured pure \gls{rewriting} time, i.e., without time required to parse and type check in version 2.5.5, and without time required for compilation to \microzinc{} in the new system (compilation is usually very fast).
|
||||
Times are averages of 10 runs.
|
||||
|
||||
\Cref{sfig:rew-compareruntime} compares the \gls{rewriting} time for each of \instances{}.
|
||||
|
@ -15,7 +15,7 @@
|
||||
The complex expression language used in \cmls{}, such as \minizinc{}, often requires the use of \gls{reif} in order to arrive at a \gls{slv-mod}.
|
||||
If the Boolean expression \mzninline{pred(...)} is seen in a non-\rootc{} context, then a new Boolean \variable{} \mzninline{b} is introduced to replace the expression.
|
||||
We call \mzninline{b} the \gls{cvar} of the expression.
|
||||
The \gls{rewriting} process then enforces a \constraint{} \mzninline{pred_reif(...,b)}, which binds the \variable{} to be the truth-value of the expression (\ie\ \mzninline{b <-> pred(...)}).
|
||||
The \gls{rewriting} process then enforces a \constraint{} \mzninline{pred_reif(...,b)}, which binds the \variable{} to be the truth-value of the expression (i.e., \mzninline{b <-> pred(...)}).
|
||||
|
||||
\textcite{feydy-2011-half-reif} show that although using \gls{reif} in the \gls{rewriting} process is well-understood, it suffers from certain weaknesses.
|
||||
|
||||
@ -36,11 +36,11 @@ It follows from the idea that in many cases it is sufficient to use the logical
|
||||
Additionally, for many \solvers{} the \gls{decomp} of a \gls{reif} is more complex than the \gls{decomp} of a \gls{half-reif}.
|
||||
We will show that using \glspl{half-reif} can therefore lead to a reduction in \gls{native} \constraints{} in the \gls{slv-mod}.
|
||||
|
||||
\Gls{half-reif} can be used instead of full \gls{reif} when the resulting \gls{cvar} can never be forced to be false.
|
||||
\Gls{half-reif} can be used instead of full \gls{reif} when the resulting \gls{cvar} can never be forced to be \false{}.
|
||||
This requirement follows from the difference between implication and logical equivalences.
|
||||
Setting the left-hand side of an implication to false does not influence the value on the right-hand side.
|
||||
This is why the \gls{cvar} should never be forced to be false, since this would not enforce the negation of the \constraint{}.
|
||||
Setting the right-hand side of an implication to true also does not influence the left-hand side.
|
||||
Setting the left-hand side of an implication to \false{} does not influence the value on the right-hand side.
|
||||
This is why the \gls{cvar} should never be forced to be \false{}, since this would not enforce the negation of the \constraint{}.
|
||||
Setting the right-hand side of an implication to \true{} also does not influence the left-hand side.
|
||||
This is, however, not an issue since in this case the value can just be assigned by the \gls{propagation} of other \constraints{} or a \gls{search-decision}.
|
||||
|
||||
\begin{example}
|
||||
@ -61,8 +61,8 @@ This is, however, not an issue since in this case the value can just be assigned
|
||||
constraint b1 \/ b2;
|
||||
\end{mzn}
|
||||
|
||||
However, independent of the value of \mzninline{b1}, if \mzninline{b2} takes the value true, then it can never make the disjunction false.
|
||||
Therefore, \mzninline{propagation} of the disjunction can never force \mzninline{b2} to take the value false.
|
||||
However, independent of the value of \mzninline{b1}, if \mzninline{b2} takes the value \true{}, then it can never make the disjunction \false{}.
|
||||
Therefore, \gls{propagation} of the disjunction can never force \mzninline{b2} to take the value \false{}.
|
||||
Consequently, this means using \gls{half-reif} is \gls{eqsat}.
|
||||
\Gls{rewriting} using \gls{half-reif} will result in the following model.
|
||||
|
||||
@ -87,14 +87,14 @@ Since Boolean expressions in \minizinc{} can be used in, for example, integer ex
|
||||
\end{mzn}
|
||||
|
||||
Making the left-hand side of the \constraint{} larger will only ever help satisfy the \constraint{}.
|
||||
This means \mzninline{propagation} of the expressions \mzninline{x = 5} can never force them to take the value false.
|
||||
This means \gls{propagation} of the expressions \mzninline{x = 5} can never force them to take the value \false{}.
|
||||
The \gls{rewriting} process can thus use \glspl{half-reif} instead of \glspl{reif} for these expressions.
|
||||
\end{example}
|
||||
|
||||
To systematically analyse whether Boolean expressions can be \gls{half-reified}, we study the \emph{monotonicity} of \constraints{} \wrt{} an expression.
|
||||
A relation \( r(\ldots{}, a, \ldots{}) \) is said to be \emph{monotone} \wrt{} its argument \(a\) when given two possible values for \(a\), \(x\) and \(y\), if \(x > y\), then \(r(\ldots{}, x, \ldots{}) \geq{} r(\ldots{}, y, \ldots{})\), independent of any other arguments.
|
||||
Contrariwise, the relation is said to be \emph{antitone} \wrt{} its argument \(a\) if given two possible values for \(a\), \(x\) and \(y\), if \(x > y\), then \(r(\ldots{}, x, \ldots{}) \leq{} r(\ldots{}, y, \ldots{}) \), independent of any other arguments.
|
||||
Where, for clarification, we assume \( \text{false} < \text{true} \).
|
||||
To systematically analyse whether Boolean expressions can be \gls{half-reified}, we study the \emph{monotonicity} of \constraints{} w.r.t. an expression.
|
||||
A relation \( r(\ldots{}, a, \ldots{}) \) is said to be \emph{monotone} w.r.t. its argument \(a\) when given two possible values for \(a\), \(x\) and \(y\), if \(x > y\), then \(r(\ldots{}, x, \ldots{}) \geq{} r(\ldots{}, y, \ldots{})\), independent of any other arguments.
|
||||
Contrariwise, the relation is said to be \emph{antitone} w.r.t. its argument \(a\) if given two possible values for \(a\), \(x\) and \(y\), if \(x > y\), then \(r(\ldots{}, x, \ldots{}) \leq{} r(\ldots{}, y, \ldots{}) \), independent of any other arguments.
|
||||
Where, for clarification, we assume \( \false{} < \true{} \).
|
||||
|
||||
Using these definitions, we introduce extra distinctions in the context of expressions.
|
||||
Before, we would merely distinguish between \rootc{} context and non-\rootc{} context.
|
||||
@ -102,21 +102,21 @@ Now, we will categorize the latter into the following three contexts.
|
||||
|
||||
\begin{description}
|
||||
|
||||
\item[\posc{}] An expression is in \posc{} context when the enclosing \constraint{} (in \rootc{} context) is \textbf{monotone} \wrt{} the expression.
|
||||
\item[\posc{}] An expression is in \posc{} context when the enclosing \constraint{} (in \rootc{} context) is \textbf{monotone} w.r.t. the expression.
|
||||
|
||||
\item[\negc{}] An expression is in \negc{} context when the enclosing \constraint{} (in \rootc{} context) is \textbf{antitone} \wrt{} the expression.
|
||||
\item[\negc{}] An expression is in \negc{} context when the enclosing \constraint{} (in \rootc{} context) is \textbf{antitone} w.r.t. the expression.
|
||||
|
||||
\item[\mixc{}] An expression is in \mixc{} context when the enclosing \constraint{} (in \rootc{} context) it is \textbf{neither} monotone, nor antitone \wrt{} the expression.
|
||||
\item[\mixc{}] An expression is in \mixc{} context when the enclosing \constraint{} (in \rootc{} context) it is \textbf{neither} monotone, nor antitone w.r.t. the expression.
|
||||
|
||||
\end{description}
|
||||
|
||||
Determining the monotonicity of a \constraint{} \wrt{} an expression is a hard problem.
|
||||
Determining the monotonicity of a \constraint{} w.r.t. an expression is a hard problem.
|
||||
An expression might be monotone or antitone only through complex interactions, possibly through unknown \gls{native} \constraints{}.
|
||||
Therefore, for our analysis, we slightly relax these definitions.
|
||||
We say an expression is in \mixc{} context when it cannot be determined whether the enclosing \constraint{} is monotone or antitone \wrt{} the expression.
|
||||
We say an expression is in \mixc{} context when it cannot be determined whether the enclosing \constraint{} is monotone or antitone w.r.t. the expression.
|
||||
|
||||
Expressions in \posc{} context are the ones we discussed before.
|
||||
A Boolean expression in \posc{} context cannot be forced to be false.
|
||||
A Boolean expression in \posc{} context cannot be forced to be \false{}.
|
||||
As such, the\gls{half-reif} can be used for expressions in \posc{} context.
|
||||
Although expressions in a \negc{} context cannot be directly \gls{half-reified}, the negation of an expression in a \negc{} context can be \gls{half-reified}.
|
||||
|
||||
@ -143,7 +143,6 @@ Expressions in a \mixc{} context are in a position where \gls{half-reif} is impo
|
||||
Only full \gls{reif} can be used for expressions that are in this context.
|
||||
|
||||
\begin{example}
|
||||
|
||||
An example of a \constraint{} that introduces \mixc{} contexts is the following.
|
||||
|
||||
\begin{mzn}
|
||||
@ -153,8 +152,7 @@ Only full \gls{reif} can be used for expressions that are in this context.
|
||||
This \constraint{} forces either \mzninline{x} or \mzninline{y}, but not both, to take the value five.
|
||||
The equalities in this constraint are in \mixc{} context, because whether \mzninline{y} can and must take the value 5 now directly depends on if \mzninline{x} has already taken the value five, and vice versa.
|
||||
As such, when \mzninline{x} takes the value five it forces \mzninline{y} to not take the value five.
|
||||
This means we cannot use a \gls{half-reif}, since it does not enforce the negated \constraint{}
|
||||
|
||||
This means we cannot use a \gls{half-reif}, since it does not enforce the negated \constraint{}.
|
||||
\end{example}
|
||||
|
||||
|
||||
@ -166,32 +164,32 @@ Logically, there are three tasks that a \gls{propagator} for any \constraint{} m
|
||||
\begin{enumerate}
|
||||
\item \(check\) whether the \constraint{} can still be satisfied (and otherwise declare the current state \gls{unsat}),
|
||||
\item \(prune\) values from the \glspl{domain} of \variables{} that would violate\glsadd{violated} the \constraint{}, and
|
||||
\item check whether the \constraint{} is \(entailed\) (\ie{}, proven to be \gls{satisfied}).
|
||||
\item check whether the \constraint{} is \(entailed\) (i.e., proven to be \gls{satisfied}).
|
||||
\end{enumerate}
|
||||
|
||||
When creating a \gls{propagator} for the \gls{half-reif} of a \constraint{}, it can be constructed from these tasks.
|
||||
The \gls{half-reified} \gls{propagator} is dependent on an additional argument \(b\), the \gls{cvar}.
|
||||
The Boolean \variable{} can be in three states, it can currently not have been assigned a value, it can be assigned true, or it can be assigned false.
|
||||
The Boolean \variable{} can be in three states, it can currently not have been assigned a value, it can be assigned \true{}, or it can be assigned \false{}.
|
||||
Given \(check\), \(prune\), \(entailed\), and \(b\) \cref{alg:half-prop} shows pseudocode for the \gls{propagation} of the \gls{half-reif} of the \constraint{}.
|
||||
|
||||
\begin{algorithm}[t]
|
||||
|
||||
\KwIn{The functions \(check\), \(prune\), and \(entailed\) that form the for non-\gls{reified} propagator of \constraint{} \(c\) and a Boolean \gls{cvar} \(b\).
|
||||
}
|
||||
\KwResult{This pseudocode propagates the \gls{half-reif} of \(c\) (\ie{} \(b \implies\ c\)) and returns whether the \constraint is entailed.}
|
||||
\KwResult{This pseudocode propagates the \gls{half-reif} of \(c\) (i.e., \(b \implies\ c\)) and returns whether the \constraint is entailed.}
|
||||
|
||||
\BlankLine{}
|
||||
\If{\(b \text{ is unassigned}\)}{
|
||||
\If{\(\neg{}check()\)}{
|
||||
\(b \longleftarrow \text{false}\)\;
|
||||
\Return{} \(\text{true}\)\;
|
||||
\(b \longleftarrow \false{}\)\;
|
||||
\Return{} \(\true{}\)\;
|
||||
}
|
||||
}
|
||||
\If{\(\texttt{b} = \text{true}\)}{
|
||||
\If{\(\texttt{b} = \true{}\)}{
|
||||
\(prune()\)\;
|
||||
\Return{} \(entailed()\)\;
|
||||
}
|
||||
\Return{} \(\text{false}\)\;
|
||||
\Return{} \(\false{}\)\;
|
||||
\caption{\label{alg:half-prop} \gls{propagation} pseudocode for the \gls{half-reif} of a \constraint{} \(c\), based on the \gls{propagator} for \(c\).}
|
||||
\end{algorithm}
|
||||
|
||||
@ -214,31 +212,31 @@ Although this might seem reasonable for small \constraints{}, such as integer eq
|
||||
|
||||
\KwIn{The functions \(check\), \(prune\), and \(entailed\) that form the for non-\gls{reified} propagator of \(c\), The functions \(checkNeg\), \(pruneNeg\), and \(entailedNeg\) that form the for non-\gls{reified} \gls{propagator} of \(\neg{} c\), and a Boolean \gls{cvar} \(b\).
|
||||
}
|
||||
\KwResult{This pseudocode propagates the \gls{reif} of \(c\) (\ie{} \(b \leftrightarrow{} c\)) and returns whether the \constraint{} is entailed.}
|
||||
\KwResult{This pseudocode propagates the \gls{reif} of \(c\) (i.e., \(b \leftrightarrow{} c\)) and returns whether the \constraint{} is entailed.}
|
||||
|
||||
\BlankLine{}
|
||||
\If{\(b \text{ is unassigned}\)}{
|
||||
\If{\(\neg{} check()\)}{
|
||||
\(b \longleftarrow \text{false}\)\;
|
||||
\(b \longleftarrow \false{}\)\;
|
||||
}
|
||||
\If{\(\neg{} checkNeg()\)}{
|
||||
\(b \longleftarrow \text{true}\)\;
|
||||
\(b \longleftarrow \true{}\)\;
|
||||
}
|
||||
}
|
||||
\If{\(\texttt{b} = \text{true}\)}{
|
||||
\If{\(\texttt{b} = \true{}\)}{
|
||||
\(prune()\)\;
|
||||
\Return{} \(entailed()\)\;
|
||||
}
|
||||
\If{\(\texttt{b} = \text{false}\)}{
|
||||
\If{\(\texttt{b} = \false{}\)}{
|
||||
\(pruneNeg()\)\;
|
||||
\Return{} \(entailedNeg()\)\;
|
||||
}
|
||||
\Return{} \(\text{false}\)\;
|
||||
\Return{} \(\false{}\)\;
|
||||
\caption{\label{alg:reif-prop} \Gls{propagation} pseudocode for the \gls{reif} of a \constraint{} \(c\), based on the \glspl{propagator} for \(c\) and \(\neg{} c\).}
|
||||
\end{algorithm}
|
||||
|
||||
\Gls{half-reified} \glspl{propagator} have certain advantages over \gls{reified} \glspl{propagator}, but also may suffer certain penalties.
|
||||
\Gls{half-reif} can cause \glspl{propagator} that use their \gls{cvar} to wake up less frequently: \glspl{cvar} that are fixed to true by full \gls{reif} will never be fixed by \gls{half-reif}.
|
||||
\Gls{half-reif} can cause \glspl{propagator} that use their \gls{cvar} to wake up less frequently: \glspl{cvar} that are \gls{fixed} to \true{} by full \gls{reif} will never be fixed by \gls{half-reif}.
|
||||
This can be advantageous, but has a corresponding disadvantage.
|
||||
When a \gls{cvar} is fixed, it can allow the simplification of the \glspl{propagator} that use them, and hence make \gls{propagation} faster.
|
||||
|
||||
@ -329,7 +327,7 @@ In this scenario, we prefer to create the full \gls{reif} as it decreases the nu
|
||||
|
||||
When taking into account the possible undefinedness of an expression, every expression in a \minizinc{} model has two different contexts: the context in which the expression itself occurs, its \emph{value context}, and the context in which the partiality of the expression is captured, its \emph{partiality context}.
|
||||
As described in \cref{subsec:back-mzn-partial}, \minizinc{} uses \gls{rel-sem} for partial functions.
|
||||
This means that if the result of a function is undefined, then its nearest enclosing Boolean expression becomes false.
|
||||
This means that if the result of a function is undefined, then its nearest enclosing Boolean expression becomes \false{}.
|
||||
In practice, this means that a condition that tests if the function will return a value is added to the nearest enclosing Boolean expression.
|
||||
The partiality context is the context in which this condition is placed.
|
||||
|
||||
@ -365,7 +363,7 @@ In the architecture introduced in \cref{ch:rewriting}, contexts of the expressio
|
||||
The analysis is best performed during the compilation process from \minizinc{} to \microzinc{}.
|
||||
It requires knowledge about all usages of each \variable{} at the same time.
|
||||
This information is not available during the interpretation of \microzinc{}.
|
||||
Without loss of generality we can define the context analysis process for \microzinc{} models.
|
||||
Without loss of generality we can define the context analysis for \microzinc{} models.
|
||||
This has the advantage that \microzinc{} does not contain \gls{partial} function calls.
|
||||
The partiality in \minizinc{} has already been translated using only total functions (see \cref{sec:rew-micronano}).
|
||||
The context analysis therefore does not have to keep track of value and partiality contexts separately.
|
||||
@ -451,7 +449,7 @@ A definition for this function for the \minizinc{} operators can be found in \cr
|
||||
|
||||
Although a standard definition for the ``argCtx'' function may cover the most common cases, it does not cover user-defined functions.
|
||||
To address this issue, we introduce the \glspl{annotation} \mzninline{promise_ctx_monotone} and \mzninline{promise_ctx_antitone} to represent the operations \changepos{} and \changeneg{} respectively.
|
||||
When a function argument is annotated with one of these \glspl{annotation}, the context of the argument in a call in context \(ctx\) is transformed with the operation corresponding to the annotation (\eg\ \(\changepos{}ctx\) or \(\changeneg{}ctx\)).
|
||||
When a function argument is annotated with one of these \glspl{annotation}, the context of the argument in a call in context \(ctx\) is transformed with the operation corresponding to the annotation (e.g., \(\changepos{}ctx\) or \(\changeneg{}ctx\)).
|
||||
If a function argument is not annotated, then the argument is evaluated in \mixc{} context.
|
||||
It may be possible to infer these \glspl{annotation} from the function body.
|
||||
However, we currently do not provide such analysis and annotate functions by hand.
|
||||
@ -517,7 +515,7 @@ Otherwise, the \compiler{} follows the following steps to try to introduce the m
|
||||
\item If \(ctx\) is \posc{} or \negc{}, then change \(ctx\) to \mixc{} and return to step 1.
|
||||
|
||||
\item Finally, if none of the earlier steps were successful, then the compilation fails.
|
||||
Note that this can only occur when there is not a definition for the \gls{reif} of a \constraint{}, \ie{} neither a \gls{native} constraint nor a \gls{decomp}.
|
||||
Note that this can only occur when there is not a definition for the \gls{reif} of a \constraint{}, i.e., neither a \gls{native} constraint nor a \gls{decomp}.
|
||||
\end{enumerate}
|
||||
|
||||
The (Access) and (ITE) rules show the context inference for \gls{array} access and \gls{conditional} expressions respectively.
|
||||
@ -650,7 +648,7 @@ It is, however, not always safe to do so.
|
||||
\end{mzn}
|
||||
|
||||
One side of the \gls{conditional} expression is also used in a disjunction.
|
||||
If \mzninline{b} evaluates to true, then \mzninline{p} is evaluated in \rootc{} context, and \mzninline{p} can take the value true in the disjunction.
|
||||
If \mzninline{b} evaluates to \true{}, then \mzninline{p} is evaluated in \rootc{} context, and \mzninline{p} can take the value \true{} in the disjunction.
|
||||
Otherwise, \mzninline{q} is evaluated in \rootc{} context, and \mzninline{p} in the disjunction must be evaluated in \posc{} context.
|
||||
In this situation, it is not safe for the \compiler{} to output calls for the \rootc{} variants of these calls.
|
||||
\end{example}
|
||||
@ -676,7 +674,7 @@ Otherwise, it will act as a normal \rootc{} context.
|
||||
\mixc & \rootc & \mixc & \mixc & \mixc & \mixc \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\caption{\label{fig:half-maybe-join} The join context operation extended with \mayberootc{}.}
|
||||
\caption{\label{fig:half-maybe-join} A table showing the result of joining two contexts, considering the \mayberootc{} context.}
|
||||
\end{figure*}
|
||||
|
||||
\begin{figure*}
|
||||
@ -696,7 +694,7 @@ Otherwise, it will act as a normal \rootc{} context.
|
||||
\Cref{fig:half-analysis-maybe-root} shows the additional inference rules for \gls{array} access and \gls{conditional} expressions.
|
||||
Looking back at \cref{ex:half-maybe-root}, these additional rules and updated join operation will ensure that the first case will correctly use \rootc{} context calls.
|
||||
For the second case, however, it detects that \mzninline{p} is used in both \posc{} and \mayberootc{} context.
|
||||
Therefore, it will output the \posc{} call for the right-hand side of \mzninline{p}, even when \mzninline{b} evaluates to true.
|
||||
Therefore, it will output the \posc{} call for the right-hand side of \mzninline{p}, even when \mzninline{b} evaluates to \true{}.
|
||||
At compile time, this is the only correct context to use.
|
||||
We will, however, discuss how to adjust contexts dynamically during \gls{rewriting} in \cref{subsec:half-dyn-context}.
|
||||
|
||||
@ -857,12 +855,12 @@ In general the following rules apply.
|
||||
\item The result of \gls{rewriting} an expression in \mixc{} context, a \gls{reif}, can be reused in \posc{}, \negc{}, and \mixc{} context.
|
||||
Since we assume that the result of \gls{rewriting} an expression in \negc{} context pushes the negation inwards, the \gls{reif} does, however, need to be negated.
|
||||
|
||||
\item If the expression was already seen in \rootc{} context, then any repeated usage of the expression can be assumed to take the value true (or false in \negc{} context).
|
||||
\item If the expression was already seen in \rootc{} context, then any repeated usage of the expression can be assumed to take the value \true{} (or \false{} in \negc{} context).
|
||||
|
||||
\end{itemize}
|
||||
|
||||
When considering these compatibility rules, the result of \gls{rewriting} is highly dependent on the order in which expressions are seen.
|
||||
It would always be better to encounter the expression in a context that results in a reusable expression, \eg{} \mixc{}, before seeing the same expression in another context, \eg{} \posc{}.
|
||||
It would always be better to encounter the expression in a context that results in a reusable expression, e.g., \mixc{}, before seeing the same expression in another context, e.g., \posc{}.
|
||||
This avoids creating both a full \gls{reif} and a \gls{half-reif} of the same expression.
|
||||
|
||||
In the \microzinc{} \interpreter{}, this problem is resolved by only keeping the result of their joint context.
|
||||
@ -963,7 +961,7 @@ The same situation can be caused by \gls{propagation}.
|
||||
constraint b -> (2*x = y);
|
||||
\end{mzn}
|
||||
|
||||
Since the values in the \domain{} of \mzninline{x} are strictly smaller than the values in the \domain{} of \mzninline{y}, \gls{propagation} of \mzninline{b} will set it to the value true.
|
||||
Since the values in the \domain{} of \mzninline{x} are strictly smaller than the values in the \domain{} of \mzninline{y}, \gls{propagation} of \mzninline{b} will set it to the value \true{}.
|
||||
This however means that the \constraint{} is equivalent to the following \constraint{}.
|
||||
|
||||
\begin{mzn}
|
||||
@ -1022,7 +1020,7 @@ In each \instance{} certain values have already been fixed.
|
||||
It is not always possible for all rows and columns to contain only distinct values.
|
||||
|
||||
In \minizinc{} counting the number of rows/columns with all different values can be accomplished using a \gls{reified} \mzninline{all_different} \constraint{}.
|
||||
Since the goal of the problem is to maximize the number of \mzninline{all_different} \constraints{} that hold, these \constraints{} are never forced to be false.
|
||||
Since the goal of the problem is to maximize the number of \mzninline{all_different} \constraints{} that hold, these \constraints{} are never forced to be \false{}.
|
||||
This means these \constraints{} are in \posc{} context and can be \gls{half-reified}.
|
||||
|
||||
\Cref{tab:half-qcp} shows the comparison of two solving configurations in \gls{chuffed} for the QCP-max problem.
|
||||
@ -1034,7 +1032,7 @@ This \gls{propagator} is an adjusted version from the existing \gls{boundsz-con}
|
||||
The implementation of the \gls{propagator} was already split into parts that check the violation of the \constraint{} and parts that prune the \glspl{domain} of the \variables{}.
|
||||
Therefore, the transformation described in \cref{sec:half-propagation} can be directly applied.
|
||||
Since \gls{chuffed} is a \gls{lcg} \solver{}, the explanations created by the \gls{propagator} have to be adjusted as well.
|
||||
These adjustments happen similar to the adjustments of the general algorithm: explanations used for the violation\glsadd{violated} of the \constraint{} can now be used to set the \gls{cvar} to false, and the explanations given to prune a \variable{} are extended with a literal that ensures the \gls{cvar} is true.
|
||||
These adjustments happen similar to the adjustments of the general algorithm: explanations used for the violation\glsadd{violated} of the \constraint{} can now be used to set the \gls{cvar} to \false{}, and the explanations given to prune a \variable{} are extended with a literal that ensures the \gls{cvar} is \true{}.
|
||||
|
||||
In our second configuration the \mzninline{all_different} \constraint{} is enforced using the \gls{decomp} shown in \cref{lst:half-alldiff}.
|
||||
The \mzninline{!=} \constraints{} produced by this redefinition are \gls{reified}.
|
||||
@ -1069,8 +1067,8 @@ In this experiment we can show how \gls{half-reif} can reduce the overhead of ha
|
||||
The \minizinc{} model for this problem contains an \gls{array} lookup \mzninline{pos[next[i]]}, where the \domain{} of \mzninline{next[i]} is larger than the index set of \mzninline{pos}.
|
||||
We compare safe \gls{decomp} of this \mzninline{element} \constraint{} against a \gls{propagator} of its \gls{half-reif}.
|
||||
The \gls{decomp} creates a new \variable{} that takes the value of the index only when it is within the index set of the \gls{array}.
|
||||
Otherwise, it will set its surrounding context to false.
|
||||
The \gls{half-reif} implicitly performs the same task by setting its \gls{cvar} to false whenever the resulting \variable{} does not equal the element to which the index \variable{} points, or when the index points outside the \gls{array}.
|
||||
Otherwise, it will set its surrounding context to \false{}.
|
||||
The \gls{half-reif} implicitly performs the same task by setting its \gls{cvar} to \false{} whenever the resulting \variable{} does not equal the element to which the index \variable{} points, or when the index points outside the \gls{array}.
|
||||
Again, for the implementation of the \gls{propagator} of the \gls{half-reif} \constraint{} we adjust the direct \gls{propagator} as described above.
|
||||
|
||||
\begin{table}
|
||||
|
@ -1,4 +1,4 @@
|
||||
\noindent{}Whether a \constraint{} has to be \gls{reified} is a crucial decision made during \gls{rewriting}.
|
||||
\noindent{}Determining whether a \constraint{} has to be \gls{reified} is a crucial decision made during \gls{rewriting}.
|
||||
\minizinc{} allows us to write complex \constraints{} that in the process of \gls{rewriting} result in multiple \constraints{} that reason about each other.
|
||||
However, using a \gls{reif} \(b \leftrightarrow{} c\), that determines whether a \constraint{} \(c\) holds, can slow the \solver{} down.
|
||||
Even in \gls{cp} \solvers{}, not many \glspl{reif} are \gls{native} to the \solvers{}, and the \glspl{propagator}, for the ones that are, are often weak.
|
||||
|
@ -71,7 +71,7 @@ Instead of the complex \minisearch{} definitions, we propose to add support for
|
||||
A \gls{restart} happens when a solver abandons its current search efforts, returns to its initial \gls{search-space}, and begins a new exploration.
|
||||
Many \gls{cp} \solvers{} already provide support for controlling their restarting behaviour.
|
||||
They can periodically restart after a certain number of nodes, or restart for every \gls{sol}.
|
||||
Typically, \solvers{} also support posting additional \constraints{} upon restarting that are only valid for the particular \gls{restart} (\eg{} Comet \autocite{michel-2005-comet}).
|
||||
Typically, \solvers{} also support posting additional \constraints{} upon restarting that are only valid for the particular \gls{restart} (e.g., Comet \autocite{michel-2005-comet}).
|
||||
These \constraints{} are ``retracted'' for the next \gls{restart}.
|
||||
|
||||
In its simplest form, we can therefore implement \gls{lns} by merely specifying a \gls{neighbourhood} predicate.
|
||||
@ -86,7 +86,7 @@ Calling the predicate, as in \mzninline{::on_restart(my_neighbourhood())}, would
|
||||
The predicate needs to be called for each restart.
|
||||
As a workaround, we currently pass the name of the predicate to be called for each restart as a string (see the definition of the new \mzninline{on_restart} annotation in \cref{lst:inc-restart-ann}).
|
||||
|
||||
The second component of our \gls{lns} definition is the ``restarting strategy'', defining how much effort the \solver{} should put into each \gls{neighbourhood} (\ie{} \gls{restart}), and when to stop the overall search. We propose adding new search \glspl{annotation} to the \minizinc{} to control this behaviour.
|
||||
The second component of our \gls{lns} definition is the ``restarting strategy'', defining how much effort the \solver{} should put into each \gls{neighbourhood} (i.e., \gls{restart}), and when to stop the overall search. We propose adding new search \glspl{annotation} to the \minizinc{} to control this behaviour.
|
||||
The proposed \glspl{annotation} are shown in \cref{lst:inc-restart-ann}.
|
||||
|
||||
The \mzninline{restart_on_solution} annotation tells the solver to restart immediately for each \gls{sol}, rather than looking for the best one in each restart.
|
||||
@ -228,13 +228,17 @@ Instead, we introduce the following function that can be used to signal to the s
|
||||
function var bool: complete();
|
||||
\end{mzn}
|
||||
|
||||
\noindent{}When the result of this function is said to be true, then search is complete.
|
||||
\noindent{}When the result of this function is said to be \true{}, then search is complete.
|
||||
If any \gls{sol} was found, it is declared an \gls{opt-sol}.
|
||||
|
||||
Using the same methods it is also possible to describe optimization strategies with multiple \glspl{objective}.
|
||||
An example of such a strategy is lexicographic search.
|
||||
Lexicographic search can be employed when there is a strict order between the importance of different \variables{}.
|
||||
It required that, once a \gls{sol} is found, each subsequent \gls{sol} must either improve the first \gls{objective}, or have the same value for the first \gls{objective} and improve the second \gls{objective}, or have the same value for the first two \glspl{objective} and improve the third \gls{objective}, and so on.
|
||||
Once a \gls{sol} is found, we first consider the most important \gls{objective}.
|
||||
Any subsequent \gls{sol} must improve the quality of this \gls{objective}.
|
||||
If there does not exist such a \gls{sol}, then we move on to the next important \gls{objective}.
|
||||
We then look for a \gls{sol} that improves the quality of this \gls{objective}, without decreasing the quality of more important \glspl{objective}.
|
||||
We then repeat this process until we reach the least important \gls{objective}, and we cannot find \glspl{sol} that improve it any longer.
|
||||
A predicate that implements lexicographic search is shown in \cref{lst:inc-lex-min}.
|
||||
|
||||
\begin{listing}
|
||||
@ -320,7 +324,7 @@ It simply replaces the functional form by a predicate \mzninline{status} (declar
|
||||
|
||||
The \mzninline{sol} function is overloaded for different types.
|
||||
Our \glspl{slv-mod} do not support overloading.
|
||||
Therefore, we produce type-specific \gls{native} \constraints{} for every type of \gls{native} \variable{} (\eg{} \mzninline{int_sol(x, xi)}, and \mzninline{bool_sol(x, xi)}).
|
||||
Therefore, we produce type-specific \gls{native} \constraints{} for every type of \gls{native} \variable{} (e.g., \mzninline{int_sol(x, xi)}, and \mzninline{bool_sol(x, xi)}).
|
||||
The resolving of the \mzninline{sol} function into these specific \gls{native} \constraints{} is done using an overloaded definition, like the one shown in \cref{lst:inc-int-sol} for integer \variables{}.
|
||||
If the value of the \variable{} has become known during \gls{rewriting}, then we use its \gls{fixed} value instead.
|
||||
Otherwise, the function call is rewritten into a type specific \mzninline{int_sol} \gls{native} \constraint{} that will be executed by the solver.
|
||||
@ -378,7 +382,7 @@ In addition, for the new \constraints{} the \solver{} is extended using the foll
|
||||
This is straightforward by using a \mzninline{last_val} \gls{propagator}.
|
||||
It wakes up whenever its argument is fixed, and updates the last value (a non-\gls{backtrack}able value).
|
||||
\item[Random number functions] Fix their \variable{} argument to a random number in the appropriate probability distribution.
|
||||
\item[\mzninline{complete_reif(c)}] Stop and mark the search as ``complete'' when its \variable{} argument is forced to be true.
|
||||
\item[\mzninline{complete_reif(c)}] Stop and mark the search as ``complete'' when its \variable{} argument is forced to be \true{}.
|
||||
\end{description}
|
||||
|
||||
Importantly, these \constraints{} need to be propagated in a way that their effects can be undone for the next \gls{restart}.
|
||||
@ -394,15 +398,15 @@ For example, consider the model from \cref{lst:inc-basic-complete} again that us
|
||||
\end{mzn}
|
||||
|
||||
\Cref{lst:inc-flat-pred} shows a part of the resulting \gls{slv-mod}.
|
||||
\Lrefrange{line:6:status:start}{line:6:status:end} define a Boolean variable \mzninline{b1} that is true if-and-only-if the status is not \mzninline{START}.
|
||||
\Lrefrange{line:6:status:start}{line:6:status:end} define a Boolean variable \mzninline{b1} that takes the value \true{} if-and-only-if the status is not \mzninline{START}.
|
||||
The second block of code, \lrefrange{line:6:x1:start}{line:6:x1:end}, represents the \gls{decomp} of the following expression.
|
||||
|
||||
\begin{mzn}
|
||||
(status() != START /\ uniform(0.0, 1.0) > 0.2) -> x[1] = sol(x[1])
|
||||
\end{mzn}
|
||||
|
||||
It is the result of merging the implication from the \mzninline{basic_lns} predicate with the \mzninline{if} expression from \mzninline{uniformNeighbourhood}.
|
||||
The code first introduces and constrains a variable for the random number, then adds two Boolean \variables{}: \mzninline{b2} is constrained to be true if-and-only-if the random number is greater than 0.2; while \mzninline{b3} is constrained to be the conjunction of the two.
|
||||
It is the result of merging the implication from the \mzninline{basic_lns} predicate with the \gls{conditional} expression from \mzninline{uniformNeighbourhood}.
|
||||
The code first introduces and constrains a variable for the random number, then adds two Boolean \variables{}: \mzninline{b2} is constrained to take the value \true{} if-and-only-if the random number is greater than 0.2; while \mzninline{b3} is constrained to be the conjunction of the two.
|
||||
\Lref{line:6:x1:sol} constrains \mzninline{x1} to be the value of \mzninline{x[1]} in the previous \gls{sol}.
|
||||
Finally, the \gls{half-reified} \constraint{} in \lref{line:6:x1:end} implements the following expression.
|
||||
|
||||
@ -420,14 +424,14 @@ Note that the \flatzinc{} \gls{slv-mod} shown here has been simplified for prese
|
||||
\end{listing}
|
||||
|
||||
The first time the \solver{} is invoked, it sets \mzninline{s} to one (\mzninline{START}).
|
||||
\Gls{propagation} will fix \mzninline{b1} to false and \mzninline{b3} to false.
|
||||
\Gls{propagation} will fix \mzninline{b1} to \false{} and \mzninline{b3} to \false{}.
|
||||
Therefore, the implication in \lref{line:6:x1:end} is not activated, leaving \mzninline{x[1]} unconstrained.
|
||||
The \gls{neighbourhood} \constraints{} are effectively switched off.
|
||||
|
||||
When the \solver{} \glspl{restart}, all the special \glspl{propagator} are re-executed.
|
||||
Now \mzninline{s} is not one, and \mzninline{b1} is set to true.
|
||||
Now \mzninline{s} is not one, and \mzninline{b1} is \gls{fixed} to \true{}.
|
||||
The \mzninline{float_random} \gls{propagator} assigns \mzninline{rnd1} a new random value and, depending on whether it is greater than \mzninline{0.2}, the Boolean \variables{} \mzninline{b2}, and consequently \mzninline{b3} is assigned.
|
||||
If it is true, the \constraint{} in \lref{line:6:x1:end} becomes active and assigns \mzninline{x[1]} to its value in the previous \gls{sol}.
|
||||
If it is set to \true{}, the \constraint{} in \lref{line:6:x1:end} becomes active and assigns \mzninline{x[1]} to its value in the previous \gls{sol}.
|
||||
|
||||
Furthermore, it is not strictly necessary to guard \mzninline{int_uniform} against being invoked before the first \gls{sol} is found.
|
||||
The \mzninline{sol} \constraints{} will simply not propagate anything until the first \gls{sol} is recorded, but we use this simple example to illustrate how these Boolean conditions are rewritten and evaluated.
|
||||
@ -459,7 +463,8 @@ This includes results of \gls{propagation}, \gls{cse} and other simplifications.
|
||||
|
||||
After evaluating the first \constraint{}, the \domain{} of \mzninline{x} is changed to be less than ten.
|
||||
Evaluating the second \constraint{} causes the \domain{} of \mzninline{y} to be less than nine.
|
||||
If we now, however, try to remove the first \constraint{}, then it is not just the direct inference on the \domain{} of \mzninline{x} that has to be undone, but also any further effects of those changes --- in this case, the changes to the \domain{} of \mzninline{y}.
|
||||
If we now, however, try to remove the first \constraint{}, then it is not just the direct inference on the \domain{} of \mzninline{x} that has to be undone.
|
||||
All consequent effects of those changes, in this case, the changes to the \domain{} of \mzninline{y}, also have to be changed back.
|
||||
|
||||
\end{example}
|
||||
|
||||
@ -502,7 +507,7 @@ In particular, this means that until the first choice point is created \gls{rewr
|
||||
Then the \gls{trail} stores the inverse of all modifications that were made to the \nanozinc{} as a result of \mzninline{c}.
|
||||
The following code fragment illustrates the elements in this \gls{trail}.
|
||||
The reversal actions are annotated on the different elements.
|
||||
The \mzninline{attach} and \mzninline{detach} actions signal the \interpreter{} to attach/detach a \constraint{} to the argument \variable{}, or the global \cmodel{} in case the argument is true.
|
||||
The \mzninline{attach} and \mzninline{detach} actions signal the \interpreter{} to attach/detach a \constraint{} to the argument \variable{}, or the global \cmodel{} in case the argument is the value \true{}.
|
||||
The \mzninline{add} action tells to \interpreter{} to add a \variable{} to the \nanozinc{} program.
|
||||
Finally, the \mzninline{set_domain} action makes the \interpreter{} restore the \domain{} using declaration to which it was attached.
|
||||
|
||||
|
@ -26,7 +26,7 @@ The \gls{rewriting} process of a \minizinc{} \instance{} into a \gls{slv-mod} th
|
||||
The latter operates on a (partial) \glspl{slv-mod}, expressed using the \nanozinc{} language.
|
||||
Distinctively, \nanozinc{} has the ability to attach \constraints{} to a \variable{}.
|
||||
During \gls{rewriting} \constraints{} introduced to define a \variable{} are attached to it.
|
||||
This ensures that if it is discovered that a \variable{} becomes unused (\ie{} it is not referred to by \constraints{} any longer), it can correctly be removed.
|
||||
This ensures that if it is discovered that a \variable{} becomes unused (i.e., it is not referred to by \constraints{} any longer), it can correctly be removed.
|
||||
|
||||
Crucially, the architecture is easily extended with well-known simplification techniques to improve the quality of the produced \solver{} specifications.
|
||||
|
||||
@ -66,7 +66,7 @@ In these \solvers{}, a functionally defined \variable{} can become unused when t
|
||||
Like we can remove the defining \constraint{} during \gls{rewriting}, in a \gls{cp} \solver{} we could stop further \gls{propagation} of this \constraint{} and possibly speed up the solving.
|
||||
|
||||
\section*{Reasoning about Reification}
|
||||
Whether to a \constraint{} is \gls{reified} is a crucial decision that has to be made during \gls{rewriting}.
|
||||
Determining whether to a \constraint{} is \gls{reified} is a crucial decision that has to be made during \gls{rewriting}.
|
||||
Making the wrong decision can significantly impact \gls{solver} performance.
|
||||
In \cref{ch:half-reif}, we extend our architecture with our second contribution: \textbf{a formal analysis to reason about the \gls{reif} of \constraints{}}.
|
||||
Not only does this analysis reduce the number of required \glspl{reif}, it is the first implementation that also automatically introduces \glspl{half-reif} when possible.
|
||||
@ -101,10 +101,10 @@ It is clear that the use of \gls{half-reif} is beneficial in some cases, but it
|
||||
It is thus important that we achieve a better understanding of when the latter occurs.
|
||||
As also discussed by \textcite{feydy-2011-half-reif}, we see that \gls{cp} solvers are sometimes negatively impacted because \glspl{half-reif} do not fix their \gls{cvar}, requiring more search.
|
||||
As a solution to this problem we could consider a form in between \gls{half-reif} and full \gls{reif}.
|
||||
In this form the propagator would set the \gls{cvar} to true if the \constraint{} holds, but does not propagate the negation of the \constraint{} when it is set to false.
|
||||
In this form the propagator would set the \gls{cvar} to \true{} if the \constraint{} holds, but does not propagate the negation of the \constraint{} when it is set to \false{}.
|
||||
The downside of this form is that it is not equivalent to a logical implication, which means that measures such as \gls{chain-compression} would not be applicable.
|
||||
However, \glspl{propagator} for this form are still easy to design/implement, and they ensure that the \gls{cvar} is fixed through \gls{propagation}.
|
||||
Finally, automated \gls{half-reif} in \minizinc{} will allow new solving performance improvements by allowing \solver{} implementers to experiment with \glspl{decomp} or \glspl{propagator} for \gls{half-reified} \constraints{}.
|
||||
Finally, automated \gls{half-reif} in \minizinc{} allows for new solving performance improvements by allowing \solver{} implementers to experiment with \glspl{decomp} or \glspl{propagator} for \gls{half-reified} \constraints{}.
|
||||
|
||||
\section*{Incremental Solving}
|
||||
Using a \cml{} as the interface for a \gls{meta-optimization} toolchain can be very intuitive and opens up new opportunities.
|
||||
|
Reference in New Issue
Block a user