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 6-tuples, 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 6-tuples, 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 theorem-prover 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 definite-clause 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 definite-clause. 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 definite-clauses? 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 Indo-Arabic 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 "pre-load" these into Prolog. If so, how many entries do we consider pre-loading (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 "looks-up" its inter- nal table, and returns the truth-value of the comparison. Prolog has the standard comparison functions > and <, as well as the built-in 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,y-x) 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 "built-in" 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(n-1) + f(n-2) 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 | | d------c 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,[A|Path],Graph,[A|Path]). path1(A,[Y|Visited],Graph,Path):- adjacent(Graph,X,Y), not(member(X,Visited)), path1(A,[X,Y|Visited],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.