addDigits(A,B,X,Y) :- myXor(A,B,X), myAnd(A,B,Y).
myAnd(A,B,R) :- A == 1, B == 1, R is 1.
myAnd(A,B,R) :- A == 0, B == 0, R is 0.
myAnd(A,B,R) :- A == 1, B == 0, R is 0.
myAnd(A,B,R) :- A == 0, B == 1, R is 0.
myOr(A,B,R) :- A == 0, B == 0, R is 0.
myOr(A,B,R) :- A == 0, B == 1, R is 1.
myOr(A,B,R) :- A == 1, B == 0, R is 1.
myor(A,B,R) :- A == 1, B == 1, R is 1.
正确返回x作为2个二进制数字的总和作为携带。现在我知道我需要加法器。现在,我被卡住了。这是我目前拥有的,但不起作用。注意:提示是LSB的开始,但我目前不这样做。
addNumbers([HA|TA],[HB|TB],X) :- adder(HA,HB,Cin,Sum,Cout,X),
append(Sum, X, X),
addNumbers(TA,TB,X).
adder(X,Y,Cin,Sum,Cout) :- addDigits(X,Y,Sum1,Carry1),
addDigits(Sum1, Cin, Sum, Carry2),
myOr(Carry1, Carry2, Cout).
任何帮助/建议将不胜感激。 Cheers
您的轨道很好。您的主要问题是了解典型的植物递归。
,但首先,您的二进制函数:它们是正确的,但是这样更容易,更可读(无论如何您都缺少这一点):
myXor(1,0,1).
myXor(0,1,1).
myXor(1,1,0).
myXor(0,0,0).
在第四种情况下,您的错字是:您用较低的情况“ O”拼写。有了这个定义,您的
myOr
现在,关于递归:您确实需要从LSB开始,否则您甚至不知道要添加哪个位,因为数字不一定是相同的长度。幸运的是,您可以通过将呼叫包裹在
adder
S中来轻松执行此操作:
reverse
这是Prolog中的一个常见模式:addNumbers/3调用addNumbers/5具有递归所需的更多参数。 “ 0”是初始携带,[]是结果的累加器。 这是AddNumbers/5,与您的版本进行了一些更改:
addNumbers(N1, N2, Sum) :-
reverse(N1, N12),
reverse(N2, N22),
addNumbers(N12, N22, 0, [], Sum0),
reverse(Sum0, Sum).
首先,请注意,您需要在此处接收CIN作为输入参数!同样,我们将X0作为“累加器”变量,也就是说,每个递归调用都会增长更长的时间。最终呼叫将具有结果,因此它可以使其成为输出变量。为此,您还需要基本案例:
addNumbers([HA|TA],[HB|TB],Cin,X0,X) :-
adder(HA,HB,Cin,Sum,Cout),
append(X0, [Sum], X1),
addNumbers(TA,TB,Cout,X1,X).
请参阅上面的附加结果不是x1(另一个中间变量),而是x?这是因为它的最终结果,并且将与相同的x整个键统一,然后将其变成整个addnumbers/5调用的输出!不过,我还没有完成它,所以有一些(很少)的工作要做:也需要考虑CIN的基础案件...