二进制到十进制 - prolog

Binary to decimal - prolog

我在堆栈上找到了这个:reversible "binary to number" predicate

但是我不明白

:- 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 _ )

另外,library(clpfd) 是做什么的?

为什么是 reverse(Bs0, Bs)?我把它拿走了它仍然可以正常工作...

提前谢谢

在原文中,binary_number([], _, N, N)._表示你不关心变量的值是什么。如果您使用 binary_number([], X, N, N).(不关心 X 是什么),Prolog 将发出单例变量警告。还有,这个predicate从句说的是,当第一个参数是[](空列表)时,那么第3个和第4个参数是统一的

如评论中所述,use_module(library(clpfd)) 导致 Prolog 将库用于 有限域上的约束逻辑编程。您还可以通过 Google 搜索 "prolog clpfd".

找到很多关于它的有用信息

通常,在Prolog中,比较的算术表达式要求表达式被完全实例化:

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

Prolog 将评估并进行比较并得出真或假。如果这些变量中的任何一个没有被实例化,它就会抛出一个错误。同样,对于赋值,is/2 谓词要求右侧表达式可以使用所有实例化的特定变量进行完全评估:

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

使用 CLPFD,您可以获得 Prolog "explore" 解决方案。您还可以进一步指定要将变量限制到哪个域。因此,您可以说 X + Y #= Z + 2,Prolog 可以枚举 XYZ.

中的可能解决方案

顺便说一句,可以对原始实现进行一些重构,以避免每次取幂并消除 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).