40
Declarative Programming Lists in PROLOG Autumn 2014

Declarative Programming Lists in PROLOG Autumn 2014

Embed Size (px)

Citation preview

Page 1: Declarative Programming Lists in PROLOG Autumn 2014

Declarative Programming

Lists in PROLOG

Autumn 2014

Page 2: Declarative Programming Lists in PROLOG Autumn 2014

Example - Fibonacci numbers

Fibonacci numbers are defined as follows:

0, if i = 0 F(i) = 1, if i = 1

F(i–1) + F(i – 2), if i > 1

Page 3: Declarative Programming Lists in PROLOG Autumn 2014

Example - Fibonacci numbers

Fibonacci numbers are defined as follows:

0, if i = 0 F(i) = 1, if i = 1

F(i–1) + F(i – 2), if i > 1

fibonacci(0,0).fibonacci(1,1).

fibonacci(X,R) :- X1 is X–1, X2 is X–2, fibonacci(X1,R1), fibonacci(X2,R2),R is R1+R2.

Page 4: Declarative Programming Lists in PROLOG Autumn 2014

Example - Fibonacci numbers

We can try to write a predicate that computesboth values F(i) and F(i – 1)

fibonacci(1,1,0).

fibonacci(X,R1,R2) :- X1 is X–1,fibonacci(X1,R2,R3),R1 is R2+R3.

Page 5: Declarative Programming Lists in PROLOG Autumn 2014

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).

Page 6: Declarative Programming Lists in PROLOG Autumn 2014

Example - Fibonacci numbers

What, if we want something like this:

0, if i = 0S(i) = 1, if i = 1

i*S(0)+ (i–1)*S(1)+...+2S(i–1), if i > 1

Page 7: Declarative Programming Lists in PROLOG Autumn 2014

Example - Fibonacci numbers

What, if we want something like this:

0, if i = 0S(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...

Page 8: Declarative Programming Lists in PROLOG Autumn 2014

Lists - the idea

nil represents the empty listlist(a,nil) represents list alist(a,list(b,nil)) represents list a,blist(a,list(b,list(c,nil))) represents list a,b,c...

Page 9: Declarative Programming Lists in PROLOG Autumn 2014

Example - list of Fibonacci numbers

fibonacci(0,list(0,nil)).fibonacci(1,list(1,list(0,nil))).

fibonacci(X,list(R, list(R1,list(R2,Z)))) :- X1 is X–1, fibonacci(X1,list(R1,list(R2,Z))), R is R1+R2.

Page 10: Declarative Programming Lists in PROLOG Autumn 2014

Lists - predefined notation

[] represents the empty list.(a,[]) represents list a.(a,.(b,[])) represents list a,b.(a,.(b,.(c,[]))) represents list a,b,c...

Page 11: Declarative Programming Lists in PROLOG Autumn 2014

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]

Page 12: Declarative Programming Lists in PROLOG Autumn 2014

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).

Page 13: Declarative Programming Lists in PROLOG Autumn 2014

Lists - useful operations

There are special predicate “|” that does not require the use of “.” notation

head([H|_],H).tail([_|T],T).

Page 14: Declarative Programming Lists in PROLOG Autumn 2014

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).

Page 15: Declarative Programming Lists in PROLOG Autumn 2014

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.

Page 16: Declarative Programming Lists in PROLOG Autumn 2014

Lists - examples (from Clocksin)

nil

.(a, nil)

.(a, .(b, nil)

.(a, .(b, .(c, .(d, .(e. nil)))))

.(a,b) (note this is a pair, not a proper list)

.(a, X) (this might be a list, or might not!)

.(a, .(b, nil)), .(c, nil))

Page 17: Declarative Programming Lists in PROLOG Autumn 2014

Lists can be written as trees

a nil a

b nil

a

b

c

d

e nil

a b a X

a

b nil

a nil

Page 18: Declarative Programming Lists in PROLOG Autumn 2014

Lists - PROLOG syntax

Nil is written [].

The list consisting of n elements t1, t2, …,tn is written [t1, t2, …,tn].

.(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].

Page 19: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 1

Identify the heads and tails of these lists (if any):

[a, b, c]

[a]

[]

[[the, cat], sat]

