nonogram.lp (clingo input file describing the nonogram puzzle type)
% constraint(Type,N,I,Len) - the Ith group in row/col N must be Len blocks long
% row(Y). Y is a valid row number.
% col(X). X is a valid column number.
% color(X,Y). From a column constraint, we infer that (X,Y) is colored in
% rowcolor(X,Y). From a row constraint, we infer that (X,Y) is colored in
% rowrun(Y,I,X). The Ith run in row Y starts at cell (X,Y).
% colrun(X,I,Y). The Ith run in col X starts at cell (X,Y).
% This following lines simplifies data entry directly into clingo by allowing
% constraints to be entered as a group. This could easily be elminated with
% some pre-processing in, say, Perl.
%
% constraints(col/row,I,A,B,C,...) - The lengths of blocks of filled-in
% cells in column/row I are A,B,C,...
constraint(Type,N,1,A) :- constraints(Type,N,A).
constraint(Type,N,1,A) :- constraints(Type,N,A,B).
constraint(Type,N,1,A) :- constraints(Type,N,A,B,C).
constraint(Type,N,1,A) :- constraints(Type,N,A,B,C,D).
constraint(Type,N,1,A) :- constraints(Type,N,A,B,C,D,E).
constraint(Type,N,1,A) :- constraints(Type,N,A,B,C,D,E,F).
constraint(Type,N,1,A) :- constraints(Type,N,A,B,C,D,E,F,G).
constraint(Type,N,2,B) :- constraints(Type,N,A,B).
constraint(Type,N,2,B) :- constraints(Type,N,A,B,C).
constraint(Type,N,2,B) :- constraints(Type,N,A,B,C,D).
constraint(Type,N,2,B) :- constraints(Type,N,A,B,C,D,E).
constraint(Type,N,2,B) :- constraints(Type,N,A,B,C,D,E,F).
constraint(Type,N,2,B) :- constraints(Type,N,A,B,C,D,E,F,G).
constraint(Type,N,3,C) :- constraints(Type,N,A,B,C).
constraint(Type,N,3,C) :- constraints(Type,N,A,B,C,D).
constraint(Type,N,3,C) :- constraints(Type,N,A,B,C,D,E).
constraint(Type,N,3,C) :- constraints(Type,N,A,B,C,D,E,F).
constraint(Type,N,3,C) :- constraints(Type,N,A,B,C,D,E,F,G).
constraint(Type,N,4,D) :- constraints(Type,N,A,B,C,D).
constraint(Type,N,4,D) :- constraints(Type,N,A,B,C,D,E).
constraint(Type,N,4,D) :- constraints(Type,N,A,B,C,D,E,F).
constraint(Type,N,4,D) :- constraints(Type,N,A,B,C,D,E,F,G).
constraint(Type,N,5,E) :- constraints(Type,N,A,B,C,D,E).
constraint(Type,N,5,E) :- constraints(Type,N,A,B,C,D,E,F).
constraint(Type,N,5,E) :- constraints(Type,N,A,B,C,D,E,F,G).
constraint(Type,N,6,F) :- constraints(Type,N,A,B,C,D,E,F).
constraint(Type,N,6,F) :- constraints(Type,N,A,B,C,D,E,F,G).
constraint(Type,N,7,G) :- constraints(Type,N,A,B,C,D,E,F,G).
row(1..ymax).
col(1..xmax).
ymax(ymax).
xmax(xmax).
% For each constraint, choose a starting cell for the run.
1 { rowrun(Y,I,X) : col(X) : col(X+Len-1) } 1 :- constraint(row,Y,I,Len).
1 { colrun(X,I,Y) : row(Y) : row(Y+Len-1) } 1 :- constraint(col,X,I,Len).
% Must leave at least one space between two adjacent run.
:- rowrun(N,I,Start1), rowrun(N,J,Start2), constraint(row,N,I,Len), I < J, Start2 < Start1 + Len + 1.
:- colrun(N,I,Start1), colrun(N,J,Start2), constraint(col,N,I,Len), I < J, Start2 < Start1 + Len + 1.
% Infer the color of the cells in each run
color(X,Start..Start+Len-1) :- colrun(X,I,Start), constraint(col,X,I,Len), row(X).
rowcolor(Start..Start+Len-1,Y) :- rowrun(Y,I,Start), constraint(row,Y,I,Len), col(Y).
% The inferred color from the row runs must be the same as those from the column runs.
:- color(X,Y), not rowcolor(X,Y), row(X), col(Y).
:- not color(X,Y), rowcolor(X,Y), row(X), col(Y).
#hide.
#show color/2.
#show xmax/1.
#show ymax/1.
#show constraint/4.