Binary Prolog-二进制加法?
我需要编写一个Prolog谓词来计算列表中表示的2个二进制数的总和。 列表已经颠倒,例如([0,1]base 2)=(2 base 10) 例如,它应该与模式二进制_plus(+、+、-)一起工作Binary Prolog-二进制加法?,binary,prolog,addition,Binary,Prolog,Addition,我需要编写一个Prolog谓词来计算列表中表示的2个二进制数的总和。 列表已经颠倒,例如([0,1]base 2)=(2 base 10) 例如,它应该与模式二进制_plus(+、+、-)一起工作 ?- binary_plus([1,1],[1],X). X = [0,0,1]. ?- binary_plus(X,X,[0,1]). X = [1]. 和模式二进制加(-,,+),例如 ?- binary_plus([1,1],[1],X). X = [0,0,1]. ?- binary_p
?- binary_plus([1,1],[1],X).
X = [0,0,1].
?- binary_plus(X,X,[0,1]).
X = [1].
和模式二进制加(-,,+),例如
?- binary_plus([1,1],[1],X).
X = [0,0,1].
?- binary_plus(X,X,[0,1]).
X = [1].
Im不允许使用剪切符号、findall、否定或if-then-else
这是我的密码:
is_binary([]).
is_binary([X]):- X is 1.
is_binary([X|Xs]):-
append(_,[1],Xs),
member(X,[0,1]),
is_binary(Xs).
binary_plus([],X,X):-
is_binary(X).
binary_plus(X,[],X):-
is_binary(X).
binary_plus([0|Xs],[Y|Ys],[Y|Zs]):-
binary_plus(Xs,Ys,Zs).
binary_plus([1|Xs],[0|Ys],[1|Zs]):-
binary_plus(Xs,Ys,Zs).
binary_plus([1|Xs],[1|Ys],[0|Zs]):-
binary_plus(Xs,[1],Ws),
binary_plus(Ws,Ys,Zs).
我不知道我错在哪里,因为有些奇怪的问题我无法解决,
如果有人能帮我,我会很感激的。
谢谢。 < P>当描述列表时,总是考虑使用DCG表示法。例如,在你的情况下,考虑把这个写为:
:- use_module(library(clpfd)).
binary_addition(Xs, Ys, As) :-
phrase(binary_addition_(Xs, Ys, 0), As).
binary_addition_([], [], 0) --> [].
binary_addition_([], [], 1) --> [1].
binary_addition_([X|Xs], [], C) --> binary_addition_([X|Xs], [C], 0).
binary_addition_([], [Y|Ys], C) --> binary_addition_([C], [Y|Ys], 0).
binary_addition_([X|Xs], [Y|Ys], C0) -->
{ [X,Y] ins 0..1,
Sum #= X + Y + C0 },
sum_carry(Sum, C),
binary_addition_(Xs, Ys, C).
sum_carry(0, 0) --> [0].
sum_carry(1, 0) --> [1].
sum_carry(2, 1) --> [0].
示例查询及其解决方案:
?- binary_addition([1,0],[0,1,1], Sum).
Sum = [1, 1, 1] .
?- binary_addition([1,1],[1,0,1], Sum).
Sum = [0, 0, 0, 1] .
?- binary_addition([0,1],[1,1], Sum).
Sum = [1, 0, 1] .
请注意,它也在另一个方向工作:
?- binary_addition(Xs, Ys, [1,1]).
Xs = [1, 1],
Ys = [] ;
Xs = [],
Ys = [1, 1] ;
Xs = [_G2510, 1],
Ys = [_G2522],
_G2510 in 0..1,
_G2510+_G2522#=1,
_G2522 in 0..1 ;
etc.
如果您想要反向列表,只需将
reverse/2
目标添加到binary\u addition/3
。这里是我对没有任何内容的二进制加法的理解。我理解您不能使用clpfd:
binary_plus(A,B,C) :- binary_plus_0(A,B,C).
binary_plus_0([], [], []).
binary_plus_0([], [B|Bs],[B|Bs]).
binary_plus_0([A|As],[], [A|As]).
binary_plus_0([A|As],[B|Bs],[C|Cs]) :- binary_plus_0(A,B,C,As,Bs,Cs).
binary_plus_0(0,0,0,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(0,1,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(1,0,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(1,1,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1([], [], [1]).
binary_plus_1([], [B|Bs],Cs) :- binary_plus_0([1],[B|Bs],Cs).
binary_plus_1([A|As],[], Cs) :- binary_plus_0([A|As],[1],Cs).
binary_plus_1([A|As],[B|Bs],[C|Cs]) :- binary_plus_1(A,B,C,As,Bs,Cs).
binary_plus_1(0,0,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_1(0,1,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1(1,0,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1(1,1,1,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
非常感谢您的快速回答!!但是我刚刚开始使用prolog,我不允许使用这种技术。我编辑了我的帖子。@DaniLiat,mat的解决方案没有任何你的问题所说的不允许使用的结构。
是二进制([X]):-X是1。
应该是是二进制([X]):-X=1。
或者更好,是二进制([1])。
。术语X是1
是表达式赋值。尽管它碰巧起作用,=/2
是为了统一,这是您想要的。+1是为了非常明智的要求,不使用/0
,如果是,则其他,等等。!这些结构通常会使程序变得非单调且不那么通用。在SWI Prolog中,这留下了一个选择点:?-binary_plus([0,1,1],[0,0,1],X)。X=[0,1,0,1];错-(:-(在我的Prolog系统中,(+,+,-)模式查询没有留下选择点。但是,(+,-,+)查询有一些非规范化的结果:?-binary_plus([0,1,1],X[0,1,0,1])。X=[0,0,1];X=[0,0,1,0]。这可能是可以修复的吗?