Prolog - 在列表上应用带有一个固定参数的谓词

问题描述 投票:0回答:1

我正在尝试编写一个程序来解决

n-queens problem
。为了检查女王是否攻击存储在列表
L
中的另一个女王,作为列表及其坐标(
[X,Y], etc...
),我编写了这段代码:

safe_queens([X1,Y1],[X2,Y2]) :-
    X1 \== X2,
    Y1 \== Y2,
    abs(X1 - X2) \== abs(Y1 - Y2).

no_attack([_,_],[]).
no_attack(R0,[R|L]) :-
    maplist(safe_queens(R0,_),L)
    no_attack(R,L).

safe_queens
检查 2 个皇后是否不能互相攻击。我想申请
safe_queens
成为列表中其余成员的女王
R0

如何将 R0 冻结为谓词的一个参数,并让另一个参数在列表中取值

L

prolog
1个回答
1
投票

您可以通过构建另一个谓词来循环列表并使用 R0 在每个元素上应用 safe_queens 来实现此目的,如下所示:

safe_queens([X1,Y1],[X2,Y2]) :-
    X1 \== X2,
    Y1 \== Y2,
    abs(X1 - X2) \== abs(Y1 - Y2).

mapThroughList(_,[]).
mapThroughList(R0,[H|T]):-
    safe_queens(R0,H),
    mapThroughList(R0,T).

no_attack([_,_],[]).
no_attack(R0,[R|L]) :-
    mapThroughList(R0,[R|L]),
    no_attack(R,L).

此外,这是 N-Queen Problem 的解决方案,您可以找到以下代码:

solve(N,P) :-
    numlist(0,N,NL),
    permutation(NL,P),
    diagonals(NL,P,S,D),
    all_diff(S),
    all_diff(D). 

diagonals([],[],[],[]).
diagonals([X1|X],[Y1|Y],[S1|S],[D1|D]):- 
    S1 is X1 + Y1,
    D1 is X1- Y1,
    diagonals(X,Y,S,D).

all_diff([_]).
all_diff([X|Y]) :-
    \+member(X,Y),
    all_diff(Y).
© www.soinside.com 2019 - 2024. All rights reserved.