# Accumulators

Compare the following two definitions of the
`list-length`

predicate. Do a trace to see how the
result is computed.

list_length1([],0). list_length1([_|Tail],Length) :- list_length1(Tail,TailLength), Length is TailLength + 1.Download knowledge base.

list_length2(List,Length) :- list_length2(List,0,Length). list_length2([],Length,Length). list_length2([_|Tail],Accumulator,Length) :- NewAcc is Accumulator + 1, list_length2(Tail,NewAcc,Length).Download knowledge base.

The main difference that you can observe when doing a trace is
that `list_length1`

computes the result when coming
out of the recursion, while `list_length2`

computes
the result while going into the recursion. At the time where the
bottom of the recursion (the empty list) has been reached, the
length of the list has already been established. To be able to
do this, `list_length2`

uses an *accumulator*,
i.e., an argument for storing intermediate results. In the
beginning, the accumulator is instantiated with 0. In each
recursive call, the accumulator argument is increased by one (to
indicate that one more list element has been processed). By the
time the empty list is reached, the accumulator argument
contains a number corresponding to the length of the list.

The accumulator adds an extra argument to the predicate which has to be instantiated when the predicate is first called. We use a wrapper predicate to do this automatically:

list_length2(List,Length) :- list_length2(List,0,Length).

Define an accumulator version of the predicate
`max/2`

that you had to define in this exercise.

Hint

Define a predicate `mirror(+InList,?OutList)`

which
takes a list as argument and turns it around. For example, the
query `mirror([a,b,c,d],L)`

should yield the answer
`L = [d,c,b,a]`

. Use an accumulator and don't use
`append`

, such that the result is ready when the
empty list is reached.

Hint

Define an accumulator version of the flattening predicate
defined in this exercise.

Hint