问题
Is it possible to reverse a list in Prolog with only two arguments? Such as:
reverse_list(List, Reversed).
This is not homework, I'm reading Seven Programming Languages in Seven Weeks and I got curious.
With three arguments you could use an accumulator (much like in functional programming):
reverseList([], Accumulator, Accumulator).
reverseList([Head|Tail], Accumulator, Solution) :-
reverseList(Tail, [Head|Accumulator], Solution).
reverseList(List, Solution) :-
reverseList(List, [], Solution).
Clarification: I saw a solution with append, I was wondering if you could do that without other prolog functions
回答1:
sure:
reverseList([[], Accumulator, Accumulator]).
reverseList([[Head|Tail], Accumulator, Solution]) :-
reverseList([Tail, [Head|Accumulator], Solution]).
reverseList([List, Solution]) :-
reverseList([List, [], Solution]).
edit:actually that has only one :b
a non-cheating approach:
reverse([],[]).
reverse([H|T],L):-
reverse(T,R),
append(R,[H],L).
the problem is that the performance will be quite bad: you will recurse over the list and for each element you will do one append/3. using time/1 and a random list of 1,000,000 elements:
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)
回答2:
You can write a rev_list function with two arguments:
rev_list([], []).
rev_list([Head|Tail], Reversed) :- rev_list(Tail, TailReversed),
append(TailReversed, [Head], Reversed).
Maybe you are more familiar with this function if it is in functional programming:
rev x::xs = rev xs @ [x]
However, you should notice that the 3-argument version is preferred because it is tail-recursive.
回答3:
I know I'm late to the party, but there is a way to do this without "cheating" or using append:
rev([], []).
rev([Head], [Head]).
rev([Head|Tail], [RHead|RTail]) :-
rev(Tail, [RHead|RMid]),
rev(RMid, Mid),
rev([Head|Mid], RTail).
It is not very efficient (O(3^n) time), but it is elegant and can even be useful for theorem proving.
来源:https://stackoverflow.com/questions/8046108/is-it-possible-to-reverse-a-list-with-only-two-arguments