如何在寻找多个答案时避免出现全局堆栈错误?

时间:2016-04-11 18:42:08

标签: prolog failure-slice

使用SWI-Prolog加载以下程序并输入

等查询
cells([o,x,o,x,o], A).

cells(A, [o,x,o,x,o]).

第一个结果似乎总是正确的,但在提交分号以寻找更多结果后(我不知道在任何一种情况下是否应该有其他结果),我得到一个PROLOG SYSTEM ERROR提到垃圾收集和分别超出全局堆栈错误。

regla(o,o,o,o).
regla(x,o,o,x).
regla(o,x,o,o).
regla(o,o,x,x).
regla(x,o,x,x).
regla(x,x,o,x).
regla(o,x,x,x).
regla(x,x,x,o).

cells([X | XS], [Y | YS]) :-
    X = o,
    Y = o,
    length([X | XS], LX),
    LX >= 3,
    length([Y | YS], LY),
    LY is LX + 2,
    append([o, o], [X | XS], W),
    append(W, [o, o], Z),
    cellsR(Z, [Y | YS]).

cellsR(_, []).
cellsR([A, B, C | R], [H | T]) :-
    regla(A, B, C, H),
    cellsR([B, C | R], T).

我假设错误与处理递归的方式有关,所以也许有人可以查看代码并告诉我哪里出错了。

1 个答案:

答案 0 :(得分:3)

我的第一个建议:不要使用示踪剂。它对你没什么帮助。终止比逐步跟踪器向您显示的要复杂得多。让我告诉你程序没有终止的原因,首先:

cells([X | XS], [Y | YS]) :-
    X = o,
    Y = o,
    length([X | XS], LX),
    LX >= 3,
    length([Y | YS], LY), false,
    LY is LX + 2,
    append([o, o], [X | XS], W),
    append(W, [o, o], Z),
    cellsR(Z, [Y | YS]).

这突出显示了您 要修改以解决问题的程序部分。换句话说,只要你保持这部分不变,你的问题就不会消失。

最小的改变是添加另一个目标,在使用length/2之前首先确定这两个列表的长度之间的关系:

cells([X | XS], [Y | YS]) :-
    X = o,
    Y = o,
    list_samelength([_,_|XS], YS),
    length([X | XS], LX),
    LX >= 3,
    length([Y | YS], LY),
    LY is LX + 2,
    append([o, o], [X | XS], W),
    append(W, [o, o], Z),
    cellsR(Z, [Y | YS]).

list_samelength([], []).
list_samelength([_|Xs], [_|Ys]) :-
   list_samelength(Xs, Ys).

有关此技术的更多信息,请参阅