Download
:- use_module(library(lists)).
% Schur's Lemma (CSPLib prob015)
% Colour the integers 1..N with C colours so that no colour class contains
% three integers x, y, z (not necessarily distinct) with x + y = z.
% schur(+N, +C, -Colours)
schur(N, C, Colours) :-
N >= 1,
numlist(1, C, Palette), % the available colours 1..C
% symmetry break: integer 1 is fixed to colour 1, then integers 2..N in order
colour(2, N, Palette, [1-1], Colours).
% colour(+I, +N, +Palette, +Assigned, -Colours)
% Assigned holds Integer-Colour pairs for the integers already coloured.
colour(I, N, _, Assigned, Colours) :-
I > N, % every integer has a colour
reverse(Assigned, Pairs),
pairs_values(Pairs, Colours).
colour(I, N, Palette, Assigned, Colours) :-
I =< N,
member(Col, Palette), % try a colour for integer I
safe(I, Col, Assigned), % colouring I with Col stays sum-free
I1 is I + 1,
colour(I1, N, Palette, [I-Col|Assigned], Colours).
% safe(+I, +Col, +Assigned): giving integer I the colour Col creates no
% monochromatic x + y = I among the already-coloured integers.
safe(I, Col, Assigned) :-
\+ ( between(1, I, X), % X is one summand of I
Y is I - X, Y >= X, % Y the other; Y >= X avoids checking twice
memberchk(X-Col, Assigned), % X already carries colour Col
memberchk(Y-Col, Assigned) ). % Y already carries colour Col