3.3 Middle-End
3.3.2 Flattening
In many cases, a target solver does not directly support expressions as they are formulated in a rich, solver-independent modelling language: in solvers, constraints are implemented
aspropagatorswhich are ‘granular’ constraints that take only variables as arguments i.e.
their expression tree depth is 1 (exceptions are solvers such as ECLiPSe Prolog, that flatten their input internally). Thus, many expressions need to be decomposed into a conjunc- tion of simpler expressions that conform to the constraints provided by the solver. This decomposition is generally known asflattening.
Definition 3.3.1. A flat representation ES! of expression tree E wrt target solver S is a
conjunction of simple expression trees, defined asE!
S:=∧iEi!, where for each conjoint ex-
Algorithm 3.2FLATTEN(E,flatten2Aux) recursive procedure that flattens expression tree
E, whereflatten2Auxdenotes ifEwill be flattened to an auxiliary variable.
Require: E: expression tree, flatten2Aux: Boolean 1: if¬(all ofE’s children are leaves)then
2: for allei∈children(E)do 3: if ¬(ei.isLeaf)then
4: e!
i←FLATTEN(ei, true) 5: E.replaceChildWith(ei,e!i) 6: if flatten2Auxthen
7: Aux←createNewVariable(E.lb,E.ub);auxVars.add(Aux)
8: constraintBuffer.add(‘Aux=E’)
9: return Aux
10: else
pressionE!
ithere exists a propagatorpin solverSthat matches the tree structure ofEi!, and
Es! ≡E.
We assume that prior to flattening, every expression tree has been preprocessed such that its tree structure conforms to the propagators provided by solverS. In other words, for every nodeN inE, there exists a propagator in solverS that corresponds to operationN and has the same arity as nodeN has children (e.g. ifE contains a sum-node withnchildren, then solverS must have ann-ary sum propagator). Note, that this preprocessing procedure can be embedded into flattening, but has been left out in this discussion to not obscure the task of flattening. If all constraints in a modelM are adapted to solver S in this way, we will refer to it asMS.
Flattening is a well-understood technique, however, we summarise a standard flattening algorithm, FLATTEN INSTANCE , in Alg. 3.1 that applies a recursive helper procedure, FLATTEN (Alg. 3.2), on every constraint in instance MS. FLATTEN iterates over the ex-
pression tree in a bottom up fashion and replaces all nodesNi inE(except the root node)
with an auxiliary variable Auxi, generating the constraint ‘Auxi = N!
i’ that connects ev-
ery auxiliary variable with its corresponding flat subtree N!
i (line 7-9 in Alg. 3.2). Af-
ter flattening every subnode Ni of expressionE, the ‘Auxi=Ni!’-constraints are conjoined
with the flat root node (line 5 in Alg. 3.1), yielding the flat representation of E. As an example, consider Figure 3.7 that illustrates how FLATTEN decomposes the expression a⇒((x<3)∧(y>5)∧(z=0)).
An important issue in flattening is deriving tight bounds for auxiliary variables. In FLAT- TEN, the procedurecreateNewVariablecreates an auxiliary variable with lower bound lb and upper boundub(line 7 in Alg. 3.2). lbandubare obtained from the domain attribute of nodeE that contains the lower and upper bound of the subtreeE (see Sec. 3.2 or Fig. 3.3). In this way, we can assign tight bounds to the auxiliary variables.
After generating the flat representation E!
S for every constraintE in instanceMS, FLAT-
TEN INSTANCEconstructs the flat instanceMS!, consisting of the flat constraints andMs’s
decision variables combined with the auxiliary variables (line 7) in Alg. 3.1). Clearly, FLATTEN INSTANCE will generate a valid flat instanceM!
S: FLATTENis applied to every
constraintEofMS, which is recursively applied to all subnodes ofE, creating an auxiliary
variable for each. Since we assume that every node in E corresponds to a propagator in target solverS, it is sufficient to replace each subnode that is not a leaf with an auxiliary variable to conform to the target solver.
Lemma 3.3.1. If constraint instanceMS containsn constraints that contain m nodes in
their expression trees (withm ≥ n), then FLATTEN INSTANCE will generate flat instance
M!
S withmconstraints andm−nauxiliary variables.
Proof. FLATTEN INSTANCEapplies FLATTENto every constraintEinMS(line 4 in Alg.
3.1). FLATTEN is recursively invoked on every subnode that is not a leaf (line 4 in Alg. 3.2), and creates an auxiliary variable and constraint for every node, except the root node
Figure 3.7: Example: Flatteninga → ((x<3)∧(y>5)∧(z=0))using FLATTEN(Alg. 3.2). Arrows pointing at nodes denote that FLATTENhas been invoked on the subtree.TandFrepresent the Boolean value forflatten2Aux. The numbers represent parts of Algorithm 3.2: (1)invoke FLATTENon non-leaf children (line 4-5),(2)return expression (line 10-11),(3)flatten to auxiliary variable (line 7-9).
(flatten2Aux=falseonly for the root node, line 4 in Alg. 3.1). Thus, FLATTENcreates one auxiliary variable and one ‘Aux=E’-constraint for all m nodes, except the n root nodes. For allnroot nodes, one constraint is returned (line 11 in Alg. 3.2). Therefore, FLATTEN generatesm−nauxiliary variables andmconstraints.
As an example, consider the constraint instance consisting of the constraint from Fig. 3.7: a⇒((x<3)∧(y>5)∧(z=0)). MScontains 1 constraint (n=1) and 5 nodes (m=5), therefore
FLATTENgeneratesM!
Scontaining 5 constraints using 5-1 auxiliary variables.
Theorem 3.3.1. Thetime complexityofFLATTEN INSTANCElies inO(n).
Proof. Let f be the number of atomic operations required to flatten a node of an expres-
sion (note that f is a constant that is the same for every subexpression but which might differ between machines). From Lemma 3.3.1 we know that FLATTEN INSTANCE per- forms these operationsntimes, since it is applied to every node in MS. Therefore, FLAT-
TEN INSTANCEhas a runtime off∗nwhich lies inO(n), sincef is a constant (recall that we are assuming atomic operations in the implementation).
Theorem 3.3.2. Thespace complexityofFLATTEN INSTANCElies inO(n).
Proof. FLATTEN INSTANCE employs the lists flatCts, auxVars and ctBuffer, as well as
the representation of constraint model MS and M!. All of these data structures require a
maximal capacity of n, where n is the number of subexpressions in MS (Lemma 3.3.1).