【问题标题】:Prolog: Increment value in list using nth1/3Prolog:使用 nth1/3 增加列表中的值
【发布时间】:2018-05-08 01:26:23
【问题描述】:

我正在尝试实现一个递归 Prolog 谓词,当给定一个全 0 列表 ResultListDim 元素和另一个值高达 Dim 的列表时,它会在第二个列表中运行并增加 +1 到ResultList 的第 n 个元素并返回 ResultList,到目前为止我有:

increment_list([],_).
increment_list([Element|Tail],ResultList):-
    nth1(Element,ResultList,_ is _+1),
    increment_list(Tail,ResultList).

例如

?-increment_list([1,2,4,3,4],[0,0,0,0]).

会返回:

[1,1,1,2]

我显然遇到的困难和困惑是如何增加值,是否可以在不定义额外谓词或使用单例变量的情况下做到这一点?

【问题讨论】:

  • 不,如果不定义额外的谓词就不可能做到这一点,尽管lambda 库可能会使它更容易。在对nth1/3 的调用中坚持_ is _+1 的想法绝对行不通。请记住,Prolog 将统一这些值,而不是计算它们; is/2 将执行算术运算,但这个表达式在任何地方都没有多大意义,因为您正在丢弃加法的结果。另请记住,Prolog 不会就地评估表达式。这是 Prolog 的核心区别。

标签: list prolog


【解决方案1】:

在 prolog 中,您不能修改列表中的值。你可以这样做:

increment_list([],L,L).
increment_list([H|T],LT,LO):-
    increment_nth(H,1,LT,LT1),
    increment_list(T,LT1,LO).

increment_nth(_,_,[],[]).
increment_nth(I,I,[H1|T1],[H2|T1]):-!, 
    succ(H1,H2).
increment_nth(I,C,[H|T1],[H|T2]):-
    C1 is C+1,
    increment_nth(I,C1,T1,T2).

基本上是一个嵌套循环。在每个循环中,您都会创建一个新列表,它与之前的列表相同,只是您考虑的索引处的值是之前的索引加一。

?- increment_list([1,2,4,3,4,1],[0,0,0,0],LO).
LO = [2, 1, 1, 2]

编辑

感谢 Daniel Lyons,我修改了谓词。

【讨论】:

  • 您的increment_list/3 完全没有必要,您可以删除它并将increment_list_/3 重命名为increment_list/3。另外,我建议succ/2succ(I,I1), succ(H1,H2);这个谓词的优点是它可以递增和递减,并有助于使用其他调用模式制作谓词。虽然很好的解决方案! +1
  • 我无法理解increment_nth,尤其是I1 is I+1H2 is H1+1C1 is C+1,我们究竟在哪里增加最终列表?假设我希望它减少而不是增加它,我应该在哪里更改它我假设它是H1
  • @spacing 你不能在 Prolog 中改变一个变量。使increment_nth/4 起作用的原因是H2T2 结束的第四个参数中发生的事情。您可以将其视为此谓词的返回路径,尽管这只是此处的约定,语言不需要。
  • 最新版本 damiano 添加消除了我的困惑,我在最后一次编辑后能够弄清楚!谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多