Since I have not written much about
Tailor before, here is a short presentation of the system:
TAILOR is a tool that facilitates modelling and solving constraint models. TAILOR's graphical user interface (GUI) allows the user to directly solve an Essence' problem model with either solver MINION or GECODE, and is hence especially aimed at people who are novices in constraint programming or have no experience with constraint solvers Minion and Gecode. Note that TAILOR is not intended to compare solvers, but to generate effective solver input from a solver-independent problem model.
...
TAILOR provides a command-line and an interactive graphical version. TAILOR is distributed as a Java .jar file and can easily be executed on every platform.
Tailor is developed by
Andrea Rendl of University of St Andrews in Scotland, UK.
New version v0.3.2
A new Tailor version was released some days ago. From the NEWS:
July 15, 2009: NEW RELEASE : TAILOR v0.3.2 (bug-fixed update from July 19, 2009)
New Features
* New output format: Flatzinc (still limited though)
* New GUI options:
o Solve your model directly in TAILOR with solver Gecode by using the Gecode-Flatzinc interpreter
* Extended Gecode Translation (still restricted though)
* several bugfixes (especially with XCSP format)
The Flatzinc output format is especially interesting, since there are now a lot of different solvers for solving Essence' models. A later finding reveals that there may have to be some tweakings in the FlatZinc file for using it with other solvers than Gecode/FlatZinc, since the translation (tailoring) is done explicitly for Gecode/FlatZinc.
Also, right now Tailor cannot generate FlatZinc files when the Essence' model contains multi dimensional arrays (matrices), but - as I understand it - this may come quite soon.
One should note that in Essence' it is not possible to stating search heuristics options. But it's quite easy to manually change that for the generated FlatZinc models (or, as I probably will do: make a program doing that). For the Minion solver there is a
-varorder
switch that change the variables order, but "[t]his flag is experimental and minion's default ordering might be faster" (to quote the help for the switch).
This can be examplified by the
Calculs d'enfer puzzle, a minimizing alphametic puzzle. This is very slow for both Gecode/FlatZinc and Minion using the default solver settings. These remedies makes it much faster:
* FlatZinc: change (in the FlatZinc file) the solver clause to
solve :: int_search(A, first_fail, indomain, complete) minimize a_max;
* Minion: Run Minion as
minion -varorder srf calculs_d_enfer.eprime.minion
Update:
In my simple wrapper program
eprime.pl
(Perl program) which I tend to use, I have now added support for "annotations" in the Eseence' file which handle these things The model now contains these two lines::
$ MINION :: -varorder srf
$ FLATZINC:: solve :: int_search(A, first_fail, indomain_min, complete) minimize a_max;
The MINION annotation simply adds
-varorder srf
to the argument list of the minion program, and the FLATZINC annotation replaces the default line
solve satisfy,
with the
int_search
parameter.
Note: The program
eprime.pl
is not very tidy but may be obtainable upon request.
(end of update)
Some notes about the Essence' language
The language used in Tailor is Essence' (it also supports
XCSP files ). This is a simplified version of
ESSENCE (no prime). For more about Essence' see
Modelling with Essence' and the
examples. Also, see the
Tailor tutorial.
Essence' is similiar to MiniZinc in its high-level approach, and it was very easy to translate (most of) the MiniZinc models to Essence'.
Example: Minesweeper
As an example, here is the complete model of
Minesweeper (the
param
lines are usually in a separate
parameter file):
ESSENCE' 1.0
letting X be -1 $ the unknowns
letting AB be domain int(-1..1)
given r : int $ rows
given c : int $ column
$ encoding: -1 for unknown, >= 0 for number of mines in the neighbourhood
given game : matrix indexed by [int(1..r),int(1..c)] of int(-1..8)
find mines : matrix indexed by [int(1..r),int(1..c)] of int(0..1)
$ Problem from Gecode/examples/minesweeper.cc problem 0
param r be 6
param c be 6
param game be [
[-1,-1,2,-1,3,-1],
[2,-1,-1,-1,-1,-1],
[-1,-1,2,4,-1,3],
[1,-1,3,4,-1,-1],
[-1,-1,-1,-1,-1,3],
[-1,3,-1,3,-1,-1]
]
forall i : int(1..r) . forall j : int(1..c) .
(
((game[i,j] > -1) => (mines[i,j] = 0)) /\
((mines[i,j] = 1) => (game[i,j] = -1)) /\
(
(game[i,j] >= 0 ) =>
(
game[i,j] = sum a,b : AB .
( (i+a > 0) /\ (j+b > 0) /\
(i+a <= r) /\ (j+b <= c)) * (mines[i+a,j+b])
)
)
)
Compared to the MiniZinc model
minesweeper.mzn, we can see some things:
* The
where
clause is missing in Essence'. Instead a condition is used, here:
(game[i,j] >= 0 ) =>
.
* Also, the syntax of the
forall
statement is somewhat different.
Otherwise it's quite similiar.
One feature I like it the "array slice" operator (e.g.
x[i,..]
) which slices all the columns of row
i
. For example, in
quasigroup_completion.eprime the following to constraints makes a matrix a lating square:
forall i : int(1..n) .
alldiff(x[i,..]),
forall j : int(1..n) .
alldiff(x[..,j])
One of the biggest differences between Essence' and MiniZinc languages (and all the other constraint programming systems I've tested so far) is, in my view, that Essence' don't support
predicates (user defined functions), which can make the model less clear; predicates (say, decomposed global constraints) is a nice way of structuring models.
Array access in Essence'
One of the things I test when learning a new system is how to access matrices consisting of decision variable indexed by another decision variables. I wrote about this in
Learning constraint programming - part II: Modeling with the Element constraint and
Learning Constraint Programming IV: Logical constraints: Who killed Agatha? revisited.
There was no problem at all in Essence' of modeling the Agatha problem: The model is here
who_killed_agatha.eprime. The following two constraints, which has been a problem in some other systems, worked as a charm in the Essence' model:
hates[the_killer, the_victim] = 1,
richer[the_killer, the_victim] = 0,
The crossword problem, however, is another story. I used exactly the same principle as in the MiniZinc model
crossword.mzn, but the Essence' constraint
A[E1, 3] = A[E2, 1]
give the following error:
Flattening error. Cannot translate array element with non-constant element index:A[E3,5]
.
Well, this is consistent with the section
6. Limitations and Known Bugs in the README file of the distribution:
The translator is still under development, so there are some limitations.
The following is not supported yet:
- decision variable arrays with 4 or more dimensions
- parameter arrays with 4 or more dimensions
- absolute value
- power with decision variable as exponent
- element constraint on 2-dimensional arrays
Translation to Gecode:
- no parameter arrays supported
- complicated quantified sums not supported
Translation to Flatzinc:
- not supported: multi-dimensional arrays
- no support for table, element, atmost, atleast, gcc
- no modulo, power, division
My Essence'/Tailor page
Inspired by this new Tailor release, I implemented some Essence' models which now are collected at
My Essence'/Tailor page. As usual, I started with my
"learning models", and implemented almost all of them.
Here are the Essence' models (and related parameter/data files) as of writing:
I have also updated
Common constraint programming problems to include these Essence' models.