1. A Modula-2 set is a collection of items of the same scalar non-real type without regard to order, whereas an abstract set is a collection of items of any type.
2. A subrange of a scalar type is a sequence of consecutive values of the host type, unlike a subset which is a collection of values (in no particular order) taken from a set.
3. TYPE month30 = SET OF [jan, mar, may, jul, oct, dec]; month31 = SET OF [apr, jun, aug, sep, nov];
4. Sets in older versions of Modula-2 were of limited use because most of them followed the suggestion of Wirth which limited the ranges of a set (usually to a maximum of 16 or 32 elements). Some implemented the language to limit sets to cardinal ranges starting at zero. Instead of making a maximum allowable, the ISO standard requires a SET OF CHAR to be permitted.
5. All the driver modules export flags that are sets. They are compatible because they are defined elsewhere, imported, then re-exported.
6. Union: creates a new set that contains all the elements present in either of the two original sets. Intersection: creates a new set that contains only those elements common to the original pair of sets. Difference: creates a new set consisting of all elements of one set that are not in the other.
Symmetric Set Difference: creates a new set whose elements are in either of the original sets, but not in both. INCL: same as set union, but only one element is inserted into the set. EXCL: same as set difference, but only one element is removed from the set.
7. A BITSET is a set of [0..bitsperbitset-1] with membership in the set dependent on whether the bit position at that number contains a one or a zero. A PACKEDSET is similar, but the maximum bit number is user-defined. Operations that are used on these types are SHIFT, which shift all the bits of the pattern n positions to the left or right, and ROTATE, which rotates all the bits of the pattern n positions to the left or right.
8. Shifting 1 bit to the left equals multiplication by 2. Shifting one bit right is division by 2. Shifting n bits is multiplication or division by the nth power of 2.
9. (a) {1,3,5}
(b) {1,4,5}
(c) {4}
(d) {'a','2'}
(e) {1,10}
(f) {'m'}
(g) {5,7,9}
(h) {4,8}
(i) {'y'}
(j) {2,3,4,a,b,c}
10. (a) TRUE
(b) FALSE
(c) TRUE
11. In Modula-2, a record is a data abstraction designed to allow for aggregates of various types of related data named by a single identifier. In mathematics a record is an item taken from a cross product of two or more sets, producing tuples.
12.
TYPE String = ARRAY [0..50] OF CHAR; Time = RECORD Year, Month, Day : CARDINAL; END; traveller = RECORD name : String; addr : String; airline : String; flightnum : CARDINAL; arrival : Time; departure : Time; luggage : BOOLEAN; END;
Mathematically:
(namestring) * (addstring) * (CARDINAL) * (timestring) * (timestring) * (BOOLEAN)
13.
PROCEDURE Filltraveller (VAR rectype : traveller); BEGIN WITH rectype DO name := 'Jack'; addr := '1600 Pensylvania Ave.'; airline := 'Air Canada'; flightnum := 654321; WITH arrival DO Year := 1999; Month := 12; Day := 31; END; WITH departure DO Year := 2000 Month := 1; Day := 1; END; luggage := TRUE; END; END Filltraveller;
14.
student = RECORD name : string; sid : CARDINAL; age : [0..100]; owing : REAL; END;
15.
PROCEDURE FillStudent (VAR sturec : student); BEGIN WITH sturec DO WriteString ("Enter student's name: "); ReadString (name); SkipLine; WriteLn; WriteString ("Enter SID#: "); ReadCard (sid); SkipLine; WriteLn; WriteString ("Enter age: "); ReadCard (age); SkipLine; WriteLn; WriteString ("Enter amount owing: "); ReadReal (owe); SkipLine; WriteLn; END; END FillStudent;
16.
TYPE Address = RECORD num : CARDINAL; street : string; postal : CARDINAL; city : string; END; Customer = RECORD name : string; addr : Address; amount : REAL; END; PROCEDURE FillCustomer (VAR customer : Customer); BEGIN WITH customer DO name := 'Steve'; WITH addr DO num := 1492; street := 'Glover Rd.' postal := 654321; city := 'Langley'; END; amount := 0.00 END; END FillCustomer;
17. An array should be used when grouping items of the same types and only a simple structure is needed A record on the other had should be used when there is a diverse group of data that need to be combined into one abstraction. An array could be used to hold the number of runs that were scored in an inning of a baseball game where one would have an array of 1 to n. A record could be used to store patient information in a clinic stating the name, address, birthday, etc.
18. A qualified identifier has the individual fields of a record preceded by the record name itself. It is similar to a qualified import. The former are unqualified by WITH, the latter by FROM.
19. The first and simplest way is using regular ASCII characters. The record however can take up a lot of storage space. A second way of storing records is as binary information. The same idea is applied for this technique, but using a raw format to write instead of an ASCII format. The third is to use a random access technique. Here since memory size is similar to disk storage size, one can find a particular item by searching for a particular item or else, use the position markers and end-of-file markers.
20. Random access has the ability to calculate and set a position marker to read and write anywhere in the file. ISO Modula-2 uses the module RndFile to implement the random access model.
21. A sequential file should be used when a file does not need large amounts of insertions in different parts of the file, or when few changes are needed for the file in the span of its life. If the file is subject to frequent change, and requires insertions, then a random access file would be better.
22. A file position variable is a variable that marks a location in the file, whether it be at the beginning, the middle, or the end of the file. Manipulation of this variable is done automatically by procedures that read or write, and manually by StartPos, CurrentPos, EndPos, NewPos, and SetPos.
23. The end-of-file marker is important, because it tell the program where the end of the file is and it does not permit writing after that position.
24. OpenOld will open an existing file and set the read/write position to the start of the file. Using OpenClean will truncate the file to zero length.
25. After reading the file, the position marker moves to the end of the last read. If one were to write immediately after reading, the writing will be done in the incorrect position. To overcome this problem, one needs to reset the position marker to the position where the last record was read
26. Reading/writing to a position beyond the limits of a file produces a run time error.
27. Answer left to student.
28. Answer left to student.
29. Answer left to student.
Note: Not all problems are shown. Most problems are left up to students as labs.
(* Created June 17 1999 Chapter 9 Question 31 *) MODULE LetterCheck; FROM STextIO IMPORT WriteString, WriteLn, WriteChar, ReadString, ReadChar, SkipLine; FROM SIOResult IMPORT ReadResult, ReadResults; TYPE CharSet = SET OF CHAR; CharType = (const, vowel); CharArray = ARRAY [65..90] OF BOOLEAN; VAR VowelSet : CharSet; CharList : CharArray; type : CharType; ch : CHAR; PROCEDURE Init (array : CharArray); (* pre: none post: initializes an array of boolean to FALSE; *) VAR count : CARDINAL; BEGIN FOR count := 65 TO 90 DO array[count] := FALSE; END; END Init; PROCEDURE WriteType (list : CharArray; type : CharType); (* pre: none post: writes out the type indicated *) VAR count, format : CARDINAL; BEGIN format := 0; FOR count := 65 TO 90 DO IF list[count] THEN IF type = vowel THEN IF VAL(CHAR, count) IN VowelSet THEN WriteChar (VAL(CHAR, count)); WriteString (" "); INC (format); (* for formatting purposes *) END; (* end IF *) ELSE IF NOT ( VAL(CHAR, count) IN VowelSet) THEN WriteChar (VAL(CHAR, count)); WriteString (" "); INC (format); (* for formatting purposes *) END; (* end IF *) END; (* end IF *) END; (* end IF *) IF format = 5 THEN WriteLn; format := 0; END; END; (* end FOR *) END WriteType; BEGIN (* set the vowels *) VowelSet := CharSet {'A', 'E', 'I', 'O', 'U'}; WriteString ("Enter a string and I will show you which are consonats and which "); WriteLn; WriteString ("vowels."); WriteLn; WriteLn; WriteLn; WriteString ("Enter the string: "); (* initialize the string *) Init (CharList); (* check and mark of vowels used *) REPEAT ReadChar(ch); IF (ORD(CAP(ch)) >= 65) AND (ORD(CAP(ch)) <= 90) THEN CharList[ORD(CAP(ch))] := TRUE; END; UNTIL ReadResult () # allRight; SkipLine; WriteLn; WriteLn; (* write out the results *) WriteString ("**********VOWELS**********"); WriteLn; type := vowel; WriteType (CharList, type); WriteLn; WriteLn; WriteString ("********CONSONANTS********"); WriteLn; type := const; WriteType (CharList, type); WriteLn; WriteLn; WriteLn; (* let user read results before killing program *) WriteString ("Press ENTER to continue"); SkipLine; END LetterCheck.
(* Created June.17.1999 Chapter 9 Question 37 NO ERROR TRAPPING This program collects information about individuals and stores them in array of records. The student may elaborate on this an store the record to a file NOTE: no error checking is done on the inputs. *) MODULE Collection; FROM STextIO IMPORT WriteString, WriteLn, ReadString, ReadChar, WriteChar, SkipLine; FROM SRealIO IMPORT ReadReal, WriteFixed; FROM SWholeIO IMPORT ReadCard; CONST max = 3; TYPE String = ARRAY [0..30] OF CHAR; sexType = (M, F); List = ARRAY [1..max] OF CARDINAL; person = RECORD name : String; height : REAL; mass : REAL; sex : sexType; hair : String; eye : String; church : String; END; VAR quit : BOOLEAN; option, howmany : CARDINAL; Person : person; list : List; PROCEDURE FillPerson (VAR recType : person); (* pre: none post: fills a with given information *) VAR tempnum : REAL; tempsex : CHAR; BEGIN WITH recType DO WriteString ("Enter the name: "); ReadString (name); SkipLine; WriteLn; WriteString ("Enter the hight (in cm): "); (* since we use metric in canada *) ReadReal (height); SkipLine; WriteLn; WriteString ("Enter the weight (in kgs): "); (* since we use metric in canada *) ReadReal (mass); SkipLine; WriteLn; WriteString ("Enter the sex: "); ReadChar (sex); SkipLine; IF (tempsex = 'M') OR (tempsex = 'm') THEN sex := M; ELSE sex := F; END; WriteLn; WriteString ("Enter the hair colour: "); ReadString (hair); SkipLine; WriteLn; WriteString ("Enter the eye colour: "); ReadString (eye); SkipLine; WriteLn; WriteString ("Enter the church affiliation: "); ReadString (church); SkipLine; WriteLn; END (* end WITH *) END FillPerson; PROCEDURE menu (VAR option : CARDINAL); BEGIN WriteString ("**************************************************"); WriteLn; WriteString ("Select an option"); WriteLn; WriteLn; WriteString ("1. Add an individual to the list"); WriteLn; WriteString ("2. Display the list"); WriteLn; WriteString ("3. Exit"); WriteLn; WriteString ("***************************************************"); WriteLn; WriteLn; WriteString ("Option desired: "); WriteLn; ReadCard (option); SkipLine; END menu; PROCEDURE DisplayRec (list : List; recType : person); VAR count : CARDINAL; BEGIN FOR count := 1 TO howmany DO WITH recType DO WriteString ("Name: "); WriteString (name);WriteLn; WriteString ("Height: "); WriteFixed (height, 2, 1);WriteLn; WriteString ("Weight: "); WriteFixed (mass, 2, 1);WriteLn; WriteString ("Sex: "); IF sex = M THEN WriteChar ('M'); ELSE WriteChar ('F'); END; WriteLn; WriteString ("Hair Colour: "); WriteString (hair);WriteLn; WriteString ("Eye Colour: "); WriteString (eye);WriteLn; WriteString ("Church Affiliaiton: "); WriteString (church);WriteLn; END; (* end WITH *) WriteLn; WriteLn; END; (* end FOR *) END DisplayRec; (* start main program *) BEGIN WriteString ("This program will take input from the user and store it in a list."); WriteLn; WriteLn; WriteLn; howmany := 0; REPEAT menu(option); IF option = 1 THEN FillPerson (Person); INC (howmany); ELSIF option = 2 THEN DisplayRec (list, Person); WriteString ("Press ENTER to continue"); WriteLn; SkipLine; ELSE quit := TRUE; END; UNTIL quit; END Collection.