<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
   <channel>
      <title>My Constraint Programming Blog</title>
      <link>http://www.hakank.org/constraint_programming_blog/</link>
      <description>This is my blog about constraint programming and related paradigms, e.g. news about and models in some of my favorite constraint programming languages (MiniZinc, JaCoP, Choco, Gecode, Gecode/R, Comet, ECLiPSe, Minion/Tailor, SICStus Prolog, etc). See http://www.hakank.org/ for more about me (Hakan Kjellerstrand, hakank@bonetmail.com).</description>
      <language>en</language>
      <copyright>Copyright 2010</copyright>
      <lastBuildDate>Wed, 17 Mar 2010 19:25:10 +0100</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/?v=3.2</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

            <item>
         <title>MiniZinc version 1.1 released</title>
         <description><![CDATA[<p><a href="http://www.g12.csse.unimelb.edu.au/minizinc/">MiniZinc</a> version 1.1 has been released. See below how my existing (and maybe others')  MiniZinc models are affected by the changes.</p>

<p>From the <a href="http://www.g12.csse.unimelb.edu.au/minizinc/downloads/doc-0.11/NEWS">NEWS</a>:<br />
<blockquote>G12 MiniZinc Distribution version 1.1<br />
-------------------------------------</p>

<p>Changes to the MiniZinc language:</p>

<p>* The following built-in operations have been introduced:</p>

<p>      int:        lb_array(array[int] of var int)<br />
      float:      lb_array(array[int] of var float)<br />
      set of int: lb_array(array[int] of var set of int)<br />
  <br />
      int:        ub_array(array[int] of var int)<br />
      float:      ub_array(array[int] of var float)<br />
      set of int: ub_array(array[int] of var set of int)<br />
  <br />
      set of int: dom_array(array[int] of var int)<br />
  <br />
  These new operations are synonyms for the following existing built-in<br />
  MiniZinc operations:</p>

<p>      int:        lb(array[$T] of var int)<br />
      float:      lb(array[$T] of var float)<br />
      set of int: lb(array[$T] of var set of int)<br />
  <br />
      int:        ub(array[$T] of var int)<br />
      float:      ub(array[$T] of var float)<br />
      set of int: ub(array[$T] of var set of int)<br />
  <br />
      set of int: dom(array[$T] of var int)</p>

<p>  These latter operations are now deprecated.  Support for them will<br />
  be removed in the next release.  This change is being made in order<br />
  to preserve compatibility with the full Zinc language.</p>

<p>  Note: that only the versions of lb, ub and dom that take an array<br />
  as a an argument are deprecated.  The MiniZinc lb, ub and dom operations<br />
  on non-array values are *not* deprecated.</p>

<p><br />
Changes to the FlatZinc language:</p>

<p>* Boolean variable expressions as constraints are no longer supported.<br />
  All constraints in FlatZinc must now be predicate applications.</p>

<p>* String parameters are no longer supported.  String literals are restricted<br />
  to appearing as the arguments of annotations.</p>

<p>* Set of bool and set of float parameters and literals are no longer<br />
  supported.</p>

<p>* The int_float_lin/4 objective expression is no longer supported.</p>

<p>* FlatZinc now has two additional evaluation outcomes: "unknown"<br />
  for when search terminates without having explored the whole search<br />
  space and "unbounded", for when the objective of an optimization<br />
  problem is unbounded.</p>

<p>* The semantics of the int_div/3 and int_mod/3 built-ins has been changed.<br />
  See the ``Specification of FlatZinc'' for further details.</p>

<p><br />
Other Changes:</p>

<p>* The single pass MiniZinc interpreter, minizinc, has been deprecated.<br />
  It will be removed in a future release.</p>

<p>* The MiniZinc-to-FlatZinc converter, mzn2fzn, has been rewritten.<br />
  The new implementation is smaller and more efficient.<br />
  Computation of variable bounds has also been improved.</p>

<p>* mzn2fzn now outputs singleton sets as ranges.  [Bug #94]</p>

<p>* A bug that caused expressions containing abs/1 to be incorrectly<br />
  flattened has been fixed.  [Bug #91]</p>

<p>* The FlatZinc interpreter's finite-domain backend now implements<br />
  global_cardinality_low_up as a built-in.</p>

<p>* The FlatZinc interpreter's lazy clause generation solver now supports<br />
  the int_mod/3 built-in.</p>

<p>* Two additional modes of operation have been added to the FlatZinc<br />
  solution processing tools, solns2dzn, that allow it to extract the first<br />
  or last solution from a FlatZinc output stream.  Also, there is no longer<br />
  a default mode of operation for solns2dzn, it must now be specified by<br />
  the user or an error will occur.</p>

<p>* The following new global constraints have been added to the MiniZinc<br />
  library:</p>

<p>      all_equal<br />
      decreasing<br />
      diffn<br />
      lex2<br />
      lex_greater	(Synonym for lex_less with arguments swapped.)<br />
      lex_greatereq	(Synonym for lex_lesseq with arguments swapped.)<br />
      sliding_sum<br />
      strict_lex2</p>

<p>* The following synonyms for existing global constraints have been added<br />
  to the MiniZinc library (the existing name is given in parentheses):</p>

<p>      alldifferent      (all_different)<br />
      atleast           (at_least)<br />
      atmost            (at_most)<br />
      atmost1           (at_most1)</p>

<p>* The sequence constraint is deprecated.  Models should use the new<br />
  sliding_sum constraint instead.</p>

<p>* The 'table' constraint decompositions in the MiniZinc library have been<br />
  modified so as to fit better with the G12 MiniZinc-to-FlatZinc conversion:<br />
  now no scaling constraints are created.</p>

<p>* The decompositions of the constraints in the 'lex' family have been<br />
  tweaked to enable a little more propagation.<br />
</blockquote></p>

<h3>Documents</h3>
Here are the three new <a href="http://www.g12.csse.unimelb.edu.au/minizinc/specifications.html">specification documents</a> for MiniZinc version 1.1 (and Zinc version 0.11):
<ul>
<li> <a href="http://www.g12.csse.unimelb.edu.au/minizinc/downloads/doc-0.11/zinc-spec.pdf">Specification of Zinc version 0.11 and MiniZinc version 1.1. </a> (PDF)
<li> <a href="http://www.g12.csse.unimelb.edu.au/minizinc/downloads/doc-0.11/flatzinc-spec.pdf">Specification of FlatZinc, version 1.1. </a> (PDF)
<li> <a href="http://www.g12.csse.unimelb.edu.au/minizinc/downloads/doc-0.11/fzn_transition.pdf">Transition guide</a>  (PDF) to assist FlatZinc implementors in updating their implementations from version 1.0.X.
</ul>

<h2>Comments</h2>
The next few days I will change <a href="http://www.hakank.org/minizinc/">my MiniZinc models</a> so they comply to version 1.1, and I have already started this work. The following will be changed:<ul>   <li><b>lb/ub for arrays</b><br>
 <code>lb(array)</code> and <code>ub(array)</code> will be changed to <code>lb_array(array)</code> and <code>ub_array(array)</code> respectively.
  <li> <b>Comparing/copying arrays</b><br>
One thing that should not work even in MiniZinc version 1.0.3 - but for some reason did - was copying/equality/comparison of arrays in the <code>constraint</code> section or in predicates. This don't work in MiniZinc version 1.1. E.g., the following no longer works:
<pre>
int: n = 4;
array[1..n] of var 1..n: x;
constraint
   <b>x = [1,2,3,4]</b> % no longer works
;
</pre>
Instead, the arrays must now be handled element-wise. Since many of my models use the above construct, especially for testing the global constraints, the models use a new predicate family <code>cp&lt;n&gt;d</code> (where &lt;n&gt is the dimension, 1, 2, etc), e.g. <code>cp1d</code> and <code>cp2d</code>. Example of one version of <code>cp1d</code>:
<pre>
int: n = 4;
array[1..n] of var 1..n: x;
solve satisfy; 
% arrays of 1d where both arguments are var int
predicate cp1d(array[int] of var int: x, array[int] of var int: y) =
  assert(index_set(x) = index_set(y),
           "cp1d: x and y have different sizes",
     forall(i in index_set(x)) ( x[i] = y[i] ));
constraint
   <b>cp1d(x, [1,2,3,4])</b> % this works
;
</pre>
Some examples are collected in the model <a href="http://www.hakank.org/minizinc/copy_arrays.mzn">copy_arrays.mzn</a>.

<p>I estimate that over 200 of my models have to be fixed in this way.As mentioned above, some of models are now already changed.<br />
<li> <b>Renamed models</b><br><br />
Some of my MiniZinc models has been renamed since they clash with new built-in predicates:<br />
    <ul> <br />
        <li> <a href="http://www.hakank.org/minizinc/all_equal_me.mzn">all_equal_me.mzn</a><br />
        <li> <a href="http://www.hakank.org/minizinc/decreasing_me.mzn">decreasing_me.mzn</a><br />
        <li> <a href="http://www.hakank.org/minizinc/diffn_me.mzn">diffn_me.mzn</a><br />
        <li> <a href="http://www.hakank.org/minizinc/lex2_me.mzn">lex2_me.mzn</a><br />
        <li> <a href="http://www.hakank.org/minizinc/lex_greater_me.mzn">lex_greater_me.mzn</a><br />
        <li> <a href="http://www.hakank.org/minizinc/sliding_sum_me.mzn">sliding_sum_me.mzn</a><br />
    </ul><br />
</ul></p>

<p>After the changes are done, I will also update the G12's <a href="http://www.g12.cs.mu.oz.au/mzn/">MiniZinc SVN repository</a>, the <a href="http://www.g12.cs.mu.oz.au/mzn/hakank">hakank</a> directory.</p>

<p><b>Two more things</b><ul><li> One model that I have not mentioned is  <a href="http://www.hakank.org/minizinc/spinning_disks.mzn">spinning_disks.mzn</a>: The spinning disks problem from <a href="http://skepticsplay.blogspot.com/2010/03/spinning-disks.html">Skeptic's Play</a></p>

<p><li> I'm now in the AUTHORS file.  :-)<br />
</ul></p>

<p>Also see, <a href="http://www.hakank.org/minizinc/">my MiniZinc Page</a>.<br />
</p>]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/03/minizinc_version_11_released.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/03/minizinc_version_11_released.html</guid>
         <category>MiniZinc</category>
         <pubDate>Wed, 17 Mar 2010 19:25:10 +0100</pubDate>
      </item>
            <item>
         <title>Gecode version 3.3.0 released</title>
         <description><![CDATA[<a href="http://www.gecode.org/">Gecode</a> version 3.3.0 has been released. 

From the <a href="http://www.gecode.org/doc-latest/reference/PageChange.html#SectionChanges_3_3_0">Changelog</a>:
<blockquote>
<h3>Changes in Version 3.3.0 (2010-03-15)</a></h3>
This release provides some fixes, some performance improvements for domain propagators, and quite some clean ups how propagators and advisors report their status to the kernel. Many of these clean ups are essential to make it easier to program propagators and branchers with Gecode.<p>
</p><ul>
<li>Kernel<ul>
<li>Additions<ul>
<li>Advisors now can force its propagator to be rescheduled, including recomputation of its cost used for scheduling (normally, a propagator is only rescheduled if its modification event delta changes). An advisor can signal forceful rescheduling by returning ES_NOFIX_FORCE or returning the return value of ES_NOFIX_FORCE_DISPOSE. Read the forthcoming "Modeling and Programming with Gecode" for details. (minor)</li>
</ul>
</li><li>Other changes<ul>

<li>The failure macros for posting GECODE_ES_FAIL and GECODE_ME_FAIL now only accept a single argument and assume that "home" actually refers to the home space. Read the forthcoming "Modeling and Programming with Gecode" for details. (minor)</li><li>The functions ES_FIX_PARTIAL, ES_NOFIX_PARTIAL, ES_FIX_DISPOSE, and ES_NOFIX_DISPOSE are now member of Space. Read the forthcoming "Modeling and Programming with Gecode" for details. (minor)</li><li>The function ES_SUBSUMED now is a member of Space and accepts a propagator as its single argument. The variant with a size as the second argument is available as ES_SUBSUMED_DISPOSED but use is highly discouraged. Read the forthcoming "Modeling and Programming with Gecode" for details. (minor)</li><li>The functions ES_SUBSUMED_FIX and ES_SUBSUMED_NOFIX for advisors have been renamed to ES_FIX_DISPOSE and ES_NOFIX_DISPOSE. Read the forthcoming "Modeling and Programming with Gecode" for details. (minor)</li></ul>
</li><li>Bug fixes<ul>
<li>ViewValBrancher with random value selection did not produce a random sequence of values. (minor)</li></ul>
</li></ul>
</li><li>Finite domain integers<ul>
<li>Additions<ul>
<li>Integer sets (IntSet) now have a in member function for testing whether an integer is included. (minor)</li></ul>
</li><li>Other changes<ul>

<li>Patterns for reified propagators have been moved to the <code>Gecode::Int</code> namespace. (minor)</li></ul>
</li><li>Performance improvements<ul>
<li>Considerably improved performance and memory consumption of the DFA-based extensional constraint (regular). (major)</li></ul>
</li></ul>
</li><li>Finite integer sets<ul>
<li>Other changes<ul>
<li>Patterns for set propagators have been moved to the <code>Gecode::Set</code> namespace. (minor)</li></ul>

</li></ul>
</li><li>Minimal modeling support<ul>
<li>Additions<ul>
<li>Linear expressions can freely mix integer and Boolean variables and support construction from variable arrays via a sum function. (minor)</li></ul>
</li><li>Removals<ul>
<li>Removed special cases for posting linear and Boolean expressions consisting of a single variable only (was highly ambigious). (minor)</li></ul>
</li></ul>
</li><li>Support algorithms and datastructures<ul>
<li>Performance improvements<ul>
<li>Changed to single, really efficient bitset implementation used allover the system. (major)</li></ul>

</li></ul>
</li><li>Gist<ul>
<li>Bug fixes<ul>
<li>Avoid inter-thread call to QWidget::update, which apparently causes a slight memory leak (and warning messages on stderr) on Mac OS. (minor)</li></ul>
</li></ul>
</li><li>Gecode/FlatZinc<ul>
<li>Other changes<ul>
<li>The FlatZinc interpreter can now be extended by plugins that implement custom search strategies. The plugins are implemented as dynamically loaded libraries using the Qt plugin mechanism. An example can be found in the directory gecode/flatzinc/exampleplugin. (minor)</li><li>The index of the variable used for optimization is now available in the FlatZincSpace class. (minor)</li><li>Added command line option -print, which controls whether all solutions are printed or only the last one that is found, and -search, to choose between branch-and-bound and restart optimization. (minor)</li><li>The FlatZinc library can now parse a FlatZinc model into any subclass of FlatZincSpace, so that custom extensions can be built. Annotations on the solve item can now be accessed from the returned FlatZincSpace, so that additional search strategies can be implemented. (minor)</li></ul>

</li><li>Bug fixes<ul>
<li>The FlatZinc interpreter ignored the -c-d and -a-d command line switches when used with Gist. (minor)</li>
</blockquote>

I'm really looking forward to the forthcoming document <b>Modeling and Programming with Gecode</b> mentioned above. Also, I'm doing some experiments with the new search annotations using AFC (Accumulated Failure Count, a.k.a. weighted degree of a variable) for Gecode/fz (the FlatZinc solver): <ul><li> afc_min
<li> size_afc_min
<li> afc_max
<li> size_afc_max
</ul>
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/03/gecode_version_330_released.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/03/gecode_version_330_released.html</guid>
         <category>Gecode</category>
         <pubDate>Tue, 16 Mar 2010 20:59:59 +0100</pubDate>
      </item>
            <item>
         <title>Pi Day Sudoku 2009 - the models (MiniZinc and Comet)</title>
         <description><![CDATA[The 14 March is <a href="http://en.wikipedia.org/wiki/Pi_Day">Pi Day</a> (&#960; Day) and is a celebration of Pi (3.14 in the <code>mm.dd</code> date notation). There are a lot of <a href="http://www.google.se/#num=100&hl=en&safe=off&q=%22pi+day%22+activities">activities</a> for this day. One of these activities is the Pi Day Sudoku.
<br><br>
Almost exactly one year ago, I blogged about the <a href="http://brainfreezepuzzles.com/main/piday2009.html">Pi Day Sudoku 2009 problem</a>  in these two posts:
<ul><li> <a href="http://www.hakank.org/constraint_programming_blog/2009/03/pi_day_sudoku_2009.html">Pi Day Sudoku 2009</a>
<li> <a href="http://www.hakank.org/constraint_programming_blog/2009/03/solving_pi_day_sudoku_2009_wit.html">Solving Pi Day Sudoku 2009 with the global cardinality constraint</a></ul>

The problem is an extended version of a Sudoku problem: <blockquote>Rules: Fill in the grid so that each row, column, and jigsaw region contains 1-9 exactly once and &#960; [Pi] three times. </blockquote>

<a href="http://brainfreezepuzzles.com/main/puzzles/Brainfreeze_PiDay2009.jpg"><image src="http://brainfreezepuzzles.com/main/puzzles/Brainfreeze_PiDay2009.jpg" width="200" height="200"></image></a><br>
(Click to enlarge the picture)
<br><br>
Since it was a competition (closed June 1, 2009), I didn't published any models of this problem when blogging about the problem. Now, a year after, it seems to be a good time to publish them. I then implemented two version, one in MiniZinc, and one in Comet::<ul> <li> MiniZinc: <a href="http://www.hakank.org/minizinc/sudoku_pi.mzn">sudoku_pi.mzn</a>
 <li> Comet: <a href="http://www.hakank.org/comet/sudoku_pi.co">sudoku_pi.co</a>
</ul>

Both models use the same approach (details differs however). It is the same as for the plain Sudoku, with two exceptions: <ul> <li> The common approach in plain Sudoku is to use the global constraint <code>alldifferent</code> for stating that the values in the rows, columns, and regions should be different. Since there should be 3 occurrences of &#960; in each row, column and region, this approach don't work. As mentioned in <a href="http://www.hakank.org/constraint_programming_blog/2009/03/solving_pi_day_sudoku_2009_wit.html">Solving Pi Day Sudoku 2009 with the global cardinality constraint</a>, my first approach was a home made version of the constraint <code>alldifferent except 0 and Pi</code> but it was too slow. Instead (and via a suggestion of Mikael Zayenz Lagerkvist) I changed to the global constraint <code>global_cardinality</code>, which was much faster.
 <li> The other difference to the standard approach is that the regions are not 3x3 (or MxM), but "jigsaw regions". It was not especially hard to make this representation (though boring to type them in). The constraint for checking the regions are (in MiniZinc):<br>
<pre>
  /\ % the regions
  forall(i in 1..num_regions) (
    <b>check([x[regions[j,1],regions[j,2]] | j in 1+(i-1)*n..1+((i-1)*n)+11 ])</b>
  )
</pre>
</ul>

Here I will not publish the solution to the puzzle since I gather that there are a lot of people out there that will solve it by there own. And there is at least one valid solution out there.

<h3>Summary</h3>
This was a fun problem, especially since I learned some new things by implement the models. As a constraint programming challenge is was quite harder than this year puzzle: <a href="http://brainfreezepuzzles.com/main/piday2010.html">Pi Day 2010</a>: <blockquote>Rules: Fill in the grid so that each row, column, and block contains 1-9 exactly once. This puzzle only has 18 clues! That is conjectured to be the least number of clues that a unique-solution rotationally symmetric puzzle can have. To celebrate Pi Day, the given clues are the first 18 digits of &#960; = 3.14159265358979323... </blockquote>

[Yes, I have implemented a MiniZinc model for this problem as well; it is a standard Sudoku problem. No, I will not publish the model or a solution until the deadline, June 1, 2010.]
<br><br>
For more about Pi Day Sudoku 2010, see the blog 360: <a href="http://threesixty360.wordpress.com/2010/03/09/pi-day-sudoku-is-back/">Pi Day Sudoku is back</a>.

<br><br>
Also, see the following models that implements Killer Sudoku, which use the same approach as Pi Day Sudoku 2009:
<ul>  <li> MiniZinc: <a href="http://www.hakank.org/minizinc/killer_sudoku.mzn">killer_sudoku.mzn</a>
  <li> Comet: <a href="http://www.hakank.org/comet/killer_sudoku.co">killer_sudoku.co</a></ul>


<h3>The MiniZinc code</h3>
Here is the MiniZinc model (<a href="http://www.hakank.org/minizinc/sudoku_pi.mzn">sudoku_pi.mzn</a>), slightly edited.

<pre>include "globals.mzn";
int: n = 12;
int: X = 0;  % the unknown
int: P = -1; % &#960; (Pi)

predicate check(array[int] of var int: x) =
   <b>global_cardinality(x, occ)</b> % :: domain
;

array[1..n, 1..n] of var -1..9: x :: is_output;
array[-1..9] of 0..3: occ = array1d(-1..9, [3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
array[1..11] of 0..3: occ2 = [3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1];

% solve satisfy;
solve :: int_search([x[i,j] | i,j in 1..n], first_fail, indomain_min, complete) satisfy;

constraint

  % copy the hints
  forall(i in 1..n, j in 1..n) (
      x[i,j] != 0
      /\
      if dat[i,j] != X then
        x[i,j] = dat[i,j]
      else 
        true
      endif
  )

  /\ % rows
  forall(i in 1..n) (
    check([x[i,j] | j in 1..n]) 
  )

  /\ % columns
  forall(j in 1..n) (
    check([x[i,j] | i in 1..n])
  )

  /\ % the regions
  forall(i in 1..num_regions) (
    <b>check([x[regions[j,1],regions[j,2]] | j in 1+(i-1)*n..1+((i-1)*n)+11 ])</b>
  )
;

output 
[ show(occ) ++ "\n"] ++
[
  if j = 1 then "\n" else " " endif ++
   show(x[i,j])
  | i in 1..n, j in 1..n

] ++ ["\n"];


% data
array[1..n,1..n] of int: dat = array2d(1..n, 1..n,
[
 4,9,7, P,5,X,X,X,X, X,X,X,
 X,P,X, 8,X,X,9,6,1, 5,2,X,
 X,8,X, 1,X,X,X,P,X, 7,X,X,
 X,X,X, X,X,X,X,P,X, 4,X,X,
 5,3,9, 6,X,X,X,X,X, X,X,X,

 9,4,X, P,P,P,7,X,X, X,X,X,
 X,X,X, X,X,6,2,5,P, X,7,4,
 X,X,X, X,X,X,X,X,P, P,3,8,
 X,7,8, 4,6,9,X,X,X, X,X,X,

 X,X,3, X,P,X,X,4,7, 1,6,9,
 X,X,4, X,1,X,X,X,6, X,P,X,
 X,X,X, X,X,X,X,X,4, X,5,X
 ]);


% The regions
int: num_regions = 12;
array[1..num_regions*12, 1..2] of int: regions  = array2d(1..num_regions*12, 1..2,
[
  % Upper left dark green
  1,1  , 1,2  , 1,3  , 
  2,1  , 2,2  , 2,3  , 
  3,1  , 3,2  , 
  4,1  , 4,2  ,  
  5,1  , 5,2  , 
 
  % Upper mid light dark green
  1,4  ,  1,5  ,  1,6  ,  1,7  ,  1,8  ,  1,9  , 
  2,4  ,  2,5  ,  2,6  ,  2,7  ,  2,8  ,  2,9  , 

  % Upper right green
  1,10  ,  1,11  ,  1,12  , 
  2,10  ,  2,11  ,  2,12  , 
  3,11  ,  3,12  , 
  4,11  ,  4,12  , 
  5,11  ,  5,12   , 

  % Mid upper left "blue"
  3,3  ,  3,4  , 3,5  ,  3,6  , 
  4,3  ,  4,4  , 4,5  ,  4,6  , 
  5,3  ,  5,4  , 5,5  ,  5,6  , 

  % Mid Upper right blue
  3,7  ,  3,8  ,  3,9  ,  3,10  , 
  4,7  ,  4,8  ,  4,9  ,  4,10  , 
  5,7  ,  5,8  ,  5,9  ,  5,10  , 

  % Mid left green
  6,1  ,  6,2  , 6,3  , 
  7,1  ,  7,2  , 7,3  , 
  8,1  ,  8,2  , 8,3  , 
  9,1  ,  9,2  , 9,3  , 

  % Mid left blue
  6,4  , 6,5  , 
  7,4  , 7,5  , 
  8,4  , 8,5  , 
  9,4  , 9,5  , 
  10,4 , 10,5  , 
  11,4 , 11,5  , 

  % Mid mid green
  6,6  , 6,7  , 
  7,6  , 7,7  , 
  8,6  , 8,7  , 
  9,6  , 9,7  , 
  10,6 , 10,7  , 
  11,6 , 11,7  , 

  % Mid right blue
  6,8  ,  6,9  , 
  7,8  ,  7,9  , 
  8,8  ,  8,9  , 
  9,8  ,  9,9  , 
  10,8 ,  10,9  , 
  11,8 ,  11,9  , 

  % Mid right green
  6,10  ,  6,11  ,  6,12  , 
  7,10  ,  7,11  ,  7,12  , 
  8,10  ,  8,11  ,  8,12  , 
  9,10  ,  9,11  ,  9,12  , 

  % Lower left dark green
  10,1  , 10,2  ,  10,3  , 
  11,1  , 11,2  ,  11,3  , 
  12,1  , 12,2  ,  12,3  , 12,4  , 12,5  ,  12,6  , 

  % Lower right dark green
  10,10  ,  10,11  , 10,12  , 
  11,10  ,  11,11  , 11,12  , 
  12,7   ,  12,8   ,  12,9  , 12,10  , 12,11  ,  12,12  
]);
</pre>


<h3>The Comet code</h3>
The Comet model (<a href="http://www.hakank.org/comet/sudoku_pi.co">sudoku_pi.co</a>) use the same principle as the MiniZinc model. However, the representation of the regions are different where I instead of a matrix use a more object oriented approach with two <code>tuple</code> for the structures. For some reasons that I have forgot now, I didn't create a function <code>check</code> in this Comet model, instead stated the <code>cardinality</code> constraints directly.

<pre>
import cotfd;
int t0 = System.getCPUTime();

int n = 12;
int P = -1; // Pi
int X = 0; // unknown 
range R = -1..9; 

set{int} V = {-1,1,2,3,4,5,6,7,8,9};

// regions where 1..9 is alldiff + 3 Pi
tuple Pos {
  int row;
  int col;
}

tuple Region {
  set{Pos} p;
}

int num_regions = 12;
Region regions[1..num_regions] = 
[
 // Upper left dark green
 Region({Pos(1,1),Pos(1,2),Pos(1,3),
         Pos(2,1),Pos(2,2),Pos(2,3),
         Pos(3,1),Pos(3,2),
         Pos(4,1),Pos(4,2), 
         Pos(5,1), Pos(5,2)}),
 
 // Upper mid light dark green
 Region({Pos(1,4), Pos(1,5), Pos(1,6), Pos(1,7), Pos(1,8), Pos(1,9),
         Pos(2,4), Pos(2,5), Pos(2,6), Pos(2,7), Pos(2,8), Pos(2,9)}),

 // Upper right green
 Region({Pos(1,10), Pos(1,11), Pos(1,12),
         Pos(2,10), Pos(2,11), Pos(2,12),
         Pos(3,11), Pos(3,12),
         Pos(4,11), Pos(4,12),
         Pos(5,11), Pos(5,12) }),

 // Mid upper left "blue"
 Region({Pos(3,3), Pos(3,4),Pos(3,5), Pos(3,6),
         Pos(4,3), Pos(4,4),Pos(4,5), Pos(4,6),
         Pos(5,3), Pos(5,4),Pos(5,5), Pos(5,6)}),

 // Mid Upper right blue
 Region({Pos(3,7), Pos(3,8), Pos(3,9), Pos(3,10),
        Pos(4,7), Pos(4,8), Pos(4,9), Pos(4,10),
        Pos(5,7), Pos(5,8), Pos(5,9), Pos(5,10)}),

 // Mid left green
 Region({Pos(6,1), Pos(6,2),Pos(6,3),
         Pos(7,1), Pos(7,2),Pos(7,3),
         Pos(8,1), Pos(8,2),Pos(8,3),
         Pos(9,1), Pos(9,2),Pos(9,3)}),

 // Mid left blue
 Region({Pos(6,4),Pos(6,5),
         Pos(7,4),Pos(7,5),
         Pos(8,4),Pos(8,5),
         Pos(9,4),Pos(9,5),
         Pos(10,4),Pos(10,5),
         Pos(11,4),Pos(11,5)}),

 // Mid mid green
 Region({Pos(6,6),Pos(6,7),
         Pos(7,6),Pos(7,7),
         Pos(8,6),Pos(8,7),
         Pos(9,6),Pos(9,7),
         Pos(10,6),Pos(10,7),
         Pos(11,6),Pos(11,7)}),

 // Mid right blue
 Region({Pos(6,8), Pos(6,9),
         Pos(7,8), Pos(7,9),
         Pos(8,8), Pos(8,9),
         Pos(9,8), Pos(9,9),
         Pos(10,8), Pos(10,9),
         Pos(11,8), Pos(11,9)}),

 // Mid right green
 Region({Pos(6,10), Pos(6,11), Pos(6,12),
         Pos(7,10), Pos(7,11), Pos(7,12),
         Pos(8,10), Pos(8,11), Pos(8,12),
         Pos(9,10), Pos(9,11), Pos(9,12)}),

 // Lower left dark green
 Region({Pos(10,1),Pos(10,2), Pos(10,3),
         Pos(11,1),Pos(11,2), Pos(11,3),
         Pos(12,1),Pos(12,2), Pos(12,3),Pos(12,4),Pos(12,5), Pos(12,6)}),

 // Lower right dark green
 Region({Pos(10,10), Pos(10,11),Pos(10,12),
         Pos(11,10), Pos(11,11),Pos(11,12),
         Pos(12,7),Pos(12,8), Pos(12,9),Pos(12,10),Pos(12,11), Pos(12,12)})

 ];

// the hints
int data[1..n,1..n] = 
[
 [4,9,7, P,5,X,X,X,X, X,X,X],
 [X,P,X, 8,X,X,9,6,1, 5,2,X],
 [X,8,X, 1,X,X,X,P,X, 7,X,X],
 [X,X,X, X,X,X,X,P,X, 4,X,X],
 [5,3,9, 6,X,X,X,X,X, X,X,X],

 [9,4,X, P,P,P,7,X,X, X,X,X],
 [X,X,X, X,X,6,2,5,P, X,7,4],
 [X,X,X, X,X,X,X,X,P, P,3,8],
 [X,7,8, 4,6,9,X,X,X, X,X,X],

 [X,X,3, X,P,X,X,4,7, 1,6,9],
 [X,X,4, X,1,X,X,X,6, X,P,X],
 [X,X,X, X,X,X,X,X,4, X,5,X]
 ];

Integer num_solutions(0);

Solver<CP> m();
var<CP>{int} x[1..n,1..n](m, R);

// int occ[-1..9] = [3,0,1,1,1,1,1,1,1,1,1];
var<CP>{int} occ[-1..9](m,0..3);
int occ_count[-1..9] = [3,0,1,1,1,1,1,1,1,1,1];

exploreall<m> {

  // get the hints
  forall(i in 1..n) {
    forall(j in 1..n) {
      int c = data[i,j];
      if (c == P) {
        cout << "P";
      } else {
        cout << data[i,j];
      }
      if (c != 0) {
        m.post(x[i,j] == data[i,j]);
      }
      cout << " ";
    }
    cout << endl;
   }

  forall(i in 1..n, j in 1..n) {
    m.post(x[i,j] != 0);
  }

  forall(i in -1..9) {
    m.post(occ[i] == occ_count[i]);
  }  
  
  // rows
  forall(i in 1..n) {
    m.post(cardinality(occ, all(j in 1..n) x[i,j])); 
  }
    
  // columns
  forall(j in 1..n) {
    m.post(cardinality(occ, all(i in 1..n) x[i,j]));
  }

  // regions
  forall(r in 1..num_regions) {
    m.post(cardinality(occ, all(i in regions[r].p) x[i.row,i.col])); 

  }

} using {

  // reversing i and j gives faster solution
  forall(i in 1..n, j in 1..n: !x[i,j].bound()) {
    tryall<m>(v in V : x[i,j].memberOf(v)) by(v) 
      m.label(x[i,j], v);
    onFailure
      m.diff(x[i,j], v);
  }

  int t1 = System.getCPUTime();
  cout << "time:      " << (t1-t0) << endl;
  cout << "#choices = " << m.getNChoice() << endl;
  cout << "#fail    = " << m.getNFail() << endl;
  cout << "#propag  = " << m.getNPropag() << endl;
  

  num_solutions++;

   forall(i in 1..n) {
     forall(j in 1..n) {
       int c = x[i,j];
       if (c == P) {
         cout << "P";
       } else {
         cout << x[i,j];
       }
       cout << " ";
     }
     cout << endl;
   }
}

cout << "\nnum_solutions: " << num_solutions << endl;
cout << endl << endl;

int t1 = System.getCPUTime();
cout << "time:      " << (t1-t0) << endl;
cout << "#choices = " << m.getNChoice() << endl;
cout << "#fail    = " << m.getNFail() << endl;
cout << "#propag  = " << m.getNPropag() << endl;
</pre>
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/03/pi_day_sudoku_2009_the_models_1.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/03/pi_day_sudoku_2009_the_models_1.html</guid>
         <category>Puzzles, recreational mathematics</category>
         <pubDate>Fri, 12 Mar 2010 23:03:14 +0100</pubDate>
      </item>
            <item>
         <title>New book: Antoni Niederli&amp;#324;ski: Programowanie w logice z ograniczeniami (&quot;Programming in Logic with Constraints&quot;)</title>
         <description><![CDATA[<p>Some weeks ago Antoni Niederli&#324;ski wrote to the <a href="https://lists.sourceforge.net/lists/listinfo/eclipse-clp-users">ECLiPSe mailing list</a> about his new book (in Polish) about constraint logic programming with <a href="http://www.eclipse-clp.org/">ECLipSe</a>: <a href="">Programowanie w logice z ograniczeniami</a> ("Programming in Logic with Constraints"), PKJS, Gliwice 2010, 308 pages. ISBN: 9788360716953.</p>

<p>The author was kind enough to send the book to me and I received it yesterday. Since I don't understand Polish, I have now just browsed the book and tried some of the examples. It is a challenge to read code where all variable names and comments are in a unknown language, however many of the them are standard examples or variations .</p>

<p>It is a beautiful book with nice color plates of the problem's solutions as well as the principles of constraints such as propagators, etc. There are also many examples that seems to be well explained in the text, and there are 69 accompanying ECLiPSe models  which can be downloaded (see below). It would be nice if this book is translated to English, it would be a welcome addition to other introduction books to constraint (logic) programming since it contains  many different examples with explanations. However, I don't know if the author have any such plans.</p>

<p>The book is presented in the (Polish) site: <a href="http://www.pwlzo.pl">www.pwlzo.pl</a>. Translated to English by Google Translate: <a href="http://translate.google.se/translate?u=http%3A%2F%2Fwww.pwlzo.pl%2F&sl=pl&tl=en&hl=&ie=UTF-8">Logic programming with constraints - Gentle introduction to Eclipse</a>:<blockquote>[N]ew book: Anthony Niederli&#324;ski, "Programming in logic with constraints. Gentle introduction to Eclipse," PKJS, Gliwice 2010, 308 + XVIII of the parties. The book contains:<br />
* accessible lecture bases logic programming with constraints (CLP) for a free Eclipse Constraint Programming System, available through the Cisco-style Mozilla Public License<br />
* descriptions and examples of basic methods of CLP with an emphasis on their intuitive understanding, and without the theoretical justification<br />
* commented on a series of sample programs of increasing difficulty; </p>

<p>The book is intended for all those who want to quickly begin to set limits and optimal solutions for combinatorial and continuous problems using the mechanisms of CLP.<br />
</blockquote></p>

<p>The contents of the book is Google translated <a href="http://translate.google.se/translate?u=http%3A%2F%2Fwww.pwlzo.pl%2F&sl=pl&tl=en&hl=&ie=UTF-8">here</a>. It is slightly edited, and I have not been able to  find a translation for some of the words.<blockquote>Contents book "Programming in logic with constraints. Gentle introduction to the Eclipse"</p>

<p>Introduction, i<br />
0.1 What is the book?, i<br />
0.2 What is the logic programming with constraints?, Ii<br />
0.3 Programming in logic with constraints and artificial intelligence, v<br />
0.4 Programming in logic with constraints and knowledge engineering, vii<br />
0.5 Programming in logic with constraints and operational research, viii<br />
0.6 How was the book?, Ix<br />
0.7 What the book contains?, Ix<br />
0.8 How to use the book?, Xiii<br />
0.9 A inconvenience Eclipse, xvi<br />
0.10 Credits, xviii<br />
1 In the beginning was the Prologue, 1<br />
1.1 Elements of the Prologue, 1<br />
1.2 Setting System 3-element, 8<br />
1.2.1 Setting up a complete review of the method, 9<br />
1.2.2 Setting method of searching the depths with standard relapses, 9<br />
1.2.3 Setting the optimum, 15<br />
1.3 Golfers, 18<br />
1.4 Three balls, 21<br />
1.5 Who killed him?, 24<br />
1.6 Hetmani [n-queens problem] - a complete overview, 26<br />
1.7 Hetmani  [n-queens problem] - searching the depths of the standard recurrences, 28<br />
1.8 Examination - searching the depths of the standard recurrences, 31<br />
1.9 Incorrect wheel in the prologue, 36<br />
1.10 How to become his own grandfather?, 37<br />
1.11 Maze, 39<br />
1.12 Field of mine, 42<br />
1.13 The man-wolf-goat-cabbage, 46<br />
1.14 Missionaries and cannibals, 49<br />
1.15 Towers of Hanoi, 54<br />
1.16 Decanting [3-jugs problem], 57<br />
2 CLP restrictions for elementary feasible solutions (63<br />
2.1 Limitations and areas of elementary variables, 63<br />
2.2 What languages are different from Prolog CLP?, 63<br />
2.2.1 n-Queens Problem in the CLP, 64<br />
2.2.2 Exploration and Forward Checking method of propagation, 65<br />
2.2.3 Exploration and propagation method of Forward Looking Ahead + Checking, 68<br />
2.3 heuristic search, 69<br />
2.4 Techniques zgodno&#347;ciowe [about consistency], 72<br />
2.5 Propagation of the failure of limitations, 73<br />
2.6 Propagation of constraints gives a solution, 76<br />
2.7 Who was with whom? - Propagation, 81<br />
2.8 Students and languages - propagation, 83<br />
2.9 Propagation of exploration: three equations in whole numbers, 89<br />
2.10 Golfers again, 91<br />
2.11 The guards - search and propagation, 93<br />
2.12 Examination - search and propagation, 94<br />
2.13 Hetman - search and propagation, 96<br />
2.14 Setting - search and propagation, 97<br />
2.15 collaborators and undercover Etosowcy The opposition, 99<br />
3.1 Declarations module, 103<br />
3.2 Limitation 'alldifferent (?Lists)', 104<br />
3.3 Limitation 'element (?Index, ++List,?Value), 106<br />
3.4 Send More Money, 106<br />
3.5 Who was with whom?, 107<br />
3.6 Golfers once again, 110<br />
3.7 Three bullets once again, 113<br />
3.8 Hetman [n-queens], 116<br />
3.9 Five halls, 117<br />
3.10 The ten classrooms, 120<br />
3.11 All for All, 126<br />
3.12 Seven of machinery - the seven operations, 131<br />
3.13 Three machines - three of the five operations, 134<br />
3.14 Three machines - five operations, 135<br />
3.15 Using the data, 138<br />
3.15.1 Structures and arrays, 138<br />
3.15.2 Recursion and iteration, 141<br />
3.16 Scalar product, 147<br />
3.17 Hetman [n-queens] again, 148<br />
3.18 Sudoku, 149<br />
3.19 Hetman [n-queens] again, 152<br />
4 CLP restrictions for elementary optimal solutions, 153<br />
4.1 General, 153<br />
4.2 Improved Branch and Bound, 154<br />
4.2.1 The optimal position commanders - a standard Branch and Bound, 155<br />
4.2.2 The optimal position commanders - Branch and Bound & Forward Checking, 156<br />
4.2.3 The optimal position commanders - Branch and Bound + Forward Looking Ahead Checking, 157<br />
4.3 The fundamental predicates, 158<br />
4.3.1 The predicate 'bb min()', 158<br />
4.3.2 The predicate 'search()', 160<br />
4.4 Setting the optimal, 162<br />
4.5 Optimizing load seven machines 165 <br />
4.6 Plan of the transport of coal 1, 168<br />
4.7 Plan of the transport of coal 2, 171<br />
4.8 Plan of the transport of coal 3, 173<br />
4.9 Coloring maps, 176<br />
4.10 knapsack problem 1, 177<br />
4.11 Urzeczowione limitations, 180<br />
4.12 Restrictions on the harvest, 181<br />
4.13 knapsack problem 2, 185<br />
4.14 Wholesale and consumers - 1, 186<br />
4.15 Wholesale and consumers - 2, 191<br />
4.16 Elementary scheduling, 194<br />
4.16.1 resource constraints - the crew, 195<br />
4.16.2 Lights and misery optimization, 199<br />
4.16.3 Limitations kolejno&#347;sciowe - building a house, 202<br />
4.16.4 Limitations [disjunctive] - limited resources, 206<br />
4.17 Optimization constraints and contradictions - photo, 209<br />
4.18 shall appoint a parliamentary committee, 213<br />
4.19 We are fighting for even udeszczowienie, 216<br />
4.20 How to cut optimally?, 220<br />
4.21 Most Send Money, 222<br />
5 CLP restrictions for global optimal solutions, 225<br />
225 5.1 Limitation of 'cumulative ()', 225<br />
5.2 Cumulative scheduling 1, 227<br />
5.3 Cumulative Scheduling 2, 228<br />
5.4 Limitation of 'disjunctive ()', 230<br />
5.5 [Disjunctive] scheduling 1, 231<br />
5.6 We read newspapers 1, 232<br />
5.7 We read newspapers 2, 238<br />
5.8 We read newspapers 3, 242<br />
5.9 Mount bicycles, 247<br />
5.10 unloads and loads the ship, 262<br />
5.11 An example of a very difficult - benchmark MT10, 269<br />
6 CLP for continuous variables, 287<br />
6.1 The curse and blessing of compound interest, 288<br />
6.1.1 On retirement as a millionaire - 1, 289<br />
6.1.2 On retirement as a millionaire - 2, 290<br />
6.1.3 Ah, those mortgages!, 292<br />
6.2 Wholesalers - suppliers, 293<br />
6.3 Mixing oils, 297<br />
6.4 How do I earn and not narobi&#263;?, 299 </blockquote></p>

<p>The examples can be downloaded here <a href="http://www.pwlzo.pl/download.php">here</a>.</p>

<h3>End note</h3>
The book contain at least one reference to my own <a href="http://www.hakank.org/eclipse/">ECLiPSe page</a> (attributed as "Constraint Programming Blog" in the reference section) which is quite fun since it is the first time my constraint programming blog/sites are referenced in a book. The example that starts on page 222 is attributed to my <a href="http://www.hakank.org/eclipse/send_most_money.ecl">send_most_money.ecl</a> model.

<p>Here is the original text in Polish, as far as I have been able to type the different accents and strikes:<blockquote><br />
Popularna &#322;amig&#322;ówka Send More Money (patrz rozdzial 3.4) ma rowniez sw&#261; wersje optymalizacyjna o nazwie Send Most Money, ktorej celem jest maksymalizacja wartosci zmiennej Money. Odpowiedni program 4_20_smm.ecl, zaczerpni&#281;ty z witryny [Kjellerstrand-10], jest postaci:</blockquote></p>

<p>Google Translate <a href="http://translate.google.se/translate_t?hl=&ie=UTF-8&text=Popularna+lamigl%C3%B3wka+Send+More+Money+%28patrz+rozdzial+3.4%29+ma+rowniez+swa+wersje+optymalizacyjna+o+nazwie+Send+Most+Money%2C+ktorej+celem+jest+maksymalizacja+wartosci+zmiennej+Money.+Odpowiedni+program+4_20_smm.ecl%2C+zaczerpniety+z+witryny+[Kjellerstrand-10]%2C+jest+postaci%3A&sl=pl&tl=en#pl|en|Popularna%20%C5%82amig%C5%82%C3%B3wka%20Send%20More%20Money%20%28patrz%20rozdzial%203.4%29%20ma%20rowniez%20sw%C4%85%20wersje%20optymalizacyjna%20o%20nazwie%20Send%20Most%20Money%2C%20ktorej%20celem%20jest%20maksymalizacja%20wartosci%20zmiennej%20Money.%20Odpowiedni%20program%204_20_smm.ecl%2C%20zaczerpni%C4%99ty%20z%20witryny%20[Kjellerstrand-10]%2C%20jest%20postaci%3A">translates</a> the text as:<br />
<blockquote>The popular puzzle Send More Money (see Chapter 3.4) also has its version of optimization, called Send Money Bridge, whose objective is to maximize the value of the variable Money. 4_20_smm.ecl appropriate program, taken from the site [Kjellerstrand-10], is of the form:</p>

<p>...</p>

</blockquote>
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/03/new_book_antoni_niederliski_pr.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/03/new_book_antoni_niederliski_pr.html</guid>
         <category>Constraint logic programming</category>
         <pubDate>Sun, 07 Mar 2010 19:25:03 +0100</pubDate>
      </item>
            <item>
         <title>Survey of Nonogram Solvers updated: one addition is a JaCoP solver</title>
         <description><![CDATA[<p><a href="http://webpbn.com/survey">Survey of Paint-by-Number Puzzle Solvers</a> by <a href="http://unixpapa.com/">Jan Wolter</a> has been updated.  One interesting addition to the solver is a <a href="http://www.jacop.eu/">JaCoP</a> solver: <a href="http://webpbn.com/survey/#raziel">Ben Raziel's JaCoP Solver</a>:<blockquote><br />
[from Ben Raziel:]<br />
"""<br />
    We use JaCoP (a free java CSP solving library) to do the line solving for us. For searching, we use a modified version of JaCoP's DFS search. I employed your probing approach and tweaked it a little in order to achieve better performance.</p>

<p>    The basic idea is to probe more cells, in order to reach a contradiction - which means we don't have to guess our next move (since a contradiction tells us what color the current cell is). The probes are ordered into "levels": each level contains cells where a contradiction is more likely to be found - which minimizes the number of cells that we have to probe until a contradiction is reached. <br />
"""<br />
The solver is not currently publically available, but the author plans to make it available, once this is cleared with the University. </blockquote></p>

<p>From the summary of  this solver<br />
<blockquote><b>Assessment</b>: Very good at hard puzzles, a bit slow at easy ones.</p>

<p>...</p>

<p>The run times on simple problems are not spectacular. Java is an interpreted language, and thus, naturally, rather slow. It is furthermore also built on top of a general solving library, JaCoP, and those typically add some overhead. But my suspicion is that part of this is also a basic design trade off - the authors were focusing more on solving hard puzzles fast than on solving easy puzzles fast.</p>

<p>But this really works very well on the harder puzzles. It solves every puzzle in the full 2,491 webpbn puzzle data set in under 15 minutes and only the "Lion" puzzle, which most solvers can't solve at all, takes more than 5 minutes. No other solver tested has accomplished this.</p>

<p>Of course, this solver, like pbnsolve, was trained on the webpbn data set, which certainly gives it an advantage when being tested against that data set. In fact the authors had the full dataset available from early in their development cycle, which is more than can be said for webpbn. <br />
</blockquote></p>

<p>There are also other updates, such as general reflections about the state of Nonogram solvers.</p>]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/03/survey_of_nonogram_solvers_upd.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/03/survey_of_nonogram_solvers_upd.html</guid>
         <category>Puzzles, recreational mathematics</category>
         <pubDate>Wed, 03 Mar 2010 18:20:31 +0100</pubDate>
      </item>
            <item>
         <title>Tailor version 0.3.3 released</title>
         <description><![CDATA[<p><a href="http://www.cs.st-andrews.ac.uk/~andrea/">Andrea Rendl</a> released version 0.3.3 of <a href="http://www.cs.st-andrews.ac.uk/~andrea/tailor/">Tailor</a> this Friday.</p>

<p>News in this version:<blockquote>  * select a dynamic variable ordering for solving in Minion (in the GUI)<br />
  * extended GUI<br />
  * several bugfixes<br />
</blockquote></p>

<p>From the README file (in the distribution):<blockquote>6. Limitations and Known Bugs<br />
----------------------------------<br />
The translator is still under development, so there are some limitations.<br />
The following is not supported yet:<br />
- decision variable arrays with 4 or more dimensions<br />
- parameter arrays with 4 or more dimensions<br />
- absolute value<br />
- power with decision variable as exponent<br />
- element constraint on 2-dimensional arrays</p>

<p>Translation to Gecode:<br />
- no parameter arrays supported<br />
- complicated quantified sums not supported</p>

<p>Translation to Flatzinc:<br />
- not supported: multi-dimensional arrays<br />
- no support for table, element, atmost, atleast, gcc<br />
- no modulo, power, division<br />
</blockquote></p>

<p><br />
Also see: <a href="http://www.hakank.org/tailor/">My Tailor page</a></p>]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/02/tailor_version_033_released_1.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/02/tailor_version_033_released_1.html</guid>
         <category>Minion/Tailor</category>
         <pubDate>Mon, 22 Feb 2010 17:31:22 +0100</pubDate>
      </item>
            <item>
         <title>Off topic II : My new English blog: Arrays in Flux</title>
         <description><![CDATA[<p>The other day, I started my second blog in English: <a href="http://www.hakank.org/arrays_in_flux/">Arrays in Flux</a>.<br />
 <br />
The first post <a href="http://www.hakank.org/arrays_in_flux/2010/02/arrays_in_flux_my_third_blog_and_second_english.html">Arrays in Flux: My third blog, and second English</a> explains more and give a background of the name. Here I will write, in English, about stuff not related to constraint programming (and related paradigms).</p>

<p>I just posted the first real post: <a href="http://www.hakank.org/arrays_in_flux/2010/02/symbolic_regression_using_genetic_programming_with_jgap_1.html">Symbolic regression (using genetic programming) with JGAP</a> and contains what I have done the last weeks . It is an extension of what I wrote in <a href="http://www.hakank.org/constraint_programming_blog/2010/01/off_topic_eureqa_equation_disc.html">Off topic: Eureqa - equation discovery with genetic programming</a>.</p>

<p>From now on, I will not clutter this blog any more with these kind of off topic posts.</p>]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/02/off_topic_ii_my_new_english_bl.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/02/off_topic_ii_my_new_english_bl.html</guid>
         <category></category>
         <pubDate>Sun, 21 Feb 2010 18:52:58 +0100</pubDate>
      </item>
            <item>
         <title>Off topic: Eureqa - equation discovery with genetic programming</title>
         <description><![CDATA[<p>The last week I have tested the equation discovery system <a href="http://ccsl.mae.cornell.edu/eureqa">Eureqa</a> which uses genetic programming (symbolic regression). Hopefully it may be of some interest.</p>

<p>Today I blogged about my (simple) experiments on my Swedish blog <a href="http://www.hakank.org/webblogg/archives/001354.html">Eureqa: equation discovery med genetisk programmering</a>. Google translation to English: <a href="http://translate.google.se/translate?u=http%3A%2F%2Fwww.hakank.org%2Fwebblogg%2Farchives%2F001354.html&sl=sv&tl=en&hl=&ie=UTF-8">Eureqa: equation discovery with genetic programming</a>. </p>

<p>Also, see <a href="http://www.hakank.org/eureqa/">My Eureqa page</a>.</p>]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/01/off_topic_eureqa_equation_disc.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/01/off_topic_eureqa_equation_disc.html</guid>
         <category></category>
         <pubDate>Sun, 24 Jan 2010 09:22:01 +0100</pubDate>
      </item>
            <item>
         <title>Some new MiniZinc models, mostly Enigma problems</title>
         <description><![CDATA[The last week I have solved some (more) of New Scientist's <a href="http://www.newscientist.com/topic/enigma">Enigma problems</a>. Note: You may have to be a subscriber to read all the articles, however there is a grace period with some free peeks (7 it seems to be).

<h3>Enigma problems</h3>
Here are the new models of Enigma problems. All are written in <a href="http://www.hakank.org/minizinc/">MiniZinc</a>.
<ul>
<li> <a href="http://www.hakank.org/minizinc/enigma_counting_pennies.mzn">enigma_counting_pennies.mzn</a>: Enigma Counting pennies (from 2005) <br>
Here all the 24 ways of permuting a list of 4 items are needed. Instead of calculating them, I simply listed all the variants and used them later as index.

<li> <a href="http://www.hakank.org/minizinc/enigma_843.mzn">enigma_843.mzn</a>: Enigma How many are whole? (#843) <br>
In this model there was problem using the following type of reifications:
<pre>
  square(ONE) /\ ( square(TWO) \/ square(THREE) \/ square(FOUR)) % /\ ..
  % or
  (square(ONE) /\ ( bool2int(square(TWO)) + bool2int(square(THREE)) + bool2int(square(FOUR)) = 1) % /\ ...
</pre>
where square is defined as:
<pre>
predicate square(var int: y) =
  let {
     var 1..ceil(sqrt(int2float(ub(y)))): z
  } in
   z*z = y;
</pre>

In some of the later versions of MiniZinc (probably 1.0.2), the handling of reification was changed. My fix was to add a boolean matrix which handled the boolean constraints. It is not beatiful:
<pre>
   % In the list ONE TWO THREE FOUR just the first and one other are perfect squares.
   square(ONE) /\ 
   [bools[1,j] | j in 1..4] = [square(ONE),square(TWO),square(THREE),square(FOUR)] /\
   sum([bool2int(bools[1,j]) | j in 1..4]) = 2 /\
   % ...
</pre>


<li> <a href="http://www.hakank.org/minizinc/enigma_1530.mzn">enigma_1530.mzn</a>: Enigma Tom Daley (#1530) <br>
A simple alphametic puzzle.

<li> <a href="http://www.hakank.org/minizinc/enigma_1535.mzn">enigma_1535.mzn</a>: Enigma Back to front (#1535) <br>
Magic square with some more constraints.
<li> <a href="http://www.hakank.org/minizinc/enigma_1555.mzn">enigma_1555.mzn</a>: Enigma Not a square (#1555) <br>
Another alphametic puzzle on a grid.
<li> <a href="http://www.hakank.org/minizinc/enigma_1557.mzn">enigma_1557.mzn</a>: Enigma Reverse Division (#1557)<br> 
Division and reversing some numbers.

<li> <a href="http://www.hakank.org/minizinc/enigma_1568.mzn">enigma_1568.mzn</a>: Enigma Odd puzzle (#1568) <br>
Long multipication alphametic puzzle.

<li> <a href="http://www.hakank.org/minizinc/enigma_1570.mzn">enigma_1570.mzn</a>: Enigma Set of cubes (#1570) <br>
Pandigital problem over at set of cubes. Here I simply listed the cubes between 0^3 and 1000^3 instead of calculating them. This may be consider cheating...

<li> <a href="http://www.hakank.org/minizinc/enigma_1575.mzn">enigma_1575.mzn</a>: Enigma All our days (#1575) <br>
Another alphametic puzzle with some more constraints.
</ul>

Some of these problem may have been better solved using other means, e.g. pure (or not so pure) mathematics, but this is after all a blog about constraint programming, and modellng them is good exercise. And fun.
<br><br>
I have also solved - or at least modeled - some of the open problems: 1573, 1574, 1576, and 1577, but will not publish the models until they are closed. I "accidentally" published problem #1574 the other day before I realized it was still open, but so be it.


<h3>Some other models/data files</h3>
Here are two simple new problems taken from <a href="http://www.emn.fr/x-info/choco-solver/doku.php">Choco's</a> (<a href="http://www.emn.fr/z-info/choco-solver/index.html">forthcoming site</a> ) example distribution:
<ul>
  <li> <a href="http://www.hakank.org/minizinc/candles.mzn">candles.mzn</a>: Birthday Candles
  <li> <a href="http://www.hakank.org/minizinc/how_old_am_i.mzn">how_old_am_i.mzn</a>: How old am I
</ul>
Also, a new data file for the <a href="http://www.hakank.org/minizinc/bridge_and_torch_problem.mzn">Bridge and Torch model</a>: <a href="http://www.hakank.org/minizinc/bridge_and_torch_problem8.dzn">bridge_and_torch_problem8.dzn</a>, which is, as I understand it, the same as Choco's U2planning problem.


<h3>Birthdays 2010 puzzle</h3>
Last, here is a very simple puzzle of my own based on a coincidence of birth years of me and my brother and the current year:
<blockquote>
This year (2010) my older brother Anders will be the same age as the year I was born in the last century, and I will be the same age as the year he was born in the last century. My brother is four years older than me. How old are we this year?
</blockquote>
A (unnecessary complex) MiniZinc model of this problem is <a href="http://www.hakank.org/minizinc/birthdays_2010.mzn">birthdays_2010.mzn</a>. Of course, it can be solved <a href="http://www.hakank.org/minizinc/birthdays_2010.mzn">much easier</a> with the simple equation: <code><a href="http://www.wolframalpha.com/input/?i={H%2BA%3D110%2CA-H%3D4}">{H+A=110,A-H=4}</a></code> (link to Wolfram Alpha), or in MiniZinc:
<pre>
constraint H+A = 110 /\ A-H = 4;
</pre>

But this latter version is not very declarative, and I - in general - prefer the declarative way.
<br><br>
<font color="red">Update:</font> Added link to Wolfram Alpha for the simple equation above.]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/01/some_new_minizinc_models_mostl.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/01/some_new_minizinc_models_mostl.html</guid>
         <category>MiniZinc</category>
         <pubDate>Thu, 14 Jan 2010 19:59:46 +0100</pubDate>
      </item>
            <item>
         <title>Finding celebrities at a party</title>
         <description><![CDATA[This problem is from Uwe Hoffmann <a href="http://www.codemanic.com/papers/celebs/celebs.pdf">Finding celebrities at a party</a> (PDF):
<blockquote>
Problem: Given a list of people at a party and for each person the list of
people they know at the party, we want to find the celebrities at the party. 
A celebrity is a person that everybody at the party knows but that 
only knows other celebrities. At least one celebrity is present at the party.
</blockquote>
(This paper contains an implementation of the problem in Scala.)
<br><br>
Note: The original of this problem is Richard Bird and Sharon Curtis: "Functional pearls: Finding celebrities: A lesson in functional programming" (J. Funct. Program., 16(1):13–20, 2006), but I (nor Hoffmann) have not been able to access this paper. <font color="red">Update: </font> I have now got hold of this paper. Thank you SW!
<br><br>
The example in Hoffmann's paper is to find of who are the 
celebrity/celebrities in this party graph:
<pre>
Adam  knows {Dan,Alice,Peter,Eva},
Dan   knows {Adam,Alice,Peter},
Eva   knows {Alice,Peter},
Alice knows {Peter},
Peter knows {Alice}
</pre>
Solution: the celebrities are Peter and Alice.

<h3>MiniZinc model</h3>
The MiniZinc model of this problem is <a href="http://www.hakank.org/minizinc/finding_celebrities.mzn">finding_celebrities.mzn</a>. 
<br><br>
Following are some discussion of the two constraints
 <ul>
   <li> All must knows a celebrity
   <li> Celebrities only knows a celebrity
 </ul>

But first a comment how the party graph is represented.

<h3>Party graph</h3>
Here I have chosen to represent the party as an array of sets:
<pre>
  Adam  (1) knows {Dan,Eva,Alice,Peter}  {2,3,4,5}
  Dan   (2) knows {Adam,Alice,Peter}     {1,4,5}
  Eva   (3) knows {Alice,Peter}          {4,5}
  Alice (4) knows {Peter}                {5}
  Peter (5) knows {Alice}                {4}
</pre>
This is coded in MiniZinc as:
<pre>
party = [
          {2,3,4,5}, % 1, Adam
          {1,4,5},   % 2, Dan 
          {4,5},     % 3, Eva
          {5},       % 4, Alice
          {4}        % 5, Peter
         ];
</pre>

This corresponds to the following incidence matrix, which is calculated in the model. For simplifying the calculations, we assume that a person know him/herself (this is also handled in the model).
<pre>
% 1 2 3 4 5
  1,1,1,1,1, % 1
  1,1,0,1,1, % 2
  0,0,1,1,1, % 3
  0,0,0,1,1, % 4
  0,0,0,1,1  % 5
</pre>

This conversion from incidence sets (<code>party<code>) to incidence matrix (<code>graph</code>) is done by the <code>set2matrix</code> predicate:
<pre>
predicate set2matrix(array[int] of var set of int: s,
                     array[int,int] of var int: mat) =
     forall(i in index_set(s)) ( graph[i,i] = 1)
     /\
     forall(i,j in index_set(s) where i != j) (
      j in party[i] <-> graph[i,j] = 1
    )
</pre>

<h3>All must know a celebrity</h3>
I started this model by consider the celebrities as a <b>clique</b>, and therefore using the constraint <code>clique</code> (which is still included in the model). However, is not enough to identify the clique since there may be other cliques but are not celebrities. In the above example there is another clique: <code>{Dan,Adam}</code>.
<br><br>
In fact, the <code>clique</code> constraint is not needed at all (and it actually makes the model slower). Instead we can just look for person(s) that <b>everybody</b> knows, i.e. where there are all 1's in the column of a celebrity in the party graph matrix (<code>graph</code> in the model). This is covered by the constraint:
<pre>
forall(i in 1..n) (
   (i in celebrities -> sum([graph[j,i] |j in 1..n]) = n)
)  
</pre>
This is a necessary condition but not sufficient for identifying celebrities.

<h3>Celebrities only know each other</h3>
We must also add the constraint that all people in the celebrity clique don't know anyone outside this clique. This is handled by the constraint the all celebrities must knows the same amount of persons, i.e. the size (cardinality) of the clique:
<pre>
forall(i in 1..n) (
   i in celebrities -> sum([graph[i,j] | j in 1..n]) = num_celebrities
)
</pre>
As noted above, a person is assumed to know him/herself.

<h3>Running the model</h3>
If we run the MiniZinc model <a href="http://www.hakank.org/minizinc/finding_celebrities.mzn">finding_celebrities.mzn</a> we found the following solution:
<pre>
celebrities = 4..5;
num_celebrities = 2;
</pre>
which means that the celebrities are {4,5}, i.e. {Alice, Peter}.
<br><br>

<h3>Another, slightly different party</h3>
We now change the party matrix slightly by assuming that Alice (4) also know Adam (1), i.e. the following incidence matrix:
<pre>
 % 1 2 3 4 5
   1,1,1,1,1, % 1
   1,1,0,1,1, % 2
   0,0,1,1,1, % 3
   <b>1</b>,0,0,1,1, % 4
   0,0,0,1,1  % 5
]);
</pre>

This makes Alice a non celebrity since she knows the non celebrity Adam,
and this in turn also makes Peter a non celebrity since he knows the non
celebrity Alice. In short, in this party there are no celebrities.
<br><br>
The model also contains a somewhat larger party graph with 10 persons.
<br><br>
<font color="red">Update about 8 hours later</font>
There is now a version which uses just set constraints, i.e. no conversion to an incidence matrix: <a href="http://www.hakank.org/minizinc/finding_celebrities2.mzn">finding_celebrities2.mzn</a>. The constraint sections is now:
<pre>
constraint
  num_celebrities >= 1

  /\ % all persons know the celebrities,
     % and the celebrities only know celebrities
  forall(i in 1..n) (
     (i in celebrities -> 
             forall(j in 1..n where j != i) (i in party[j]))
     /\
     (i in celebrities -> 
             card(party[i]) = num_celebrities-1)
  )
</pre>
I have kept the same representation of the party (the array of sets of who knows who) as the earlier model which means that a person is now not assuming to know him/herself. The code reflects this change by using <code>where j != i</code> and <code>num_celebrities-1</code>.]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2010/01/finding_celebrities_at_a_party.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2010/01/finding_celebrities_at_a_party.html</guid>
         <category>MiniZinc</category>
         <pubDate>Mon, 04 Jan 2010 11:19:32 +0100</pubDate>
      </item>
            <item>
         <title>1 year anniversary and Secret Santa problem II </title>
         <description><![CDATA[Exactly <a href="http://www.hakank.org/constraint_programming_blog/2008/12/welcome_to_my_my_constraint_pr_1.html">one year ago</a>, I started this blog. Little did I 
know what to expect. Through this blog and <a href="http://www.hakank.org/constraint_programming/">its accompanying pages</a> - I have met many very interesting persons that has learned me much in my pursuit of learning constraint programming. I am very grateful for your help and inspiration! And thanks to all my (other) readers.
<br><br>
I hope the following year will be as rewarding as this last.

<h3>Secret Santa problem II</h3>
As an anniversary gift, here is another Secret Santa problem (compare with
<a href="http://www.hakank.org/constraint_programming_blog/2009/12/merry_christmas_secret_santas.html">Merry Christmas: Secret Santas Problem</a>) with a slightly different touch.
<br><br>
The problem formulation is from Maple Primes forum <a href="http://www.mapleprimes.com/blog/jpmay/secretsantagraphtheory">Secret Santa Graph Theory</a>:
<blockquote>
Every year my extended family does a "secret santa" gift exchange. Each person draws another person at random and then gets a gift for them. At first, none of my siblings were married, and so the draw was completely random. Then, as people got married, we added the restriction that spouses should not draw each others names. This restriction meant that we moved from using slips of paper on a hat to using a simple computer program to choose names. Then people began to complain when they would get the same person two years in a row, so the program was modified to keep some history and avoid giving anyone a name in their recent history. This year, not everyone was participating, and so after removing names, and limiting the number of exclusions to four per person, I had data something like this:
<br><br>
Name: Spouse, Recent Picks
<br><br>
<b>Noah</b>: Ava. Ella, Evan, Ryan, John<br>
<b>Ava</b>: Noah, Evan, Mia, John, Ryan<br>
<b>Ryan</b>: Mia, Ella, Ava, Lily, Evan<br>
<b>Mia</b>: Ryan, Ava, Ella, Lily, Evan<br>
<b>Ella</b>: John, Lily, Evan, Mia, Ava<br>
<b>John</b>: Ella, Noah, Lily, Ryan, Ava<br>
<b>Lily</b>: Evan, John, Mia, Ava, Ella<br>
<b>Evan</b>: Lily, Mia, John, Ryan, Noah<br>
</blockquote>

I have interpreted the problem as follows:
<ul>
   <li> one cannot be a Secret Santa of one's spouse nor of oneself
   <li> one cannot be a Secret Santa for somebody two years in a row
   <li> objective: maximize the "Secret Santa distance", i.e. the number of years since the last assignment of the same person
</ul>
My MiniZinc model for this problem is <a href="http://www.hakank.org/minizinc/secret_santa2.mzn">secret_santa2.mzn</a>.

<br><br>
This is a more traditional linear programming problem compared to Secret Santa I, using a distance matrix for maximizing the "Secret Santa Distance". <code>M</code> is a "large" number (number of persons + 1) for coding that there have been no previous Secret Santa assignment.
<pre>
rounds = array2d(1..n, 1..n, [
%N  A  R  M  El J  L  Ev 
 0, M, 3, M, 1, 4, M, 2, % Noah
 M, 0, 4, 2, M, 3, M, 1, % Ava 
 M, 2, 0, M, 1, M, 3, 4, % Ryan
 M, 1, M, 0, 2, M, 3, 4, % Mia 
 M, 4, M, 3, 0, M, 1, 2, % Ella
 1, 4, 3, M, M, 0, 2, M, % John
 M, 3, M, 2, 4, 1, 0, M, % Lily
 4, M, 3, 1, M, 2, M, 0  % Evan
]);

</pre>

The original problem don't say anything about single persons, i.e. those without spouses. In this model, singleness (no-spouseness) is coded as spouse = 0, and the no-spouse-Santa constraint has been adjusted to takes care of this.
<br><br>
The <code>constraint</code> part is the following, where <code>n</code> is the number of persons:
<pre>
constraint
   all_different(santas)

   /\ % no Santa for one self or the spouse
   forall(i in 1..n) (
      santas[i] != i /\
      if spouses[i] > 0 then santas[i] != spouses[i] else true endif
   )

   /\ % the "santa distance" (
   forall(i in 1..n) ( santa_distance[i] = rounds[i,santas[i]] )

   /\ % cannot be a Secret Santa for the same person two years in a row.
   forall(i in 1..n) (
      let { var 1..n: j } in
       rounds[i,j] = 1 /\ santas[i] != j
   )

   /\
   z = sum(santa_distance)
</pre>

<h4>Solution</h4>
This model gives - when using <code>solve satisfy</code> and the constraint <code> z >= 67</code> - the following 8 solutions with a total of Secret Santa distance of 67 (<code>sum(santa_distance)</code>). If all Secret Santa assignments where new it would have been a total of <code>n*(n+1) = 8*9 = 72</code>. As we can see there is always one Santa with a previous existing assignment. (With one Single person and the data I faked, we can get all brand new Secret Santas. See the model for this.)

<pre>
santa_distance: 9 9 4 9 9 9 9 9
santas        : 7 5 8 6 1 4 3 2

santa_distance: 9 9 4 9 9 9 9 9
santas        : 7 5 8 6 3 4 1 2

santa_distance: 9 9 9 4 9 9 9 9
santas        : 7 5 6 8 1 4 3 2

santa_distance: 9 9 9 4 9 9 9 9
santas        : 7 5 6 8 3 4 1 2

santa_distance: 9 9 9 9 4 9 9 9
santas        : 4 7 1 6 2 8 3 5

santa_distance: 9 9 9 9 4 9 9 9
santas        : 4 7 6 1 2 8 3 5

santa_distance: 9 9 9 9 9 9 4 9
santas        : 4 7 1 6 3 8 5 2

santa_distance: 9 9 9 9 9 9 4 9
santas        : 4 7 6 1 3 8 5 2
</pre>

]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2009/12/1_year_anniversary_and_secret_1.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2009/12/1_year_anniversary_and_secret_1.html</guid>
         <category>MiniZinc</category>
         <pubDate>Tue, 29 Dec 2009 19:50:34 +0100</pubDate>
      </item>
            <item>
         <title>Merry Christmas: Secret Santas Problem</title>
         <description><![CDATA[Here is a fun little problem related to the holiday. Merry Christmas, everyone! (For the Swedish readers: Sorry for the one day off greeting.)
<br><br>
This problem is from the Ruby Quiz#2 <a href="http://www.rubyquiz.com/quiz2.html">Secret Santas</a>
<blockquote>
Honoring a long standing tradition started by my wife's dad, my friends 
all play a Secret Santa game around Christmas time. We draw names and 
spend a week sneaking that person gifts and clues to our identity. On the 
last night of the game, we get together, have dinner, share stories, and, 
most importantly, try to guess who our Secret Santa was. It's a crazily 
fun way to enjoy each other's company during the holidays.
<br><br>
To choose Santas, we use to draw names out of a hat. This system was 
tedious, prone to many "Wait, I got myself..." problems. This year, we 
made a change to the rules that further complicated picking and we knew 
the hat draw would not stand up to the challenge. Naturally, to solve 
this problem, I scripted the process. Since that turned out to be more 
interesting than I had expected, I decided to share.
<br><br>
This weeks Ruby Quiz is to implement a Secret Santa selection script.
<br><br>
Your script will be fed a list of names on STDIN. 
<br><br>
...
<br><br>
Your script should then choose a Secret Santa for every name in the list. 
Obviously, a person cannot be their own Secret Santa. In addition, my friends 
no longer allow people in the same family to be Santas for each other and your 
script should take this into account.
</blockquote>

The MiniZinc model <a href="http://www.hakank.org/minizinc/secret_santa.mzn">secret_santa.mzn</a> skips the parts of input and mailing. Instead, we assume that the friends are identified with a unique number from <code>1..n</code>, and the families are identified with a number <code>1..num_families</code>. 
<br><br>
We use two arrays:
<ul>
  <li> the array <code>x</code> represents whom a person should be a Santa of. <code>x[1] = 10</code> means that person 1 is a Secret Santa of person 10, etc.
  <li> the <code>family</code> array consists of the family identifier of each person.
</ul>
Now, the three constraints can easily be stated in a constraint programming system like MiniZinc:
<ul>
  <li> "everyone gives and received a Secret Santa gift": this is handled with a permutation of the values 1..n using <code>all_different(x)</code>.
  <li> "one cannot be one own's Secret Santa". This is captured in the <code>no_fix_point</code> predicate, stating that there can be no <code>i</code> for which <code>x[i] = i</code> (i.e. no "fix point").
  <li> "no Secret Santa to a person in the same family". Here we use the <code>family</code> array and checks that for each person (<code>i</code>), the family of <code>i</code> (family[i]) must not be the same as the family of the person that receives the gift (<code>family[x[i]]</code>).
</ul>
Here is the complete MiniZinc model (in a slightly compact form):
<pre>
include "globals.mzn"; 
int: n = 12;
int: num_families = 4;
array[1..n] of 1..num_families: family = [1,1,1,1, 2, 3,3,3,3,3, 4,4];
array[1..n] of var 1..n: x :: is_output;

% Ensure that there are no fix points in the array.
predicate no_fix_points(array[int] of var int: x) = 
      forall(i in index_set(x)) ( x[i] != i  );

solve satisfy;

constraint
  % Everyone gives and receives a Secret Santa
  all_different(x) /\      

  % Can't be one own's Secret Santa
  no_fix_points(x) /\   

  % No Secret Santa to a person in the same family
  forall(i in index_set(x)) (   family[i] != family[x[i]]  )
; 

% output (just for the minizinc solver)
output [
   "Person " ++ show(i) ++ 
   " (family: " ++ show(family[i]) ++ ") is a Secret Santa of " ++ 
    show(x[i]) ++ 
   " (family: " ++ show(family[x[i]]) ++ ")\n"
   | i in 1..n
] ++ 
["\n"];
</pre>

<h3>Solution</h3>
Here is the first solution (of many):
<pre>
[10, 9, 8, 5, 12, 4, 3, 2, 1, 11, 7, 6]
</pre>
This means that person 1 should be a Secret Santa of person 10, etc.
<br><br>
The minizinc solver gives the following, using the <code>output</code> code (slightly edited):
<pre>
Person  1 (family: 1) is a Secret Santa of 10 (family: 3)
Person  2 (family: 1) is a Secret Santa of  9 (family: 3)
Person  3 (family: 1) is a Secret Santa of  8 (family: 3)
Person  4 (family: 1) is a Secret Santa of  5 (family: 2)
Person  5 (family: 2) is a Secret Santa of 12 (family: 4)
Person  6 (family: 3) is a Secret Santa of  4 (family: 1)
Person  7 (family: 3) is a Secret Santa of  3 (family: 1)
Person  8 (family: 3) is a Secret Santa of  2 (family: 1)
Person  9 (family: 3) is a Secret Santa of  1 (family: 1)
Person 10 (family: 3) is a Secret Santa of 11 (family: 4)
Person 11 (family: 4) is a Secret Santa of  7 (family: 3)
Person 12 (family: 4) is a Secret Santa of  6 (family: 3)
</pre>

<h3>Bales of Hay</h3>
As an extra, here is another MiniZinc model: <a href="http://www.hakank.org/minizinc/bales_of_hay.mzn">bales_of_hay.mzn</a> which solves the following problem (from <a href="http://www.mathlesstraveled.com/?p=582">The Math Less Traveled</a> the other day):
<blockquote>
You have five bales of hay.
<br><br>
For some reason, instead of being weighed individually, they were weighed
in all possible combinations of two. The weights of each of these
combinations were written down and arranged in numerical order, without
keeping track of which weight matched which pair of bales. The weights,
in kilograms, were 80, 82, 83, 84, 85, 86, 87, 88, 90, and 91.
<br><br>
How much does each bale weigh? Is there a solution? Are there multiple
possible solutions?
</blockquote>

The answer? There is a unique solution (when bales are ordered on weight): 39, 41, 43, 44, 47.
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2009/12/merry_christmas_secret_santas.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2009/12/merry_christmas_secret_santas.html</guid>
         <category>MiniZinc</category>
         <pubDate>Fri, 25 Dec 2009 11:32:59 +0100</pubDate>
      </item>
            <item>
         <title>Some updated SICStus Prolog models </title>
         <description><![CDATA[<a href="http://www.sics.se/~matsc/">Mats Carlsson</a> (designer and main implementer of <a href="http://www.sics.se/isl/sicstuswww/site/index.html">SICStus Prolog</a>) was kind enough to send me alternative versions of some of <a href="http://www.hakank.org/sicstus/">my SICStus Prolog models</a>, which now are included in the models (marked with his name). His versions are - of course - more elegant and faster than mine. Thanks, Mats.
<h3>Assignment problem</h3>
Model: <a href="http://www.hakank.org/sicstus/assignment.pl">assignment.pl</a> using the global constraint <code>global_cardinality</code>.
<pre>
assignment2(Problem) :-
        cost(Problem, Mode, CostRows),
        format('\nProblem ~d\n~w\n', [Problem,Mode]),
        transpose(CostRows, CostCols),
        length(CostRows, R),
        length(CostCols, C),
        length(Vars, R),
        domain(Vars, 1, C),
        (   for(I,1,C),
            foreach(I-Y,Ys)
        do  Y in 0..1
        ),
        global_cardinality(Vars, Ys, [cost(Cost,CostRows)]),
        (Mode==minimize -> Dir=up ; Dir=down),
        labeling([Dir], [Cost]),
        labeling([], Vars), !,
        format('assignment = ~w, cost = ~d\n', [Vars,Cost]),
        fd_statistics, nl.
</pre>

<h3>Bin Packing</h3>
Model: <a href="http://www.hakank.org/sicstus/bin_packing.pl">bin_packing.pl</a>. Here is the global constraint <code>cumulative</code> used. Note: The representation of the filled bins is however not the same as in my approach.
<pre>
bin_packing2(Problem) :-
        problem(Problem, StuffUnordered, BinCapacity),
        portray_clause(problem(Problem, StuffUnordered, BinCapacity)),
        length(StuffUnordered, N),
        N1 is N+1,
        (   foreach(H,StuffUnordered),
            foreach(task(S,1,E,H,1),Tasks),
            foreach(NH-S,Tagged),
            foreach(S,Assignment),
            foreach(_-X,Keysorted),
            foreach(X,Vars),
            param(N1)
        do  S in 1..N1,
            E in 2..N1,
            NH is -H
        ),
        keysort(Tagged, Keysorted),
        maximum(Max, Vars),
        cumulative(Tasks, [limit(BinCapacity)]),
        labeling([minimize(Max),step], Vars),
        portray_clause(assignment(Assignment)),
        fd_statistics,
        nl.
</pre>

<h3>Post Office Problem</h3>
Model: <a href="http://www.hakank.org/sicstus/post_office_problem2.pl">post_office_problem2.pl</a>. This is a much better way of solving this problem in Prolog than my translation from MiniZinc.
<pre>
go2 :-
        Days = 7,
        % requirements number workers per day
        Need = [17, 13, 15, 19, 14, 16, 11],
        % Total cost for the 5 day schedule.
        % Base cost per day is 100.
        % Working saturday is 100 extra
        % Working sunday is 200 extra.
        Cost = [500, 600, 800, 800, 800, 800, 700],
        % Decision variables. X[I]: Number of workers starting at day I
        length(X, Days),
        domain(X, 0, 10),
        append(X, X, [_,_,_|Ys]),
        (   foreach(Nd,Need),
            fromto(Ys, Ys1, Ys2, _)
        do  Ys1 = [Y1|Ys2],
            Ys2 = [Y2,Y3,Y4,Y5|_],
            Y1+Y2+Y3+Y4+Y5 #>= Nd
        ),
        scalar_product(Cost, X, #=, Total),
        labeling([minimize(Total),bisect], X),
        format('assignment = ~w, total cost = ~d\n', [X,Total]),
        fd_statistics.
</pre>

I also corrected a weird (and wrong) way of calculating the total cost in my version (as well as in the MiniZinc model <a href="http://www.hakank.org/minizinc/post_office_problem2.mzn">post_office_problem2.mzn</a>).
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2009/12/some_updated_sicstus_prolog_mo.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2009/12/some_updated_sicstus_prolog_mo.html</guid>
         <category>SICStus Prolog</category>
         <pubDate>Tue, 22 Dec 2009 19:10:23 +0100</pubDate>
      </item>
            <item>
         <title>Choco&apos;s new site</title>
         <description><![CDATA[Soon the website for Choco constraint programming solver will be changed to a <a href="http://www.emn.fr/z-info/choco-solver/index.html">this site</a> (will replace <a href="http://www.emn.fr/x-info/choco-solver/doku.php">the old one</a>). There are some broken links and missing information, but it seems to be well organized.
<br><br>
Some links:
<ul>
<li> New jar files can be downloaded <a href="http://www.emn.fr/z-info/choco-solver/choco-download.html">here</a>.
<li> <a href="http://www.emn.fr/z-info/choco-solver/tex/choco.pdf">Documentation</a> (PDF, about 2Mb)
<li> <a href="http://www.emn.fr/z-info/choco-solver/choco-faq.html">FAQ</a>
<li><a href="http://www.emn.fr/z-info/choco-solver/project-info.html">Project information</a>
</ul>

For anyone not familiar with Choco, here is a short description (from the new site):
<blockquote>
choco is a java library for constraint satisfaction problems (CSP), constraint programming (CP) and explanation-based constraint solving (e-CP).<br>
It is built on a event-based propagation mechanism with backtrackable structures.
<br><br>
choco can be used for:
<br><br>
    * teaching (a user-oriented constraint solver with open-source code)<br>
    * research (state-of-the-art algorithms and techniques, user-defined constraints, domains and variables)<br>
    * real-life applications (many application now embed choco)<br>
</blockquote>
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2009/12/chocos_new_site.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2009/12/chocos_new_site.html</guid>
         <category>Choco</category>
         <pubDate>Sat, 19 Dec 2009 09:35:34 +0100</pubDate>
      </item>
            <item>
         <title>SweConsNet 2010 (May 21, 2010 in Uppsala, Sweden)</title>
         <description><![CDATA[<a href="http://www.sics.se/~agren/SweConsNet2010/">SweConsNet 2010</a> is to be held May 21 2010 in Uppsala, Sweden. This is the 9th workshop of the Network for Sweden-based researchers and practitioners of Constraint programming (<a href="http://www.it.uu.se/research/SweConsNet/">SweConsNet</a>). It is collocated with the <a href="http://www.sais.se/sais2010/">SAIS Workshop 2010</a> (May 20-21).
<br><br>
From the SweConsNet 2010 site:
<blockquote>
The purpose of this workshop is to learn about ongoing research in constraint programming, existing projects and products, and further development of the network.
<br><br>
The workshop is open to everybody interested in the theory and practice of constraint programming, whether based in Sweden or elsewhere.
<br><br>
...
<br><br>
Please forward this information to people who might be interested in this workshop but are not yet on the SweConsNet mailing list. They can subscribe to it by sending a message to <a href="http://user.it.uu.se/~justin">Justin Pearson</a>.
<br><br>
...

<h4>Location</h4>
Uppsala University, Information Technology Center (ITC),
Polacksbacken, house 1
(<a href="http://www.it.uu.se/contact">Directions</a>).
<h4>Programme</h4>
<p> List of speakers (preliminary):
</p><ul>
  <li> <a href="http://4c.ucc.ie/%7Ehsimonis">Helmut  Simonis</a>, Cork Constraint Computation Centre, Ireland 
  (SAIS/SweConsNet joint invited speaker)</li>
  <li> <a href="http://www.it.uu.se/research/group/astra">ASTRA  Research Group</a>, Uppsala University</li>
  <li> <a href="http://www.cs.brown.edu/people/serdark">Serdar  Kad&#305;o&#287;lu</a>, Brown University, USA </li>
  <li> <a href="http://www.dis.uniroma1.it/%7Etmancini">Toni  Mancini</a>, Sapienza Università di Roma, Italy </li>
  <li> Tomas Nordlander, <a href="http://www.sintef.no">Sintef</a>,  Norway </li>
  <li> <a href="http://www.cs.lth.se/home/Carl_Christian_Rolf"> Carl  Christian Rolf</a>, Lund Institute of Technology</li>
  <li> <a href="http://web.it.kth.se/%7Ecschulte">Christian Schulte</a>,  Royal Institute of Technology </li>
</ul>
<h4>Organisation</h4>
SweConsNet 2010 is chaired by <a href="http://www.sics.se/people/agren">Magnus Ågren</a> (SICS). Local arrangements are made by <a href="http://user.it.uu.se/%7Epierref">Pierre Flener</a> and <a href="http://user.it.uu.se/%7Ejustin">Justin Pearson</a> (Uppsala University).
</blockquote>
<br>
The last work shop (May this year) was very interesting and fun, and I'm really looking forward to SweConsNet 2010. For more about SweConsNet 2009,  see its <a href="http://www.it.uu.se/research/group/astra/SweConsNet09/">homepage</a> and my own <a href="http://www.hakank.org/constraint_programming_blog/2009/05/report_from_sweconsnet2009_inc.html">Report from SweConsNet2009, including my presentation</a>.
]]></description>
         <link>http://www.hakank.org/constraint_programming_blog/2009/12/sweconsnet_2010_may_21_2010_in.html</link>
         <guid>http://www.hakank.org/constraint_programming_blog/2009/12/sweconsnet_2010_may_21_2010_in.html</guid>
         <category>Constraint programming, general</category>
         <pubDate>Tue, 15 Dec 2009 19:46:23 +0100</pubDate>
      </item>
      
   </channel>
</rss>
