prolog nurikabe谜题:未定义谓词

prolog nurikabe谜题:未定义谓词,prolog,infinite-loop,gnu-prolog,Prolog,Infinite Loop,Gnu Prolog,我试图在prolog中运行这段代码来解决nurikabe难题, 但是我发现这个错误谓词fd\u域/3没有定义 我试图确保最终得到一个包含以下内容的解决方案: 表示sea->水平和垂直连接且不形成2×2块的单元 表示孤岛的单元格->每个孤岛都是孤立的,并且在水平或垂直方向上孤岛之间没有连接 我正在使用swi prolog % SWI-Prolog version 7.6.4 by Jan Wielemaker (jan@swi-prolog.org) 链接到拼图https://en.wikipe

我试图在prolog中运行这段代码来解决nurikabe难题, 但是我发现这个错误
谓词fd\u域/3没有定义

我试图确保最终得到一个包含以下内容的解决方案:

表示sea->水平和垂直连接且不形成2×2块的单元

表示孤岛的单元格->每个孤岛都是孤立的,并且在水平或垂直方向上孤岛之间没有连接

我正在使用swi prolog

% SWI-Prolog version 7.6.4 by Jan Wielemaker (jan@swi-prolog.org)
链接到拼图
https://en.wikipedia.org/wiki/Nurikabe_(拼图)

代码:

