【问题标题】:Creating second list with increment from other list in prolog从序言中的其他列表创建第二个列表
【发布时间】:2021-06-22 11:36:09
【问题描述】:

我正在尝试从 list1 创建 list2,但每个成员都应该有 Z 增量。
如果 Z=1 则:
[1,2,3] -> [2,3,4]

addZ(Z,[X | Xs],[Y | Ys]):-
Y is X+Z,
addZ(Z,Xs,Ys).

如果我尝试addZ(1,[1,2,3],X).,我只会得到否定的答案。

【问题讨论】:

  • 两个列表都为空时会发生什么?您需要使“基本案例”成功。目前,没有什么可以告诉 Prolog 接受这种情况。
  • @DavidTonhofer 谢谢,我添加了addZ(_,[],[]).,现在它可以工作了,但它不会停止而不返回。
  • Prolog 顶层打印第一个答案,但不确定是否还有另一个答案,因此您必须输入 ; 来请求。然而实际上没有第二个答案,所以 Prolog 顶层打印 false。这是预期的,不是问题。您始终可以通过将查询包装到 once/1: once(addZ(1,[1,2,3],X)) 中来要求只输出一个答案。

标签: list prolog


【解决方案1】:

添加基本情况后,按照@DavidTonhofer 的建议,您可以更改谓词前两个参数的顺序以避免虚假选择点(因为 Prolog 应用第一个参数索引来快速缩小下适用条款):

addZ([], _, []).

addZ([X|Xs], Z, [Y|Ys]):-
    Y is X + Z,
    addZ(Xs, Z, Ys).

例子:

?- addZ([1,2,3], 1, Z).
Z = [2, 3, 4].

?- 

【讨论】:

    【解决方案2】:

    一如既往,最有趣的事情始于您使用 CLP,例如

    :- use_module(library(clpz)).
    
    addZ(_, [], []).
    addZ(I, [X|Xs], [Y|Ys]) :- 
        Y #= I + X, 
        addZ(I, Xs, Ys).
    
    

    现在您可以执行以下操作:

    ?- addZ(1, [1, 2, 3], C).
       C = [2,3,4].
    
    ?- addZ(1, [1, 2, X], [X, Y, 9]).
    false.
    
    ?- addZ(4, [1, 2, X], [A, Y, 9]).
       A = 5, Y = 6, X = 5.
    
    ?- addZ(I, [1, 2, X], [5|Ys]).
       I = 4, Ys = [6,_A], clpz:(4+X#=_A).
    

    【讨论】:

      【解决方案3】:

      这是另一个使用maplist/3 和库yall 的解决方案:

      addZ(Z, Xs, Ys):-
        maplist({Z}/[X, Y]>>(Y is X+Z), Xs, Ys).
      

      样本运行

      ?- addZ(1, [1,2,3], X).
      X = [2, 3, 4].
      
      ?- addZ(5, [1,2,3], X).
      X = [6, 7, 8].
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        • 2022-11-17
        • 2022-12-29
        • 1970-01-01
        相关资源
        最近更新 更多