% test_case(N, Sol, Test, Result): Test case number N is Test,
% and the sorted list of its results in Sol is  Result.
test_case(01, true, consistent([[1]]),                                     [true]).
test_case(02, true, consistent([[0]]),                                     [true]).
test_case(03, true, consistent([[1,0,0,1],[0,0,0,0],[0,0,0,0],[0,0,0,0]]), []).
test_case(04, true, consistent([[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,0,2]]), []).
test_case(05, true, consistent([[0,0,0,0],[3,0,0,3],[0,0,0,0],[0,0,0,0]]), []).
test_case(06, true, consistent([[1,0,0,0],[0,0,0,0],[0,0,0,0],[1,0,0,0]]), []).
test_case(07, true, consistent([[0,0,0,0],[0,0,0,2],[0,0,0,0],[0,0,0,2]]), []).
test_case(08, true, consistent([[0,0,0,0],[0,0,3,0],[0,0,3,0],[0,0,0,0]]), []).
test_case(09, true, consistent([[1,0,0,0],[0,1,0,0],[0,0,0,0],[0,0,0,0]]), []).
test_case(10, true, consistent([[0,0,0,2],[0,0,2,0],[0,0,0,0],[0,0,0,0]]), []).
test_case(11, true, consistent([[0,0,0,0],[0,0,0,0],[3,0,0,0],[0,3,0,0]]), []).
test_case(12, true, consistent([[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]), [true]).
test_case(13, true, consistent([[1,0,0,0],[0,0,1,0],[0,0,0,0],[0,0,0,0]]), [true]).
test_case(14, true, consistent([[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0]]), [true]).
test_case(15, true, consistent([[1,0,1,0],[0,1,0,0],[1,0,0,0],[0,0,0,0]]), []).
test_case(16, true, consistent([[2,1,8,3,6,4,8,7,5],[4,3,7,1,8,5,9,6,2],[6,5,0,7,9,2,3,1,4],[1,9,4,8,5,7,6,2,3],[5,2,6,4,1,3,7,9,8],[8,7,3,6,2,9,5,4,1],[7,6,1,2,3,8,4,5,9],[9,8,2,5,4,6,1,3,7],[3,4,5,9,7,1,2,8,6]]), []).
test_case(17, true, consistent([[7,6,5,8,9,4,3,2,1],[8,9,3,6,2,1,7,4,5],[1,4,2,3,7,5,6,9,8],[6,8,1,5,9,0,4,7,2],[9,5,7,1,4,2,8,6,3],[3,2,4,7,8,6,5,1,9],[4,7,8,9,1,3,2,5,6],[5,3,9,2,6,7,1,8,4],[2,1,6,4,5,8,9,3,7]]), []).
test_case(18, true, consistent([[5,7,8,9,1,4,2,3,6],[2,4,3,7,6,5,1,8,0],[9,1,6,2,8,3,5,4,7],[8,2,5,1,7,0,4,6,9],[1,6,7,3,4,8,9,2,5],[3,9,4,5,2,6,7,1,8],[7,8,2,6,5,1,3,9,4],[6,5,9,4,3,2,8,7,1],[4,3,1,8,9,7,6,5,2]]), []).
test_case(19, true, consistent([[2,5,3,8,9,6,1,4,7],[1,4,7,2,3,5,8,9,6],[8,6,9,1,4,7,2,3,5],[4,3,1,9,6,2,5,7,8],[9,7,6,5,8,3,4,1,2],[5,8,2,7,1,4,9,6,3],[6,2,4,3,5,9,7,8,1],[7,9,8,6,2,1,3,5,4],[3,1,5,4,7,8,6,2,9]]), [true]).
test_case(20, true, consistent([[11,12,6,7,13,1,3,16,9,4,2,14,15,5,10,8],[16,3,14,15,11,7,9,4,5,8,13,10,12,1,6,2],[1,2,9,13,6,8,5,10,11,3,15,12,14,4,7,16],[10,5,8,4,15,14,2,12,1,16,6,7,3,11,9,13],[13,16,3,14,10,9,11,2,15,1,8,6,5,12,4,7],[2,15,1,6,12,13,16,3,4,7,14,5,11,10,8,9],[12,11,5,10,14,4,7,8,2,9,3,13,1,15,16,6],[7,9,4,8,5,15,1,6,12,11,10,16,13,2,3,14],[14,1,10,9,8,12,6,13,3,15,16,4,2,7,5,11],[15,8,13,5,2,3,4,9,14,12,7,11,6,16,1,10],[4,6,12,16,7,5,14,11,13,10,1,2,9,8,15,3],[3,7,2,11,1,16,10,15,8,6,5,9,4,13,14,12],[5,14,11,2,3,6,15,7,16,13,4,8,10,9,12,1],[9,13,15,3,16,2,8,5,10,14,12,1,7,6,11,4],[6,4,16,12,9,10,13,1,7,5,11,3,8,14,2,15],[8,10,7,1,4,11,12,14,6,2,9,15,16,3,13,5]]), [true]).
test_case(21, true, consistent([[5,14,13,6,10,8,11,16,4,2,15,1,3,12,7,9],[8,11,12,2,6,15,3,14,7,13,5,9,4,16,1,10],[16,1,3,15,4,13,7,9,8,10,6,12,5,14,11,2],[7,9,10,4,1,2,5,12,3,16,11,14,15,8,6,13],[11,16,4,8,15,10,14,13,12,5,2,7,9,6,3,1],[1,15,9,3,8,11,12,5,13,6,10,16,7,4,2,14],[14,13,7,10,2,3,6,1,15,4,9,11,16,5,8,12],[6,2,5,12,16,4,9,7,1,14,3,8,10,15,13,11],[13,10,8,16,3,6,4,15,9,11,7,2,14,1,12,5],[4,7,15,11,5,9,1,2,6,12,14,3,8,13,10,16],[12,6,14,5,13,7,16,8,10,15,1,4,2,11,9,3],[9,3,2,1,12,14,10,11,16,8,13,5,6,7,4,15],[15,8,11,13,9,12,2,3,14,7,16,6,1,10,5,4],[2,4,16,9,14,5,13,6,11,1,8,10,12,3,15,7],[10,5,1,7,11,16,8,4,2,3,12,15,13,9,14,6],[3,12,6,14,7,1,15,10,5,9,4,13,11,2,16,8]]), [true]).
test_case(22, true, consistent([[6,2,13,4,5,16,1,10,3,15,8,9,14,11,7,12],[15,7,14,8,2,6,4,9,16,12,13,11,5,3,10,1],[1,5,11,3,12,8,15,7,4,2,10,14,9,6,16,13],[10,16,9,12,14,13,3,11,6,1,7,5,15,2,4,8],[4,12,10,9,7,15,2,3,11,6,1,16,13,8,14,5],[16,1,5,14,13,12,8,4,7,3,9,2,11,10,6,15],[8,6,15,7,11,10,16,14,13,4,5,12,3,1,9,2],[3,13,2,11,9,1,6,5,8,14,15,10,16,7,12,4],[9,14,1,13,8,5,7,16,10,11,3,4,12,15,2,6],[12,11,8,10,3,9,13,2,15,5,6,7,4,16,1,14],[5,4,6,2,10,11,12,15,9,16,14,1,8,13,3,7],[7,3,16,15,1,4,14,6,2,13,12,8,10,9,5,11],[11,15,7,6,4,14,9,8,5,10,2,3,1,12,13,16],[13,8,3,5,16,2,11,1,12,9,4,6,7,14,15,10],[2,9,4,1,15,7,10,12,14,8,16,13,6,5,11,3],[14,10,12,16,6,3,5,13,1,7,11,15,2,4,8,9]]), [true]).
test_case(23, true, consistent([[24,14,6,19,8,3,13,2,16,4,7,25,21,12,11,1,9,20,5,22,23,18,10,17,15],[2,10,20,11,16,25,17,1,15,22,5,4,9,24,23,6,8,14,13,18,3,7,12,21,19],[7,9,13,15,3,11,21,18,19,23,2,16,1,8,22,10,4,17,12,24,14,20,25,5,6],[23,12,22,18,25,20,7,8,5,9,14,17,19,6,10,3,11,21,15,2,4,16,1,13,24],[1,5,4,21,17,6,14,10,12,24,3,20,18,13,15,16,23,19,7,25,22,2,8,9,11],[22,16,7,9,2,23,18,4,6,15,19,24,13,20,21,25,3,11,17,12,10,1,14,8,5],[25,1,10,5,4,19,24,14,20,11,8,2,22,18,7,23,13,16,21,15,6,3,17,12,9],[11,3,23,17,18,2,1,22,7,16,25,15,10,5,12,24,6,8,14,9,13,21,20,19,4],[21,13,19,14,6,8,12,5,10,17,23,3,16,9,4,22,1,2,20,7,18,24,15,11,25],[15,20,8,12,24,21,25,9,3,13,17,6,11,1,14,19,18,5,4,10,16,22,2,23,7],[14,8,9,25,12,16,3,21,4,19,24,18,17,7,2,5,15,23,22,20,1,11,13,6,10],[4,11,5,6,15,10,23,24,17,25,12,19,3,21,13,2,16,9,8,1,7,14,22,18,20],[13,24,21,3,1,7,8,11,18,12,20,22,15,10,16,17,14,4,6,19,5,23,9,25,2],[18,19,2,23,20,13,5,6,22,1,4,9,25,14,8,11,10,7,24,21,15,12,3,16,17],[10,22,17,16,7,9,15,20,14,2,6,11,5,23,1,13,25,12,18,3,21,19,24,4,8],[16,2,3,13,5,1,20,25,24,8,15,21,6,11,19,9,22,10,23,14,17,4,18,7,12],[12,4,14,20,10,15,9,17,11,3,16,23,7,25,18,8,19,1,2,5,24,13,6,22,21],[19,17,25,1,23,5,6,7,13,18,9,10,12,22,24,21,20,15,16,4,2,8,11,3,14],[8,6,18,7,11,22,4,23,21,10,1,5,14,2,20,12,17,24,3,13,9,25,19,15,16],[9,21,15,24,22,12,16,19,2,14,13,8,4,3,17,18,7,6,25,11,20,10,5,1,23],[20,15,1,4,21,14,10,12,23,6,18,13,24,17,25,7,5,22,19,8,11,9,16,2,3],[3,7,24,22,13,18,19,16,8,20,11,14,23,4,6,15,2,25,9,17,12,5,21,10,1],[5,18,11,10,19,17,2,13,25,7,21,12,20,16,9,4,24,3,1,6,8,15,23,14,22],[6,23,12,8,14,4,11,15,9,5,22,1,2,19,3,20,21,13,10,16,25,17,7,24,18],[17,25,16,2,9,24,22,3,1,21,10,7,8,15,5,14,12,18,11,23,19,6,4,20,13]]), [true]).
test_case(24, true, consistent([[24,14,6,19,8,3,13,2,16,4,7,25,21,12,11,1,9,20,5,22,23,18,10,17,15],[2,10,20,11,16,25,17,1,15,22,5,4,9,24,23,6,8,14,13,18,3,7,12,21,19],[7,9,13,15,3,11,21,18,19,23,2,16,1,8,22,10,4,17,12,24,14,20,25,5,6],[23,12,22,18,25,20,7,8,5,9,14,17,19,6,10,3,11,21,15,2,4,16,1,13,24],[1,5,4,21,17,6,14,10,12,24,3,20,18,13,15,16,23,19,7,25,22,2,8,9,11],[22,16,7,9,2,23,18,4,6,15,19,24,13,20,21,25,3,11,17,12,10,1,14,8,5],[25,1,10,5,4,19,24,14,20,11,8,2,22,18,7,23,13,16,21,15,6,3,17,12,9],[11,3,23,17,18,2,1,22,7,16,25,15,10,5,12,24,6,8,14,9,13,21,20,19,4],[21,13,19,14,6,8,12,5,10,17,23,3,16,9,4,22,1,2,20,7,18,24,15,11,25],[15,20,8,12,24,21,25,9,3,13,17,6,11,1,14,19,18,5,4,10,16,22,2,23,7],[14,19,9,25,12,16,3,21,4,2,24,18,17,7,8,5,15,23,22,20,1,11,13,6,10],[4,11,5,6,15,10,23,24,17,25,12,19,3,21,13,2,16,9,8,1,7,14,22,18,20],[13,24,21,3,1,7,8,11,18,12,20,22,15,10,16,17,14,4,6,19,5,23,9,25,2],[18,8,2,23,20,13,5,6,22,19,4,9,25,14,1,11,10,7,24,21,15,12,3,16,17],[10,22,17,16,7,9,15,20,14,1,6,11,5,23,2,13,25,12,18,3,21,19,24,4,8],[16,2,3,13,5,1,20,25,24,8,15,21,6,11,19,9,22,10,23,14,17,4,18,7,12],[12,4,14,20,10,15,9,17,11,3,16,23,7,25,18,8,19,1,2,5,24,13,6,22,21],[19,17,25,1,23,5,6,7,13,18,9,10,12,22,24,21,20,15,16,4,2,8,11,3,14],[8,6,18,7,11,22,4,23,21,10,1,5,14,2,20,12,17,24,3,13,9,25,19,15,16],[9,21,15,24,22,12,16,19,2,14,13,8,4,3,17,18,7,6,25,11,20,10,5,1,23],[20,15,1,4,21,14,10,12,23,6,18,13,24,17,25,7,5,22,19,8,11,9,16,2,3],[3,7,24,22,13,18,19,16,8,20,11,14,23,4,6,15,2,25,9,17,12,5,21,10,1],[5,18,11,10,19,17,2,13,25,7,21,12,20,16,9,4,24,3,1,6,8,15,23,14,22],[6,23,12,8,14,4,11,15,9,5,22,1,2,19,3,20,21,13,10,16,25,17,7,24,18],[17,25,16,2,9,24,22,3,1,21,10,7,8,15,5,14,12,18,11,23,19,6,4,20,13]]), [true]).
test_case(25, Sol, sudoku0([[2,3,4,1],[4,0,2,0],[0,2,1,4],[0,4,0,2]],Sol), [[[2,3,4,1],[4,1,2,3],[3,2,1,4],[1,4,3,2]]]).
test_case(26, Sol, sudoku0([[2,3,4,1],[4,0,2,0],[0,0,0,4],[0,0,0,0]],Sol), [[[2,3,4,1],[4,1,2,3],[1,2,3,4],[3,4,1,2]],[[2,3,4,1],[4,1,2,3],[3,2,1,4],[1,4,3,2]]]).
test_case(27, Sol, sudoku0([[2,3,4,1],[4,0,2,0],[0,0,0,0],[0,0,0,0]],Sol), [[[2,3,4,1],[4,1,2,3],[1,2,3,4],[3,4,1,2]],[[2,3,4,1],[4,1,2,3],[1,4,3,2],[3,2,1,4]],[[2,3,4,1],[4,1,2,3],[3,2,1,4],[1,4,3,2]],[[2,3,4,1],[4,1,2,3],[3,4,1,2],[1,2,3,4]]]).
test_case(28, Sol, sudoku0([[2,3,4,1],[0,0,0,0],[0,0,0,0],[0,0,0,0]],Sol), [[[2,3,4,1],[1,4,2,3],[3,2,1,4],[4,1,3,2]],[[2,3,4,1],[1,4,2,3],[4,1,3,2],[3,2,1,4]],[[2,3,4,1],[1,4,3,2],[3,1,2,4],[4,2,1,3]],[[2,3,4,1],[1,4,3,2],[3,2,1,4],[4,1,2,3]],[[2,3,4,1],[1,4,3,2],[4,1,2,3],[3,2,1,4]],[[2,3,4,1],[1,4,3,2],[4,2,1,3],[3,1,2,4]],[[2,3,4,1],[4,1,2,3],[1,2,3,4],[3,4,1,2]],[[2,3,4,1],[4,1,2,3],[1,4,3,2],[3,2,1,4]],[[2,3,4,1],[4,1,2,3],[3,2,1,4],[1,4,3,2]],[[2,3,4,1],[4,1,2,3],[3,4,1,2],[1,2,3,4]],[[2,3,4,1],[4,1,3,2],[1,4,2,3],[3,2,1,4]],[[2,3,4,1],[4,1,3,2],[3,2,1,4],[1,4,2,3]]]).
test_case(29, Sol, sudoku0([[2,1,8,3,6,4,8,7,5],[4,3,7,1,8,5,9,6,2],[6,5,0,7,9,2,3,1,4],[1,9,4,8,5,7,6,2,3],[5,2,6,4,1,3,7,9,8],[8,7,3,6,2,9,5,4,1],[7,6,1,2,3,8,4,5,9],[9,8,2,5,4,6,1,3,7],[3,4,5,9,7,1,2,8,6]],Sol), []).
test_case(30, Sol, sudoku0([[0,0,0,0,0,0,8,7,5],[4,3,7,1,8,5,9,6,2],[6,5,0,7,9,2,3,1,4],[1,9,4,8,5,7,6,2,3],[5,2,6,4,1,3,7,9,8],[8,7,3,6,2,9,5,4,1],[7,6,1,2,3,8,4,5,9],[9,8,2,5,4,6,1,3,7],[3,4,5,9,7,1,2,8,6]],Sol), [[[2,1,9,3,6,4,8,7,5],[4,3,7,1,8,5,9,6,2],[6,5,8,7,9,2,3,1,4],[1,9,4,8,5,7,6,2,3],[5,2,6,4,1,3,7,9,8],[8,7,3,6,2,9,5,4,1],[7,6,1,2,3,8,4,5,9],[9,8,2,5,4,6,1,3,7],[3,4,5,9,7,1,2,8,6]]]).


:- use_module(library(samsort)).

test_all :-
    test_case(N, Sol, Goal, ExpectedSols),
    statistics(runtime, [T0,_]),
    findall(Sol, Goal, UnsortedSols),
    statistics(runtime, [T1,_]),
    T is T1-T0,
    samsort(UnsortedSols, Sols),     % sorts without removing duplicates
    (    Sols == ExpectedSols -> format('Test case ~t~w~12| OK, run time ~3d sec\n', [N,T])
    ;    format('Test case ~t~w~12|: Run time ~3d sec, expected ~w, got ~w\n', [N,T,ExpectedSols,Sols])
    ),
    fail.
test_all.
