Problem Solving Lab #4
Prolog
All Submissions are due Thursday, November 3

This lab is being done in order to help you learn various topics discussed in lecture. You will be asked to submit your programs and other answers to try. You are to do the work in pairs. You must choose a partner that you have not had yet in this course. Since this lab is for your learning and since different people will learn at different rates, you may not finish all of the lab during the lab but you should make reasonable progress. You should at least submit the required parts of the lab.

First, create a new directory, cd to that directory, and fetch the files for this lab by typing

get swm hmwk4
Each of you should edit the file team.txt to give the account number of your team member. Then submit this file with all submissions but the "reflections" activity.

This is a lab on Prolog programming.


Introduction and Warmup

This is a lab on programming in prolog. The Prolog Reference Manual and Prolog User Guide can be consulted to possibly get some help. The implementation we are running is a much earlier version than this documentation so the documentation may not be too useful.

To start prolog running type pl to the unix shell. This will start prolog running and give you a prompt. Anything you type is evaluated as a query to be run against the current database. To load a database you type [file]. and this will load the file file.pl.

Here are some other useful prolog commands:

If you put:

/* -*- Mode: prolog -*-
*/
at the beginning of your file then emacs will go into prolog mode (if you care).

In the following activities you are to submit files that define certain predicates. It is OK if your file contains other helper predicates or predicates from other activities. Just make sure that your file loads without error, i.e., that [relations]. loads the file without error. I will only check that the indicated predicates work for each activity so other predicates that I don't test do not have to work correctly (or at all).


Part I - Family Relations

There is a file family.pl that you downloaded with the get command that contains the primitive relationships of a family. There are three types of relationships in the file:

There is another file relations.pl that defines some common relationships between people. You are to write more relationship predicates (some are already written for you). You can make your predicates depend on other relationship predicates. Be careful that your predicates do not go into infinite loops - you can check them by running relationship(X, Y). after loading the family database and it should print out all possible people with that relationship. There should be no duplicate answers unless there are more than one way for the relationship to be established. Now answer the questions in the file relatives.txt. You can copy and paste the answers from the running prolog program. Show the query you used to answer the question and the answer. Submit this activity with the command
% try swm-grd hmwk4-1 team.txt relations.pl relatives.txt
Be sure that your team.txt file is correct.


Part II - Simple Prolog Exercises

In the file predicates.pl are defined some predicates. You are to add definitions to this file of the following predicates. You may use other predicates in the file but not system predicates that have similar functionality.

Submit this activity with the command
% try swm-grd hmwk4-2 team.txt predicates.pl 
Be sure that your team.txt file is correct.


Part III - Map Coloring

A map maker wants to color some maps with as few colors as possible. He would like to color his map with the minimum number of colors. In the files map1.pl, map2.pl, and map3.pl are descriptions of three maps. The cities are named with lower case names and there are relations borders(state, neighborStates). indicating the neighboring states for each state. For each map you are to givew a coloring using the minimum number of colors. (A file map0.pl has been included for testing that contains three states in a row.)

To get you started, the file color.pl has been started for you and the following predicate definitions are to be implemented:

Predicates for Map Coloring

borders(state, [neighboring states])

Given a state as the first argument unifies the second argument with a list of all states it touches. It is guaranteed that a state does not touch itself and if state A touches state B then state B touches state A. These are defined in the map file and specify the map to be colored.

nextTo(state1, state2)

True if state1 touches state2.

noClash(state1, color1, state2, color2)

The two states with their respective colors are legal, i.e., if the states touch then the colors are different.

goodState(state, color, stateColors)

The color or state is consistent with the colorings of the stateColors list.

colorStates(states, colors, stateColors))

Given a list of states and a list of colors the stateColors is unified with a list of state|color pairs that are legal. The order of the states is the same in both the states list and the stateColors list.

Activity

The files map1.pl, map2.pl, and map3.pl contain descriptions of maps to color. Each file contains several predicates borders(State, TouchingStates) that will unify the second argument with a list of states touching the first argument. How can we use this information to assign colors to states so that two touching states are colored with different colors? We will write a predicate color(States, Colors, ColorMap) that takes a list of States and a list of Colors and produces a list of state/color associations satisfying the constraints.

There is a file color.pl that is a beginning of a program to solve this problem. Finish this prolog program so that it will answer this question. The map[n].pl files of the countries in each file is given by the predicate countries(X). that will unify X with a list of the countries.

Submit this activity with the command

% try swm-grd hmwk4-3 team.txt color.pl colorings.txt
Be sure that your team.txt file is correct.


Part IV - Reflections

Each of you should submit (from your own account - this is not a team activity) a file called reflections.txt after the lab is over. The goal of the file is for you to reflect on what you have learned in the lab, how far you got in the lab, what you had problems with, what I could do better next time, what you would have liked to do, and to give me feedback about the lab. This is an individual submission and not a team submission. In order to submit this file, type:
% try swm-grd hmwk4-4 reflections.txt
Be sure that your team.txt file is correct.


Part V - Graduate Students (and those who really really want to for extra credit)

Writing a Parser in Prolog

One technique that is frequently used in prolog is to represent part of a list as a pair of variables, one refering to the beginning of the list segment and one refering to the list just after the list segment. Then pieces of the list can be unified in different clauses. For example, to concatenate the result of two clauses we could do:


combination(L1, L2) :- firstPiece(L1, LX), secondPiece(LX, L2).

firstPiece([first|REST], REST).

secondPiece([second|REST], REST).

Then with the query combination(X, [end]). we get

X = [first, second, end] ;

This way we can manipulate fragments of a list independently and join them up into a bigger list.

To write a parser that parses a list of tokens we can convert the syntax


a -> b, c, d
a -> e

into the prolog statements

a(W, Z, a(B, C, D)) :- b(W, X, B), c(X, Y, C), d(Y, Z, D).
a(W, X, e(E)) :- e(W, X, E).

This means, in the first clause, we can parse the list from W to Z and get the result a(B, C, D) if we can parse the list from W to X as b with result B and the list from X to Y as c with result C and the list from Y to Z as d with result D. The second clause is similar. We then call our parser with, say a([t,o,k,e,n,s],[],X) and the result of the parse will be in X.

Since this is a top-down parser it will have trouble with grammars with left recursion, i.e., rules of the type

exp -> exp term.

because it will get into an infinite loop expanding exp as an exp.

Implement the following grammar (which parses a language containing a's followed by b's followed by c's with the same number of a's as b's or the same number of b's as c's) using the above technique.


goal -> w x
goal -> y z
w -> a w b
w ->
x -> c x
x ->
y -> a y
y ->
z -> b z c
z ->

Try out your parser on the following input:

[]
[a,b,c]
[a,a,b,c]
[a,b,c,c]
[a,a,b,b,c,c]

Submit this activity with the command
% try swm-grd hmwk4-5 team.txt parser.pl
Be sure that your team.txt file is correct.