List 只有两个参数的列表是否可以反转?

List 只有两个参数的列表是否可以反转?,list,prolog,List,Prolog,在Prolog中,只有两个参数可以反转列表吗?例如: reverse_list(List, Reversed). 这不是家庭作业,我在七周内阅读了七种编程语言,我很好奇 通过三个参数,您可以使用累加器(与函数式编程非常相似): 澄清:我看到了一个带有append的解决方案,我想知道您是否可以在没有其他prolog函数的情况下实现这一点您可以编写一个带有两个参数的revu list函数: rev_list([], []). rev_list([Head|Tail], Reversed) :- r

在Prolog中,只有两个参数可以反转列表吗?例如:

reverse_list(List, Reversed).
这不是家庭作业,我在七周内阅读了七种编程语言,我很好奇

通过三个参数,您可以使用累加器(与函数式编程非常相似):


澄清:我看到了一个带有append的解决方案,我想知道您是否可以在没有其他prolog函数的情况下实现这一点

您可以编写一个带有两个参数的
revu list
函数:

rev_list([], []).
rev_list([Head|Tail], Reversed) :- rev_list(Tail, TailReversed), 
                                       append(TailReversed, [Head], Reversed).
如果在函数式编程中,您可能更熟悉此函数:

reverseList([], Accumulator, Accumulator).
reverseList([Head|Tail], Accumulator, Solution) :-
  reverseList(Tail, [Head|Accumulator], Solution).
reverseList(List, Solution) :-
  reverseList(List, [], Solution).
rev x::xs = rev xs @ [x]
但是,您应该注意到,3参数版本是首选的,因为它是尾部递归的。

当然:

reverseList([[], Accumulator, Accumulator]).
reverseList([[Head|Tail], Accumulator, Solution]) :-
  reverseList([Tail, [Head|Accumulator], Solution]).
reverseList([List, Solution]) :-
  reverseList([List, [], Solution]).
编辑:实际上只有一个:b

非作弊方法:

reverse([],[]).
reverse([H|T],L):-
    reverse(T,R),
    append(R,[H],L).
问题是性能会很差:您将在列表上递归,并且对每个元素执行一个append/3。 使用时间/1和1000000个元素的随机列表:

accumulator:    % 2,000,003 inferences, 0.652 CPU in 0.652 seconds (100% CPU, 3066292 Lips)
arity-2         % 1,000,003 inferences, 0.178 CPU in 0.178 seconds (100% CPU, 5602426 Lips)

我知道我要迟到了,但有一种方法可以做到这一点,而不必“作弊”或使用
append

rev([], []).
rev([Head], [Head]).
rev([Head|Tail], [RHead|RTail]) :-
  rev(Tail, [RHead|RMid]),
  rev(RMid, Mid),
  rev([Head|Mid], RTail).

它不是很有效(
O(3^n)
time),但它很优雅,甚至可以用于定理证明。

请不要在标题中添加伪标记。这就是标记的用途。我看到了一个带有append的解决方案,我想知道您是否可以在没有其他prolog函数的情况下完成它。@重复一下,因为它不使用任何外部函数,所以很容易看到它的功能。我使用了一个类,我记得我们让ACL2证明这个版本等同于追加版本和尾部递归版本。然后我们可以在我们的程序中使用高效的尾部递归方法,但是在证明程序正确性时,让ACL2用这个方法或附加方法(取决于哪个更方便)替换它。