这是以下问题的后续问题:限制 Prolog 中的搜索 - Magic Sqare
感谢Isabelle Newbie迄今为止的帮助。
在 Isabelle Newbie 的帮助下,我的代码可以正常工作,但遗憾的是仅适用于 4x4 Squares。
我对 Prolog 很陌生,所以也许我错过了一些明显的东西。
下面的代码基本上很快就生成了一个 4x4 的幻方。我以某种方式实现了所有规则,它们也应该适用于更高尺寸的正方形,如 8x8 或 12x12,但由于某种原因它不起作用。
:- use_module(library(clpfd)).
diag2_sum(0, _, _, _, _).
diag2_sum(I0, N, C1, Row1, Row3) :-
I0 > 0,
nth1(I0,Row1,A),
V1 is N - 2,
(I0 =:= V1 -> I2 = N ; I2 is mod(I0 + 2,N)),
nth1(I2,Row3,B),
C1 #= A + B,
I1 is I0 - 1,
diag2_sum(I1, N, C1, Row1, Row3).
diag_sum([_,_], _, _).
diag_sum([Row1|Tail], C1, N) :-
nth1(2,Tail,Row3),
diag2_sum(N, N, C1, Row1,Row3),
diag_sum(Tail, C1, N).
square_sum_x(_, _, _, 0, _).
square_sum_x(Row1, Row2, C2, I0, N) :-
V1 is N - 1,
(I0 =:= V1 -> I2 = N ; I2 is mod(I0 + 1,N)),
nth1(I0,Row1,Elem1),
nth1(I2,Row1,Elem2),
nth1(I0,Row2,Elem3),
nth1(I2,Row2,Elem4),
C2 #= Elem1 + Elem2 + Elem3 + Elem4,
I1 is I0 - 1,
square_sum_x(Row1, Row2, C2, I1, N).
square_sum_y(_, _, 0, _).
square_sum_y(Matrix, C2, I0, N) :-
V1 is N - 1,
(I0 =:= V1 -> I2 = N ; I2 is mod(I0 + 1,N)),
nth1(I0,Matrix,Row1),
nth1(I2,Matrix,Row2),
square_sum_x(Row1,Row2, C2, N, N),
I1 is I0 - 1,
square_sum_y(Matrix, C2, I1, N).
magic_square_(N, Matrix) :-
Nmax is N * N,
C1 is Nmax + 1,
C2 is C1 * 2,
write(C1),nl,write(C2),nl,
length(Matrix, N),
maplist(same_length(Matrix), Matrix),
append(Matrix, Vs),
Vs ins 1..Nmax, all_different(Vs),
diag_sum(Matrix, C1, N),
square_sum_y(Matrix, C2, N, N).
magic_square(N, Matrix) :-
magic_square_(N, Matrix),
maplist(label, Matrix).
4x4 魔方(有效):
?- magic_square(4, Matrix).
17
34
Matrix = [[1, 8, 10, 15], [12, 13, 3, 6], [7, 2, 16, 9], [14, 11, 5, 4]]
8x8 幻方(不起作用):
?- magic_square(8, Matrix).
65
130
false.