这是如何计算的?我试图了解如何在列表中分配H的值

时间:2012-04-02 17:00:33

标签: recursion prolog backtracking

此谓词应打印一个大小为N的列表,其中包含01的可能排列。

我的问题是:H的值是否会在每次递归时结转,或者在回溯阶段是否创建值为bit(H)的列表?

bit(0).
bit(1).
gen(0,[]).
gen(N,[H|T]) :-
   N > 0,
   bit(H),
   N1 is N - 1,
   gen(N1,T).

3 个答案:

答案 0 :(得分:2)

Prolog的执行完全取决于选择点。这里,bit/1谓词在每个递归步骤中留下一个选择点。 当您要求Prolog为您提供另一种解决方案时,它将回到最年轻的选择点。在这里,它不是通过bit/1的第一个子句并将H绑定到0,而是通过第二个子句并将H绑定到1。一旦选择了两个条款,Prolog将返回较旧的选择点等等......直到最终所有选择点都用尽并且程序返回false.

您可以使用trace/0谓词自行尝试:

?- trace, gen(3, Result).

答案 1 :(得分:2)

我可以先给你一个更直接的定义:

gen(N, Xs) :-
   length(Xs, N),
   maplist(between(0,1), Xs).

在此定义中,所有递归部分现在都隐藏在一些内置函数中。第一个目标确保Xs是长度为N的列表。下一个目标确保每个元素介于0和1之间。如果查看答案,您将了解解决方案的枚举顺序:

?- gen(4, Xs).
Xs = [0,0,0,0] ;
Xs = [0,0,0,1] ;
Xs = [0,0,1,0] ;
Xs = [0,0,1,1] ;
Xs = [0,1,0,0] ;
Xs = [0,1,0,1] ;
Xs = [0,1,1,0] ; ...

答案 2 :(得分:0)

这个谓词在二进制系统中生成所有数字(有序)以理解它你必须理解prolog回溯,你可以画一些替换树来理解它