Date post: | 14-Apr-2018 |
Category: |
Documents |
Upload: | yogesh-bansal |
View: | 215 times |
Download: | 0 times |
of 70
7/27/2019 PrologCh9
1/70
1
Part 1 The Prolog Language
Chapter 9
Operations on Data Structure
7/27/2019 PrologCh9
2/70
2
9.1 Sorting lists
A list can be sorted if there is an ordering relationbetween the items in the list.
Assume that there is an ordering relation
gt( X, Y)meaning the X is greater than Y.
If our items are numbers then the gt relation isdefined as:
gt( X, Y) :- X > Y.
If the items are atoms then we can define:gt( X, Y) :- X @> Y.
Remember that this relation also orderscompound terms.
7/27/2019 PrologCh9
3/70
3
9.1 Sorting lists
Let
sort( List, Sorted)
denote a relation where List is a list of items andSorted is a list of the same items sorted in the
ascending order according to the gt relation.
7/27/2019 PrologCh9
4/70
4
9.1 Sorting lists
To sort a list, List:
Find two adjacent elements, X and Y, in List such thatgt(X, Y) and swap X and Y in List, obtaining List1;then sort List1.
If there is no pair of adjacent elements, X and Y, inList such that gt(X, Y), then List is already sorted.
Bubble sort:
bubblesort( List, Sorted) :-
swap( List, List1), !,bubblesort( List1, Sorted).
bubblesort( Sorted, Sorted).
swap([X, Y| Rest], [Y, X| Rest]) :- gt( X, Y).
swap([Z|Rest],[Z|Rest1]) :- swap( Rest, Rest1).
7/27/2019 PrologCh9
5/70
5
9.1 Sorting lists| ?- bubblesort([3,5,2,4], L).
1 1 Call: bubblesort([3,5,2,4],_24) ?2 2 Call: swap([3,5,2,4],_93) ?3 3 Call: gt(3,5) ?4 4 Call: 3>5 ?4 4 Fail: 3>5 ?3 3 Fail: gt(3,5) ?3 3 Call: swap([5,2,4],_80) ?4 4 Call: gt(5,2) ?5 5 Call: 5>2 ?5 5 Exit: 5>2 ?
4 4 Exit: gt(5,2) ?3 3 Exit: swap([5,2,4],[2,5,4]) ?2 2 Exit: swap([3,5,2,4],[3,2,5,4]) ?6 2 Call: bubblesort([3,2,5,4],_24) ?7 3 Call: swap([3,2,5,4],_223) ?8 4 Call: gt(3,2) ?9 5 Call: 3>2 ?9 5 Exit: 3>2 ?8 4 Exit: gt(3,2) ?7 3 Exit: swap([3,2,5,4],[2,3,5,4]) ?10 3 Call: bubblesort([2,3,5,4],_24) ?11 4 Call: swap([2,3,5,4],_326) ?
12 5 Call: gt(2,3) ?13 6 Call: 2>3 ?13 6 Fail: 2>3 ?12 5 Fail: gt(2,3) ?12 5 Call: swap([3,5,4],_313) ?13 6 Call: gt(3,5) ?14 7 Call: 3>5 ?14 7 Fail: 3>5 ?13 6 Fail: gt(3,5) ?13 6 Call: swap([5,4],_339) ?14 7 Call: gt(5,4) ?
15 8 Call: 5>4 ?15 8 Exit: 5>4 ?14 7 Exit: gt(5,4) ?13 6 Exit: swap([5,4],[4,5]) ?12 5 Exit: swap([3,5,4],[3,4,5]) ?11 4 Exit: swap([2,3,5,4],[2,3,4,5]) ?16 4 Call: bubblesort([2,3,4,5],_24) ?17 5 Call: swap([2,3,4,5],_483) ?18 6 Call: gt(2,3) ?19 7 Call: 2>3 ?19 7 Fail: 2>3 ?
18 6 Fail: gt(2,3) ?18 6 Call: swap([3,4,5],_470) ?19 7 Call: gt(3,4) ?20 8 Call: 3>4 ?20 8 Fail: 3>4 ?19 7 Fail: gt(3,4) ?19 7 Call: swap([4,5],_496) ?20 8 Call: gt(4,5) ?21 9 Call: 4>5 ?21 9 Fail: 4>5 ?20 8 Fail: gt(4,5) ?20 8 Call: swap([5],_522) ?
21 9 Call: swap([],_548) ?21 9 Fail: swap([],_548) ?20 8 Fail: swap([5],_522) ?19 7 Fail: swap([4,5],_496) ?18 6 Fail: swap([3,4,5],_470) ?17 5 Fail: swap([2,3,4,5],_471) ?16 4 Exit: bubblesort([2,3,4,5],[2,3,4,5]) ?10 3 Exit: bubblesort([2,3,5,4],[2,3,4,5]) ?6 2 Exit: bubblesort([3,2,5,4],[2,3,4,5]) ?1 1 Exit: bubblesort([3,5,2,4],[2,3,4,5]) ?
L = [2,3,4,5]
(94 ms) yes{trace}
7/27/2019 PrologCh9
6/70
6
9.1 Sorting lists
To sort a non-empty list, L = [X|T]:
Sort the tail T ofL.
Insert the head, X, ofL into the sorted tail at such aposition that the resulting list is sorted. The result is
the whole sorted list.
Insertion sort:
insertsort( [], []).
insertsort( [X|Tail], Sorted) :-
insertsort( Tail, SortedTail),insert( X, SortedTail, Sorted).
insert(X, [Y| Sorted], [Y| Sorted1]) :-
gt( X, Y), !, insert( X, Sorted, Sorted1).
insert(X, Sorted, [X|Sorted]).
7/27/2019 PrologCh9
7/70
7
9.1 Sorting lists| ?- insertsort([3,5,2,4], L).
1 1 Call: insertsort([3,5,2,4],_24) ?2 2 Call: insertsort([5,2,4],_93) ?3 3 Call: insertsort([2,4],_117) ?4 4 Call: insertsort([4],_141) ?5 5 Call: insertsort([],_165) ?5 5 Exit: insertsort([],[]) ?6 5 Call: insert(4,[],_191) ?6 5 Exit: insert(4,[],[4]) ?4 4 Exit: insertsort([4],[4]) ?7 4 Call: insert(2,[4],_220) ?8 5 Call: gt(2,4) ?9 6 Call: 2>4 ?9 6 Fail: 2>4 ?8 5 Fail: gt(2,4) ?7 4 Exit: insert(2,[4],[2,4]) ?3 3 Exit: insertsort([2,4],[2,4]) ?
8 3 Call: insert(5,[2,4],_249) ?9 4 Call: gt(5,2) ?10 5 Call: 5>2 ?10 5 Exit: 5>2 ?9 4 Exit: gt(5,2) ?
11 4 Call: insert(5,[4],_236) ?12 5 Call: gt(5,4) ?13 6 Call: 5>4 ?
13 6 Exit: 5>4 ?12 5 Exit: gt(5,4) ?14 5 Call: insert(5,[],_313) ?14 5 Exit: insert(5,[],[5]) ?11 4 Exit: insert(5,[4],[4,5]) ?8 3 Exit: insert(5,[2,4],[2,4,5]) ?2 2 Exit: insertsort([5,2,4],[2,4,5]) ?15 2 Call: insert(3,[2,4,5],_24) ?16 3 Call: gt(3,2) ?17 4 Call: 3>2 ?17 4 Exit: 3>2 ?16 3 Exit: gt(3,2) ?18 3 Call: insert(3,[4,5],_421) ?19 4 Call: gt(3,4) ?20 5 Call: 3>4 ?20 5 Fail: 3>4 ?19 4 Fail: gt(3,4) ?
18 3 Exit: insert(3,[4,5],[3,4,5]) ?15 2 Exit: insert(3,[2,4,5],[2,3,4,5]) ?1 1 Exit:insertsort([3,5,2,4],[2,3,4,5]) ?
L = [2,3,4,5]
(94 ms) yes{trace}
7/27/2019 PrologCh9
8/70
8
9.1 Sorting lists
The sorting procedures bubblesort and insertsortare simple, but inefficient. (time complexity is n2).
A much better sorting algorithm is quicksort.
For example:[5,3,7,8,1,4,7,6]
[3,7,8,1,4,7,6]
[3,1,4] [7,8,7,6]
[1,3,4] [6,7,7,8]
[1,3,4,5,6,7,7,8]
Delete X, X=5
sort sort
split all > 5all
7/27/2019 PrologCh9
9/70
9
9.1 Sorting lists
To sort a non-empty list, L: Delete some element X from L and split the rest
ofL into two lists, called Small and Big, asfollows:
All elements in L that are greater then X belongto Big,
And all others to Small.
Sort Small obtaining SortedSmall.
Sort Big obtaining SortedBig. The whole sorted list is the concatenation of
SortedSmall and [X| SortedBig].
7/27/2019 PrologCh9
10/70
10
9.1 Sorting lists
Quick sort:
% Figure 9.2 Quicksort.
quicksort( [], []).
quicksort( [X|Tail], Sorted) :-split( X, Tail, Small, Big),
quicksort( Small, SortedSmall),
quicksort( Big, SortedBig),
conc( SortedSmall, [X|SortedBig], Sorted).
split( X, [], [], []).split( X, [Y|Tail], [Y|Small], Big) :-
gt( X, Y), !, split( X, Tail, Small, Big).
split( X, [Y|Tail], Small, [Y|Big]) :-
split( X, Tail, Small, Big).
7/27/2019 PrologCh9
11/70
11
9.1 Sorting lists| ?- quicksort([3,5,2,4], L).
1 1 Call: quicksort([3,5,2,4],_24) ?2 2 Call: split(3,[5,2,4],_95,_96) ?3 3 Call: gt(3,5) ?4 4 Call: 3>5 ?4 4 Fail: 3>5 ?3 3 Fail: gt(3,5) ?3 3 Call: split(3,[2,4],_123,_82) ?4 4 Call: gt(3,2) ?5 5 Call: 3>2 ?
5 5 Exit: 3>2 ?4 4 Exit: gt(3,2) ?6 4 Call: split(3,[4],_110,_82) ?7 5 Call: gt(3,4) ?8 6 Call: 3>4 ?8 6 Fail: 3>4 ?7 5 Fail: gt(3,4) ?7 5 Call: split(3,[],_110,_188) ?7 5 Exit: split(3,[],[],[]) ?6 4 Exit: split(3,[4],[],[4]) ?3 3 Exit: split(3,[2,4],[2],[4]) ?
2 2 Exit: split(3,[5,2,4],[2],[5,4])?8 2 Call: quicksort([2],_257) ?9 3 Call: split(2,[],_283,_284) ?9 3 Exit: split(2,[],[],[]) ?10 3 Call: quicksort([],_308) ?10 3 Exit: quicksort([],[]) ?11 3 Call: quicksort([],_333) ?11 3 Exit: quicksort([],[]) ?12 3 Call: conc([],[2],_361) ?12 3 Exit: conc([],[2],[2]) ?
8 2 Exit: quicksort([2],[2]) ?13 2 Call: quicksort([5,4],_387) ?
14 3 Call: split(5,[4],_413,_414) ?15 4 Call: gt(5,4) ?16 5 Call: 5>4 ?16 5 Exit: 5>4 ?15 4 Exit: gt(5,4) ?17 4 Call: split(5,[],_400,_491) ?17 4 Exit: split(5,[],[],[]) ?14 3 Exit: split(5,[4],[4],[]) ?18 3 Call: quicksort([4],_517) ?19 4 Call: split(4,[],_543,_544) ?
19 4 Exit: split(4,[],[],[]) ?20 4 Call: quicksort([],_568) ?20 4 Exit: quicksort([],[]) ?21 4 Call: quicksort([],_593) ?21 4 Exit: quicksort([],[]) ?22 4 Call: conc([],[4],_621) ?22 4 Exit: conc([],[4],[4]) ?18 3 Exit: quicksort([4],[4]) ?23 3 Call: quicksort([],_647) ?23 3 Exit: quicksort([],[]) ?24 3 Call: conc([4],[5],_675) ?
25 4 Call: conc([],[5],_662) ?25 4 Exit: conc([],[5],[5]) ?24 3 Exit: conc([4],[5],[4,5]) ?13 2 Exit: quicksort([5,4],[4,5]) ?26 2 Call: conc([2],[3,4,5],_24) ?27 3 Call: conc([],[3,4,5],_719) ?27 3 Exit: conc([],[3,4,5],[3,4,5]) ?26 2 Exit: conc([2],[3,4,5],[2,3,4,5]) ?1 1 Exit: quicksort([3,5,2,4],[2,3,4,5]) ?
L = [2,3,4,5] ?
(78 ms) yes{trace}
7/27/2019 PrologCh9
12/70
12
9.1 Sorting lists
Quick sort:
If the list is split into two lists of approximately equallengths then the time complexity of this sortingprocedure is of the order nlogn, where n is the length
of the list to be sorted. If splitting always results in one list far bigger than the
other, then the complexity is in the order ofn2.
The program in Figure 9.2 is not a goodimplementation because using the concatenationoperation.
The program in Figure 9.3 is a more efficientimplementation ofquicksort using difference-pairrepresentation for list.
7/27/2019 PrologCh9
13/70
13
9.1 Sorting lists
To use the difference-pair representation in thesorting procedure, the list in the program of Figure9.2 can be represented by pairs of lists of the formA-Z as follows (see Page 186):
SortedSmall is represented by A1
Z1SortedBig is represented by A2 Z2
The resulting concatenated list is represented by
A1 Z2 (and Z1 = [X|A2])
L1 L2
A1 Z1 A2 Z2
L3
7/27/2019 PrologCh9
14/70
14
9.1 Sorting lists
% Figure 9.3 A more efficient implementation of quicksort usingdifference-pair representation for lists.
quicksort( List, Sorted) :-quicksort2( List, Sorted - [] ).
quicksort2( [], Z - Z).quicksort2( [X | Tail], A1 - Z2) :-
split( X, Tail, Small, Big),quicksort2( Small, A1 - [X | A2] ),quicksort2( Big, A2 - Z2).
split( X, [], [], []).
split( X, [Y|Tail], [Y|Small], Big) :-
gt( X, Y), !, split( X, Tail, Small, Big).
split( X, [Y|Tail], Small, [Y|Big]) :-
split( X, Tail, Small, Big).
7/27/2019 PrologCh9
15/70
15
9.1 Sorting lists|?- quicksort([3,5,2,4], L).
1 1 Call: quicksort([3,5,2,4],_24) ?2 2 Call: quicksort2([3,5,2,4],_24-[]) ?3 3 Call: split(3,[5,2,4],_122,_123) ?4 4 Call: gt(3,5) ?5 5 Call: 3>5 ?5 5 Fail: 3>5 ?4 4 Fail: gt(3,5) ?4 4 Call: split(3,[2,4],_150,_109) ?
5 5 Call: gt(3,2) ?6 6 Call: 3>2 ?6 6 Exit: 3>2 ?5 5 Exit: gt(3,2) ?7 5 Call: split(3,[4],_137,_109) ?8 6 Call: gt(3,4) ?9 7 Call: 3>4 ?9 7 Fail: 3>4 ?8 6 Fail: gt(3,4) ?8 6 Call: split(3,[],_137,_215) ?8 6 Exit: split(3,[],[],[]) ?
7 5 Exit: split(3,[4],[],[4]) ?4 4 Exit: split(3,[2,4],[2],[4]) ?3 3 Exit: split(3,[5,2,4],[2],[5,4]) ?9 3 Call: quicksort2([2],_24-[3|_250]) ?10 4 Call: split(2,[],_315,_316) ?10 4 Exit: split(2,[],[],[]) ?11 4 Call: quicksort2([],_24-[2|_306]) ?11 4 Exit: quicksort2([],[2|_306]-[2|_306]) ?12 4 Call: quicksort2([],_306-[3|_250]) ?
12 4 Exit: quicksort2([],[3|_250]-[3|_250]) ?9 3 Exit: quicksort2([2],[2,3|_250]-[3|_250]) ?
13 3 Call: quicksort2([5,4],_250-[]) ?14 4 Call: split(5,[4],_428,_429) ?15 5 Call: gt(5,4) ?16 6 Call: 5>4 ?16 6 Exit: 5>4 ?15 5 Exit: gt(5,4) ?17 5 Call: split(5,[],_415,_506) ?17 5 Exit: split(5,[],[],[]) ?14 4 Exit: split(5,[4],[4],[]) ?18 4 Call: quicksort2([4],_250-[5|_498]) ?19 5 Call: split(4,[],_563,_564) ?19 5 Exit: split(4,[],[],[]) ?20 5 Call: quicksort2([],_250-[4|_554]) ?20 5 Exit: quicksort2([],[4|_554]-[4|_554]) ?21 5 Call: quicksort2([],_554-[5|_498]) ?21 5 Exit: quicksort2([],[5|_498]-[5|_498]) ?18 4 Exit: quicksort2([4],[4,5|_498]-
[5|_498]) ?
22 4 Call: quicksort2([],_498-[]) ?22 4 Exit: quicksort2([],[]-[]) ?13 3 Exit: quicksort2([5,4],[4,5]-[]) ?2 2 Exit: quicksort2([3,5,2,4],[2,3,4,5]-[]) ?1 1 Exit: quicksort([3,5,2,4],[2,3,4,5]) ?
L = [2,3,4,5] ?
(31 ms) yes{trace}
7/27/2019 PrologCh9
16/70
16
9.2 Representing sets by binary trees
A disadvantage of using a list for representing a setis that the set membership testing is relativelyinefficient.
Using the predicate member( X, L) to find X in a
list L is very inefficient because this procedure scansthe list element by element until X is found or theend of the list is encountered.
For representing sets, there are various treestructures that facilitate more efficient
implementation of the set membership relation.
We will here consider binary trees.
7/27/2019 PrologCh9
17/70
17
9.2 Representing sets by binary trees
A binary tree is either empty or it consists of threethings:
A root;
A left subtree;
A right subtree.
The root can be anything, but the subtrees have to bebinary tree again.
a
c
d
b
Rightsubtree
Leftsubtree
root
7/27/2019 PrologCh9
18/70
18
9.2 Representing sets by binary trees
The representation of a binary tree:
Let the atom nil represent the empty tree.
Let the functor be t so the tree that has a root X, a leftsubtree L, and a right subtree Ris represented by the
term t(L, X, R).
Xt( L, X, R)
L R
a
c
d
b
t( t( nil, b, nil), a, t( t( nil, d, nil), c, nil))
7/27/2019 PrologCh9
19/70
19
9.2 Representing sets by binary trees
Let use consider the set membership relation in. Agoal
in( X, T)
is true ifX is a node in a tree T.
X is in tree T if The root of T is X, or
X is in the left subtree of T, or
X is in the right subtree of T.
in( X, t( _, X, _)).
in( X, t( L, _, _)) :- in( X, L).
in( X, t( _, _, R)) :- in( X, R).
The goal in( X, nil) will fail for any X.
7/27/2019 PrologCh9
20/70
7/27/2019 PrologCh9
21/70
7/27/2019 PrologCh9
22/70
7/27/2019 PrologCh9
23/70
23
9.2 Representing sets by binary trees
% Figure 9.7 Finding an item X in a binary dictionary.
in( X, t( _, X, _) ).
in( X, t( Left, Root, Right) ) :-
gt( Root, X), in( X, Left).
in( X, t( Left, Root, Right) ) :-
gt( X, Root), in( X, Right).
The relation gt( X, Y) means X is greater than Y.
The in procedure itself can be also used forconstructing a binary dictionary. For example:
| ?- in( 5, D), in( 3, D), in( 8, D).
D = t(t(_,3,_),5,t(_,8,_)) ?
(16 ms) yes
7/27/2019 PrologCh9
24/70
24
9.2 Representing sets by binary trees
5
3 8
3
5
8
| ?- in( 5, D), in(3, D), in(8, D).D = t(t(_,3,_),5,t(_,8,_)) ?(16 ms) yes
| ?- in( 3, D), in(5, D), in(8, D).D = t(_,3,t(_,5,t(_,8,_))) ?yes
7/27/2019 PrologCh9
25/70
25
9.2 Representing sets by binary trees
A tree is (approximately) balanced if, for each nodein the tree, its two subtrees accommodate() an
approximately equal number of items.
If a dictionary with n nodes is nicely balanced then
its height is proportional to logn.
If the tree gets out of balance its performance willdegrade.
In extreme cases of totally unbalanced trees, a treeis reduced to a list. In such a case the trees height
is n, and the trees performance is equally poor asthat of a list.
7/27/2019 PrologCh9
26/70
26
9.3 Insertion and deletion in a binary
trees
When maintaining a dynamic set of data we mayinsert new items into the set and delete some olditems from the set.in( X, S) X is a member of S
add( S, X, S1) Add X to S giving S1del( S, X, S1) Delete X from S giving S1
add relation: Insert nodes into a binary dictionaryat the leaf level
5
3 8
5
3 8
6
add(D1, 6, D2)
D1D2
7/27/2019 PrologCh9
27/70
7/27/2019 PrologCh9
28/70
7/27/2019 PrologCh9
29/70
29
9.3 Insertion and deletion in a binary
trees
% Figure 9.10 Inserting an item as a leaf into the binarydictionary.
addleaf( nil, X, t( nil, X, nil)).
addleaf( t( Left, X, Right), X, t( Left, X, Right)).
addleaf( t( Left, Root, Right), X, t( Left1, Root, Right)) :-
gt( Root, X),
addleaf( Left, X, Left1).
addleaf( t( Left, Root, Right), X, t( Left, Root, Right1)) :-
gt( X, Root),
addleaf( Right, X, Right1).
7/27/2019 PrologCh9
30/70
7/27/2019 PrologCh9
31/70
7/27/2019 PrologCh9
32/70
32
9.3 Insertion and deletion in a binary
trees
Consider delete operation:
It is easy to delete a leaf, but deleting an internal nodeis more complicated.
The deletion of a leaf can be in fact defined as theinverse operation of inserting at the leaf level:
delleaf( D1, X, D2) :- addleaf( D2, X, D1) What happens if X is an internal node?
A
X
Left Right
A
?
Left Right
Delete X
7/27/2019 PrologCh9
33/70
7/27/2019 PrologCh9
34/70
7/27/2019 PrologCh9
35/70
35
9.3 Insertion and deletion in a binary
trees
Another elegant() solution ofadd:
The add relation can be defined non-deterministicallyso that a new item is inserted at any level of the tree,not just at the leaf level.
To add X to a binary dictionary D either: Add X at the root ofD (so that X becomes the new
root), or
If the root ofD is greater than X than insert X into theleft subtree ofD, otherwise insert X into the rightsubtree ofD.
7/27/2019 PrologCh9
36/70
7/27/2019 PrologCh9
37/70
7/27/2019 PrologCh9
38/70
7/27/2019 PrologCh9
39/70
7/27/2019 PrologCh9
40/70
7/27/2019 PrologCh9
41/70
7/27/2019 PrologCh9
42/70
7/27/2019 PrologCh9
43/70
7/27/2019 PrologCh9
44/70
44
9.3 Insertion and deletion in a
binary trees
| ?- add(nil, 3, D1), add(D1, 5, D2), add(D2, 1, D3), add(D3, 6, D),show( D).
65
31
D = t(t(nil,1,t(t(nil,3,nil),5,nil)),6,nil)D1 = t(nil,3,nil)D2 = t(t(nil,3,nil),5,nil)D3 = t(nil,1,t(t(nil,3,nil),5,nil)) ? ;
65
3
1D = t(nil,1,t(t(t(nil,3,nil),5,nil),6,nil))D1 = t(nil,3,nil)D2 = t(t(nil,3,nil),5,nil)D3 = t(nil,1,t(t(nil,3,nil),5,nil)) ? ;
6
1
3
5
7/27/2019 PrologCh9
45/70
45
9.3 Insertion and deletion in a
binary trees
6
5
3
1
D = t(nil,1,t(t(nil,3,nil),5,t(nil,6,nil)))
D1 = t(nil,3,nil)
D2 = t(t(nil,3,nil),5,nil)D3 = t(nil,1,t(t(nil,3,nil),5,nil)) ? ;
6
5
3
1D = t(t(t(nil,1,t(nil,3,nil)),5,nil),6,nil)
D1 = t(nil,3,nil)
D2 = t(t(nil,3,nil),5,nil)
D3 = t(t(nil,1,t(nil,3,nil)),5,nil) ? ;
7/27/2019 PrologCh9
46/70
7/27/2019 PrologCh9
47/70
7/27/2019 PrologCh9
48/70
48
9.5 Graphs
9.5.1 Representing graphs
The representation of graphs:
Method 1:
connected( a, b),
connected( b, c),
arc( s, t, 3),arc( t, v, 1),
Method 2:
G1 = graph([a,b,c,d], [e(a,b), e(b,d), e(b,c), e(c,d)])
G2 = digraph([s, t, u, v], [a(s,t,3), a(t,v,1), a(t,u,5),a(u,t,2), a(v,u,2)])
Method 3:
G1 = [a->[b], b->[a,c,d], c->[b,d], d->[b,c]]
G2 = [s->[t/3], t->[u/5,v/1], u->[t/2],v->[u/2]]
The symbols -> and / are infix operators.
a
b
c
d
s
t
v
u
3 1
25
2
G1 G2
7/27/2019 PrologCh9
49/70
49
9.5 Graphs
9.5.1 Representing graphs
What is the most suitable representation? Depending on the application and on operations to be
performed on graphs.
Two typical operations are:
Find a path between two given nodes;
Find a subgraph, with some specified properties, of agraph.
7/27/2019 PrologCh9
50/70
7/27/2019 PrologCh9
51/70
7/27/2019 PrologCh9
52/70
7/27/2019 PrologCh9
53/70
53
9.5.2 Finding a path
The adjacent( X, Y, G) relation If G is represented as a pair of sets,
G = graph( Nodes, Edges)
then
adjacent( X, Y, graph( Nodes, Edges)) :-
member( e( X, Y), Edges)
;member( e( Y, X), Edges).
For example
| ?- G1 = graph([a,b,c,d], [e(a,b), e(b,d), e(b,c), e(c,d)]),
path(a, d, G1, Path).
G1 = graph([a,b,c,d],[e(a,b),e(b,d),e(b,c),e(c,d)])Path = [a,b,d] ? ;
G1 = graph([a,b,c,d],[e(a,b),e(b,d),e(b,c),e(c,d)])Path = [a,b,c,d] ? ;
no
a
b
c
d
7/27/2019 PrologCh9
54/70
7/27/2019 PrologCh9
55/70
7/27/2019 PrologCh9
56/70
7/27/2019 PrologCh9
57/70
7/27/2019 PrologCh9
58/70
58
9.5.2 Finding a path
| ?- G1 = graph([a,b,c,d], [e(a,b), e(b,d), e(b,c), e(c,d)]),path(a, c, G1, Path, C).
C = 2
G1 = graph([a,b,c,d],[e(a,b),e(b,d),e(b,c),e(c,d)])Path = [a,b,c] ? ;
C = 3
G1 = graph([a,b,c,d],[e(a,b),e(b,d),e(b,c),e(c,d)])
Path = [a,b,d,c] ? ;
(16 ms) no
a
b
c
d
7/27/2019 PrologCh9
59/70
59
9.5.2 Finding a path
We can fine the minimum cost path:
| ?- G1 = graph([a,b,c,d], [e(a,b), e(b,d), e(b,c), e(c,d)]),path(a, c, G1, MinPath, MinCost),
not(( path( a,c, G1, _, Cost), Cost < MinCost)).
G1 = graph([a,b,c,d],[e(a,b),e(b,d),e(b,c),e(c,d)])
MinCost = 2
MinPath = [a,b,c] ? ;
no
a
b
c
d
7/27/2019 PrologCh9
60/70
7/27/2019 PrologCh9
61/70
7/27/2019 PrologCh9
62/70
7/27/2019 PrologCh9
63/70
9 3 Fi di i f
7/27/2019 PrologCh9
64/70
64
9.5.3 Finding a spanning tree of a
graph
% Figure 9.22 Finding a spanning tree of a graph: an `algorithmic'program. The program assumes that the graph is connected.
stree( Graph, Tree) :-member( Edge, Graph), spread( [Edge], Tree, Graph).
spread( Tree1, Tree, Graph) :-addedge( Tree1, Tree2, Graph), spread( Tree2, Tree, Graph).
spread( Tree, Tree, Graph) :- not addedge( Tree, _, Graph).
addedge( Tree, [A-B | Tree], Graph) :-adjacent( A, B, Graph),node( A, Tree), not node( B, Tree).
adjacent( Node1, Node2, Graph) :-member( Node1-Node2, Graph);member( Node2-Node1, Graph).
node( Node, Graph) :- adjacent( Node, _, Graph).
9 5 3 Fi di i t f
7/27/2019 PrologCh9
65/70
65
9.5.3 Finding a spanning tree of a
graph
| ?- stree([a-b, b-c, b-d, c-d], Tree).Tree = [b-d,b-c,a-b] ? ;Tree = [b-d,b-c,a-b] ? ;Tree = [c-d,b-c,a-b] ? ;Tree = [b-c,b-d,a-b] ? ;
Tree = [b-c,b-d,a-b] ? ;Tree = [d-c,b-d,a-b] ? ;Tree = [b-a,b-d,b-c] ? ;
| ?- G = [a-b, b-c, b-d, c-d], stree( G, Tree).G = [a-b,b-c,b-d,c-d]Tree = [b-d,b-c,a-b] ? ;G = [a-b,b-c,b-d,c-d]Tree = [b-d,b-c,a-b] ? ;G = [a-b,b-c,b-d,c-d]Tree = [c-d,b-c,a-b] ? ;G = [a-b,b-c,b-d,c-d]Tree = [b-c,b-d,a-b] ? ;
a
b
c
d
a
b
c
d
7/27/2019 PrologCh9
66/70
7/27/2019 PrologCh9
67/70
9 5 3 Fi di i t f
7/27/2019 PrologCh9
68/70
68
9.5.3 Finding a spanning tree of a
graph
% Figure 9.23 (con.) Finding a spanning tree of a graph: a`declarative' program. Relations node and adjacent are as in Figure9.22.
adjacent( Node1, Node2, Graph) :-member( Node1-Node2, Graph);member( Node2-Node1, Graph).
node( Node, Graph) :-adjacent( Node, _, Graph).
path( A, Z, Graph, Path) :-path1( A, [Z], Graph, Path).
path1( A, [A | Path1], _, [A | Path1] ).
path1( A, [Y | Path1], Graph, Path) :-adjacent( X, Y, Graph),not member( X, Path1),path1( A, [X, Y | Path1], Graph, Path).
9 5 3 Fi di i t f
7/27/2019 PrologCh9
69/70
69
9.5.3 Finding a spanning tree of a
graph
| ?- stree1([a-b, b-c, b-d, c-d], Tree).
Tree = [a-b,b-d,c-d] ? ;Tree = [a-b,b-c,c-d] ? ;Tree = [a-b,b-c,b-d] ? ;
(31 ms) no
| ?- G1 = [a-b, b-c, b-d, c-d], stree1(G1, Tree).
G1 = [a-b,b-c,b-d,c-d]
Tree = [a-b,b-d,c-d] ? ;G1 = [a-b,b-c,b-d,c-d]Tree = [a-b,b-c,c-d] ? ;G1 = [a-b,b-c,b-d,c-d]Tree = [a-b,b-c,b-d] ? ;no
a
b
c
d
a
b
c
d
9 5 3 Fi di i t f
7/27/2019 PrologCh9
70/70
9.5.3 Finding a spanning tree of a
graph
| ?- covers([a-b, b-c], [a-b, b-c, a-c]).yes
| ?- covers([a-b, b-c], [a-b, a-c]).yes
| ?- covers([a-b, b-c], [a-b, b-c]).yes
| ?- covers([a-b, b-c], [a-b, b-c, c-d]).no
| ?- covers([a-b], [a-b, b-c]).
no
| ?- subset([a-b, b-c, a-c], [a-b, b-c]).true ?yes
| ?- subset([a-b, b-c, a-c], [a-b, a-c]).true ?
yes
| ?- subset([a-b, b-c, a-c], [a-c, a-c]).no
| ?- subset([a-b, b-c, a-c], [a-c, a-b]).no