我创建了一个函数,其中我调用了几个函数,但是当其中一个函数返回false时,主函数停止并返回false。那么,是否有一种方法可以告诉Prolog如果函数返回false,然后跳过它并检查其余的呢?
详细说明:我正在尝试把15益智游戏作为一个项目,我想要做的功能,给我所有可能的下一步。
最后,我将调用控制空白瓷砖的所有前面的函数。
next_move(Board, Moves):-
swapup(Board,Result),
swapdown(Board,Result),
swapright(Board,Result),
swapleft(Board,Result).我希望这个函数返回下一个可能的动作。
以下是完整的代码:
position([Tile|_], Tile, 0).
position([_|Tail], Tile, Index):-
position(Tail, Tile, Index1),
Index is Index1+1.
swap(Board,I,J,R) :-
same_length(Board,R),
append(BeforeI,[AtI|PastI],Board),
append(BeforeI,[AtJ|PastI],Bs),
append(BeforeJ,[AtJ|PastJ],Bs),
append(BeforeJ,[AtI|PastJ],R),
length(BeforeI,I),
length(BeforeJ,J).
swapup(Board,Result):-
position(Board,0,Index),
Index \=0,
Index \=1,
Index \=2,
Index \=3,
Up is Index-4,
swap(Board,Up,Index,Result).
swapdown(Board,Result):-
position([],0,Index),
Index \=12,
Index \=13,
Index \=14,
Index \=15,
Down is Index+4,
swap(Board, Down, Index, Result).
swapright(Board,Result):-
position([],0,Index),
Index \=3,
Index \=7,
Index \=11,
Index \=15,
Right is Index+1,
swap(Board, Right, Index, Result).
swapleft(Board,Result):-
position([],0,Index),
Index \=0,
Index \=4,
Index \=8,
Index \=12,
Left is Index-1,
swap(Board, Left, Index, Result).
swap(Board,Result) :- swapup(Board,Result).
swap(Board,Result) :- swapdown(Board,Result).
swap(Board,Result) :- swapright(Board,Result).
swap(Board,Result) :- swapleft(Board,Result).
next_move(Board,Moves) :- findall(Result,swap(Board,Result),Moves).发布于 2022-01-01 04:33:19
下面是一个简单的程序:
a.
b :- fail.
c.
g :- a, b, c.我可以问g是否成功:
?- g.
false.事实并非如此。
我可以解决这两种方法。
(1)
g :- a, b, c.
g :- a, c.(2)
g :- a, (b; true), c.无论哪种方式,g现在都成功了:
?- g.
true.更新
这是您发布的代码:
next_move(Board, Moves) :-
swapup(Board,Result),
swapdown(Board,Result),
swapright(Board,Result),
swapleft(Board,Result).在LHS上,您有一个变量Moves,它不在RHS上。Moves永远不能统一,并且始终是一个变量。
让我们暂时忽略这一点,看看swap谓词。
如果假设Result是一个有效的移动,考虑到Board的当前状态,那么当每个swap谓词成功时,next_move(Board, Moves)就会成功,除非您从每个swap谓词获得的移动是相同的,否则这是不可能发生的。
一旦swapup(Board,Result)成功,它将把Result与“交换向上”动作统一起来。然后,您会问swapdown(Board,Result)是否成功。好吧,Result不再是变量了,所以您要问的是,从swapdown获得的Result是否与从swapup获得的Result相同。我猜不是。
你可能需要这样的东西:
next_move(Board,[U,D,R,L]):-
swapup(Board,U),
swapdown(Board,D),
swapright(Board,R),
swapleft(Board,L).但这还不清楚,因为我不知道当你在董事会上的开放空间已经处于边缘时,你得到了什么价值。
很可能你更需要这个:
swap(Board,Result) :- swapup(Board,Result).
swap(Board,Result) :- swadown(Board,Result).
swap(Board,Result) :- swapright(Board,Result).
swap(Board,Result) :- swapleft(Board,Result).
next_move(Board,Moves) :- findall(Result,swap(Board,Result),Moves).但所有这些都是猜测,没有看到完整的代码。
这是你的代码现在有效了。有一些问题。
position/3就是不起作用。
这里有一个版本是这样的:
position(List,Element,Index) :-
position(List,Element,0,Index).
position([Element|_],Element,Index,Index).
position([_|Tail],Element,Counter,Index) :-
Next is Counter + 1,
position(Tail,Element,Next,Index).您总是使用两个索引的相同顺序调用swap/4。你必须确保他们按升序进入。swap/4在任何情况下都不起作用。以下是新版本:
swap(BoardIn,I,J,BoardOut) :-
position(BoardIn,X,I), % find the value `X` at position `I`
position(BoardIn,Y,J), % find the value `Y` at position `J`
append(Left,[X|MiddleEnd1],BoardIn), % find the list that is `Left` of `X`
append(Middle,[Y|End],MiddleEnd1), % find the `Middle` that is left of `Y` and the list `End` that is to the right of `Y`
append(Middle,[X|End],MiddleEnd2), % put `X` between `Middle` and `End`.
append(Left,[Y|MiddleEnd2],BoardOut). % put the `Y` between `Left` & `Middle`.我清理了swap*/2谓词。
swapup(BoardIn,BoardOut):-
position(BoardIn,0,Index),
Up is Index - 4,
Up >= 0,
swap(BoardIn,Up,Index,BoardOut).
swapdown(BoardIn,BoardOut):-
position(BoardIn,0,Index),
Down is Index + 4,
Down =< 15,
swap(BoardIn,Index,Down,BoardOut).
swapright(BoardIn,BoardOut):-
position(BoardIn,0,Index),
Index mod 4 =\= 3,
Right is Index + 1,
swap(BoardIn,Index,Right,BoardOut).
swapleft(BoardIn,BoardOut):-
position(BoardIn,0,Index),
Index mod 4 =\= 0,
Left is Index - 1,
swap(BoardIn,Left,Index,BoardOut).
swap(BoardIn,BoardOut) :- swapup(BoardIn,BoardOut).
swap(BoardIn,BoardOut) :- swapdown(BoardIn,BoardOut).
swap(BoardIn,BoardOut) :- swapright(BoardIn,BoardOut).
swap(BoardIn,BoardOut) :- swapleft(BoardIn,BoardOut).最后,下面是next_move/2谓词:
next_move(BoardIn,Moves) :-
length(BoardIn,16),
position(BoardIn,0,_),
findall(BoardOut,swap(BoardIn,BoardOut),Moves).现在我可以调用这个查询:
?- next_move([1,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15],Result),write(Result).我得到了这个结果:
[[1,5,2,3,4,0,6,7,8,9,10,11,12,13,14,15],[1,2,0,3,4,5,6,7,8,9,10,11,12,13,14,15],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]https://stackoverflow.com/questions/70546872
复制相似问题