开发者

sudoku solver infinite recursion

I am writing a sudoku solver. It has been a long time since I have touched prolog, thus I don't remember everything regarding unification, backtracking, etc. I think that I cause the system to backtrack forever (but I don't get any stack exceptions - at least not immediately). This is what I have so far (the puzzle can be found at http://en.wikipedia.org/wiki/File:Sudoku-by-L2G-20050714.svg):

% representation of the example puzzle
puzzle([5, 3, _, _, 7, _, _, _, _],
       [6, _, _, 1, 9, 5, _, _, _],
       [_, 9, 8, _, _, _, _, 6, _],
       [8, _, _, _, 6, _, _, _, 3],
       [4, _, _, 8, _, 3, _, _, 1],
       [7, _, _, _, 2, _, _, _, 6],
       [_, 6, _, _, _, _, 2, 8, _],
       [_, _, _, 4, 1, 9, _, _, 5],
       [_, _, _, _, 8, _, _, 7, 9]).

% solve(S)
% the starting point of the program
% saves the solution in the variable S
solve(R1, R2, C1) :-
    % save the rows into variables
    puzzle(R1, R2, R3, R4, R5, R6, R7, R8, R9),
    % solve for each row
    allunique(R1), allunique(R2), allunique(R3),
    allunique(R4), allunique(R5), allunique(R6),
    allunique(R7), allunique(R8), allunique(R9),
    % the columns must be created first
    nelement(R1, 1, C11), nelement(R2, 1, C21), nelement(R3, 1, C31),
    nelement(R4, 1, C41), nelement(R5, 1, C51), nelement(R6, 1, C61),
    nelement(R7, 1, C71), nelement(R8, 1, C81), nelement(R9, 1, C91),
    C1 = [C11, C21, C31, C41, C51, C61, C71, C81, C91],
    allunique(C1).

% allunique(List)
% Succeeds if all the numbers of List are between 1-9
% and each number exists only once
allunique([]). % Recursion stops when the list is empty

% A member should be between 1-9 and not a member of the tail
allunique([H|T]) :-
    allunique(T),
    member(H, [1, 2, 3, 4, 5, 6, 7, 8, 9]),
    not(member(H, T)).

% nelement(List, N-th, X)
% Saves the nth element of a list in variable X
nelement([H|_], 1, H). % The first element is the head

% All other elements will be found in the tail
nelement([_|T], N, X) :-
    N > 1,
    N1 is N-1,
    nelement(T, N1, X).

The line allunique(C1) causes the problem. It seems that the system puts a 7 in the first empty box of the 1st column and never changes it (or at least not in the near future). An example 开发者_如何学JAVAC1 list is [5, 6, 7, 8, 4, 7, 9, 8, 6]. I am curious to find out why this is happening.


  1. Your example list [5, 6, 7, 8, 4, 7, 9, 8, 6] doesn't satisfy allunique since it contains 8 twice.
  2. solve/3 is incorrect since it checks all rows, but only one column and no "region" (the 3x3 squares).
  3. The solve/1 predicate promised in the comments doesn't appear, so I can't test your code; allunique/1 and nelement/3 seem fine.
  4. Even if you complete this program, I doubt it's ever going to return an answer. I've seen similar Prolog programs run for hours without finding the solution. Check out CLP(fd) if you want to do this fast (link is for SWI, but SICStus, GNU, and ECLiPSe have similar libraries.)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