This is another typical constraint satisfaction problem. There is a
grid board. We are required to assign each grid a different digit from 1 to N such that all rows, all columns, and both of the diagonals have the same total. This example illustrates how to use the sum function.
Figure 5.4: A solution to the
magic square problem.
The following shows the program.
main class Magic {
public static final int N = 3;
component Cell cells[N][N];
attribute int total;
for (i in 0..N-1) //columns
sum(cells[i][j].value, j in 0..N-1)==total;
for (j in 0..N-1) //rows
sum(cells[i][j].value, i in 0..N-1)==total;
sum(cells[i][i].value,i in 0..N-1) == total;
//left-upper-down diagonal
sum(cells[i][j].value,
i in 0..N-1, j in 0..N-1, i+j==N-1) == total;
// left-bottom-up diagonal
for (i1 in 0..N-1, j1 in 0..N-1,
i2 in 0..N-1, j2 in 0..N-1)
(i1!=i2 || j1!=j2) -> cells[i1][j1].value != cells[i2][j2].value;
// all different
grid(cells); // constrain the position
}
class Cell {
component Label lb;
attribute int value in 1..Magic.N*Magic.N;
lb.text == String(value);
}
Each grid is an object of the class Cell, which is simply a
label. For each grid, there is a domain variable called value
that ranges from 1 to
. The constraint lb.text ==
String(value) relates the label and the value of a grid. With the
sum function, expressing the constraints are quite
straightforward. Figure
shows a solution to the
magic problem.