通过给出可能的移动在列表中移动。序言

Moving within a list, by giving the possible moves. Prolog

所以我最近开始学习 Prolog,我有一个关于做一个谓词的问题,这个谓词给你所有可能的解决方案(下一步行动),因为当前点是给定的。最好的例子是迷宫。所以这是我的数据,它告诉我 5x5 迷宫中的 'w = white' 和 'b = black':

grid([ [w, w, w, b, w],
    [b ,b, w, w, w],
    [w, w, w, b, w],
    [w, b, b, b, b],
    [w, w, w, w, w] ]). 

我还实现了一个名为 white/1 的谓词,它告诉我迷宫中的给定点是否为白色:

white(X/Y) :-
    grid(M),
    nth1(X, M, Line),
    nth1(Y, Line, w).

我现在想做的是做一个谓词,让我在迷宫中找到所有可能的动作。例如,如果我查询:

?- move(5/2, NextState).
NextState = 4/2 ;
NextState = 5/1 ;
NextState = 5/3 ;
No

这是我的代码,但它给出了错误,我知道这是完全错误的,但我不知道如何实现这样的谓词:

move(5/5, _).

move(X/Y, NextState) :-
    white(X/Y),
    X1 is X + 1,
    X1 =< 5,
    move(X1/Y, NextState),
    Y1 is Y + 1,
    Y1 =< 5,
    move(X/Y1, NextState),
    X2 is X - 1,
    X2 >= 5,
    move(X2/Y, NextState),
    Y2 is Y - 1,
    Y2 >= 0,
    move(X/Y2, NextState).

如果有人能帮助我,我将不胜感激! :)

编辑:

move(X/Y, _) :-
    white(X/Y).

move(X/Y, X/Y) :-
    X1 is X + 1,
    move(X/Y, X1/Y);
    X2 is X - 1,
    move(X/Y, X2/Y);
    Y1 is Y + 1,
    move(X/Y, X/Y1);
    Y2 is Y - 1,
    move(X/Y, X/Y2).

如果我查询它给我:

?- move(3/3, NextState).
true ;
NextState = 3/3 ;
NextState = 3/3 ;
NextState = 3/3 ;
NextState = 3/3 ;
move(X/Y, X1/Y1, Xm/Ym) :-
    X1 is X + 1, Y1 = Y, X1 =< Xm;
    X1 is X - 1, Y1 = Y, X1 > 0;
    X1 = X, Y1 is Y + 1, Y1 =< Ym;
    X1 = X, Y1 is Y - 1, Y1 > 0.

对于上述谓词中的每一行,我们都有一个新的方向。 Xm/Ym 是迷宫的边界。

| ?- move(5/2, X, 5/5).

X = 4/2 ? ;

X = 5/3 ? ;

X = 5/1

yes

您可以删除 Xm/Ym 作为参数,然后将 5 放在正文中。或者你可以定义一个新的谓词

move1(Current, Next) :- move(Current, Next, 5/5)

除了析取,我们还可以写多个子句。

move(X/Y, X1/Y) :- X1 is X + 1, X1 =< 5.
move(X/Y, X1/Y) :- X1 is X - 1, X1 > 0.
move(X/Y, X/Y1) :- Y1 is Y + 1, Y1 =< 5.
move(X/Y, X/Y1) :- Y1 is Y - 1, Y1 > 0.

两者是等价的,这个更清楚