-------------------------------------------------------------------------- Software Design and Development Winter 1994 COM 1205 --------------------------------------------------------------------------- Midterm 117 points total QUESTION 1: 49 UNKNOWNs, 1 point each QUESTION 2: 11 UNKNOWNs, 1 point each QUESTION 3: 24 UNKNOWNs, 1 point each QUESTION 4: 33 UNKNOWNs, 1 point each --------------------------------------------------------------------------- Open book and open notes. To make the grading easier, please put your values for the unknowns on the enclosed answer sheet. THE GAME OF REDUNDANCY AND UNKNOWNS ----------------------------------- Most of the questions in this exam ask you to determine unknowns of the form UNKNOWN1, UNKNOWN2, ... This makes it easier for you to answer the questions, since you get extra context information. Yet you need to master the behavioral objectives of the course to answer the questions. Guessing an answer is not a successful strategy and therefore a "game of redundancy" test is more interesting than a multiple choice test. The questions have the following pattern: I show you several artifacts which are related by the theory of object-oriented design and programming. Because of the dependencies between the artifacts, some of the information is redundant and can be recovered from the context by applying the objectives covered in the course. The information which you should discover is marked UNKNOWNx. If an unknown is not uniquely determined, mark the answer with *CHOICE*. An unknown may be anything, e.g., a number, an identifier, a character, two identifiers with a blank between them, a string etc. If an unknown is the empty string, give NOTHING as answer, e.g., UNKNOWN = NOTHING. Example: 5 + UNKNOWN1 = 8 UNKNOWN1 = 3 --------------- UNKNOWN2 * UNKNOWN3 = 20 UNKNOWN2 = 4 *CHOICE* UNKNOWN3 = 5 *CHOICE* At the beginning of a question we give the number of points per unknown. Question 1: =========== 49 unknowns, 1 point each /proj/adaptive/lieber/regression-test/f-exercise-v Remark: At = Bt Ct. is an abbreviation for At = Bt Ct. Consider the following class dictionary: ------------------------------------------------------------- Class Dictionary ------------------------------------------------------------- 1 Example = B1. 2 A1 : B1 | B2 *common* [A2] "endA1". 3 A2 : B3 | B4 *common* [A3] "endA2". 4 A3 : B5 | B6. 5 B1 = "b1" ["down" C1] ["b2" B2]. 6 B2 : C1 *common* [B3] "endB2". 7 B3 = "b3" ["down" C2] ["b4" B4]. 8 B4 : C2 *common* [B5] "endB4". 9 B5 = "b5" ["down" C3] ["b6" B6]. 10 B6 : C3. 11 C1 = "c1". 12 C2 = "c2". 13 C3 = "c3". ------------------------------------------------------------- Alphabetically Sorted Cross Reference List ------------------------------------------------------------- A1 :2 A2 :3 2 A3 :4 3 B1 :5 1 2 B2 :6 2 5 B3 :7 3 6 B4 :8 3 7 B5 :9 4 8 B6 :10 4 9 C1 :11 5 6 C2 :12 7 8 C3 :13 9 10 Example :1 =================================================== Find the unknowns in the following propagation directives and propagation graphs: Propagation directive: *traverse* *from* Example *bypassing* -> B3,*,UNKNOWN1, -> *,a3,*, -> *,*,UNKNOWN2 *to* C3 Equivalent propagation directive, expanded for class dictionary: *from* Example *bypassing* -> B3 , c2 , C2 , -> B3 , b4 , B4 , -> A2 , a3 , A3 , -> B5 , c3 , C3 *to* C3 Propagation graph for traversal: *source* { Example } Example = < b1 > UNKNOWN3 (*inherits* ) . A1 : UNKNOWN4 *common* UNKNOWN5. A2 : UNKNOWN6 *common* (*inherits* ) . B1 = UNKNOWN7 (*inherits* UNKNOWN8 ) . B2 : UNKNOWN9 *common* (*inherits* UNKNOWN10 ) . UNKNOWN11 : UNKNOWN12 *common* [ < UNKNOWN13 > UNKNOWN14 ] (*inherits* ) . B5 = UNKNOWN15 (*inherits* ) . B6 : UNKNOWN16 *common* (*inherits* ) . C1 = (*inherits* UNKNOWN17 ) . C2 = (*inherits* UNKNOWN18 ) . C3 = (*inherits* UNKNOWN19) . // There are 13 classes in total // There are 11 classes in the propagation schema // There are 2 classes not in the propagation graph // They are UNKNOWN20 UNKNOWN21 =========================================================== Propagation directive: *traverse* *from* Example *bypassing* -> A1,*,*, -> A2,*,*, -> *,*,C1, -> *,*,C2, -> *,*,C3 *to* C3 Equivalent, expanded propagation directive *from* Example *bypassing* -> A1 , a2 , A2 , -> A2 , a3 , A3 , -> B1 , c1 , C1 , -> B3 , c2 , C2 , -> B5 , c3 , C3 *to* C3 Propagation graph: *source* Example *target* C3 *paths* Example = < b1 > B1 (*inherits* ) . UNKNOWN22 = UNKNOWN23 (*inherits* ) . B2 : UNKNOWN24 *common* UNKNOWN25 (*inherits* ) . B3 = UNKNOWN26 (*inherits* ) . B4 : C2 *common* UNKNOWN27 (*inherits* ) . B5 = UNKNOWN28 (*inherits* ) . UNKNOWN29 : UNKNOWN30 *common* (*inherits* ) . C1 = (*inherits* UNKNOWN31 ) . C2 = (*inherits* UNKNOWN32 ) . C3 = (*inherits* UNKNOWN33) . // There are 13 classes in total // There are 10 classes in the propagation schema // There are 3 classes not in the propagation graph // They are UNKNOWN34 UNKNOWN35 UNKNOWN36 ======================================== Find the unknowns in the following propagation pattern and corresponding C++ program. *operation* void f6() *traverse* *from* Example *bypassing* -> A1,*,*, -> A2,*,*, -> *,*,C1, -> *,*,C2, -> *,*,C3 *to* C3 *wrapper* C3 *prefix* (@ cout << endl << "done" << endl; @) C++ program: void Example::f6( ) { this->get_b1()->f6( ); } void UNKNOWN37::f6( ) { if ( UNKNOWN38 ) { UNKNOWN39 }} void B2::f6( ) { if ( UNKNOWN40 ) { UNKNOWN41 } } void B3::f6( ) { UNKNOWN42 } void B4::f6( ) { UNKNOWN43 } void B5::f6( ) { UNKNOWN44 } void UNKNOWN45::f6( ) { UNKNOWN46 } void C1::f6( ) { this->UNKNOWN47::f6( ); } void C2::f6( ) { UNKNOWN48 } void UNKNOWN49::f6( ) { cout << endl << "done" << endl; } Question 2: =========== 11 unknowns, 1 point each /proj/adaptive/lieber/regression-test/f-exercise-v ======================================== Consider the flattened form of the class dictionary of question 1. Example = B1 . A1 : B1 | B2 *common* . A2 : B3 | B4 *common* . A3 : B5 | B6 *common* . B1 = "b1" [ "down" C1 ] [ "b2" B2 ] [ A2 ] "endA1" . B2 : C1 *common* . B3 = "b3" [ "down" C2 ] [ "b4" B4 ] [ A3 ] "endA2" . B4 : C2 *common* . B5 = "b5" [ "down" C3 ] [ "b6" B6 ] . B6 : C3 *common* . C1 = "c1" [ B3 ] "endB2" [ A2 ] "endA1" . C2 = "c2" [ B5 ] "endB4" [ A3 ] "endA2" . C3 = "c3" . Find the unknowns in the following object and corresponding sentence: Object: : Example ( < b1 > : B1 ( < UNKNOWN1 > : UNKNOWN2 ( < UNKNOWN3 > : UNKNOWN4 ( < UNKNOWN5 > : UNKNOWN6 ( < UNKNOWN7 > : UNKNOWN8 ( < c3 > : UNKNOWN9 ( ) < b6 > : UNKNOWN10 ( ) ) ) ) ) ) ) Sentence: (// is the comment character) UNKNOWN11 down c1 b3 down c2 b5 down c3 b6 c3 endB4 // for C2 endA2 // for C2 endA2 // for B3 endB2 // for C1 endA1 // for C1 endA1 // for B1 Question 3: =========== 24 unknowns, 1 point each. Consider the following ------------------------------------------------------------- Class Dictionary ------------------------------------------------------------- 1 Example = A1. 2 A1 : B. 3 B = C H. 4 D1 : C *common* E. 5 C = . 6 E = F H. 7 G1 : F *common* G. 8 F = . 9 G = H. 10 H = . ------------------------------------------------------------- Alphabetically Sorted Cross Reference List ------------------------------------------------------------- A1 :2 1 B :3 2 C :5 3 4 D1 :4 E :6 4 Example :1 F :8 6 7 G :9 7 G1 :7 H :10 3 6 9 Find the unknowns in the following object. It corresponds to the empty sentence. : Example ( < UNKNOWN1 > : UNKNOWN2 ( < UNKNOWN3 > : UNKNOWN4 ( < UNKNOWN5 > : UNKNOWN6 ( < UNKNOWN7 > : UNKNOWN8 ( < UNKNOWN9 > : UNKNOWN10 ( < UNKNOWN11 > : H ( ) ) ) < UNKNOWN12 > : UNKNOWN13 ( ) ) ) < UNKNOWN14 > : H ( ) ) ) ======================================== Find the unknowns in the following propagation pattern and corresponding C++ program: Propagation pattern: *operation* void fun() *traverse* *from* Example *via* E *to* H *wrapper* H *prefix* (@ cout << endl << "done" << endl; @) C++ program: void Example::fun( ) { this->UNKNOWN15()->fun( ); } void A1::fun( ) { UNKNOWN16} void B::fun( ) { this->UNKNOWN17()->fun( ); } void D1::fun( ) { this->UNKNOWN18()->fun( ); } void C::fun( ) { UNKNOWN19 } void E::fun( ) { this->UNKNOWN20()->fun( ); this->UNKNOWN21()->fun( ); } void G1::fun( ) { this->UNKNOWN22()->fun( ); } void F::fun( ) { this->G1::fun( ); } void G::fun( ) { this->UNKNOWN23()->fun( ); } void UNKNOWN24::fun( ) { // prefix blocks cout << endl << "done" << endl; } Question 4: =========== 33 unknowns, 1 point each f-meal-t Consider the following ------------------------------------------------------------- Class Dictionary ------------------------------------------------------------- 1 RestaurantOrder = OrderList. 2 OrderList ~ {Order}. 3 Order = "ORDER:" 4 [ "Appetizer:" Appetizer_List ] 5 "Entree:" Entree 6 "Salad" Salad 7 [ "Dessert" Dessert ] 8 "Bon" "Appetit!". 9 Appetizer_List ~ Appetizer { "and" Appetizer }. 10 Entree : Beef | Chicken | Vegetarian | Fish . 11 Dessert = "with" DemNumber "calories". 12 Appetizer : Soup| Nachos | 13 Potato_Skins | Stuffed_Mushrooms. 14 Soup = "Soup". 15 Nachos = "Nachos". 16 Potato_Skins = "Potato" "Skins". 17 Stuffed_Mushrooms = "Stuffed" "Mushrooms". 18 Salad = Lettuce "with" 19 Salad_Dressing "dressing" 20 "and" Vegetable. 21 Beef = "Beef". 22 Chicken = "Chicken". 23 Vegetarian = "Vegetarian Entree". 24 Lettuce = . 25 Salad_Dressing = DemString "(" 26 DemNumber "calories )". 27 Vegetable : Tomato| Carrot. 28 Tomato = "tomatoes". 29 Carrot = "carrots". 30 Fish : OceanFish | LakeFish 31 *common* "Fish -" DemString. 32 LakeFish = "Lake". 33 OceanFish = "Ocean". ------------------------------------------------------------- Alphabetically Sorted Cross Reference List ------------------------------------------------------------- Appetizer :12 9 9 Appetizer_List :9 4 Beef :21 10 Carrot :29 27 Chicken :22 10 Dessert :11 7 Entree :10 5 Fish :30 10 LakeFish :32 30 Lettuce :24 18 Nachos :15 12 OceanFish :33 30 Order :3 2 OrderList :2 1 Potato_Skins :16 13 RestaurantOrder :1 Salad :18 6 Salad_Dressing :25 19 Soup :14 12 Stuffed_Mushrooms :17 13 Tomato :28 27 Vegetable :27 20 Vegetarian :23 10 Find the unknowns in the following propagation pattern, object, corresponding sentence, trace (for the object) and C++ program. // // Print the UNKNOWN1 and UNKNOWN2 for the // orders which have UNKNOWN3 on the salad. // *operation* void f() *traverse* *from* RestaurantOrder *to* Salad *wrapper* Salad *prefix* (@ this -> f(dressing); @) *operation* void f(Salad_Dressing* d) *traverse* *from* Salad *to* Carrot *wrapper* Carrot *prefix* (@ d->g_print(); cout << "\n"; @) : RestaurantOrder ( < orders > : UNKNOWN4 { : Order ( < entree > : Beef ( ) < salad > : Salad ( < greens > : Lettuce ( ) < dressing > : Salad_Dressing ( < brandName > : DemString "UNKNOWN5" < calories > : DemNumber "UNKNOWN6" ) < garnish > : UNKNOWN7 ( ) ) < dessert > : Dessert ( < calories > : DemNumber "UNKNOWN8" ) ) , : Order ( < appetizer > : Appetizer_List { : UNKNOWN9 ( ) , : UNKNOWN10 ( ) , : Soup ( ) } < entree > : UNKNOWN11 ( ) < salad > : Salad ( < greens > : Lettuce ( ) < dressing > : Salad_Dressing ( < brandName > : DemString "UNKNOWN12" < calories > : DemNumber "UNKNOWN13" ) < garnish > : UNKNOWN14 ( ) ) ) , : Order ( < appetizer > : Appetizer_List { : UNKNOWN15 ( ) } < entree > : UNKNOWN16 ( < name > : DemString "Native Swordfish" ) < salad > : Salad ( < greens > : Lettuce ( ) < dressing > : Salad_Dressing ( < brandName > : DemString "Italian" < calories > : DemNumber "250" ) < garnish > : UNKNOWN17 ( ) ) < dessert > : Dessert ( < calories > : DemNumber "UNKNOWN18" ) ) } ) Sentence: ORDER: Entree: Beef Salad with "Bleu Cheese" (1500 calories ) dressing and carrots Dessert with 1000 calories Bon Appetit! ORDER: Appetizer: Nachos and Potato Skins and Soup Entree: Chicken Salad with "French" (550 calories ) dressing and tomatoes Bon Appetit! ORDER: Appetizer: Stuffed Mushrooms Entree: Ocean Fish - "Native Swordfish" Salad with "Italian" (250 calories ) dressing and carrots Dessert with 5700 calories Bon Appetit! Trace: (object above is used as input) >> void RestaurantOrder::f() >> void OrderList::f() >> void Order::f() >> void UNKNOWN19::f() >> void Salad::f(Salad_Dressing* d) >> void UNKNOWN20::f(Salad_Dressing* d) UNKNOWN21 << void UNKNOWN22::f(Salad_Dressing* d) << void Salad::f(Salad_Dressing* d) << void UNKNOWN23::f() << void Order::f() >> void Order::f() >> void Salad::f() >> void Salad::f(Salad_Dressing* d) >> void Tomato::f(Salad_Dressing* d) << void Tomato::f(Salad_Dressing* d) << void Salad::f(Salad_Dressing* d) << void Salad::f() << void Order::f() >> void Order::f() >> void UNKNOWN24::f() >> void Salad::f(Salad_Dressing* d) >> void UNKNOWN25::f(Salad_Dressing* d) UNKNOWN26 << void UNKNOWN27::f(Salad_Dressing* d) << void Salad::f(Salad_Dressing* d) << void UNKNOWN28::f() << void Order::f() << void OrderList::f() << void RestaurantOrder::f() C++ program: void RestaurantOrder::f( ) { this->get_orders()->f( ); } void OrderList::f( ) { Order_list_iterator next_Order(*this); Order* each_Order; while ( each_Order = UNKNOWN29 ) { each_Order->f( ); } } void Order::f( ) { this->UNKNOWN30()->f( ); } void Salad::f( ) { // prefix blocks this -> f(dressing); } void Salad::f( Salad_Dressing* d ) { this->UNKNOWN31()->f( d ); } void Vegetable::f( Salad_Dressing* d ) { UNKNOWN32 } void Tomato::f( Salad_Dressing* d ) { } void Carrot::f( Salad_Dressing* d ) { // prefix blocks d->UNKNOWN33(); cout << "\n"; }