declarative programming lists in prolog autumn 2014
Post on 14-Dec-2015
223 Views
Preview:
TRANSCRIPT
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
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.
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.
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).
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
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...
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...
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.
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...
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]
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).
Lists - useful operations
There are special predicate “|” that does not require the use of “.” notation
head([H|_],H).tail([_|T],T).
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).
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.
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))
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
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].
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]
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]
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]
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]
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]
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]
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]]
Lists - Exercise 2
A variable may be instantiated to any term.
X
Y Zmary
likes
wine []
[mary, likes, wine] [X,Y|Z]
“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).
“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’
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]).
Length of a list - Exercise 4
Naïve method:
length([], 0).
length([H|T], N) :- length(T, NT), N is NT + 1.
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.
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.
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.
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).
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.
“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
“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
“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
“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
“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
top related