Programming Assignment 2.
Assigned Nov 16, Due Nov 30.
Thanks to Ashwin Srinivasan who first developed these exercises as part
of a set of labs at Oxford University, for a course taught by Ashwin,
Stephen Muggleton and myself.
From the CS instructional machines (e.g., the king machines), you can
load Yap Prolog by typing yap at the prompt. Or you can download Yap
onto your laptop (Google "Yap Prolog"). You can enter your program
into a file (in this example, called "filename") and then typing at
the Yap prompt either:
consult(filename).
or
[filename].
You can then run any predicate in your program by typing a goal to it; for example, if the predicate is a binary predicate p, you can type:
p(a,b).
and hit the Enter key to run it.
Exercise 1.
Consider the map below:
___________________________________
 1 
 
 ______________________ 
  2  5  
  ______   
      
 ___ 4 ____  
  ______   
  ______ 
  3  6  
 _____________________ 
___________________________________
We want to colour this map with the four colours red, green,
blue and yellow. No two adjacent countries are to have the
same colour. The colourings allowed can be considered exten
sionally as a set of ordered 6tuples, with each entry
representing a colour for each region.
Consider the following sets:
Colour = {red, green, blue, yellow}
DiffColour = {  x in Colour and y in Colour, and x =/= y}
Define the set Map as a set of ordered 6tuples, where each
argument corresponds to a colour for that region, and adja
cent regions have a different colour. Somewhat informally:
Map = {  x1..x6 in Colour and
in DiffColour
for all i and j that share a border}
Write definitions for Colour using a unary (monadic) predicate.
Write definitions for DiffColour using a binary predicate.
Now complete this definition for Map:
map(X1,X2,X3,X4,X5,X6):
.....
Check an assignment of colours to regions 1..6 is consistent
with the requirements.
In fact, you should be able to do better than just check a
particular assignment. What does the following Prolog query
accomplish:
map(C1,C2,C3,C4,C5,C6).
Exercise 2.
Consider the following definitions:
bachelor(X): not(married(X)), male(X).
married(john).
male(john).
male(bill).
Does the following query succeed correctly:
bachelor(X).
What about:
bachelor(bill).
and
bachelor(john).
What happens if the definition of bachelor was written as:
bachelor(X): male(X), not(married(X)).
Recall the warning about the idiosyncratic behaviour of not.
We now have a rule that MUST be followed when using not:
There should be NO uninstantiated variables in the call to
not.
Prolog's theoremprover is not guaranteed to be correct if
this rule is not followed.
Exercise 3.
In relational databases all data are represented in tables
called relations. Here are 2 such relations:
teaches:
INSTRUCTOR COURSE
Wallen Logic
Wallen Proof Theory
Muggleton Logic Programming
Hoare Software Eng
Jones Hardware
takes:
STUDENT COURSE GRADE
Adams Logic A
Adams Logic Prog B
Arnold Logic B
Arnold Proof Theory C
Arnold Software Eng A
Milton Software Eng A
The column headings are called "attributes". The set of all
attributes is called a "scheme". So, the scheme for "takes"
is {STUDENT, COURSE, GRADE}. A row of a relation, like
is called a tuple.
Represent the table above as a set of definiteclause facts.
Does your representation lose any information over that pro
vided in the table?
A relational algebra is a system of operators that take one
or two relations as arguments and return a relation as a
result. Select, project, and join are fundamental
operations of a relational algebra.
Select pulls out a subset of the tuples in a relation based
on some selection condition. This condition is either 1) a
comparison between an attribute (that is, column heading)
and a constant; or 2) a comparison between two attributes.
Project is similar to select, but pulls out a subset of the
columns of a relation, rather than a subset of the tuples.
Join combines two relations on common attributes in their
schemes. A tuple t is in the join of two relations r and s
if t agrees with some tuple in r on the scheme of r and with
some tuple in s on the scheme of s. The scheme of the join
of r and s is the union of the schemes of r and s.
Many simple queries can now be expressed with just with
these three operators.
Which sequence of the 3 operations will be needed to
represent the statement:
The students who have taken a course with Wallen.
Usually 3 additional binary operators are needed: Union, In
tersect, and Difference. All these operate on relations with
the same scheme, with set operations on the sets of tuples
in argument relations.
Any query language that can perform Select, Project,
Union, Intersect, and Difference is termed Relationally
complete (Join can be implemented using the others).
Prolog is one such "relationally complete" language. Let us
look at how relational operators can be written in this
language. We shall represent the operators with a predicate
called result.
Result is a predicate that has an argument for each attri
bute in the result of any algebraic expression that uses the
relational operators. For example, to find the courses that
Wallen teaches (a selection):
result(wallen,C):
teaches(wallen,C).
This is an example where Select with an equality condition
(in this case INSTRUCTOR = Wallen) is done by putting a con
stant (here wallen) in the position corresponding to the at
tribute involved.
Select with an inequality condition will require some addi
tional predicate to test the condition. For example:
result(S,C,G):
takes(S,C,G), lteq(G,c).
Project is handled by defining the result predicate to con
tain only the columns of interest.
Represent a Project operation that gives the list of grades
in the various courses.
Now try Join. Represent a join to connect students with the
instructors of their courses.
A relational algebra expression involving Project, Select,
and Join can often be written as a single definiteclause.
Write a clause representing:
The students who have taken a course with Wallen.
Exercise 4.
Consider now the courses students want, and those that are
are available to them.
Write definite clause statements for the following rela
tions:
wants:
STUDENT COURSE
Adams Semantics
Adams Proofs and Types
Arnold Semantics
Arnold Proofs and Types
Milton Requirements
avail:
STUDENT COURSE
Adams Semantics
Arnold Proofs and Types
Milton Semantics
Milton Proofs and Types
How can you represent the operations:
wants Union avail
wants Intersect avail
What about:
wants Diff avail
Consider an "employee" relation with scheme {EMPLOYEE'S
NAME, IMMEDIATE BOSS'S NAME}. Is it possible to define in a
relational algebra the relation "below" with scheme
{EMPLOYEE'S NAME, BOSS'S NAME} such that it contains all
pairs of names where the second is somewhere above the first
in the company's heirarchy?
Can you define the "below" relation with a pair of
definiteclauses?
Exercise 5.
In this exercise, you will see how you can execute the de
finitions of simple arithmetic functions. It is possible to
treat numbers as any other constant, and functions and
predicates on them just like any other predicates. But the
naming scheme of Zero = the constant symbol 0, One = s(0),
Two = s(s(0)) is cumbersome. It would be much better to name
them using the standard IndoArabic conventions. Prolog al
lows this.
Next, what do we do with predicates for comparing numbers.
Do we declare them explicitly each time, for the numbers
that we want, or do we "preload" these into Prolog. If so,
how many entries do we consider preloading (comparisons of
all integers upto 2^32 perhaps?)
For all practical purposes, you may assume that Prolog has
access to a (nearly) infinite table of such facts. How it
does it is not really our concern here. Sufficient to say
that, given a pair of numbers, Prolog "looksup" its inter
nal table, and returns the truthvalue of the comparison.
Prolog has the standard comparison functions > and <, as well as
the builtin functions +,,* and /. A larger math library is
available (you can find it by doing a Google search).
There is one more predicate that you may not have spotted.
The infix predicate is/2 is used all the time when dealing with numbers
in Prolog. This predicate is used to evaluate arithmetic expres
sions. To understand this, try entering the following at the
prompt:
X = 2 + 3.
Now try:
X is 2 + 3.
So, the moral is as follows: if you want an arithmetic ex
pression to be evaluated, then you must use is/2.
Those of you who are used to programming in imperative
languages like Pascal, Fortran, C etc. may also walk into
another trap. Now it is quite common in those languages to
decrement the value of a variable, and assign the new value
back to the same variable. For example, in Pascal:
x := 2 + 3;
x := x  1;
leaves the variable x with the value 4. Now from what you
have just seen, you know that the is/2 predicate has to be
used to achieve the effect of := . What happens when Prolog
is given the following conjunction:
X is 2 + 3, X is X  1.
What about:
X is 2 + 3, Y is X  1.
Let us now look at using these functions and predicates to
execute the definitions of some simple arithmetic functions.
Greatest Common Divisor of numbers x,y:
Definition:
gcd(x,y) = x if x = y
= gcd(x,yx) if x < y
= gcd(y,x) if x > y
This function will be specified by a predicate gcd(X,Y,Z):
true if Z is the greatest common divisor of X and Y
Write a 3 clause definition for gcd/3. You will need the
"builtin" predicates 0
The factorial function will be specified by the predicate
factorial(N,F): true if F is the factorial of N
Write a 2 clause definition for the factorial function.
Verify its correctness by checking the factorial of the
first 10 natural numbers.
Fibonacci numbers
Definition:
f(n) = 0 if n = 0
= 1 if n = 1
= f(n1) + f(n2) if n > 1
Again, let fib(N,M): true if M is the Nth number in the Fi
bonacci sequence
Write a 3 clause definition to generate the Fibonacci se
quence.
Complete the following table:
n f(n)
____________________
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
Exercise 6.
Make sure you can write, and understand, definitions for the
following:
member(X,L): true if X is a member of a list L
append(L1,L2,L): true if L is L2 concatenated to L1
Write a definition for delete(X,L,L1): delete(X,L,L1) is
true for all X,L,L1 s.t X is in L, and L1 is the list L with
an occurrence of X removed. So:
delete(a,[1,a],[1]) is true
delete(a,[1,a,a], [1,a]) is true
delete(a,[1,a,a],[1]) is false
delete(a,[1,b],[1,b]) is false
Exercise 7.
A graph is defined by a set of nodes (or vertices) and a set
of edges, where each edge is a pair of nodes. Directed edges
are called arcs. A set of arcs is a set of ordered pairs.
Labels can be attached to any edge. These labels may be
names, costs etc. Examples are: example
An undirected graph g1:
b
  
  
a  
dc
A directed graph g2:
> b
 
 v
a < c  > e
 
> d

> f
A graph can be represented either by a single predicate
graph(G,N,E): N is the set of nodes in the graph G and E is
the set of edges (or arcs)
For example, the first graph above (using lists to implement
sets) is given by the predicate:
graph(g1,[a,b,c,d],[edge(a,b), edge(b,d), edge(b,c), edge(c,d)])
Alternatively, a predicate can be used to represent the sets
of nodes and edges (or arcs). For example, in the second
graph above:
node(g2,a).
node(g2,b).
node(g2,c).
node(g2,d).
node(g2,e).
node(g2,f).
arc(g2,a,b). arc(g2,b,c). arc(g2,c,a).
arc(g2,a,d). arc(g2,d,f). arc(g2,d,e).
Let a graph G consist of the two sets N and E; representing
nodes and edges. A "path" from Np to Nq for Np,q in N is a
sequence Np,Ni1,Ni2...,Nin,Nq s.t (Np,Ni1), (Ni1,Ni2)...,
(Nin,Nq) in E. The "length" of a path is the number of
edges on it. A "simple" path is a path is which all nodes
except possibly the first and last are distinct. A "cycle"
is a simple path in which the first and last nodes are the
same. An undirected graph G = (N,E) is called "connected"
is for every pair of nodes Ni,j in N, there is a path from
Ni to Nj.
Consider the following definition for a path between two
nodes in a graph:
path(A,Z,G,P):
path1(A,[Z],G,P).
path1(A,[APath],Graph,[APath]).
path1(A,[YVisited],Graph,Path):
adjacent(Graph,X,Y),
not(member(X,Visited)),
path1(A,[X,YVisited],Graph,Path).
adjacent(G,A,B):
edge(G,A,B).
adjacent(G,A,B):
edge(G,B,A).
What does the predicate path1/4 define?
Write a definition for connected(G,N,E): true if graph G
represented by the sets N,E (implemented by lists) is con
nected.
Verify graph g1 in the example above is connected.
Remove edge(b,d) from the set E for graph g1. Is g1 still
connected? What if edge(c,d) was removed as well?
A Hamiltonian path is an acyclic path comprising all nodes
in the graph G Assume set of nodes in the graph are
represented by a binary predicate node:
node(G,N): true if N is a node in graph G.
and the set of edges in the graph by:
edge(G,N1,N2): true if there is an edge N1,N2 in G
Write a definition for:
hamiltonian(G,P): true if P is a hamiltonian path in G.
Exercise 8.
An extra argument to the edge/3 predicate to reflect a
"cost" from moving to one node to the other. For example,
the nodes could be cities, and the cost could be cheapest
airfare between a pair of cities.
Modify the path/4 predicate by adding an extra argument that
contains the cost of a path.
Let Pij be the set of paths between a pair of nodes Ni, Nj
in a graph G. The minimum cost path between Ni,j in graph G
is defined informally as:
mcp(Ni,Nj,G) = {p  p in Pij, cost(p) < cost(pk) for all pk in Pij}
Complete the following definition:
mincost(Ni,Nj,G,P):
....
mincost(Ni,Nj,G,P) is true if P is an element of
mcp(Ni,Nj,G).
Exercise 9.
T is a spanning tree of graph G if:
1) T is a subset of G; and
2) T is a tree; and
3) Every node of G is in T.
A set of edges T is a tree if:
1) T is connected; and
2) T has no cycles.
To make things simple, let us change our representation of
of graphs. For the moment, forget about the set of nodes,
and only think of the edges. For example g1 is represented
simply by [edge(a,b), edge(b,c), edge(b,d), edge(c,d)].
Write a definition for the predicate spanning_tree(G,T):
true if T is a spanning tree of graph G.
You will need to write auxillary definitions for notions of
"subset", "tree", "cyclic" etc. in the definition above.