5
Example - Fibonacci numbers If we want, we can now add a predicate just for computing of F(i) fibonacci(1,1,0). fibonacci(X,R1,R2) :- X1 is X – 1,fibonacci(X1,R2,R3),R1 is R2+R3. fibonacci(0,0). fibonacci(X,R) :- fibonacci(X,R,R1).

7
Example - Fibonacci numbers What, if we want something like this: 0, if i = 0 S(i) = 1,if i = 1 i*S(0)+ (i–1)*S(1)+...+2S(i–1), if i > 1 A predicate that computes all the values S(0)...S(i) at once could be useful...

11
Lists - predefined notation There is also a special shortcut notation for lists in PROLOG.(a,.(b,.(c,[]))) can also be written as [a,b,c]

12
Lists - useful operations Often it is useful to divide non-empty list into the first element (head) and the remaining list (tail) head(.(H,_),H). tail(.(_,T),T).

13
Lists - useful operations There are special predicate “|” that does not require the use of “.” notation head([H|_],H). tail([_|T],T).

14
Lists - useful operations Any fixed number of initial elements can be accessed first_7([F1,F2,F3,F4,F5,F6,F7|_],F1,F2,F3,F4,F5,F6,F7).

15
Lists (from Clocksin) Lists are the same as in other languages (such as ML) in that a list of terms of any length is composed of list cells that are ‘consed’ together. The list of length 0 is called nil, written []. The list of length n is.(head,tail), where tail is a list of length n-1. So a list cell is a functor ‘.’ of arity 2. Its first component is the head, and the second component is the tail.

18
Lists - PROLOG syntax Nil is written []. The list consisting of n elements t 1, t 2, …,t n is written [t 1, t 2, …,t n ]..(X,Y) is written [X|Y] [X|[]] is written [X] The term.(a,.(b,.(c,Y))) is written [a,b,c|Y]. If Y is instantiated to [], then the term is a list, and can be written [a,b,c|[]] or simply [a,b,c].

31
Length of a list - Tail recursion Procedures such as length/2: length([], 0). length([H|T], N) :- length(T, NT), N is NT + 1. often crash when processing large lists, even with a few thousand elements. This happens because in the recursive rule, the recursive call is not the last goal on the rhs and so may need to be backtracked into. For each call, Prolog must store the choice points in a memory stack of fixed size.

32
Length of a list - Tail recursion No matter how large this memory stack is, it will overflow if the list is long enough. This is less likely to happen if the recursive call is the last goal on the rhs - because within each call there is no choice point for it. Procedures in which recursive calls appear as the last goal in the rule(s) are known as tail recursive. There is a way of re-writing procedures such as length/2 to make them tail recursive.

33
Length of a list - Tail recursion The accumulator algorithm for the length of a list is: Initialise the current sub-total, LengthSoFar, to 0. To find the length of L while L is non-empty do for each element of L remove the element and add 1 to LengthSoFar when L is empty set Length = LengthSoFar.