【问题标题】:prolog add two list using successor notationprolog 使用后继符号添加两个列表
【发布时间】:2021-05-04 09:08:03
【问题描述】:

我是 prolog 的新手,我正在做一些练习。我在后继符号中添加了两个列表。问题和答案应该以后继符号显示,但为方便起见,我将其写成数字。

  1. 列表([1,1,1,1],[2,2,2,2],[3,3,3,3])
  2. 列表([9,9,9,9],[1,1,1,1],[1,1,1,1,0])

我很容易用后继表示法得到问题二 [10,10,10,10] 的答案,但答案需要我们处理数字,这意味着期望 ans 是 [s(0),s(0 ),s(0),s(0),0].

【问题讨论】:

  • 显示您的部分解决方案。
  • 列表([],[],[])。 List([H1|L1],[H2|L2],[H3|L3]) :- lsum(L1,L2,L3), sum(H1,H2,0,H3)。
  • sum(a,b,c,d) 是一个方程 a+b = c+d。问我们的问题参考上一个问题。
  • [9, 9, 9, 9] 和 [1, 1, 1, 1] 的和不应该是 [1, 1, 1, 1, 0] 吗?
  • 是的,对不起。让我编辑问题。真的很抱歉我的错误

标签: list prolog add


【解决方案1】:

我使用的是简单的结转加法。

add(0, X, X).
add(s(X), Y, s(Z)) :-
    add(X, Y, Z).

% Helper to convert b/w decimal and succ notation.
sform(0, 0).
sform(N, s(S)) :-
    N > 0, N1 is N - 1,
    sform(N1, S).

sumdigits([], [], [], 0).
sumdigits([X|Xs], [Y|Ys], [Z|Zs], C) :-
    sumdigits(Xs, Ys, Zs, C1),
    (C1 = 0 -> add(X, Y, Z1); add(X, s(Y), Z1)),
    (  Z1 = s(s(s(s(s(s(s(s(s(s(Z))))))))))
    -> C = s(0)
    ;  Z1 = Z, C = 0
    ).

sumdigits(Xs, Ys, Zs) :-
    sumdigits(Xs, Ys, Zs1, C),
    (C = 0 -> Zs = Zs1; Zs = [C|Zs1]).
?- maplist(sform, [9, 9, 9, 9], X), maplist(sform, [1, 1, 1, 1], Y), sumdigits(X, Y, Z).
X = [s(s(s(s(s(s(s(s(s(0))))))))), s(s(s(s(s(s(s(s(s(0))))))))), s(s(s(s(s(s(s(s(s(0))))))))), s(s(s(s(s(s(s(s(s(0)))))))))],
Y = [s(0), s(0), s(0), s(0)],
Z = [s(0), s(0), s(0), s(0), 0] 

【讨论】:

  • 我不确定这对初学者有多友好。你确定这个练习适合初学者吗?
  • 另一个要求是不允许在 Prolog 中使用任何内置谓词。我已经根据您的解决方案考虑了一个小时,但仍然无法解决。请给我一些提示好吗?
  • 这是我们拼贴的作业,它在一堂课和一个教程中介绍了序言和声明式编程。目的是让我们尝尝prolog。
  • 我最大的问题是不知道如何将这部分转换为谓词。我可以在我的程序中获得 C1 的值。这部分是内置谓词吗?谢谢 (C1 = 0 -> add(X, Y, Z1); add(X, s(Y), Z1)), ( Z1 = s(s(s(s(s(s(s(s(s(s( s(Z)))))))))-> C = s(0) ; Z1 = Z, C = 0).
  • (A -> B; C) 视为if A then B else C。所以该语句说:如果进位(C1)为零,则Z1 = X+Y,否则Z1 = X+Y+1。接下来说:如果 Z1 大于 10,则将最终进位(C)设置为 1,将 Z 设置为 Z1-10,否则将进位(C)设置为 0,将 Z 设置为 Z1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 2016-01-12
  • 2013-02-07
相关资源
最近更新 更多