Question 1: =========== ? UNKNOWNS, 3 points each (directory c-oopsla94) The program below separates the phones into phones which are either on-hook or off-hook. You are given the propagation patterns, the input sentence and corresponding object graph (in textual form) and you are asked to determine the propagation graph. The propagation patterns are: (concatenate has the following definition obtained with the command man Repetition void concatenate( repetition* lst ); Destructively appends lst to the end of the receiver list. The original list is contained in the result.) *operation* Phone_List* find_phones_on_hook() *init* (@ new Phone_List(); @) *traverse* *from* Building *to* Phone *wrapper* Phone *prefix* (@ return_val -> concatenate(this -> find_phones_on_hook(this)); @) *operation* Phone_List* find_phones_on_hook(Phone* p) *init* (@ new Phone_List(); @) *traverse* *from* Phone *to* OnHook *wrapper* OnHook *prefix* (@ return_val -> append(p); @) *operation* Phone_List* find_phones_off_hook() *init* (@ new Phone_List(); @) *traverse* *from* Building *to* Phone *wrapper* Phone *prefix* (@ return_val -> concatenate(this -> find_phones_off_hook(this)); @) *operation* Phone_List* find_phones_off_hook(Phone* p) *init* (@ new Phone_List(); @) *traverse* *from* Phone *to* OffHook *wrapper* OffHook *prefix* (@ return_val -> append(p); @) The input object graph is: : Building ( < phones > : Phone_List { : HomePhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : Ringing ( ) < hookStatus > : OnHook ( ) < talkingStatus > : NonTalking ( ) ) ) ) , : BusinessPhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : NonRinging ( ) < hookStatus > : OffHook ( ) < talkingStatus > : Talking ( ) ) ) ) , : HomePhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : NonRinging ( ) < hookStatus > : OnHook ( ) < talkingStatus > : NonTalking ( ) ) ) ) } ) Traversal directive: *from* { Building } *to* { Phone } Propagation graph for traversal: *source* { Building } *target* { Phone } *paths* Building = < phones > Phone_List . Phone : *common* . Phone_List ~ { Phone } . Traversal directive: *from* { Phone } *to* { OffHook } Propagation graph for traversal: *source* { Phone } *target* { OffHook } *paths* Phone : BusinessPhone | HomePhone . Hardware = < status > Status . Status = < hookStatus > HookStatus . HookStatus : OffHook *common* . OffHook = . BusinessPhone = < status > Hardware . HomePhone = < status > Hardware. Find the UNKNOWNs in the following C++ member function which is generated: void Phone_List::find_phones_on_hook_( Phone_List* & return_val ) { // outgoing calls Phone_list_iterator next_Phone(*this); Phone* each_Phone; while ( each_Phone = next_Phone() ) { // repetition edge prefix wrappers each_Phone->find_phones_on_hook_( return_val ); // repetition edge suffix wrappers } } Question 2: ========== ? UNKNOWNS, 3 points each (directory c-oopsla94) Parsing from several files. The main program fragment below is a test program for testing whether the result object is equal to the expected output. Such a program is useful as part of a regression test. The result object is computed by method find_phones_off_hook. The expected output is stored in file expected as a sentence. If the result object is equal to the expected object, the message SUCCESS is printed and else the message failure. We want to call the run demeter-input expected run demeter-input In either case, file expected is used as input file. Find the UNKNOWNS below. //---------------------------------------- // Your own code follows after this //---------------------------------------- Phone_List* result = iBuilding -> find_phones_off_hook(); cout << "\n*** PHONES OFF HOOK ***\n" << result << endl; Phone_List* expected = new Phone_List(); if( argc >= 3 ) expected = (Phone_List*)expected->g_parse( argv[2] ); else expected = (Phone_List*)expected->g_parse( "expected" ); if ( expected == NULL ) { cerr << "Parser error." << endl; exit(1); } cout << endl; if( result->g_equal( expected ) ) cout << "SUCCESS"; else cout << "FAILURE"; cout << endl; Question 3: =========== ? UNKNOWNS, 4 points each (directory c-oopsla94) Adaptiveness through parsing. When you print the following object graph with g_print: : Building ( < phones > : Phone_List { : HomePhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : Ringing ( ) < hookStatus > : OnHook ( ) < talkingStatus > : NonTalking ( ) ) ) ) , : BusinessPhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : NonRinging ( ) < hookStatus > : OffHook ( ) < talkingStatus > : Talking ( ) ) ) ) , : HomePhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : NonRinging ( ) < hookStatus > : OnHook ( ) < talkingStatus > : NonTalking ( ) ) ) ) } ) the following sentence is printed: ( home phone ringing on-hook non-talking phone quiet off-hook talking home phone quiet on-hook non-talking ) which corresponds to the object built in variable iBuilding20 produced by the C++ program below. Phone_List* iPhone_List1 = new Phone_List(); HomePhone* iHomePhone2 = new HomePhone( ); Ringing* iRinging3 = new Ringing( ); OnHook* iOnHook4 = new OnHook( ); NonTalking* iNonTalking5 = new NonTalking( ); Status* iStatus6 = new Status( iRinging3,iOnHook4,iNonTalking5 ); Hardware* iHardware7 = new Hardware( iStatus6 ); iHomePhone2->set_status(iHardware7 ); iPhone_List1->append( iHomePhone2 ); BusinessPhone* iBusinessPhone8 = new BusinessPhone( ); NonRinging* iNonRinging9 = new NonRinging( ); OffHook* iOffHook10 = new OffHook( ); Talking* iTalking11 = new Talking( ); Status* iStatus12 = new Status( iNonRinging9,iOffHook10,iTalking11 ); Hardware* iHardware13 = new Hardware( iStatus12 ); iBusinessPhone8->set_status(iHardware13 ); iPhone_List1->append( iBusinessPhone8 ); HomePhone* iHomePhone14 = new HomePhone( ); NonRinging* iNonRinging15 = new NonRinging( ); OnHook* iOnHook16 = new OnHook( ); NonTalking* iNonTalking17 = new NonTalking( ); Status* iStatus18 = new Status( iNonRinging15,iOnHook16,iNonTalking17 ); Hardware* iHardware19 = new Hardware( iStatus18 ); iHomePhone14->set_status(iHardware19 ); iPhone_List1->append( iHomePhone14 ); Building* iBuilding20 = new Building( iPhone_List1 ); The corresponding class dictionary is: Building = List(Phone). Phone : BusinessPhone | HomePhone *common* "phone" Hardware. Hardware = Status. Status = RingingStatus HookStatus TalkingStatus. RingingStatus : Ringing | NonRinging. Ringing = "ringing". NonRinging = "quiet". HookStatus : OnHook | OffHook. OnHook = "on-hook". OffHook = "off-hook". TalkingStatus : Talking | NonTalking. Talking = "talking". NonTalking = "non-talking". BusinessPhone = . HomePhone = "home". List(S) ~ "(" {S} ")". Find the UNKNOWNS. Question 4: =========== 15 UNKNOWNS, 3 points each (directory c-oopsla94-2) Program evolution Instead of dealing with the objects in question 1, we want now to work with the following kinds of objects: Drawing the object: Building HAS 1 PART( Phone_List HAS 3 ELEMENTS{ HomePhone HAS 1 PART( Hardware HAS 1 PART( Status HAS 3 PARTS( Ringing HAS 0 PART() HookStatus HAS 0 PART() NonTalking HAS 0 PART()))) BusinessPhone HAS 1 PART( Hardware HAS 1 PART( Status HAS 3 PARTS( NonRinging HAS 0 PART() Missing optional part! Talking HAS 0 PART()))) HomePhone HAS 1 PART( Hardware HAS 1 PART( Status HAS 3 PARTS( NonRinging HAS 0 PART() HookStatus HAS 0 PART() NonTalking HAS 0 PART())))}) End of drawing. Displaying the object as a tree: : Building ( < phones > : Phone_List { : HomePhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : Ringing ( ) < hookStatus > : HookStatus ( ) < talkingStatus > : NonTalking ( ) ) ) ) , : BusinessPhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : NonRinging ( ) < talkingStatus > : Talking ( ) ) ) ) , : HomePhone ( < status > : Hardware ( < status > : Status ( < ringingStatus > : NonRinging ( ) < hookStatus > : HookStatus ( ) < talkingStatus > : NonTalking ( ) ) ) ) } ) End of display. (In other words: we have changed the class dictionary. Instead of an alternation class we use now an optional part.) How do you have to change the propagation patterns so that they still properly compute the phones which are on-hook and off-hook as in question 1 On input (as sentence) ( home phone ringing on-hook non-talking phone quiet talking home phone quiet on-hook non-talking ) The operation on-hook should produce the following phone list: *** PHONES ON HOOK *** ( home phone ringing on-hook non-talking home phone quiet on-hook non-talking ) The operation off-hook should produce the following phone list: *** PHONES OFF HOOK *** ( phone quiet talking ) Find the UNKNOWNs below. *operation* Phone_List* find_phones_on_hook() *init* (@ new Phone_List(); @) *traverse* *from* Building *to* Phone *wrapper* Phone *prefix* (@ return_val -> concatenate(this -> find_phones_on_hook(this)); @) *operation* Phone_List* find_phones_on_hook(Phone* p) *init* (@ new Phone_List(); @) *traverse* *from* Phone *to* HookStatus // *from* Phone *to* OffHook *wrapper* HookStatus *prefix* (@ return_val -> append(p); @) *operation* Phone_List* find_phones_off_hook() *init* (@ new Phone_List(); @) *traverse* *from* Building *to* Phone *wrapper* Phone *prefix* (@ return_val -> concatenate(this -> find_phones_off_hook(this)); @) *operation* Phone_List* find_phones_off_hook(Phone* p) *init* (@ new Phone_List(); @) *traverse* *from* Phone *to* Status // *from* Phone *to* OffHook *wrapper* Status *prefix* // next line new (@ if (this -> get_hookStatus() == NULL) return_val -> append(p); @)