2

我正在研究 Ivan Bratko 书上的 Prolog:人工智能编程,并且在书中我发现了这个版本的 8 Queens 问题,它使用空间状态“图”来解决问题:

s(Queens, [Queen|Queens]) :- member(Queen, [1,2,3,4,5,6,7,8]),
                             noattack(Queen, Queens).

goal([_,_,_,_,_,_,_,_]).

noattack(_,[],_).

noattack(Y,[Y1|Ylist],Xdist) :-
                                  Y1-Y =\= Xdist,
                      Y-Y1 =\= Xdist,
                                  Dist1 is Xdist + 1,
                                  noattack(Y,Ylist,Dist1).

solve(N,[N]) :- goal(N).

solve(N, [N|Sol1]) :- s(N,N1),
                      solve(N1,Sol1).

它结合了基于排列的 8 个皇后问题解决方案(使用它的noattack/3关系)和我认为构建可能的后继状态状态的s/2谓词(我的图表的节点)。所以我有类似的东西:

s(实际状态,后继状态)

我认为目标/1谓词只指定我必须准确放置 8 个皇后。

在书上说我执行这个查询:solve([],Solution)它将产生一个随着皇后数量增加的棋盘位置列表,并且这个列表将以八个皇后的安全配置结束。

但是,如果我尝试执行此查询不起作用,我将获得此输出:

?- solve([],Solution).
ERROR: s/2: Undefined procedure: noattack/2
ERROR:   However, there are definitions for:
ERROR:         noattack/3

因为,正确地,在第 2 行中调用的noattack谓词只接受 2 个参数,但noattack谓词必须有 3 个参数……书上的 bue 是以这种错误的方式给出的,我不知道如何解决这个问题……

为什么?我错过了什么?

4

1 回答 1

3

几个错误:

s(Queens, [Queen|Queens]) :- member(Queen, [1,2,3,4,5,6,7,8]),
                             noattack(Queen, Queens, 1).

noattack(_,[],_) :- !.
noattack(Y,[Y1|Ylist],Xdist) :-   Y =\= Y1,
                                  Y1-Y =\= Xdist,
                                  Y-Y1 =\= Xdist,
                                  Dist1 is Xdist + 1,
                                  noattack(Y,Ylist,Dist1).

然后,

18 ?- solve([],_X), last(_X,S).
S = [4, 2, 7, 3, 6, 8, 5, 1] ;
S = [5, 2, 4, 7, 3, 8, 6, 1] ;
S = [3, 5, 2, 8, 6, 4, 7, 1] ;
S = [3, 6, 4, 2, 8, 5, 7, 1] ;
S = [5, 7, 1, 3, 8, 6, 4, 2] ;
S = [4, 6, 8, 3, 1, 7, 5, 2]

和,

25 ?- findall( X, solve([],X), _S), length(_S,N).
N = 92.
于 2013-05-08T13:14:03.100 回答