首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何告诉prolog,如果函数返回false,然后跳过它?(15益智游戏)

如何告诉prolog,如果函数返回false,然后跳过它?(15益智游戏)
EN

Stack Overflow用户
提问于 2022-01-01 03:50:08
回答 1查看 83关注 0票数 0

我创建了一个函数,其中我调用了几个函数,但是当其中一个函数返回false时,主函数停止并返回false。那么,是否有一种方法可以告诉Prolog如果函数返回false,然后跳过它并检查其余的呢?

详细说明:我正在尝试把15益智游戏作为一个项目,我想要做的功能,给我所有可能的下一步。

最后,我将调用控制空白瓷砖的所有前面的函数。

代码语言:javascript
复制
next_move(Board, Moves):-
  swapup(Board,Result),
  swapdown(Board,Result),
  swapright(Board,Result),
  swapleft(Board,Result).

我希望这个函数返回下一个可能的动作。

以下是完整的代码:

代码语言:javascript
复制
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).
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-01 04:33:19

下面是一个简单的程序:

代码语言:javascript
复制
a.
b :- fail.
c.

g :- a, b, c.

我可以问g是否成功:

代码语言:javascript
复制
?- g.
false.

事实并非如此。

我可以解决这两种方法。

(1)

代码语言:javascript
复制
g :- a, b, c.
g :- a, c.

(2)

代码语言:javascript
复制
g :- a, (b; true), c.

无论哪种方式,g现在都成功了:

代码语言:javascript
复制
?- g.
true.

更新

这是您发布的代码:

代码语言:javascript
复制
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相同。我猜不是。

你可能需要这样的东西:

代码语言:javascript
复制
next_move(Board,[U,D,R,L]):-
    swapup(Board,U),
    swapdown(Board,D),
    swapright(Board,R),
    swapleft(Board,L).

但这还不清楚,因为我不知道当你在董事会上的开放空间已经处于边缘时,你得到了什么价值。

很可能你更需要这个:

代码语言:javascript
复制
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就是不起作用。

这里有一个版本是这样的:

代码语言:javascript
复制
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在任何情况下都不起作用。以下是新版本:

代码语言:javascript
复制
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谓词。

代码语言:javascript
复制
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谓词:

代码语言:javascript
复制
next_move(BoardIn,Moves) :-
    length(BoardIn,16),
    position(BoardIn,0,_),
    findall(BoardOut,swap(BoardIn,BoardOut),Moves).

现在我可以调用这个查询:

代码语言:javascript
复制
?- next_move([1,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15],Result),write(Result).

我得到了这个结果:

代码语言:javascript
复制
[[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]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70546872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档