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

Posted

技术标签:

【中文标题】通过给出可能的移动,在列表中移动。序言【英文标题】:Moving within a list, by giving the possible moves. Prolog 【发布时间】:2021-11-27 13:55:28 【问题描述】:

所以我最近开始学习 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 ;

【问题讨论】:

这里需要析取。了解如何使用; @rajashekar You need disjunctions here. Learn how to use ; 这让我想起了这个笑话。 A person is drowning 100 meters off the shore. The lifeguard throws them a line. The by stander notes that the line is only 51 meters long. The lifeguard says, I went more than half way. 虽然; 很好,但没有解释它,它只能获得大约一半的 OP。 :( 另一半可以剪掉!,有条件的-&gt;或更复杂的东西。 @rajashekar 我实现了分号 (;),它给了我 4 种可能的解决方案,但错误。我个人认为我的基本情况不正确。 撞到墙上会发生什么? 感兴趣的:RosettaCode Maze solving - 虽然没有按照您的方式解决迷宫问题,但代码很有价值。 【参考方案1】:
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.

两者是等价的,这更清楚了。

【讨论】:

以上是关于通过给出可能的移动,在列表中移动。序言的主要内容,如果未能解决你的问题,请参考以下文章

UWP 动画列表项移动

想要追踪用户移动的路线

为啥从Vue.js中的列表中删除项目时移动转换需要绝对位置

在列表框中向上或向下移动项目

如何在移动 Safari 的下拉列表中禁用选择选项 [重复]

角度下拉菜单 - 使用键盘上/下键在下拉列表中移动项目