Prolog 填充列表(作为一个数组):如果不使用cut,回溯将在给出正确的产品后导致无限递归

Prolog 填充列表(作为一个数组):如果不使用cut,回溯将在给出正确的产品后导致无限递归,prolog,prolog-cut,Prolog,Prolog Cut,我需要用有限个元素初始化一些列表,所有这些都是一样的 fill( 0, [], _ ) :- !. fill( Index, [Value|List], Value ) :- NextIndex is Index - 1, fill( NextIndex, List, Value ). 为了避免无限递归和失败结果,必须进行切割 我试图修改规则#2,但在给出预期解决方案后,目标失败: fill( Index, [Value|List], Value ) :- Index

我需要用有限个元素初始化一些列表,所有这些都是一样的

fill( 0, [], _ ) :- !.
fill( Index, [Value|List], Value ) :-
    NextIndex is Index - 1,
    fill( NextIndex, List, Value ).
为了避免无限递归和失败结果,必须进行切割

我试图修改规则#2,但在给出预期解决方案后,目标失败:

fill( Index, [Value|List], Value ) :-
    Index > 0,
    NextIndex is Index - 1,
    fill( NextIndex, List, Value ).
工作原理:

?- fill( 7, AllFalse, false ).
AllFalse = [false, false, false, false, false, false, false].

?-
虽然没有外部切割,
length/2
将它们设置为生成模式

您正在解构整数值,在检查其值时,始终会创建一个choicepoint。如果有一个自然数在数学上实现如下,那么您可以有一个确定性填充谓词

nat(0).
nat(suc(X)) :- nat(X).

fill_nat(0, [], _).
fill_nat(suc(N), [V|Xs], V) :-
    fill_nat(N, Xs, V).

?- fill_nat(suc(suc(suc(0))), Xs, a).
Xs = [a, a, a].

我相信这是正确的:

fill(0, [], _).
fill(N, [Val|Tail], Val) :- 
    N > 0,
    N2 is N-1,
    fill(N2, Tail, Val).
(这相当于您的第二个版本,没有剪切)

但在给出预期的解决方案后,目标失败了

它给你一个解决方案,如果你想要更多的解决方案,它会说“没有任何解决方案”


苏克?它不是成功的,而是你的选择,只是
继任者的简称。
第一个提议更复杂,在调用中隐藏了削减,它不是一个解决方案。我认为没有确定的解决方案,除非你使用上面的
nat
之类的方法。
length/2
不需要削减,因为它是一个外部实现的函数,但非逻辑性来自它。如果跟踪代码,您将看到回溯和失败。@Aubin它无法找到更多解决方案。这就是为什么它会打印
false
。为什么这是个问题?@Aubin没有无限递归,也没有
。使用单元测试时,会显示一条关于选择点的警告。@Aubin问题出在测试IMO上,但我添加了另一个选项<代码>地图列表
是在我最近的一个问题中定义的。
fill(0, [], _).
fill(N, [Val|Tail], Val) :- 
    N > 0,
    N2 is N-1,
    fill(N2, Tail, Val).
?- fill(2, X, 33).
X = [33, 33] .

?-
?- fill(2, X, 33).
X = [33, 33] ;
false.

?-