Пролог все двоичные числа - PullRequest
1 голос
/ 09 января 2012

Мне нужен предикат, который будет производить все двоичные числа из N цифр.

Например, двоичный предикат (2, L)

вернет L = [[0, 0], [0, 1], [1, 0], [1, 1]].

пожалуйста, не используйте findall ....

Ответы [ 2 ]

2 голосов
/ 09 января 2012

После того, как у вас есть список, представляющий все числа с 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)
   ).
1 голос
/ 09 января 2012

Если вам нужно избежать 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)
...