/*-1为地,-2为墙*/
努里卡贝([A|L]):-
长度([A | L],H),
长度(A,W),
检查域列表([A | L],W,H),
检查网格(0,0,[A | L],W,H),
检查网格(0,0,[A | L],W,H),
检查墙壁([A | L]、W、H)。
/*设置网格的域*/
检查域列表([],,)。
检查域列表([A | L],W,H):-
Nb_值为W*H,
检查_值(A、Nb_值),
检查域列表(L、W、H)。
检查_值([],u)。
检查_值([A | L],Nb_值):-(A=-1;A=-2;fd_域(A,1,Nb_值)),检查_值(L,Nb_值)。
/*检查两个正方形是否连接*/
已连接(X1、Y1、X2、Y2、栅极、L):-
获取_值(X1,Y1,网格,V1),
获取_值(X2,Y2,网格,V2),
同类(V1,V2),
\+成员chk([X2,Y2],L)。
/*找到相邻的正方形*/
d(X,Y,X,Y,H):-Y是H-1。
d(X,Ya,X,Yb,u,H):-Yb是Ya+1,Ya\=H-1。
u(X,0,X,0,u,u)。
u(X,Ya,X,Yb,u,u):-Yb是Ya-1,Ya\=0。
r(X,Y,X,Y,W),:-X是W-1。
r(Xa,Y,Xb,Y,W,2;):-Xb是Xa+1,Xa\=W-1。
l(0,Y,0,Y,u,u)。
l(Xa,Y,Xb,Y,_,_):-Xb是Xa-1,Xa\=0。
/*检查一个岛上的方块数*/
检查计数岛(X、Y、栅格、W、H):-
连接相邻(X,Y,[[X,Y]],L,网格,W,H),
获取_值(X,Y,网格,N),
长度(L,N)。
AddithiFix-连通(x,y,席,y,l,l,网格,γ,)):
+连接(x,y,席,i,网格,L)。
AddithiFixFieldX(x,y,席,y,L,LeNew,Grand,w,h):
连接(x,y,席,i,网格,L),
连接相邻的元素(Xi,Yi,[[Xi,Yi]| L],Lnew,Grid,W,H)。
连接相邻部分(X、Y、L、Lnew、栅格、W、H):-
d(X,Y,X1,Y1,W,H),
u(X,Y,X2,Y2,W,H),
r(X,Y,X3,Y3,W,H),
l(X,Y,X4,Y4,W,H),
如果_连接(X、Y、X1、Y1、L、L2、栅极、W、H),则添加_,
如果_连接(X、Y、X2、Y2、L2、L3、电网、W、H),则添加_,
如果已连接(X、Y、X3、Y3、L3、L4、电网、W、H),则添加,
如果_连接(X、Y、X4、Y4、L4、Lnew、Grid、W、H),则添加_。
/*检查网格中的所有正数*/
检查网格(W、H、W、H)。
检查网格(X、Y、网格、W、H):-
获取_值(X,Y,网格,Val),
下一个方格(X,Y,Xnext,Ynext,W,H),
Val<0,
检查网格(X下一步、Y下一步、网格、W、H)。
检查网格(X、Y、网格、W、H):-
获取_值(X,Y,网格,Val),
下一个方格(X,Y,Xnext,Ynext,W,H),
Val>0,
检查计数岛(X、Y、栅格、W、H),
检查网格(X下一步、Y下一步、网格、W、H)。
/*检查电池是否为同一类型*/
/*要么两者都是墙,要么两者都不是墙*/
同类(Va、Vb):-
Va=-2,Vb=-2。
同类(Va、Vb):-
Va\=-2,Vb\=-2。
/*检查网格中的墙块*/
检查网格(Y,Y,H):-Y是H-1。
检查2x2网格(X、Y、网格、W、H):-
获取_值(X,Y,网格,V),
同类(-2,V),
检查_2x2(X,Y,网格,W,H),
下一个方格(X,Y,Xnext,Ynext,W,H),
检查2x2网格(Xnext、Ynext、网格、W、H)。
检查2x2网格(X、Y、网格、W、H):-
获取_值(X,Y,网格,V),
下一个方格(X,Y,Xnext,Ynext,W,H),
\+同类(-2,V),
检查2x2网格(Xnext、Ynext、网格、W、H)。
/*检查一组2x2的正方形*/
检查_2x2(X,,,W,2;):-X是W-1。
检查_2x2(X,Y,网格,W,H):-
向下(X,Y,X1,Y1,W,H),
右(X,Y,X2,Y2,W,H),
向下(X2,Y2,X3,Y3,W,H),
获取_值(X1,Y1,网格,V1),
获取_值(X2,Y2,网格,V2),
获取_值(X3,Y3,网格,V3),
\+三堵墙(V1、V2、V3)。
/*检查是否有3个正方形是墙*/
三面墙(V1,V2,V3):-相同种类(V1,V2),相同种类(V2,V3),相同种类(-2,V1)。
/*在右边和下面得到正方形的位置*/
向下(X,Yini,X,Ynext,uh):-
Ynext是Yini+1,
Ynext\=H。
右(Xini,Y,Xnext,Y,W,u):-
Xnext是Xini+1,
下一步\=W。
/*在网格中查找正方形的值*/
/*L是一个网格,其中包含每个正方形的值*/
获取_值(X,Y,[|L],Val):-
Ytmp是Y-1,
获取_值(X,Ytmp,L,Val)。
获取_值(X,0,[A |),Val):-
获取值(X,A,Val)。
获取值(X,[u124; L],Val):-
Xtmp是X-1,
获取值行(Xtmp,L,Val)。
获取值行(0,[Val | |,]Val)。
/*找到下一个广场*/
/*功能停止在位置(W,H)*/
下一个正方形(X,Y,W,H,W,H):-
X是W-1,
Y是H-1。
下一个广场(Xini,Y,Xnext,Y,W,u):-
Xnext是Xini+1,
下一步\=W。
下一个广场(西尼、伊尼、0、Ynext、W、H):-
Xini是W-1,,
Ynext是Yini+1,
Ynext\=H。
/*计算网格中的墙数*/
计数墙(W,H,W,H,0)。
计数墙壁(X、Y、栅格、W、H、N):-
获取_值(X,Y,网格,-2),
下一个方格(X,Y,Xnext,Ynext,W,H),
计数墙壁(X下一个、Y下一个、网格、W、H、Nnew),
N为Nnew+1,
X\=W。
计数墙壁(X、Y、栅格、W、H、N):-
获取_值(X,Y,网格,Val),
下一个方格(X,Y,Xnext,Ynext,W,H),
计算墙壁(X下一个、Y下一个、网格、W、H、N),
Val\=-2,
X\=W。
/*计数墙v2*/
墙的计数([],0)。
计数墙([A | L],N):-
计数墙线(A,N1),
计数壁(L,N2),
N是N1+N2。
计数墙线([],0)。
计数墙线([-2|T],Y):-
计数墙线(T,Z),
Y是1+Z。
计数墙线([uu | T],Z):-
计数墙线(T,Z)。
/*检查是否有独特的墙*/
检查墙(网格,W,H):-\+查找墙(0,0,\,\,\,\,网格,W,H)。
检查墙壁(网格、W、H):-
找到墙(0,0,X,Y,网格,W,H),
检查墙壁(X、Y、栅格、W、H)。
检查墙壁(X、Y、网格、W、H):-
连接相邻(X,Y,[[X,Y]],L,网格,W,H),
/* -1 is ground, -2 is wall */

nurikabe([A|L]) :-
    length([A|L], H),
    length(A, W),
    check_domain_list([A|L], W, H),
    check_count_grid(0, 0, [A|L], W, H),
    check_2x2_grid(0, 0, [A|L], W, H),
    check_walls([A|L], W, H).

