【问题标题】:Prolog Binary Addition Issue?Prolog二进制加法问题?
【发布时间】:2012-09-23 04:27:36
【问题描述】:

我有这个作业,我必须用 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 时,在某些条件下(仍在尝试找出它们),似乎没有返回任何结果。但我似乎无法找到我的错误。如果有人能告诉我会很高兴我做错了什么。

【问题讨论】:

  • 而不是 add([HX|TX],[HY|TY], Z) :- HX = 1, HY = 1, ..., 我猜是 add([1|TX], [1|TY], Z) :- 会更优雅。

标签: binary prolog


【解决方案1】:

有3个错误:

  • 规则 #1:应该是 add([],[],[]). 而不是 add([],[], _).。这对于等长列表会失败。
  • 规则#5 和#7:应该是add([HX|TX],[HY|TY], Z) 而不是add([HX|TX],[HY,TY], Z)。当第二个列表 (Y) 包含的元素少于两个时,此操作会失败。

修复这些问题,您的代码应该可以正常运行:请参阅 here

【讨论】:

    【解决方案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 和 rem 2,并在其他一些中添加 数字系统也是如此。

    P.S.:代码取自here

    【讨论】:

      猜你喜欢
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 2021-01-12
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多