[[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]

Page 20: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 1

Identify the heads and tails of these lists (if any):

a [b, c]

[a]

[]

[[the, cat], sat]

[[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]

Page 21: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 1

Identify the heads and tails of these lists (if any):

[a, b, c]

a []

[]

[[the, cat], sat]

[[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]

Page 22: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 1

Identify the heads and tails of these lists (if any):

[a, b, c]

[a][] (not a list, so doesn’t have head and tail. nil is a constant)

[[the, cat], sat]

[[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]

Page 23: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 1

Identify the heads and tails of these lists (if any):

[a, b, c]

[a]

[]

[the, cat] [sat]

[[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]

Page 24: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 1

Identify the heads and tails of these lists (if any):

[a, b, c]

[a]

[]

[[the, cat], sat]

[the, cardinal] [pulled, [off]], [each, [plum, coloured], shoe]

Page 25: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 2

For each pair of terms, determine whether they unify, and if so, to which terms are the variables instantiated?

[X, Y, Z] [john, likes, fish]

[cat] [X|Y]

[X,Y|Z] [mary, likes, wine]

[[the,Y]|Z] [[X,answer], [is, here]]

[X, Y, X] [a, Z, Z]

[[X], [Y], [X]] [[a], [X], [X]]

Page 26: Declarative Programming Lists in PROLOG Autumn 2014

Lists - Exercise 2

A variable may be instantiated to any term.

X

Y Zmary

likes

wine []

[mary, likes, wine] [X,Y|Z]

Page 27: Declarative Programming Lists in PROLOG Autumn 2014

“member” predicate

member(X, [X|T]).

member(X, [H|T]) :- member(X, T).

Examples:

?- member(john, [paul, john]).

?- member(X, [paul, john]).

?- member(joe, [marx, darwin, freud]).

?- member(foo, X).

Page 28: Declarative Programming Lists in PROLOG Autumn 2014

“member” predicate

member(X, [X|T]).

member(X, [H|T]) :- member(X, T).

member(X, [X|_]).

member(X, [_|T]) :- member(X, T).

Notice T isn’t ‘used’

Notice H isn’t ‘used’

Page 29: Declarative Programming Lists in PROLOG Autumn 2014

Exercise 3

Here is a mystery predicate. What does it do?

mystery(X, A, B) :- member(X, A), member(X, B).

?- mystery(a, [b, c, a], [p, a, l]).?- mystery(b, [b, l, u, e], [y, e, l, l, o, w]).?- mystery(X, [r, a, p, i, d], [a, c, t, i, o, n]).?- mystery(X, [w, a, l, n, u, t], [c, h, e, r, r, y]).

Page 30: Declarative Programming Lists in PROLOG Autumn 2014

Length of a list - Exercise 4

Naïve method:

length([], 0).

length([H|T], N) :- length(T, NT), N is NT + 1.

Page 31: Declarative Programming Lists in PROLOG Autumn 2014

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.

Page 32: Declarative Programming Lists in PROLOG Autumn 2014

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.

Page 33: Declarative Programming Lists in PROLOG Autumn 2014

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.

Page 34: Declarative Programming Lists in PROLOG Autumn 2014

Length of a list - Exercise 4

Tail-recursive method:

length(L, N) :- acc(L, 0, N).

/* acc(List, LengthSoFar, Length) */

acc([], A, A).acc([H|T], A, N) :- A1 is A + 1, acc(T, A1, N).

Page 35: Declarative Programming Lists in PROLOG Autumn 2014

Length of a list - Exercise 4

?- length([apple, pear], N).

?- length([alpha], 2).

?- length(L, 3).

Modify length to give a procedure sum such that sum(L,N) succeeds if L is a list of integers and N is their sum.

Page 36: Declarative Programming Lists in PROLOG Autumn 2014

“concat” predicate - Exercise 5

Write a predicate for concatenating 2 lists, i.e.

?-concat([a,b,c,d],[1,2,3],Result).

Result = [a,b,c,d,1,2,3] ?

Yes

Page 37: Declarative Programming Lists in PROLOG Autumn 2014

“reverse” predicate - Exercise 6

Write a predicate for reversing a list, i.e.

?-reverse([a,b,c,d],Result).

Result = [d,c,b,a] ?

Yes

Page 38: Declarative Programming Lists in PROLOG Autumn 2014

“sublist” predicate - Exercise 7

Write a predicate that checks whether a given list is

a sublist (in the same order) of another, i.e.

?-sublist([a,b,c,d],[a,c]).

Yes

?-sublist([a,b,c,d],[c,a]).

No

Page 39: Declarative Programming Lists in PROLOG Autumn 2014

“setify” predicate - Exercise 8

Write a predicate that removes duplicate elements from a given list, i.e.

?-setify([a,b,a,a,c,b,a,d],Result).

Result = [a,b,c,d] ?

Yes

Page 40: Declarative Programming Lists in PROLOG Autumn 2014

“split” predicate - Exercise 9

Write a predicate that splits a given list of numbers into lists of odd and even numbers, i.e.

?-split([1,2,3,4,5,5,6,8,7,9,2,3],R1,R2).

R1 = [1,3,5,5,7,9,3],

R2 = [2,4,6,8,2] ?

Yes