

![0_image_0.png](0_image_0.png)

![0_image_1.png](0_image_1.png)

![0_image_2.png](0_image_2.png)

class **IntVar {**

![0_image_3.png](0_image_3.png) private: int **_min, _max;**
public: int min(void) { return **_min; }**
int max(void) { return **_max; }** void adjmin(int n) { if **(n > _min) _min = n; }** void adjmax(int n) { if **(n < _max) _max = n; }**
};
class **OffsetView {**
protected: IntVar* x; int o; public: OffsetView(IntVar* x0, int **o0) : x(x0), o(o0) {}**
int min(void) { return **x->min()+o; }**
int max(void) { return **x->max()+o; }** void adjmin(int **n) { x->adjmin(n-o); }** void adjmax(int **n) { x->adjmax(n-o); }**
};
Figure 2: Integer variable and offset view implementations. On average, every propagator implementation results in 4.6 derived propagators. Propagator implementations in Gecode account for more than 40000 lines of code and documentation. As a rough estimate, deriving propagators using views thus saves around 140000 lines of code and documentation to be written, tested, and maintained. On the other hand, the views mentioned in this section are implemented in less than 8000 lines of code, yielding a 1750% return on investment.

## 5 Implementation

This section presents an implementation architecture for views and derived propagators, based on making propagators *parametric*. Deriving a propagator then means *instantiating* a parametric propagator with views. The presented architecture is an orthogonal layer of abstraction on top of any solver implementation.

## 5.1 Views

The model introduced views as functions that transform the input and output of a propagator, which maps domains to domains. In an object-oriented implementation of this model, a propagator is no longer a function, but an object with a **propagate** method that *accesses* and *modifies* a domain through the methods of variable objects. Such an object-oriented model is used for example by ILOG Solver [27] and Choco [18], and is the basis of most of the current propagation-based constraint solvers.

Figure 2 shows C++ classes for a simple integer variable (just representing bounds information) and a corresponding offset view. The view has the same interface as the variable, so that it can be used in its place. It contains a pointer to the underlying integer variable and *delegates* all the operations, performing the necessary transformations.