LABORATORY EXERCISE 1 TDDC75 Discrete Structures in Discrete Mathematics Ulf Nilsson

advertisement
TDDC75 Discrete Structures
LABORATORY EXERCISE 1
in Discrete Mathematics
Ulf Nilsson
September 19, 2010
The objective of this lab is to deepen your understanding of sets and relations
and various operations on them. Another aim is to show that sets and relations
provide a basis for computation. We will use a programming language called
Prolog (PROgramming in LOGic) – a language based on predicate logic used
for reasoning about sets (properties) and relations. We will actually use only a
small subset of the language sometimes referred to as Pure Prolog.
Below you will find a crash course on Pure Prolog and how to start and
operate SICStus Prolog – the Prolog system that will be used in the labs. The
actual lab exercises are then described. You should read all of this before coming to
the laboratory classes.
You may solve this exercises in pairs, but each group must come up with its
own solution. To pass this lab you have to demonstrate your solutions for the
teaching assistant during the labs, or hand in your solutions on paper. Solutions should be demonstrated before the first exam. It is possible to hand in
solutions also after this date but they will only be graded in connection with
the course re-exams.
1
Pure Prolog
Here we briefly describe the syntax (the form) and semantics (the meaning) of
Pure Prolog programs. Pure Prolog is a subset of the programming language
Prolog developed in the early 1970s.
A (non-empty) sequence of alpha-numeric1 characters beginning with an
upper- or lower-case letter is called an identifier. An identifier that starts with
an upper-case letter is called a variable. The following are some examples of
variables
A
1 The
Aa
XxX
X1
X222
N1N1N
characters a...öA...Ö0...9 are called alpha-numeric.
1
Prolog also allows variables to start with, or contain, underscores.
An identifier starting with a lower case letter is called a constant. Integers
(positive and negative) are also examples of constants. The following are some
examples of constants
a
aA
bill
a1
17
0
-17
A predicate symbol is an identifier starting with a lower-case letter. Every predicate symbol has an associated natural number called its arity. A predicate symbol p with associated arity n is often written p/n. A predicate symbol names a
relation or a set.
A predicate is an expression of the form
p(t1 , . . . , tn )
where p is a predicate symbol of arity n, and t1 , . . . , tn are variables or constants. A predicate p(t1 , . . . , tn ) states that (t1 , . . . , tn ) ∈ p. The following are
exemples of predicates
father(X,Y)
p(1, X)
p(X)
There are also some special predicate symbols often written in infix notation
(between the arguments); e.g. = /2, < /2.
A Pure Prolog program is a collection of facts and rules. A fact is a predicate
terminated by a period; that is, an expression
p(t1 , . . . , tn ).
It is possible to write facts containing variables, but for these exercises only
constants should be used as arguments. The following are examples of facts
laptop(sc4000).
taller(bill, mary).
The first fact states that “sc4000 is a laptop” (or belongs to the set of all laptops).
The second fact states that the tuple (bill,mary) is in the relation “taller”; or
more naturally: Bill is taller than Mary.
A rule is an expression
A0 :- A1 , . . . , An .
where A0 , . . . , An are predicates and n ≥ 1. The predicate A0 is called the head
of the rule, and A1 , . . . , An is called the body. The following are examples of
rules (note that each rule must also be terminated by a period!)
computer(X) :- laptop(X).
proud(X) :- parent(X,Y), newborn(Y).
A rule is a conditional statement; the symbol :- should be read “if” and the
commas in the body of a rule should be read “and”. The rules above should be
read
2
• X is a computer if X is a laptop. (Or X belongs to the set of all computers,
if it belongs to the set of all laptops.)
• X is proud if X is a parent of Y and Y is newborn.
The following is an example of a Pure Prolog program. The first line which
starts with the symbol % and ends at the linebreak is a comment.
% married(X,Y) iff X is married to Y
married(X,Y) :- wife(X,Y).
married(X,Y) :- wife(Y,X).
% wife(X,Y) iff X is the wife of Y
wife(anne, bill).
wife(mary, tom).
A Prolog program defines a collection of relations (or sets). The relations can
be examined by posing queries to the program. A query is an expression of the
form
?- A1 , . . . , An .
where A1 , . . . , An are predicates and n ≥ 1. The following are examples of
queries
?- computer(X).
?- taller(X,Y).
The first query should be read “which X are computers”, and the second query
“which X are taller than which Y ”.
2
How to use SICStus Prolog
The Prolog system used at IDA is called SICStus Prolog, developed by the
Swedish Institute of Computer Science. To be able to start the system you
should first type
% module add prog/sicstus
To avoid having to type this every time you log on you may additionally type
% module initadd prog/sicstus
It should now be possible to start the system by writing
% sicstus
In which case the system should respond with something like
SICStus 3.8.3 (x86-win32-nt-4): Fri May
Licensed to ida.liu.se
| ?3
5 13:28:31
2000
The last line is the Prolog prompt indicating that the system is ready to accept
your queries and commands. You may quit from the system by typing
| ?- halt.
Note that every query/command must be terminated by a period followed by
a newline.
In order to pose any meaningful queries it is first necessary to load a program into the system (this is often called consulting the program). The program
should be prepared in a separate text file using a text editor such as emacs, and
then loaded into the Prolog system. For simplicity, use Prolog file names consisting only of lower case letters, with extension “.pl”; for instance, test.pl.
The file is consulted by giving the command
| ?- [test].
Once the program is loaded you may start posing queries. For instance
| ?- married(X,Y).
Assuming that we have loaded the married/2 program above, the system would
respond with one of the married couples
X = anne,
Y = bill ?
However, there are more answers to the query; if you don’t want to see more
answers you should hit newline/enter; if you want to see more answers you
should type in a semi-colon “;” followed by a newline/enter. In this particular
case there are three more answers
X = mary,
Y = tom ? ;
X = bill,
Y = anne ? ;
X = tom,
Y = mary ? ;
no
| ?It is possible to run Prolog inside the text editor emacs. For this to work you
first have to create a file named .emacs in your home directory, containing the
following commands2 (if you already have a file named .emacs just prepend
the following to the existing file)
2 The
text can be downloaded from the course homepage.
4
(set-variable ’load-path
(cons "/home/TTIT07/emacs" load-path))
(autoload ’run-prolog "prolog"
"Start a Prolog sub-process." t)
(autoload ’prolog-mode "prolog"
"Major mode for editing Prolog programs." t)
(setq prolog-system ’sicstus)
(setq auto-mode-alist
(cons ’("\\.pl$" . prolog-mode) auto-mode-alist))
Then restart emacs and start editing a file with extension .pl. The emacs window should now look approximately like in Figure 1. When you are happy
Buffers
Files
p(a, b).
q(X,Y) :p(X, Y).
Tools
Edit
--**-Emacs: mytest.pl
Prolog
Help
(Prolog)--All-----------
Figure 1: Prolog editing mode in emacs
with your program you may consult the emacs buffer by selecting “consult
buffer” in the Prolog menu, or simply typing Ctrl-c Ctrl-b (i.e. hold down
the control button and hit c and b). The emacs window should now be split
in two buffers as shown in Figure 2. You can now toggle between the two
buffers using your mouse or typing Ctrl-x o, editing your program, and posing queries; but keep in mind to re-consult the buffer every time you make
changes to your program.
3
Operations on sets
A set such as R = {1, 2, 3} can be defined by three facts in Prolog (note that
we cannot use the predicate letter R which is a variable in Prolog so we use r
instead!).3
3 If we want to deal with sets of sets this representation of sets is not very good; but in these
exercises we will only use sets of objects which are not sets.
5
Buffers
Files
p(a, b).
q(X, Y) :p(X, Y).
Tools
Edit
Prolog
Help
--**-Emacs: mytest.pl
(Prolog)--All----------SICStus 2.1 #9: Mon Apr 3 14:00:38 MET DST 1995
| ?- {consulting /tmp/spa10976...}
{/tmp/spa10976 consulted, 10 msec 432 bytes}
yes
| ?-
--**-Emacs: *prolog*
(Comint: run)-----------
Figure 2: Consulting of a buffer
r(1).
r(2).
r(3).
The facts state that 1 ∈ r, 2 ∈ r and 3 ∈ r.
Given primitive relations defined by facts we can perform various operations on sets by means of rules. For instance, to take the intersection of the sets
r/1 and s/1 we may write
p(X) :- r(X), s(X).
That is, an element X ∈ p if X ∈ r and X ∈ s.
The union of the sets r/1 and s/1 can be defined by two rules
p(X) :- r(X).
p(X) :- s(X).
That is, X ∈ p if X ∈ r and X ∈ p if X ∈ s. (From a logical point of view this
equivalent to saying that x ∈ p if x ∈ r or x ∈ s.)
The difference between two sets cannot be easily defined in the pure subset
of Prolog. However, with the additional help of negation it is easy. The negation
of a predicate A is written \+ A. With the aid of negation the difference between
the sets r/1 and s/1 can be defined as follows
p(X) :- r(X), \+ s(X).
That is, X ∈ p if X ∈ r and X 6∈ s.
6
Exercise 1: Invent a set of students, a subset of those students taking the course
in discrete structures, and a subset of students taking the course in algebra.
Then define the following sets by means of rules
• the set of all students who take either the course in algebra or discrete
structures (or both);
• the set of students who take both the course in algebra, and the course in
discrete structures;
• the set of all students who take neither the course in algebra nor the
course in discrete structures.
4
Operations on relations
Now relations are sets (of tuples) so operations on relations can be defined
much in the same way as for sets. Primitive relations can be defined by means
of facts; for instance
salary(john,16).
salary(mary,17).
salary(tom,31).
Given primitive relations (and sets) we may define new derived relations by
means of rules. For instance, the identity relation on a set r/1 can be defined as
follows
p(X,X) :- r(X).
The composition of s/2 with r/2 is defined as follows
p(X,Z) :- r(X,Y), s(Y,Z).
The union of r/2 and s/2 can be defined as follows
p(X,Y) :- r(X,Y).
p(X,Y) :- s(X,Y).
The Cartesian product of r/1 with s/1 is defined as follows
p(X,Y) :- r(X), s(Y).
The projection of r/2 on one of its “arguments” is defined as follows
p(X) :- r(X,Y).
or as follows
p(Y) :- r(X,Y).
7
Actually such a clause is likely to trigger Prolog to write a warning that the
clause contains a “singleton variable”, that is a variable that occurs only once
in the clause. Singleton variables often occur due to typos and the easiest way
to avoid the warning is to use the anonymous variable “_” instead.4
The inverse of a relation r/2 is defined below
p(Y,X) :- r(X,Y).
The intersection of r/2 and s/2 can be defined as follows
p(X,Y) :- r(X,Y), s(X,Y).
Selecting a subset of a relation that satisfies some particular property can be
viewed as an instance of intersection; for instance the rule
father(X,Y) :- parent(X,Y), male(X).
defines the relation father/2 as the subset of the parent/2-relation where the
parent is male. Similarly, if we want to find the relation P = {(x, y) ∈ R | x 6=
a} we may do that as follows
p(X,Y) :- r(X,Y), X \= a.
Here \= is a predefined predicate for disequality written in infix notation.
It is also possible to take the closure of a relation. Given that r/2 is a relation
on a set s/1 we may define the reflexive closure as follows
p(X,Y) :- r(X,Y).
p(X,X) :- s(X).
The symmetric closure of r/2 can be defined as follows
p(X,Y) :- r(X,Y).
p(X,Y) :- r(Y,X).
For instance
married(X,Y) :- wife(X,Y).
married(X,Y) :- wife(Y,X).
wife(anne, bill).
wife(mary, tom).
Finally the transitive closure of r/2 may be defined as follows
p(X,Y) :- r(X,Y).
p(X,Z) :- r(X,Y), p(Y,Z).
4 In contrast to other variables, each occurrence of the anonymous variable is considered a
unique variable.
8
Exercise 2: Invent two primitive relations father/2 and mother/2 defining the
father/child and mother/child relations (pick your favourite family). Also defined two sets (properties) male/1 and female/1 (consistent with the relations
above). Then use rules, such as those above, to define the following relations
from relations and sets already defined.
• parent(X, Y ), X is a parent of Y ;
• child(X, Y ), X is a child of Y ;
• grandparent(X, Y ), X is a grandparent of Y ;
• ancestor(X, Y ), X is an anscestor of Y ;
• brother(X, Y ), X is a brother of Y ;
• sister(X, Y ), X is a sister of Y
• cousin(X, Y ), X is a cousin of Y
Exercise 3: A directed graph (digraph) is a pair (V, E) with a finite set of vertices (nodes) V and edges E ⊆ V × V . Invent a directed graph without cycles
and describe it in Prolog. Then define a relation path/2 on vertices in such a
way that two nodes are in the relation iff there exists a non-empty path between
the two nodes. Also describe a property maximal/1 on vertices characterizing
thoses vertices where there is no outgoing edge.
NOTE: It is important that the graph does not contain any cycles!!!
9
Download