Recursion 递归函数中的swipl增量游标

Recursion 递归函数中的swipl增量游标,recursion,prolog,tail-recursion,Recursion,Prolog,Tail Recursion,我对Prolog非常熟悉。我有一个7乘7的网格,对于每个单元格,我存储X,Y,以及其他两个东西,比如:单元格(1,1,0,0) 我想遍历网格并重置未给定的单元格值,因此我创建了以下函数: given(X, Y):- (cell(X, Y, start, _) ; cell(X, Y, end, _)). reset_cell(X, Y):- not(given(X, Y)), cell(X, Y, 0, 0). reset_grid(8, _):- write('finished resetti

我对Prolog非常熟悉。我有一个7乘7的网格,对于每个单元格,我存储
X
Y
,以及其他两个东西,比如:
单元格(1,1,0,0)

我想遍历网格并重置未给定的单元格值,因此我创建了以下函数:

given(X, Y):- (cell(X, Y, start, _) ; cell(X, Y, end, _)).
reset_cell(X, Y):- not(given(X, Y)), cell(X, Y, 0, 0).
reset_grid(8, _):- write('finished resetting').
reset_grid(X, 8):- X1 is X + 1, reset_cell(X1, 1), reset_grid(X1, 1).
reset_grid(X, Y):- reset_cell(X, Y), Y1 is Y + 1, reset_grid(X, Y1).
但这会导致一个无休止的循环,因为在最后一行中,传递给
reset\u grid
函数的参数显然保持在值
1
。我做错了什么

编辑:我忘了提到我这样调用函数:
?-reset\u grid(1,1)。

编辑2:(根据Sergey的指示更新版本):

reset_网格(X,u):-X>7,写入('finished reset')。
重置网格(X,Y):-Y>7,X1是X+1,重置网格(X1,1),重置网格(X1,1)。
重置网格(X,Y):-X<8,Y<8,重置网格单元(X,Y),Y1为Y+1,重置网格(X,Y1)。

问题是,当您有一个调用时,
重置网格(1,8)
,您的
重置网格(X,8)
子句将触发,但之后
重置网格(X,Y)
也会触发

要解决此问题,您可以添加剪切“!”到
reset_网格(X,8)
子句,或将
Y<8
添加到
reset_网格(X,Y)
,或同时执行这两项操作(以获得所谓的“绿色切割”)

调用
reset\u grid(8,8)
reset\u grid(8,8)
将匹配,但之后
reset\u grid(X,Y)
将匹配。以类似的方式固定

更新

尝试将您重置的单元格定义更改为仅记录X和Y。使用以下代码:

reset_cell(X, Y) :- write([X, Y]), nl.
reset_grid(X, _):- X > 7, write('finished resetting').
reset_grid(X, Y):- Y > 7, X1 is X + 1, reset_cell(X1, 1), reset_grid(X1, 1).
reset_grid(X, Y):- X < 8, Y < 8, reset_cell(X, Y), Y1 is Y + 1, reset_grid(X, Y1).

因此循环工作并终止。可能是上次调用重置单元(8,1)时出现的问题。?否则,它将使用
reset\u单元格
谓词本身或从
reset\u单元格
调用的谓词。显示其余代码,以便测试。

我觉得注释中的代码不合适。只需将
Y<8,X<8
添加到答案中原始代码的最后一句。对不起,我无法正确设置代码的格式。是的,我已经添加了代码。请检查我的原始邮件。如果我在最后一行写上(Y),我可以看到Y永远不会递增。非常感谢。你的解决方案有效。这是我在给定(X,Y)的函数内部进行的愚蠢调用(出于测试目的)。因此递归函数调用的是
gived(X,Y)
,而
gived(X,Y)
调用的是递归函数,这就是为什么会有一个无休止的循环。@corneliu您应该避免在prolog“谓词”中使用不正确的“函数”术语。Prolog有谓词,没有函数。它们与函数的作用不同。
reset_cell(X, Y) :- write([X, Y]), nl.
reset_grid(X, _):- X > 7, write('finished resetting').
reset_grid(X, Y):- Y > 7, X1 is X + 1, reset_cell(X1, 1), reset_grid(X1, 1).
reset_grid(X, Y):- X < 8, Y < 8, reset_cell(X, Y), Y1 is Y + 1, reset_grid(X, Y1).
?- reset_grid(1, 1).
[1,1]
[1,2]
[1,3]
[1,4]
[1,5]
[1,6]
[1,7]
[2,1]
[2,1]
[2,2]
[2,3]
[2,4]
[2,5]
[2,6]
[2,7]
[3,1]
[3,1]
[3,2]
[3,3]
[3,4]
[3,5]
[3,6]
[3,7]
[4,1]
[4,1]
[4,2]
[4,3]
[4,4]
[4,5]
[4,6]
[4,7]
[5,1]
[5,1]
[5,2]
[5,3]
[5,4]
[5,5]
[5,6]
[5,7]
[6,1]
[6,1]
[6,2]
[6,3]
[6,4]
[6,5]
[6,6]
[6,7]
[7,1]
[7,1]
[7,2]
[7,3]
[7,4]
[7,5]
[7,6]
[7,7]
[8,1]
finished resetting
true ;
false.