Prolog迷宫问题:代码从头到尾给出了无限的路径,并且没有回溯

时间:2019-01-07 09:32:24

标签: prolog maze

我正在尝试使用回溯来解决Prolog中的迷宫。

我的问题是,当我运行该程序时,它第一次可以正确运行,但是此后,它将结束位置作为起始位置,并一直从那里寻找路径,因此陷入了无限循环。当两个位置之间不存在路径时,它可以正常工作。我尝试了很多东西,但似乎没有任何效果。这是我的代码:

path(Dest, Dest, _, [], _) :- !.

path([Row0,Col0],[Row1,Col1],M,Path,1) :-
    next_move([Row0,Col0],[Rnew,Cnew]),
    is_available(Rnew, Cnew,Ret),

    write(Rnew),
    write(Cnew),

    not(member([Rnew, Cnew], M)),
    path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).

path([X0,Y0], [X1,Y1], [[X0,Y0]|M], [[X,Y]|Path], 0) :-
    path([X,Y],[X1,Y1],M,Path,1).

示例输出:

?- solves([1,1],[1,7],P).
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7]] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...], 
    [...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...], 
    [...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...], 
    [...|...]|...] .

在执行程序时,如果在两个位置之间存在路径,则应显示所有路径。否则应返回false。如上所示,我的代码进入了无限循环并不断生成路径。

请帮忙,因为我对Prolog的经验不是很丰富。 谢谢。

2 个答案:

答案 0 :(得分:1)

path/5谓词的第一个子句及其第二个子句中的递归调用是错误的。应该是:

path(Dest, Dest, _, [], _) :- !.

path([Row0,Col0],[Row1,Col1],M,[[Rnew,Cnew]|Path],1) :-
    next_move([Row0,Col0],[Rnew,Cnew]),
    is_available(Rnew, Cnew,Ret),

    write(Rnew),
    write(Cnew),

    \+ member([Rnew, Cnew], M),
    path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).

此外,请使用ISO Prolog标准\+/1谓词,而不要使用not/1传统谓词。

答案 1 :(得分:0)

在这里,我什至看到过这篇文章,还有很多讽刺意味-您正在参加PPL课程? :)

通常在序言中不必返回0或1的值来说明语句是对还是错,这隐含了谓词是否已通过。

例如 最好将is_available(Rnew,Cnew,Ret)编写为is_available(Rnew,Cnew)-如果is_available解析为false,则它将停止并开始回溯以寻找其他解决方案(如果没有其他选择)。 / p>

此外,这意味着如果没有解决方案,则在尝试评估迷宫时将打印'false'值。

关于您的输出问题-实际上这不是“中断”;它只是抑制输出! 在运行迷宫求解表达式之前,请尝试在swi终端中运行此代码:

set_prolog_flag(answer_write_options,[max_depth(0)])。

按照SWI-Prolog how to show entire answer (list)?