good_group(L) :- 
	 fd_atmost(2,L,1), fd_atmost(2,L,2), fd_atmost(2,L,3), fd_atmost(2,L,4), fd_atmost(2,L,5),
	fd_atleast(1,L,1),fd_atleast(1,L,2),fd_atleast(1,L,3),fd_atleast(1,L,4),fd_atleast(1,L,5).

board( 	Lab, L, 
	X00, X01, X02, X03, X04,
	X10, X11, X12, X13, X14,
	X20, X21, X22, X23, X24,
	X30, X31, X32, X33, X34,
	X40, X41, X42, X43, X44,
	 G1,  G2,  G3,  G4) :-
	 	L = [
			X00, X01, X02, X03, X04,
			X10, X11, X12, X13, X14,
			X20, X21, X22, X23, X24,
			X30, X31, X32, X33, X34,
			X40, X41, X42, X43, X44],
		fd_domain(L,1,5),
	 	fd_all_different([X00, X01, X02, X03, X04]),
		fd_all_different([X10, X11, X12, X13, X14]),
		fd_all_different([X20, X21, X22, X23, X24]),
		fd_all_different([X30, X31, X32, X33, X34]),
		fd_all_different([X40, X41, X42, X43, X44]),
		fd_all_different([X00, X10, X20, X30, X40]),
		fd_all_different([X01, X11, X21, X31, X41]),
		fd_all_different([X02, X12, X22, X32, X42]),
		fd_all_different([X03, X13, X23, X33, X43]),
		fd_all_different([X04, X14, X24, X34, X44]),
		good_group(G1),
		good_group(G2),
		good_group(G3),
		good_group(G4),
		lab(Lab, L).

try1(L) :- board( normal, L,
	X00, X01, X02, X03, X04,
	X10, X11, X12,   4,   3,
	X20,   1, X22, X23, X24,
	  4, X31, X32, X33, X34,
	X40, X41, X42, X43,   2,
	[X00,X01,X11,X12,  4,X03], 
	[X10,X20,  1,X22,X23,X33], 
	[  4,X31,X32,X40,X41,X42], 
	[X04,  3,X24,X34,X43,  2]).

try2(L) :- board( normal, L,
	  5, X01, X02, X03, X04,
	X10, X11, X12, X13,   4,
	X20,   2, X22, X23, X24,
	X30, X31, X32, X33, X34,
	X40, X41, X42,   1,   2,
	[  5,X10,X20,X30,  2,X31], 
	[X01,X02,X03,X04,X13,  4], 
	[X11,X12,X22,X32,X42,X41], 
	[X23,X33,  1,X24,X34,  2]).


lab(normal, L) :-
	fd_labeling(L).

lab(random, L) :-
	fd_labeling(L, [variable_method(random)]).

