First, create a new directory, cd to that directory, and fetch the files for this lab by typing
get swm hmwk4Each 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.
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:
halt. - Exit Prolog
trace. - Trace the next query
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).
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:
parent(a, b). - a is the parent of b
male(a). - a is a male
female(a). - a is a female
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.
father(a, b). - a is a male parent of
b
mother(a, b). - a is a female parent of
b
son(a, b). - a is a male child of
b
daughter(a, b). - a is a female child of
b
sibling(a, b). - a and b are
different people with the same parents
brother(a, b). - a is a male sibling
b
sister(a, b). - a is a female sibling
b
husband(a, b). - a is a male and has the same
child as a female b
wife(a, b). - a is a female and has the same
child as a male b
spouse(a, b). - a is a husband or wife of
b
motherinlaw(a, b). - a is a mother of a
spouse of b
fatherinlaw(a, b). - a is a father of a
spouse of b
aunt(a, b). - a is a sister of a parent of
b
uncle(a, b). - a is a brother of a parent of
b
nephew(a, b). - a is the son of a sibling of
b
niece(a, b). - a is the daughter of a sibling
of b
cousin(a, b). - a and b have the
same grand parents but not the same parents
ancestor(a, b). - a is a parent of
b or the parent of an ancestor of b
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.
% try swm-grd hmwk4-1 team.txt relations.pl relatives.txtBe sure that your team.txt file is correct.
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.
lastElem(X, L) :- X is the last element of the list L
last(?Elem, ?List) is predefined)
rev(L1, L2) :- L2 is the list obtained from L1 by
reversing the order of the elements so that the query rev([a,b,c], X). will result in X = [c, b, a].
reverse(+List1, -List2) is predefined)
[x, a, m, a, x])
isPalindrome(L) :- L is a palindrome list
[a, b, c] would
be transformed into [a, a, b, b, c, c]
duplicate(X, XX) :- XX is a list twice as long as X with
every element duplicated
% try swm-grd hmwk4-2 team.txt predicates.plBe sure that your
team.txt file is correct.
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:
borders(state, [neighboring states])
nextTo(state1, state2)
noClash(state1, color1, state2, color2)
goodState(state, color, stateColors)
colorStates(states, colors, stateColors))
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.txtBe sure that your
team.txt file is correct.
% try swm-grd hmwk4-4 reflections.txtBe sure that your team.txt file is correct.
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 -> einto 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.plBe sure that your team.txt file is correct.