【发布时间】:2017-03-11 03:39:34
【问题描述】:
我正在处理来自99 Prolog Problems 的问题 26:
P26 (**) 生成从 K 个不同对象中选择的组合 列表的 N 个元素
例子:
?- combination(3,[a,b,c,d,e,f],L). L = [a,b,c] ; L = [a,b,d] ; L = [a,b,e] ;
所以我的程序是:
:- use_module(library(clpfd)).
combination(0, _, []).
combination(Tot, List, [H|T]) :-
length(List, Length), Tot in 1..Length,
append(Prefix, [H], Stem),
append(Stem, Suffix, List),
append(Prefix, Suffix, SubList),
SubTot #= Tot-1,
combination(SubTot, SubList, T).
我的查询结果开始正常,但随后返回全局堆栈错误:
?- combination(3,[a,b,c,d,e,f],L).
L = [a, b, c] ;
L = [a, b, d] ;
L = [a, b, e] ;
L = [a, b, f] ;
Out of global stack
我不明白为什么它一开始可以工作,但后来挂起,直到它给出全局堆栈错误。发生在终端的 SWISH 和 swi-prolog 上。
【问题讨论】:
-
你试过
trace吗?您可能会发现,一旦您的程序找到了解决方案,它就会不断地使用append创建新的、不断增长的列表,它可以尝试以找到它永远无法满足的其他解决方案。你的第一个append(Prefix, [H], Stem)有两个变量,所以它们会无限增长。 -
@lurker,是的,我似乎有
traced,debugged,guitraced 一切,程序总是在生成L = [a, b, f] ;后挂起,直到出现堆栈错误(实际上使用debug作为查询的第一个子句,那么错误就永远不会出现并且永远挂起)。如果我把trace放在append(Prefix, [H], Stem)之前,我会得到以下输出:Call:lists:append(_14580, [_14486], _14584)Call:lists:append(_14592, [_14498], _14596)Call:lists:append(_14604, [_14510], _14608)L = [a, b, c]L = [a, b, d]L = [a, b, d]L = [a, b, e]L = [a, b, f]Out of global stack
标签: prolog permutation combinatorics backtracking failure-slice