" /> My Constraint Programming Blog: July 2009 Archives

« June 2009 | Main | August 2009 »

July 29, 2009

G12 MiniZinc version 1.0.2 released

MiniZinc version 1.0.2 has been released and can be downloaded here. From the NEWS:


There have been no changes to the definitions of the MiniZinc and FlatZinc
languages in this release. There have been no changes to the definition
of XML-FlatZinc.

Changes in this release:

* The FlatZinc interpreter's lazy clause generation solver now supports
the int_abs/2 built-in.

* The residual support for output items in the FlatZinc interpreter has been
removed.

* The MiniZinc and FlatZinc interpreters now output approximate solutions
for optimization problems when asked for more than one solution.

Bugs fixed in this release:

* Flattening of MiniZinc array expressions, for example product
or array_union, where the argument is an array variable now works.

* The FlatZinc interpreter now ensures that bounds are checked on
scalar variable assignments. [Bug #74]

* A bug in the MiniZinc-to-FlatZinc converter where:

ann a = foo::bar::baz;
constraint p(...)::a;

would be flattened to:

constraint p(...)::foo;

rather than:

constraint p(...)::foo:bar::baz;

has been fixed. [Bug #77]

For more about MiniZinc (e.g. my MiniZinc models), see My MiniZinc page.

July 25, 2009

New Tailor version (v0.3.2) and My Essence'/Tailor page

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.

July 21, 2009

Common constraint programming problems

When learning a new constraint programming system I tend to start to model some 17 "learning models" (base models). I have implemented these in all 7 constraint programming system I've learned so far (with some few exceptions).

Common Constraint Programming Problems
But there are many other problems that have been implemented in more than one system. These "common problem" are now collected on the new page Common Constraint Programming Problems. "Common" is defined as a problem that has been implemented in at least two systems. Right now there are 126 common problems consisting of 364 implemented models.

Please note that this page is generated and may contain some peculiarities.

Number of implemented models
While speaking of statistics, here is the (approximate) number of models implemented so far in each constraint programming system:

* MiniZinc: 560
* Comet: 142
* ECLiPSe: 110 (*)
* Gecode: 45
* Gecode/R: 27
* Choco: 18
* JaCoP: 18

Total: Approx. 920 models

(*) Right now, my focus is on ECLiPSe so this number will probably increase during the next weeks.

24 new ECLiPSe models

Here are 24 new ECLiPSe models, converted from my Comet or MiniZinc models. As always, the models contains more information about the problem. As of writing, My ECLiPSe page contains about 110 models.

3_jugs.ecl: 3 jugs problem, MIP model, eplex
a_round_of_golf_propia.ecl: A round of golf puzzle (Dell Logic Puzzles), Propia version
blending.ecl: Blending problem (OPL example)
crypta.ecl: crypta, alphametic problem (standard Prolog/CLP benchmark)
crypto.ecl: crypto, alphametic problem (standard Prolog/CLP benchmark)
distribute.ecl: (Decomposition of) global constraint distribute.
donald_gerald.ecl: Alphametic puzzle DONALD + GERALD = ROBERT
four_islands.ecl: Four islands puzzle (Dell Logic Puzzles)
langford.ecl: Langford's number problem (CSPLib problem 24)
langford_propia.ecl: Langford's number problem (CSPLib problem 24), Propia version
pigeon_hole.ecl: Pigeon hole problem
place_number_puzzle.ecl: Place number puzzle
rabbits.ecl: Rabbits problem (Van Hentenryck, OPL book)
spreadsheet.ecl: Simple "spreadsheet" example (Apt)
square_root_of_wonderful.ecl: Square Root of Wonderful (Martin Gardner)
stable_marriage.ecl: Stable marriage problem (examples from Van Hentenryck's OPL book, and MathWorld)
subset_sum.ecl: Subset sum problem (Murty)
talisman_square.ecl: Talisman square
traffic_lights.ecl: Traffic lights problem (CSPLib problem 16)
tunapalooza.ecl: Tunapalooza puzzle (Dell Logic Puzzles)
volsay1.ecl: Volsay production problem (Van Hentenryck, The OPL Book), eplex model
volsay2.ecl: Volsay production problem (Van Hentenryck, The OPL Book), eplex model, slightly different from volsay1.ecl
volsay3.ecl: Volsay production problem (Van Hentenryck, The OPL Book), eplex model, more general than volsay1.ecl and volsay2.ecl
warehouse.ecl: Warehouse location problem (OPL example)

July 13, 2009

26 new ECLiPSe models, and some changed

Here are my new ECLiPSe models. Almost all are more direct ports of my MiniZinc and Comet models, or at least, they use the same principal approach to the problem. In these ECLiPSe models I have experimented quite a lot, since I like to play with all the bells & whistles in ECLiPSe.

When I started to program in ECLiPSe I tend to use arrays (and arrays of arrays) dominantly since I wanted to access elements via the syntactic sugar of [] (to mimic MiniZinc/Comet) . But accessing elements via arrays is not always possible, e.g. when both the index variable and the array/matrix contains decision variables, and - as far as I know - the only possible way of accessing these structures are via listut:nth1 on lists. Therefore later models tend to use lists (and nth1) more.

Update: A comment about this. Some days later (2009-07-16) I found that often (but not always) array access using [] on an array of decision variables and index values also decision variables works when lib(propia) is just loaded (lib(propia)), even if it is not actually used (i.e. there is not explicit goal such as Goal infers most). I have already published some variants which is then called _propia.ecl (maybe _array would have been better...). For example a_round_of_golf_propia.ecl is so changed. Also, I did a stable marriage model (stable_marriage.ecl) with array access in this way which is much easier to model and understand, than a list/nth1 version..

New ECLiPSe models

a_round_of_golf.ecl: A Round of Golf (Dell Logic Puzzles)
a_round_of_golf_propia.ecl: A Round of Golf (Dell Logic Puzzles) (arrays and Propia)
added_corner.ecl: Added corner puzzle
all_interval.ecl: All interval problem (series), (CSPLib problem 7)
among.ecl: (Decomposition of) global constraint among
among_seq.ecl:(Decomposition of) global constraint among_seq
building_blocks.ecl: Building blocks puzzle (for a more general solution see labeling_dice.ecl
circuit.ecl: (Decomposition of) global constraint circuit
clique.ecl: (Decomposition of) global constraint clique
covering_opl.ecl: Set covering, selecting workers (from OPL example covering.mod)
crossword2.ecl: Crossword solving (standard constraint programming example)
cumulative_test.ecl: Test of the built in cumulative constraint
eq10.ecl: Standard benchmark problem
eq20.ecl: Standard benchmark problem
game_theory_taha.ecl: Game theory, zero sum game using eplex (from Taha, Operations Research)
global_cardinality.ecl: (Decomposition of) global constraint global cardinality count (somewhat limited)
global_contiguity.ecl: (Decomposition of) global contiguity
hidato.ecl: Hidato puzzle
inverse.ecl: (Decomposition of) global constraint inverse
kenken2.ecl: KenKen, a grid puzzle
labeled_dice.ecl: Labeled dice puzzle (contains building_blocks.ecl as a problem instance)
safe_cracking.ecl: Safe cracking problem
set_covering_skiena.ecl: Set covering problem (Skiena)
set_partition.ecl: Set partition problem
ski_assignment.ecl: Ski assignment problem
sliding_sum.ecl: (Decomposition of) global constraint sliding sum
stable_marriage.ecl: Stable marriage model (using arrays) sudoku_gcc.ecl: Sudoku, comparison of using ic_global:alldifferent and my decompositions of global cardinality and alldifferent (the rest of the code is from ECLiPSe's Sudoku example)

Some changed models

Here are some changed models.

Who killed Agatha? - now using suspend
Model: who_killed_agatha.ecl

Last I wrote about the problem with accessing for the variable matrices (as arrays):
Hates[Killer,Victim] #= 1,
Richer[Killer, Victim] #= 0
When using this syntax where Hates, Killer, and Victim are all decision variables, an instantiation fault error was thrown. Earlier I tried some remedies for this (see the cited post).

The updated version uses suspend instead:
suspend(Hates[Killer,Victim] #= 1, 2, Killer->inst),
suspend(Richer[Killer, Victim] #= 0, 2, Killer->inst),
This means that the solver suspends the constraints until Killer is instantiated. And in this case it actually works.

suspend is very powerful and is normally used for creating constraints (propagators). I haven't done this very much yet, but it's in the plans.

for loops: bin_packing2
Model:bin_packing2.ecl
As noted in the updates of Some new ECLiPSe models, e.g. Minesweeper I added a 4'th version of the foreach loop:
Version 4
Use foreach to collect S and then use sum.

 for(B,1,N),
    param(Weights,Bins,N,Capacity) do
        (for(J,1,N),
         foreach(S,Sum),
         param(Weights,Bins,B) do
              S = Weights[J]*(Bins[J] #= B)
        ),
         sum(Sum) #=< Capacity
).
Again, thanks to Joachim Schimpf for reminding me that one larger constraint sum(Sum) #=< Capacity is probably better than more small constraints, such as alot of S #= Weights[J]*(Bins[J] #= B) (note the #= here).

ECLiPSe now support MiniZinc version 1.0

Since ECLiPSe release 6.0_92 (or later) there is now support for MiniZinc version 1.0. This is great since the ic solver has in some cases been the only solver for some of the my MiniZinc models, e.g. when there is multiplication of float variables. This solver is also often very fast.

It is actually three solvers, each with its special strength: See the following modules for more about how to use these solvers: My usage
As indicated in MiniZinc/FlatZinc support in SICStus Prolog version 4.0.5, when running a MiniZinc with an ECLiPSe solver, the following is created inside a general Perl program with the variables:
$model: the MiniZinc model
$solver: one of ic, fz, or eplex
$num_solutions: number o f solutions (0 for all solutions)
:-lib(minizinc).
:-lib(flatzinc_syntax).

go :-
  minizinc:mzn_run('$model', zn_options{solver:fzn_$solver, solutions:$num_solutions}).
It is then saved as a file (e.g. model.ecl or something like that) and is then run from the shell with
eclipse  -b model.ecl -e go
See also
My ECLiPSe Page for my "real" ECLiPSe models.

July 11, 2009

Comet version 2.0-Beta released

Comet version 2.0-Beta can now be downloaded from Dynadec's Download page.

Here are some of the new things in this version, from the announcement:

Dynadec is happy to announce the pre-release of Comet 2.0. This new version is a major development and here are some of the main new features:

1. New XML library (cotxml) to read and write XML files.
2. New visualization library (qtvisual) using the Qt toolkit on all platforms (Linux, Mac, Windows).
3. New graphical debugger (-gqt command line option) on all platforms.
4. New support for external plugins.
5. New Comet language documentation with code samples.

Please look at the release notes for more details on this new version.

I haven't checked much on the list yet, but I'm very excited about the over 320 pages Comet Tutorial which is really great, and the circa 60 new accompanying examples.

From the Preface of the Comet Tutorial:

This document is a tutorial about Comet, an hybrid optimization system, combining constraint programming, local search, and linear and integer programming. It is also a full object-oriented, garbage collected programming language, featuring some advanced control structures for search and parallel programming.
This tutorial describes the basic functionalities of Comet 2.0 and how Comet can be used to solve a variety of combinatorial optimization applications. It complements the API description which describes the various classes, functions, interfaces, and libraries through a set of HTML pages. This document is constantly evolving to cover more functionalities of the Comet system and to explain how to use Comet on increasingly complex problems. The Comet system itself is constantly evolving and the material will be updated accordingly.
The tutorial is currently divided in four parts: the description of the programming language, constraint programming, local search, and mathematical programming. A fifth part, describing some of the Comet libraries, and a sixth part, describing the graphical and visualization layers, will be added subsequently. Questions about Comet, its uses, and bug reports can be posted at the Dynadec forum at http://forums.dynadec.com/.


For more about Comet, for example my own (about 160) Comet models, see My Comet page.

July 08, 2009

MiniZinc version 1.0.1 released

From the MiniZinc mailing list:

Version 1.0.1 of the G12 MiniZinc distribution has been released.

Version 1.0.1 of the distribution can be downloaded from Download.
Snapshots of the development version of the G12 MiniZinc distribution
are also available from this page.

Further information about MiniZinc and FlatZinc is available from MiniZinc and FlatZinc

Bugs may be reported via the G12 bug tracking system, which can be accessed at http://bugs.g12.csse.unimelb.edu.au.


From the NEWS file:

G12 MiniZinc Distribution version 1.0.1

---------------------------------------

There have been no changes to the definitions of the MiniZinc and FlatZinc
languages in this release. There have been no changes to the definition
of XML-FlatZinc.


Changes in this release:

* MiniZinc tools command line changes

The MiniZinc interpreter and MiniZinc-to-FlatZinc converter now
recognise files with the .dzn extension as MiniZinc data files, i.e.
you no longer need to use the --data option to use such files as data
files.

* FlatZinc output processing tool

We have added a new tool, solns2dzn, that can be used to process the
output of FlatZinc implementations in various ways. For example, it
can extract each individual solution and write it to a separate file.

* The FlatZinc interpreter's lazy clause generation solver now supports
the int_times/3 built-in.

* The global_cardinality_low_up global constraint has been added to the
MiniZinc library.

* The MiniZinc-to-FlatZinc converter now propagates annotations through
assertions during flattening, For example, the following fragment of
MiniZinc:

predicate foo(int: x, array[int] of var int y);

predicate bar(int: x, array[int] of var int y) =
assert(x > 3, "value of x must be greater than 3", foo(x, y));

constraint bar(4, ys) :: baz;

will be flattened into the following fragment of FlatZinc:

constraint foo(4, ys) :: baz;


Bugs fixed in this release:

* A bug in the implementation of the FlatZinc built-in int_mod/3 in the
FlatZinc interpreter's finite-domain backend has been fixed.

* The MiniZinc-to-FlatZinc converter now does a better job of extracting
output variables from output items.

* The solver-specific global constraint definitions for the G12 lazy
clause generation solver are now documented. They are in the
``g12_lazyfd'' directory of the MiniZinc library.

* A bug that caused a segmentation fault in the type checker when
checking large FlatZinc instances has been fixed.

* A bug where a cycle of equalities caused mzn2fzn to go into
a loop has been fixed. [Bug #65]

* mzn2fzn now imposes constraints on arguments induced by predicate
parameter types. [Bug #69]

* Flattening of set2array coercions is now supported. [Bug #70]

* A bug that caused mzn2fzn to abort on min/max expressions over empty arrays
has been fixed. [Bug #71]

* mzn2fzn now computes bounds on set cardinality variables correctly.

July 03, 2009

Some new ECLiPSe models, e.g. Minesweeper

Since I wrote Constraint programming in ECLiPSe Constraint Programming System the other day, I have published about 15 new ECLiPSe models on My ECLiPSe page.

Here these new models are, with some comments or reflections. All of the models are translations of my MiniZinc or Comet models.

Assignment problems

Model: assignment.ecl
This program contains some examples of the assigment problems from Winston's "Operations Research" and GLPK (and some other source).

Data is represented as a matrix of arrays:
% 
% Winston "Operations Research", page 398, swimming team example
% (original version)
% See http://www.hakank.org/minizinc/assignment2.mzn 
% 
cost(2, minimize, []([](54, 54, 51, 53), 
                     [](51, 57, 52, 52),
                     [](50, 53, 54, 56),
                     [](56, 54, 55, 53))).
The second argument is the "mode" of operations, i.e. if it is a maximization or minimization problem.

The main constraints are the following:
%
% exacly one assignment per row, all rows must be assigned
%
( for(I,1,Rows), param(X,Cols) do
   sum(X[I,1..Cols]) #= 1
),

%
% zero or one assignments per column
%
( for(J,1,Cols), param(X,Rows) do
     sum(X[1..Rows,J]) #=< 1
),

Bin packing problems

Model: bin_packing.ecl
Contains some small examples of bin packing from some sources.

Global constraint bin_packing

Model: bin_packing2.ecl
This is (a decomposition of) the global constraint bin_packing, related to but not the same as the common usage of bin packing (see the above).

It was also a study of translating a predicate from MiniZinc (using bool2int for reification) to ECLiPSe. Here is the MiniZinc code that was to be converted; n is the size of the weights and bins:
   forall(b in 1..n) (
      sum(j in 1..n) ( weights[j]*bool2int(bins[j] = b)) <= capacity
   )
Here are three variants of the same for loop in ECLiPSE, where N is the number of bins.

Using the same approach as MiniZinc, I (right now) prefer version 2 to version 1, since it is more succint, and prefer version 2 to version 3 since it is clearer. These preferences probably will change over the time. Update some days later: And it already did, see below.

Note that both the MiniZinc version and this ECLiPSe version are fully multidirectional, i.e. we can let either (or all) of the variables be free and it still work. Note: If we let Bins free in ECLiPSe, we ought to fix the length of it (to 3 in the program) otherwise it will not work as excepted.

Version 1, straightforward use of for and fromto and a condition
( for(B,1,N),
  param(Weights,Bins,N,Capacity) do
  ( for(J,1,N),
    fromto(0,In,Out,Sum),
    param(Weights,Bins,B) do
       Bins[J] #= B 
     -> 
      Out #= In + Weights[J] 
    ; 
      Out = In
  ),
  Sum #=< Capacity
)
Version 2, using reification like bool2int.
( for(B,1,N),
  param(Weights,Bins,N,Capacity) do
  ( for(J,1,N),
    fromto(0,In,Out,Sum),
    param(Weights,Bins,B) do
    %                        reification (0 or 1)
    Out #= In + Weights[J] * (Bins[J] #= B)
 ),
 Sum #=< Capacity
)
Version 3
Here we put the calculation in the fromto call (instead of the do body). With this change, eval(Sum) is now needed, and the param with the variables in the J loop is still needed.
( for(B,1,N),
   param(Weights,Bins,N,Capacity) do
     ( for(J,1,N),
       fromto(0,In,In + Weights[J]*(Bins[J] #= B),Sum),
       param(Weights,Bins,B) do
         true
     ),
     eval(Sum) #=< Capacity
).
Later update: Joachim Schimpf (from the ECLiPSe team) kindly remarked that it probably better to use eval since it will just create one constraint instead of many small constraints using inside the inner loop.

Joachim also mentioned a fourth version:
Version 4
Use foreach to collect S and then use sum.
 for(B,1,N),
    param(Weights,Bins,N,Capacity) do
        (for(J,1,N),
         foreach(S,Sum),
         param(Weights,Bins,B) do
              S = Weights[J]*(Bins[J] #= B)
        ),
         sum(Sum) #=< Capacity
).
Thanks Joachim. (End of update)

Calculs d'enfer

Model: calculs_d_enfer.ecl
This is a alphametic problem taken from Jianyang Zhou "The Manual of NCL version 1.2", page 33. It was quite straightforward to translate from MiniZinc.

Curious set of integers

Model: curious_set_of_integers.ecl
From Martin Gardner (February 1967)
The integers 1,4,9, and 120 form a set with a remarkable priperty: the product of any two integers is one less than a perfect square. Find a fifth number that can be added to the set without destroying this property.


Heterosquare problem

Model: heterosquare.ecl
This is yet another "grid and sum" problem. See Heterosquare for an explanation of the problem.

Minesweeper

Model: minesweeper.ecl
This is a general Minesweeper solver given problem instances of the following format:
problem(0,[]([](_,_,2,_,3,_),
             [](2,_,_,_,_,_),
             [](_,_,2,4,_,3),
             [](1,_,3,4,_,_),
             [](_,_,_,_,_,3),
             [](_,3,_,3,_,_))).
There are 14 examples, among them the 10 examples from Gecode's minesweeper.cpp.

The main constraints are implemented in the following loop. It took quite long to realize that multifor([A,B]...) was needed for the summing of the cells (in the Sum variable) for it to work, instead of two nested for(A) ... for(B)-loops. It was also quite late in the programming phase when I switched the representation of unknowns from -1 (as was used in the MiniZinc model minesweeper.mzn and other implementations) to the anonymous variable _. Now it use ground for checking if it is a hint or not.
%
% Game[I,J] = _ means that it is unknown from start, may be a mine.
% Games[I,J] >= 0 means that the value is known and that it is not a mine.
%
%
% Note: the A,B loop below must be a multifor, otherwise the Sum
%       don't work.
%
( for(I,1,R), param(Game, Mines, C, R) do
      ( for(J,1,C), param(Game, Mines, R, C, I) do
            GameIJ is Game[I,J],
            MinesIJ is Mines[I,J],

            % some reasoning about this cell
            (ground(GameIJ) -> MinesIJ #= 0 ; true),
            (MinesIJ #= 1 -> ground(GameIJ) ; true),

            % we check only those cells we are unsure of, i.e.
            % GameIJ >= 0
            ground(GameIJ)
      ->                      
            % sum the number of neighbors of this cell
            Sum :: 0..8,
            ( multifor([A,B],-1,1),  % must be a multifor
              fromto(0, In, Out, Sum), 
              param(Mines, R, C, I, J) do
                      I+A #>  0, J+B #>  0,
                      I+A #=< R, J+B #=< C
            -> 
              MinesIAJB is Mines[I+A,J+B],
              Out #= In + MinesIAJB
            ; 
              Out = In
            ),

            % all sums must sum up to Game[I,J]
            Sum #= GameIJ
      ;
        true

      )
),

Photo problem

Model: photo_problem.ecl
This is a problem from the Mozart/Oz tutorial:
Betty, Chris, Donald, Fred, Gary, Mary, and Paul want to align in one row for taking a photo. Some of them have preferences next to whom they want to stand: 1. Betty wants to stand next to Gary and Mary. 2. Chris wants to stand next to Betty and Gary. 3. Fred wants to stand next to Mary and Donald. 4. Paul wants to stand next to Fred and Donald. Obviously, it is impossible to satisfy all preferences. Can you find an alignment that maximizes the number of satisfied preferences?
The preferences are coded as an array of arrays of size 2, but there is also a (commented) variant using adjacency matrix.

This program is not very fast.

Remarkable sequence (Langford problem)

Model: remarkable_sequence.ecl
This problem (and the solution approach I use) is from R. Apt, J. Brunekreef, V. Partington and A. Schaerf Alma-0: An imperative language that supports declarative programming (1997, PDF). It is the Langford problem with 3 occurrences of each digit 0..9.

In my approach I use some nth1(J,A,I) predicate to access the J'th element in the sequence A (the decision variable), since the construct A[J] don't seems to work (see "Who killed Agatha?" for a related problem).

Set covering (and set partitioning)

Models:
set_covering.ecl
set_covering2.ecl
set_covering3.ecl
set_covering4.ecl

These are different versions of the set covering, with examples from Winston's "Operations Resear ch", Taha's "Operations Research - An Introduction", etc.

The example 2, 3, and 4 first finds the optimal value, and then finds all the solutions with that value, and it was quite easy implement this in ECLiPSe. set_covering4.ecl implements both set covering and set partitions.

Set covering deployment

Model: set_covering_deployment.ecl
This program implements the Mathword's example in Set covering deployment where the objective is to places armies in the Roman Empire.

Who killed Agatha?

Model: who_killed_agatha.ecl
This is a standard benchmark for theorem proving, originally from F. J. Pelletier: Seventy-five problems for testing automatic theorem provers., Journal of Automated Reasoning, 2: 191 216, 1986.

The problem is states:
Someone in Dreadsbury Mansion killed Aunt Agatha. Agatha, the butler, and Charles live in Dreadsbury Mansion, and are the only ones to live there. A killer always hates, and is no richer than his victim. Charles hates noone that Agatha hates. Agatha hates everybody except the butler. The butler hates everyone not richer than Aunt Agatha. The butler hates everyone whom Agatha hates. Noone hates everyone. Who killed Agatha?
I wrote about this problem in Learning Constraint Programming IV: Logical constraints: Who killed Agatha? revisited and compared the implementation in other constraint systems (MiniZinc, JaCoP, Choco, Choco, Comet, and Gecode). One of the problem I had in some of these systems was with the Element constraint when the decision variables where a matrix (or array) and the index was also a decision variable.

I have the same problem with my ECLiPSe solution. The following do not seems to work, where Hates (a matrix of 0/1 varibales), Killer, and Victim are all decision variables:
Hates[Killer,Victim] #= 1,
which states that the killer always hates the victim. However, the following works, where we loops through all the indices and use the proper one (the one that "happens to represent" Killer):
( for(I,1,N), param(Killer,Victim,Hates,Richer) do
      Killer #= I => Hates[I, Victim] #= 1,
      Killer #= I => Richer[I, Victim] #= 0
)
Other than that, the modeling was quite simple.

As noted before, this problem can be solved in many ways, as most problems can. Here I wanted to implement it the same way as the other CP systems, just to check how ECLiPSe handles Element.

Young tableaux and partitions

Model: young_tableaux.ecl
See the entries in MathWorld, and Wikipedia for more about this problem.