6

私はPrologで書かなければならないこの宿題を持っています。要件は次のようなバイナリ加算を行うコードを書くことです:

?- add([1,0,1],[1,1],X).
X = [0,0,0,1]

そして、これは私が思いついたコードです:

add([],[], _).
add([],Y, Z) :- append([], Y, Z).
add(X,[], Z) :- append(X,[],Z).
add([HX|TX],[HY|TY], Z) :-
    HX = 1,
    HY = 1,
    add(TX,TY, Z1),
    add([1],Z1, Z2),
    append([0],Z2,Z),!.
add([HX|TX],[HY,TY], Z) :-
    HX = 0,
    HY = 1,
    add(TX,TY,Z1),
    append([1],Z1, Z),!.
add([HX|TX],[HY|TY], Z) :-
    HX = 1,
    HY = 0,
    add(TX,TY,Z1),
    append([1],Z1, Z),!.
add([HX|TX],[HY,TY], Z) :-
    HX = 0,
    HY = 0,
    add(TX,TY,Z1),
    append([0],Z1, Z),!.

必要なことはやっているようですが、なかなかわからない不思議な問題がありますので、誰かが間違ったことを教えてくれたら嬉しいです。

結果:

?- add([1,1,1,1], [1,1],Z).
Z = [0, 1, 0, 0, 1]. % this is correct

?- add([1], [1],Z).
Z = [0, 1]. % this is correct

?- add([1,1,0,1], [1,1],Z).
Z = [0, 1, 1, 1]. % this is correct

?- add([1],[0],Y).
Y = [1|_G7100]. % there is an error here, but its not the big issue.

?- add([1,0,1], [1,1],Z).   
false. % no results are returned.

    104 ?- add([0], [1],Z).
    false. % no results returned either

問題:最初のバイナリリストに0があるように見えるときはいつでも、いくつかの条件下で(まだそれらを理解しようとしている)、結果が返されないようですが、エラーを見つけることができないようです。誰かが喜んでいるでしょう私が間違ったことを教えてくれます。

4

2 に答える 2

3

3つの間違いがあります:

  • ルール#1:add([],[],[]).の代わりにする必要がありadd([],[], _).ます。これは、同じ長さのリストでは失敗します。
  • ルール#5および#7:add([HX|TX],[HY|TY], Z)の代わりに使用する必要がありadd([HX|TX],[HY,TY], Z)ます。2番目のリスト(Y)に含まれる要素が2つ未満の場合、これは失敗します。

これらを修正すると、コードは正常に実行されるはずです。ここを参照してください。

于 2012-09-23T06:36:04.250 に答える
0

ルール内に2進演算を配置しているため、7つの異なるルールを使用しているようです。次のように、6つの異なるルールと開始ルールを使用できます。

add2(AL, BL, CL) :-
   add2(AL, BL, 0, CL).

add2([A | AL], [B | BL], Carry, [C | CL]) :-
   X is (A + B + Carry),
   C is X rem 2,
   NewCarry is X // 2,
   add2(AL, BL, NewCarry, CL).
add2([], BL, 0, BL) :- !.
add2(AL, [], 0, AL) :- !.
add2([], [B | BL], Carry, [C | CL]) :-
   X is B + Carry,
   NewCarry is X // 2,
   C is X rem 2,
   add2([], BL, NewCarry, CL).
add2([A | AL], [], Carry, [C | CL]) :-
   X is A + Carry,
   NewCarry is X // 2,
   C is X rem 2,
   add2([], AL, NewCarry, CL).
add2([], [], Carry, [Carry]).

実行例を次に示します。

?- add2([1,1,1,1], [1,1],Z).
Z = [0,1,0,0,1]
?- add2([1], [1],Z).
Z = [0,1]
?- add2([1,1,0,1], [1,1],Z).
Z = [0,1,1,1]
?- add2([1],[0],Y).
Y = [1]
?- add2([1,0,1], [1,1],Z).
Z = [0,0,0,1]
?- add2([0], [1],Z).
Z = [1]

上記のソリューションの主な利点は、add2 / 4の呼び出しが少なく、//2とrem2を置き換えて、他の記数法でも加算できることです。

PS:ここから取得したコード。

于 2012-09-24T16:22:40.100 に答える