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:
- 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.
- 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.
- Describe an abstract syntax representation for logical expressions
of the kind encountered in Problem 2 of HW7 in Prolog.
- Describe a representation for the assignment of truth values for a
collection of propositional variables in Prolog.
- 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.
- 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.
- 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.
- 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