通过给出可能的移动,在列表中移动。序言
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。 :( 另一半可以剪掉!
,有条件的->
或更复杂的东西。
@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.
两者是等价的,这更清楚了。
【讨论】:
以上是关于通过给出可能的移动,在列表中移动。序言的主要内容,如果未能解决你的问题,请参考以下文章