[UMN logo]

CSCI 5106: Programming Languages
Spring 2006, University of Minnesota
Homework 8


Posted: April 27, 2006

Due: By noon, May 5, 2006

Note: There is no class on Friday May 5. However, you can turn in the homework by slipping it under the door of my office (EE/CS 6-215) by the deadline.

Part 2 of Problem 5 is optional. This means that you will get comments back on it but there will be no grade for it. However, I strongly encourage you to try this problem for what you will learn from this. Problem 6 is "beyond optional:" I know you have very little time for this homework and I have included this problem in this collection only so that you can try it in the summer to realize the marvels of Prolog.

You guys have been great throughout the term and I hope you will bear with me through this one last homework! I think you will have fun with it and will also learn a lot through it.


Problem 1

Do Problem 11.2 parts (b) and (e) from the book.


Problem 2

Define relations to determine the following:
  1. Is a list L1 a permutation of another list L2? Hint: You may find the select predicate (to be) defined in class useful in doing this.

  2. Is a list formed by merging two lists? Note that a list is formed by merging two lists if it combines the elements of these lists and also preserves the relative order of their elements.


Problem 3

Part of this problem helps you contrast Prolog with ML by doing Problem 2 from HW 7 in Prolog.
  1. Describe an abstract syntax representation for logical expressions of the kind encountered in Problem 2 of HW7 in Prolog.

  2. Describe a representation for the assignment of truth values for a collection of propositional variables in Prolog.

  3. Define a predicate istrue that takes a logical expression E and an assignment L of truth values for propositional variables, both represented in the ways you have just described, and that succeeds just in case the truth value of E under the assignment L is true.

  4. A tautology is an expression in propositional logic that is true under every truth assignment for its propositional variables. Define a predicate istaut that takes a logical expression E and succeeds just in case E is a tautology. (Note: You may actually find it easier to define a predicate isnottaut that succeeds if E is not a tautology first and then to define istaut using the not predicate of Prolog over this predicate.)


Problem 4

Exercise 11.9 in the book. However, before drawing the search trees, explain any differences there might be in the behaviour of Prolog on the two queries.


Problem 5

The N queens problem requires the placement of N queens on an N-by-N grid (chess board) so that no two queens are on the same vertical, diagonal or horizontal line (i.e. attack each other). We can think of a solution to such a problem as being given by a list of N numbers where the ith number in the list denotes the column in which the queen in the ith row is to be placed. (Built into this presentation is the fact that no two queens can be placed in the same row.) The task in this problem is to eventually define a two-place predicate in Prolog called nqueens that is satisfied just in case its second argument represents a solution to the N queens problem whose size is given by its first argument. Thus, the query
?- nqueens(4,Queens).
should first produce one solution to the N queens problem of size 4 and, if the user rejects this solution, should then produce the second solution, and so on.

  1. One way to define such a predicate is to think of generating a list of the positive non-zero numbers up to the first argument from which we generate a permutation of these numbers that is then tested to determine if it represents a solution. This translates into the following Prolog clause
    nqueens(N,Qs) :-
        enumerate_interval(1,N,Ns), permutation(Ns,Qs), safe(Qs).
    
    By filling in the definitions of the predicates used in this clause, we get one program for solving the N queens problem. You already have defined the permutation predicate in Problem 2. Define enumerate_interval and safe now to complete a Prolog solution for this problem.

  2. The approach described above is an example of the generate-and-test paradigm that Prolog is ideally suited to realize. However, the program that results from the above template will not be very efficient: we will generate too many permutations that have no possibilities of being solutions. We can make it more efficient by pushing the tester into the generator. One way to do this is to think of checking each queen position as it is being determined. For this, we need an auxiliary predicate that we call nqueens_aux with the following character: assuming Safe represents the safe placement of queens in the first m rows where m <= n, and Unplaced represents the columns in which the queens in the remaining n - m rows might be placed, then nqueens_aux(Unplaced,Safe,Qs) is true if Qs represents a safe placement of n queens that extends Safe. Notice that for particular choices of Safe and Unplaced, there may be no way to choose Qs to make this predicate true. Using this predicate, we may rewrite the definition of nqueens as follows:
    nqueens(N,Qs) :-
       enumerate_interval(1,N,Ns), nqueens_aux(Ns,[],Qs).
    
    Provide the definitions of enumerate_interval and nqueens_aux so as to complete the definition of nqueens given by the clause above. Test the Prolog program that results. Be sure to check that your program will eventually find all solutions. You could do this, for instance, by considering the cases when N is 4 and 5 and first hand-generating the solutions that the program must produce.


Problem 6

Consider the task of defining a function in SML that is like the nqueens_aux predicate that you defined above in Prolog. Thus this function would take two arguments --- the remaining columns and the placements already made --- and would return a complete placement if there is one and would signal failure otherwise. You may find it difficult to construct such a definition on your own in a short time, so I have placed some code that does this here. Take a look at this code, identify the function that corresponds to nqueens_aux and understand how issues such as backtracking are handled in this code. After you have done this, explain how this code works. To help you in your thinking, you might recall what we said in class about using exceptions to signal failure in ML.

Once you have finished the one-solution program, you may want to extend this to a function that realizes the functionality of the predicate nqueens defined in Problem 3. In other words, this function presents a solution and waits for the user to indicate if another is needed. Once again, constructing this definition from scratch may be difficult, so I have placed ML code for finding all solutions for the N queens problem here. You should look at this code, understand how it works and explain its structure by analogy to the Prolog program for the same purpose.

After you have looked at the ML code and understood it, comment on the relative merits of Prolog and ML for dealing with problems that involve search of the kind manifest in the N queens problem.


Last updated on April 27, 2006 by gopalan@cs.umn.edu