2012-01-09 58 views
1

我需要一个谓词,将产生所有的N位数的二进制数字。序言所有的二进制数字

例如谓词二进制(2,L)

将返回L = [[0, 0], [0, 1], [1, 0], [1, 1]]

请不要使用的findall ....

+0

是我的尝试是不正确的,因为我不知道如何生产二进制数 – user1118501 2012-01-09 00:11:29

+0

是这个家庭作业? – salva 2012-01-09 08:47:06

+0

是的,这是作业,我需要一个解决方案,以便我可以看到如何解决,以便我为期末考试做好准备 – user1118501 2012-01-09 11:59:25

回答

1

如果你需要避免findall/3,那么你就需要一个聚合收集二进制数:

binary(N, L) :- 
    collect_binaries(N, [], L). 

然后,您在同一时间产生一个二进制并检查它是否是在汇总列表已经存在:

collect_binaries(N, R, L) :- 
    length(B, N), 
    make_binary(B), % make binary of length N 
    \+ memberchk(B, R), 
    !, 
    collect_binaries(N, [B|R], L). 

如果产生另一二元失败,你做:

collect_binaries(_, L, L). 

生成二进制文件很简单(我使用你在你的问题中提供的格式:0/1值的列表)。您遍历列表中的所有位置,并使用1或0:

make_binary([]). 
make_binary([H|T]) :- 
    member(H, [1,0]), 
    make_binary(T). 

结果:

?- binary(2, L). 
L = [[0, 0], [0, 1], [1, 0], [1, 1]] 
Yes (0.00s cpu) 
2

一旦你有一个代表所有N位数字的列表,生成N的所有号码+1位只是将每个N号码[a,b,c,...]展开为两个N + 1号码:[0,a,b,c,...][1,a,b,c,...]

更新

unfold([], []). 
unfold([H|T], [[0|H], [1|H]|L]) :- 
    unfold(T, L). 

bn(N, L) :- 
    ( N = 0 
    -> L = [[]] 
    ; N1 is N - 1, 
     bn(N1, L1), 
     unfold(L1, L) 
    ).