Elementary List Processing
Elementary List Processing
Searching graphs - 1
Searching graphs - 2
Searching this graph is essentially the same problem
as finding neighbours and friends and searching
family trees:
% 1 - boundary
route(Start, End) :-
path(Start, End).
% 2 - recursive
route(Start, End) :-
path(Start, Via),
route(Via, End).
Searching graphs - 2
Searching this graph is essentially the same problem as
finding neighbours and friends and searching family trees:
% 1 - boundary
friend(Start, End) :-
path(Start, End).
% 2 - recursive
friend(Start, End) :-
path(Start, Via),
friend(Via, End).
Searching graphs - 2
Searching this graph is essentially the same problem as
finding neighbours and friends and searching family trees:
% 1 - boundary
friend(Start, End) :-
friend_of(Start, End).
% 2 - recursive
friend(Start, End) :-
friend_of(Start, Via),
friend(Via, End).
Searching graphs - 2
Searching this graph is essentially the same problem as
finding neighbours and friends and searching family trees:
% 1 - boundary
friend(Person, Friend) :-
friend_of(Person, Friend).
% 2 - recursive
friend(Person, Friend) :-
friend_of(Person, Inter),
friend(Inter, Friend).
Searching graphs - 3
As this is the same problem as finding neighbours
and friends, we’ve seen how Prolog will search for
solutions.
But, what happens if we remove a path, eg:
path(2,5).
and then use the goal:
| ?- route(a, 5).
Unification of lists - 1
Lists are a variable length data structure
– therefore we have to have a method of processing
that doesn’t require us to know how long a list is in
advance.
Method
Refer to the head and tail of a list. In Prolog, this is
written as:
[Head|Tail]
where “|” is the list constructor.
Unification of lists - 2
Simple examples of unification are:
| ?- [a,b,c] = [Head|Tail].
Head = a
Tail = [b,c]
Note the tail is always a list – even if it is empty:
| ?- [a] = [Head|Tail].
Head = a
Tail = []
Unification of lists - 3
We can also specify more than one head:
| ?- [a,b,c] = [Hd1,Hd2|Tail].
Hd1 = a
Hd2 = b
Tail = [c]
Patterns of recursion:
Terminating at the end of the list
% 1 - terminating
len_of_list([], Length, Length).
% 2 - recursive
len_of_list([_Head|Tail],
Length1, Length) :-
Length2 is Length1 + 1,
len_of_list(Tail, Length2, Length).
| ?- len_of_list([a,b,c], 0, L).
L = 3 ;
no
Patterns of recursion:
Terminating when given element is found
| ?- memb(b, [a,b,c]).
yes
Patterns of recursion:
Terminating when given element is found
| ?- memb(Item, [a,b]).
Item = a ;
Item = b ;
no
Patterns of recursion:
Terminating when given number of
elements have been scanned - 1
% 1 – recursive
nth(Count, Item, [_|Tail]) :-
Count > 1,
Count0 is Count - 1,
nth(Count0, Item, Tail).
% 2 – terminating
nth(1, Head, [Head|_]).
Patterns of recursion:
Terminating when given number of
elements have been scanned - 2
| ?- nth(3,Item,[a,b,c,d]).
Item = c ;
no
Sundry examples - 1
– What is the terminating pattern?
– Can it be run “backwards”?
% 1 - terminating
app([], List, List).
% 2 - recursive
app([Head|L1],L2,[Head|L3]) :-
app(L1, L2, L3).
Sundry examples - 2
– What is the terminating pattern?
– Does running this “backwards” make it insert?
% 1 - terminating
delete(Head,[Head|Tail],Tail).
% 2 - recursive
delete(Item, [Head|Tail],
[Head|New_Tail]) :-
delete(Item, Tail, New_Tail).
Summary - 1
Prolog uses recursion widely to do interesting things.
Summary - 2
The list processing procedures can be classified
according to termination criterion:
– empty list
– specified member
– specified position