/* set the domain of the grid */
check_domain_list([],_, _).
check_domain_list([A|L],W,H) :-
    Nb_values is W*H,
    check_values(A,Nb_values),
    check_domain_list(L,W,H).       

check_values([],_).     
check_values([A|L],Nb_values) :- (A = -1 ; A = -2 ; fd_domain(A, 1, Nb_values)), check_values(L,Nb_values).

/* check if two squares are connected */
connected(X1, Y1, X2, Y2, Grid, L) :-
    get_value(X1, Y1, Grid, V1),
    get_value(X2, Y2, Grid, V2),
    same_kind(V1, V2),
    \+ memberchk([X2, Y2], L).

/* find the square adjacent */
d(X, Y, X, Y, _, H) :- Y is H - 1.
d(X, Ya, X, Yb, _, H) :- Yb is Ya + 1, Ya \= H - 1.
u(X, 0, X, 0, _, _).
u(X, Ya, X, Yb, _, _) :- Yb is Ya - 1, Ya \= 0.
r(X, Y, X, Y, W, _) :- X is W - 1.
r(Xa, Y, Xb, Y, W, _) :- Xb is Xa + 1, Xa \= W - 1.
l(0, Y, 0, Y, _, _).
l(Xa, Y, Xb, Y, _, _) :- Xb is Xa - 1, Xa \= 0.

/* check number of squares in an island */
check_count_island(X, Y, Grid, W, H) :-
    connect_adjacents(X, Y, [[X,Y]], L, Grid, W, H),
    get_value(X, Y, Grid, N),
    length(L, N).

add_if_connected(X, Y, Xi, Yi, L, L, Grid, _, _) :-
    \+connected(X, Y, Xi, Yi, Grid, L).
add_if_connected(X, Y, Xi, Yi, L, Lnew, Grid, W, H) :-
    connected(X, Y, Xi, Yi, Grid, L),
    connect_adjacents(Xi, Yi, [[Xi,Yi] | L], Lnew, Grid, W, H).

connect_adjacents(X, Y, L, Lnew, Grid, W, H) :-
    d(X, Y, X1, Y1, W, H),
    u(X, Y, X2, Y2, W, H),
    r(X, Y, X3, Y3, W, H),
    l(X, Y, X4, Y4, W, H),
    add_if_connected(X, Y, X1, Y1, L, L2, Grid, W, H),
    add_if_connected(X, Y, X2, Y2, L2, L3, Grid, W, H),
    add_if_connected(X, Y, X3, Y3, L3, L4, Grid, W, H),
    add_if_connected(X, Y, X4, Y4, L4, Lnew, Grid, W, H).

/* check all the positive numbers in the grid */
check_count_grid(W, H, _, W, H).
check_count_grid(X, Y, Grid, W, H) :-
    get_value(X, Y, Grid, Val),
    next_square(X, Y, Xnext, Ynext, W, H),
    Val < 0,
    check_count_grid(Xnext, Ynext, Grid, W, H).
check_count_grid(X, Y, Grid, W, H) :-
    get_value(X, Y, Grid, Val),
    next_square(X, Y, Xnext, Ynext, W, H),
    Val > 0,
    check_count_island(X, Y, Grid, W, H),
    check_count_grid(Xnext, Ynext, Grid, W, H).

/* check if cells are of the same kind */
/* either both are Walls or both are not Walls */
same_kind(Va, Vb) :-
    Va = -2, Vb = -2.
same_kind(Va, Vb) :-
    Va \= -2, Vb \= -2.

/* check blocs of wall in the grid */
check_2x2_grid(_, Y, _, _, H) :- Y is H - 1.
check_2x2_grid(X, Y, Grid, W, H) :-
    get_value(X, Y, Grid, V),
    same_kind(-2, V),
    check_2x2(X, Y, Grid, W, H),
    next_square(X, Y, Xnext, Ynext, W, H),
    check_2x2_grid(Xnext, Ynext, Grid, W, H).
check_2x2_grid(X, Y, Grid, W, H) :-
    get_value(X, Y, Grid, V),
    next_square(X, Y, Xnext, Ynext, W, H),
    \+same_kind(-2, V),
    check_2x2_grid(Xnext, Ynext, Grid, W, H).

/* check a bloc of 2x2 squares */
check_2x2(X, _, _, W, _) :- X is W - 1.
check_2x2(X, Y, Grid, W, H) :-
    down(X, Y, X1, Y1, W, H),
    right(X, Y, X2, Y2, W, H),
    down(X2, Y2, X3, Y3, W, H),
    get_value(X1, Y1, Grid, V1),
    get_value(X2, Y2, Grid, V2),
    get_value(X3, Y3, Grid, V3),
    \+three_walls(V1, V2, V3).

