此谓词应打印一个大小为N
的列表,其中包含0
和1
的可能排列。
我的问题是:H
的值是否会在每次递归时结转,或者在回溯阶段是否创建值为bit(H)
的列表?
bit(0).
bit(1).
gen(0,[]).
gen(N,[H|T]) :-
N > 0,
bit(H),
N1 is N - 1,
gen(N1,T).
答案 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回溯,你可以画一些替换树来理解它