List 序言:反向列表--can';我找不到错误

List 序言:反向列表--can';我找不到错误,list,prolog,reverse,List,Prolog,Reverse,我想写一个reverse/2函数。这是我的代码,我无法找出错误所在 rev([]). rev([H|T],X):-rev(T,X),append(T,H,_). 输出: rev ([1,2,3,4], X). false. 当List2的元素与List1相反时,rev(?List1,?List2)为true rev(Xs, Ys) :- rev(Xs, [], Ys, Ys). rev([], Ys, Ys, []). rev([X|Xs], Rs, Ys, [_|Bound])

我想写一个
reverse/2
函数。这是我的代码,我无法找出错误所在

rev([]).
rev([H|T],X):-rev(T,X),append(T,H,_).
输出:

rev ([1,2,3,4], X).
false.
List2
的元素与
List1
相反时,
rev(?List1,?List2)
true

rev(Xs, Ys) :-
    rev(Xs, [], Ys, Ys).

rev([], Ys, Ys, []).
rev([X|Xs], Rs, Ys, [_|Bound]) :-
    rev(Xs, [X|Rs], Ys, Bound).
输出:

?- rev([1,2,3,4],X).
X = [4, 3, 2, 1].

?- rev([3,4,a,56,b,c],X).
X = [c, b, 56, a, 4, 3].
第4版
的解释

待命
rev([X|Xs](1),Rs(2),Ys(3),[uu124; Bound](4))

  • [X | Xs]
    (1)
  • 列表1,我们案例中的输入列表(我们可以调用
    rev(Z,[3,2,1])。
  • Rs
    (2)ResultList是一个帮助列表,我们从一个空列表开始,在每次递归调用时,我们从
    [X|Xs](1)
    推送一个成员(添加为头成员)
  • Ys
    (3)List2,输出列表(列表1的反向列表)
  • [|Bound]
    (4)-
    帮助列表
    用于限定
    Ys
    的长度(3)(用于迭代“Ys的长度”次)
  • 在每次递归调用上
    rev(Xs(5),[X|Rs](6),Ys(3),Bound(7))。

    我们将头成员
    X
    [X|Xs]
    (1))推到
    Rs
    [X|Rs]
    (6))的前面, 以及迭代
    Ys
    Bound
    (7),
    [\u124; Bound]
    (4))的下一个成员

    rev([](9),Ys(10),Ys(3),[](12))时,递归结束。
    true

    每个
    [X|Xs]
    (1)(现在列表是空的
    []
    (9))成员按相反的顺序移动到
    Ys
    (10),我们限制了
    Ys(3)
    (使用
    [[u124;绑定](4)
    ,现在它是空的
    []
    (12))


    请注意
    append/3
    -
    append(?List1、List2、List1AndList2)。
    H
    不是
    List2
    时,在您的代码中使用了错误的
    append(T,H,)
    (它是列表的头成员)

    append/2
    append/3
    的示例用法:

    ?- append([[1,2],[3]],X).  % append/2 - Concatenate a list of lists.
    X = [1, 2, 3].
    
    ?- append([4],[5],X).      % append/3 - X is the concatenation of List1 and List2
    
    X = [4, 5].
    

    您不应该在函子名称rev和参数列表之间放置空格。通常这会导致语法错误:

    Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.1)
    SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
    
    ?- rev ([1,2,3],X).
    ERROR: Syntax error: Operator expected
    ERROR: rev
    ERROR: ** here **
    ERROR:  ([1,2,3],X) . 
    
    否则,我认为rev/4解决方案的目标是双向解决方案。如果您不需要此功能,并且希望使用不留下选择点的累加器解决方案,您可以尝试:

    reverse(X, Y) :-
       reverse2(X, [], Y).
    
    reverse2([], X, X).
    reverse2([X|Y], Z, T) :-
       reverse2(Y, [X|Z], T).
    

    请注意,
    rev([])没有任何意义。
    ,对于空列表,它应该是
    rev([],[])。
    您的意思是
    rev([],[])。rev([H | T],X):-rev(T,R),append(R,[H],X)。
    @DennisVash我指的是rev([])。作为列表为emtpy时的退出条件。为什么不起作用?@tgtrmr它从来没有叫过。。。如果要使用append实现反向,请检查Will的注释/3@tgtrmr
    rev([])
    不工作,因为从未调用过它。它从未被调用,因为对
    rev
    的所有调用都有两个参数,而不是一个。Prolog不支持“默认”参数。您能为
    rev/4
    中每个参数的含义添加一些解释吗?@WillNess添加了一些解释谢谢。所以Ys是Xs的倒数,它们的长度是一样的。另外,我猜
    rev/4
    的子句顺序对于生成用例
    rev(A,B)
    的工作很重要。