TTIT07 Discrete Structures LABORATORY EXERCISE 1 in Discrete Mathematics and Logic Ulf Nilsson 2000-08-16 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 or in groups of three, 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 will not be accepted after the 2nd of November. 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... oA...O0...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 letter has an associated natural number called its arity. A predicate p with associated arity n is often written p=n. 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 con- stants. 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). taller(X,Y) :- taller(X,Z), taller(Z,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 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.) 2 X is taller than Y if X is taller than Z and Z is taller than Y . The following is an example of a Pure Prolog program married(X,Y) :- wife(X,Y). married(X,Y) :- wife(Y,X). 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 queries n 1. The following are examples of ?- 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 SICStus 3.8.3 (x86-win32-nt-4): Fri May Licensed to ida.liu.se | ?- 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. 3 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 (and recommended!) 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) (set-variable 'load-path (cons "/home/TTIT07/emacs" load-path)) (autoload 'run-prolog "prolog" "Start a Prolog sub-process." t) 2 The text can be downloaded from the course homepage. 4 (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 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 buffers using your mouse or typing Ctrl-x o, editing your program, and pos5 ing 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 = f1; 2; 3g can be defined by three facts in Prolog (note that we cannot use the predicate letter R which is a variable in Prolog!).3 r(1). r(2). r(3). 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 is in p if X 2 r and X 2 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 2 p if X 2 r and X 2 p if X 2 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 2 p if X 2 r and X 62 s. 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. 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 need sets of objects which are not sets. 6 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=2 with s=2 is defined as follows p(X,Y,Z,W) :- r(X,Y), s(Z,W). 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). 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 = f(x; y ) 2 R j x 6= ag we may do that as follows 7 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). 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 8 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