2015-01-05 4 views
1

Я нашел это на стеке: reversible "binary to number" predicateBinary в десятичную - вводная

Но я не понимаю,

:- use_module(library(clpfd)). 

binary_number(Bs0, N) :- 
     reverse(Bs0, Bs), 
     binary_number(Bs, 0, 0, N). 

binary_number([], _, N, N). 
binary_number([B|Bs], I0, N0, N) :- 
     B in 0..1, 
     N1 #= N0 + (2^I0)*B, 
     I1 #= I0 + 1, 
     binary_number(Bs, I1, N1, N). 

Пример запроса:

?- binary_number([1,0,1], N). 
N = 5. 

?- binary_number(Bs, 5). 
Bs = [1, 0, 1] . 

Может кто-нибудь объяснить мне код

Эсперанто: binary_number([], _, N, N). (The _)

Также, что делает библиотека (clpfd)?

И почему reverse(Bs0, Bs)? Я забрал ее он все еще работает отлично ...

ТНХ заранее

+1

Попробуйте 'binary_number ([1,0,0], N)', чтобы увидеть, что требуется 'reverse/2'.Для 'library (clpfd)' смотрите [tag: clpfd]. Есть более простые примеры. 'factorial/2' - хорошее начало. – false

+1

1? - binary_number ([1,0,1,1,0,0,1], L). L = 77. Я сделал это, поэтому я не понимаю, в чем его польза. –

+1

Почему вы смотрите на более сложные запросы? Посмотрите на более простые. – false

ответ

0

В оригинале, binary_number([], _, N, N)., то _ означает, что вы не все равно, что значение переменной. Если вы использовали, binary_number([], X, N, N). (не заботясь о том, что такое X), Prolog выдаст предупреждение о одиночной переменной. Кроме того, что говорится в этом предложении предиката: когда первый аргумент равен [] (пустой список), то третий и четвертый аргументы унифицированы.

Как поясняется в комментариях, use_module(library(clpfd)) заставляет Prolog использовать библиотеку для Программирование логики Constraint по конечным областям. Вы также можете найти много полезной информации об этом через поиск Google «proog clpfd».

Обычно в Прологе, арифметические выражения сравнения требует, чтобы выражения полностью инстанцированы:

X + Y =:= Z + 2. % Requires X, Y, and Z to be instantiated 

Пролог будет оценивать и делать сравнение и выход истинным или ложным. Он выдавал бы ошибку, если бы какая-либо из этих переменных не была создана. Кроме того, для присвоения, то is/2 предиката требует, чтобы выражение правой руки полностью с конкретным анализом переменных все экземплярами:

Z is X + Y. % Requires X and Y to be instantiated 

Использованием CLPFD вы можете иметь решение Пролога «исследовать» для вас. И вы также можете указать, в какой области вы хотите ограничить переменные. Итак, вы можете сказать X + Y #= Z + 2, и Prolog может перечислять возможные решения в X, Y и Z.

Как и в сторону, оригинальная реализация может быть переработан немного, чтобы избежать экспоненциация каждый раз и устранить reverse:

:- use_module(library(clpfd)). 

binary_number(Bin, N) :- 
    binary_number(Bin, 0, N). 

binary_number([], N, N). 
binary_number([Bit|Bits], Acc, N) :- 
    Bit in 0..1, 
    Acc1 #= Acc*2 + Bit, 
    binary_number(Bits, Acc1, N). 

Это хорошо работает для запросов, таких как:

| ?- binary_number([1,0,1,0], N). 

N = 10 ? ; 

no 
| ?- binary_number(B, 10). 

B = [1,0,1,0] ? ; 
B = [0,1,0,1,0] ? ; 
B = [0,0,1,0,1,0] ? ; 
... 

Но, как отмечалось в комментариях, у него есть проблемы с завершением, например, Bs = [1|_], N #=< 5, binary_number(Bs, N). A solution was presented by @false, который просто модифицирует приведенное выше, помогает решить эти проблемы с окончанием. Я буду повторять это решение для удобства:

:- use_module(library(clpfd)). 

binary_number(Bits, N) :- 
    binary_number_min(Bits, 0,N, N). 

binary_number_min([], N,N, _M). 
binary_number_min([Bit|Bits], N0,N, M) :- 
    Bit in 0..1, 
    N1 #= N0*2 + Bit, 
    M #>= N1, 
    binary_number_min(Bits, N1,N, M). 
+1

Thx много для вашей точности и вашего времени. Вы должны быть учителем :) –

+0

Множество проблем с окончанием. См. [This] (http://stackoverflow.com/a/28442760/772868) – false

+0

@ спасибо, я действительно изучу это. Мое редактирование здесь заключалось в том, чтобы принять неубедительное решение, которое я опубликовал ранее, что также имело аналогичные проблемы с завершением и делало его менее неуклюжим. Но вы правы: проблемы завершения остаются. – lurker

Смежные вопросы