二进制到十进制 - 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 可以枚举 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).
我在堆栈上找到了这个: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 可以枚举 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).