二进制到十进制-Prolog

伊戈尔·博菲尔斯(Igor Beaufils)

我在堆栈上找到了这个:可逆的“二进制到数字”谓词

但是我不明白

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

另外,library(clpfd)有什么作用?

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

提前

潜伏者

在原始的中binary_number([], _, N, N).,这_意味着您无需关心变量的值是多少。如果您使用过binary_number([], X, N, N).(不关心是什么X),Prolog会发出单例变量警告。同样,该谓词从句中说的是,当第一个参数为[](空列表)时,则第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“探索”解决方案。然后,您可以进一步指定要将变量限制到的域。所以,可以说X + Y #= Z + 2和前导可以枚举可能的解决方案XY以及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] ? ;
...

但是,正如评论中指出的那样,它存在终止问题,例如,@false提出了Bs = [1|_], N #=< 5, binary_number(Bs, N).一种解决方案解决方案只是修改了上述内容有助于解决这些终止问题。为了方便起见,我将在此处重申该解决方案:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Prolog:将元素放在列表中以进行十进制到二进制的转换

来自分类Dev

Prolog-二进制加法?

来自分类Dev

Prolog二进制加法

来自分类Dev

十进制到二进制Clojure

来自分类Dev

QBASIC十进制到二进制转换

来自分类Dev

C ++二进制到十进制

来自分类Dev

C ++二进制到十进制?

来自分类Dev

递归二进制到十进制

来自分类Dev

十进制到二进制python算法

来自分类Dev

十进制到二进制Clojure

来自分类Dev

十进制到二进制转换C ++

来自分类Dev

二进制到十进制

来自分类Dev

C ++二进制到十进制?

来自分类Dev

递归二进制到十进制

来自分类Dev

十进制到二进制转换错误

来自分类Dev

C ++中的二进制到十进制

来自分类Dev

二进制到十进制(数量巨大)

来自分类Dev

十进制到二进制:二进制补码,更好的否定表达

来自分类Dev

swi prolog中的二进制数独

来自分类Dev

Prolog-使用DCG处理二进制数据

来自分类Dev

没有预定义方法(JAVA)的二进制到六进制十进制

来自分类Dev

C中的二进制到十进制和十六进制

来自分类Dev

十进制到二进制转换器无法计算大于1023的十进制

来自分类Dev

使用swi-prolog将prolog代码+ C代码编译为二进制

来自分类Dev

Perl十进制转换为二进制

来自分类Dev

十进制转换为二进制

来自分类Dev

十进制转二进制的C程序

来自分类Dev

十进制转二进制

来自分类Dev

十进制转二进制错误输出