/* check if 3 squares are walls */
three_walls(V1, V2, V3) :- same_kind(V1, V2), same_kind(V2, V3), same_kind(-2, V1).

/* get the position of the square at the right and below */
down(X, Yini, X, Ynext, _, H) :-
    Ynext is Yini + 1,
    Ynext \= H.
right(Xini, Y, Xnext, Y, W, _) :-
    Xnext is Xini + 1,
    Xnext \= W.

/* find the value of a square in the grid */
/* L is a grid with the value of each square */
get_value(X, Y, [_|L], Val) :-
    Ytmp is Y - 1,
    get_value(X, Ytmp, L, Val).
get_value(X, 0, [A|_], Val) :-
    get_value_line(X, A, Val).

get_value_line(X, [_|L], Val) :-
    Xtmp is X - 1,
    get_value_line(Xtmp, L, Val).
get_value_line(0, [Val|_], Val). 

/* find the next square */
/* the function stop at the position (W,H) */
next_square(X, Y, W, H, W, H) :-
    X is W - 1,
    Y is H - 1.
next_square(Xini, Y, Xnext, Y, W, _) :-
    Xnext is Xini + 1,
    Xnext \= W.
next_square(Xini, Yini, 0, Ynext, W, H) :-
    Xini is W - 1,
    Ynext is Yini + 1,
    Ynext \= H.

/* count the number of walls in the grid */
count_walls(W, H, _, W, H, 0).
count_walls(X, Y, Grid, W, H, N) :-
    get_value(X, Y, Grid, -2),
    next_square(X, Y, Xnext, Ynext, W, H),
    count_walls(Xnext, Ynext, Grid, W, H, Nnew),
    N is Nnew + 1,
    X \= W.
count_walls(X, Y, Grid, W, H, N) :-
    get_value(X, Y, Grid, Val),
    next_square(X, Y, Xnext, Ynext, W, H),
    count_walls(Xnext, Ynext, Grid, W, H, N),
    Val \= -2,
    X \= W.

/* count walls v2 */
count_wall([],0).
count_wall([A|L],N) :-
    count_wall_line(A,N1),
    count_wall(L,N2),
    N is N1+N2.

count_wall_line([],0).
count_wall_line([-2|T],Y) :-
    count_wall_line(T,Z),
    Y is 1+Z.
count_wall_line([_|T],Z) :-
    count_wall_line(T,Z).

/* check there is an unique wall */
check_walls(Grid, W, H) :- \+find_wall(0, 0, _, _, Grid, W, H).
check_walls(Grid, W, H) :-
    find_wall(0, 0, X, Y, Grid, W, H),
    check_walls(X, Y, Grid, W, H).

check_walls(X, Y, Grid, W, H) :-
    connect_adjacents(X, Y, [[X,Y]], L, Grid, W, H),
    count_walls(0, 0, Grid, W, H, N),
    length(L, N).

find_wall(X, Y, X, Y, Grid, _, _) :- get_value(X, Y, Grid, -2).
find_wall(Xi, Yi, X, Y, Grid, W, H) :-
    get_value(Xi, Yi, Grid, Val),
    next_square(Xi, Yi, Xnext, Ynext, W, H),
    Val \= -2,
    find_wall(Xnext, Ynext, X, Y, Grid, W, H).

/*
nurikabe([
    [_, 1, _, _],
    [_, _, _, 2],
    [1, _, 2, _],
    [_, _, _, _],
    [_, _, _, _],
    [2, _, 2, _]
]).

nurikabe([
    [_, _, _, _, _, _],
    [_, _, _, _, _, 5],
    [_, 2, _, _, 3, _],
    [_, _, _, _, _, _],
    [2, _, _, _, _, _],
    [_, _, 5, _, _, _]
]).

nurikabe([
    [_, 4, _, 5, _],
    [_, _, _, _, _],
    [_, _, 1, _, _],
    [4, _, _, _, _],
    [_, _, _, _, _]
]).

nurikabe([
    [_, _, _, 2, _, _,_,_,_,_],
    [_, _, _, _, _, 2,_,_,_,_],
    [_, _, 7, _, _, _,_,1,_,_],
    [_, _, _, _, 2, _,_,_,_,5],
    [_, 2, _, _, _, _,2,_,_,_],
    [_, _, _, 2, _, _,_,_,2,_],
    [7, _, _, _, _, 2,_,_,_,_],
    [_, _, 2, _, _, _,_,3,_,_],
    [_, _, _, _, 1, _,_,_,_,_],
    [_, _, _, _, _, _,3,_,_,_]
]).*/