Consider the following class dictionary, propagation patterns and main program. Find the UNKNOWNs so that the program fits the documentation. // ============================================================ // BusRoute.cd : Class dictionary for bus routes. // Written by Ali Ozmez for the COM3360 project. // Last update on Tue Nov 28 17:11:12 1995. // ============================================================ BusRoute = "BusRoute:" RouteName "total" "route" "length" ":" RouteLen "consisting" "of" "bus" "stops" ":" List(BusStop) "with" "assigned" "busses" ":" List(Bus). BusStop = StopId "at:" RouteLoc // clockwise dist. from origin "with" "waiting" "list" ":" List(Person). Bus = BusId "at:" RouteLoc // clockwise dist. from origin [ "currently" "at" "stop" ":" StopId] "capacity:" BusCapac "speed:" BusSpeed "carrying" "passenger(s)" ":" List(Person). Person = PersonId "destination:" StopId. // id of the dest. stop List(S) ~ "(" { S } ")". RouteName = DemString. RouteLen = DemNumber "ft". RouteLoc = DemNumber "ft". BusCapac = DemNumber "passengers". BusSpeed = DemNumber "ft/min". StopId = DemIdent. BusId = DemIdent. PersonId = DemIdent. // ============================================================ // simulate.pp : Propagation patterns for bus route simulation. // Written by Ali Ozmez for COM3360 project. // Last update on Tue Nov 28 21:51:23 1995. // ============================================================ // Following PP does a unit time long (1 min) simulation. *operation* void simulate() *traverse* *from* BusRoute *to* Bus *carry* *in* BusRoute *busRoute = (@ this @) *along* *from* BusRoute *to* Bus *wrapper* Bus (@ StopId *stopId = this->get_currentStop(); if (stopId != NULL) { // waiting at a stop this->drop_passengers(stopId); this->load_passengers( busRoute->find_stop(stopId) ); this->set_currentStop(NULL); // prepare to move } else { // moving along the route int prevPos = this->get_loc(); int nextPos = (prevPos + this->get_spd()) % busRoute->get_len(); BusStop *stop = busRoute->any_stop_around(prevPos, nextPos); if (stop == NULL) this->proceed_to(nextPos); else if (this->have_stop_request( stop->get_id() )) { this->proceed_to( stop->get_loc() ); this->set_currentStop( stop->get_id() ); // stop here } else { int have_room = this->get_cap() - this->count_passengers(); if ( have_room && stop->anybody_waiting() ) { this->proceed_to( stop->get_loc() ); this->set_currentStop( stop->get_id() ); // stop here } else this->proceed_to(nextPos); } } @) // PP to drop the passengers who want to get off at the current stop. // The propagation pattern updates the Bus-object with the new passenger // list. All persons who have arrived at the destination are // removed from the bus. The destination is an argument to // the propagation pattern. *operation* void drop_passengers(StopId *iStopId) *traverse* *from* Bus *to* Person *carry* *in* Person_List *newPasList = (@ new Person_List() @) *along* *from* Bus *to* Person *wrapper* Person (@ if (!iStopId->g_equal( this->get_destination() )) newPasList->append(this); @) *wrapper* Bus *suffix* (@ this->set_passengers(newPasList); @) // PP to load some (or all) of the people waiting at the stop. *operation* void load_passengers(BusStop *iStop) *traverse* *from* Bus *to* Person_List *carry* *in* Person_List *newPasList *along* *from* Bus *to* Person_List *wrapper* Bus (@ int allowance = this->get_cap() - this->count_passengers(); newPasList = iStop->give_passengers(allowance); @) *wrapper* Person_List (@ this->concatenate(newPasList); @) // PP to find the stop from its id. // Finds for a given BusRoute-object and StopId-object, // the BusStop-object with the given StopId-object. *operation* BusStop *find_stop(StopId *iStopId) *init* (@ NULL @) *traverse* *from* BusRoute *to* BusStop *wrapper* BusStop (@ if (iStopId->g_equal( this->get_id() )) return_val = this; @) *wrapper* ~> BusStop_List, BusStop (@ if (return_val) return; @) // PP to count the passengers travelling on a bus. *operation* int count_passengers() *traverse* *from* Bus *to* Person_List *wrapper* Person_List (@ return_val = this->list_length(); @) // PP to transfer people from a stop (to a bus). // The following pp transfers people from a stop to a bus. // It returns the list of passengers which the stop "gives", // and it updates the BusStop object to reflect the people // who have entered the bus. *operation* Person_List *give_passengers(int allowance) *init* (@ new Person_List() @) *traverse* *from* BusStop *to* Person *carry* *in* Person_List *newWaitList = (@ new Person_List() @) *along* *from* BusStop *to* Person *wrapper* Person (@ if (return_val->list_length() < allowance) return_val->append(this); else newWaitList->append(this); @) *wrapper* BusStop *suffix* (@ this->set_waitingList(newWaitList); @) // PP to search for a stop in the given interval of route. *operation* BusStop *any_stop_around(int prevPos, int nextPos) *init* (@ NULL @) *traverse* *from* BusRoute *to* BusStop *wrapper* BusStop (@ int stopLoc = this->get_loc(); if (prevPos < nextPos) { if ((stopLoc > prevPos) && (stopLoc <= nextPos)) return_val = this; } else if ((stopLoc > prevPos) || (stopLoc <= nextPos)) return_val = this; @) *wrapper* ~> BusStop_List, BusStop (@ if (return_val) return; @) // PP to move the bus to its new position. *operation* void proceed_to(int newPos) *traverse* *from* Bus *to* RouteLoc *wrapper* RouteLoc (@ this->get_v()->set_val(newPos); @) // PP to see if there is any passenger who wants to get off at // the specified stop. *operation* int have_stop_request(StopId *iStopId) *init* (@ 0 @) *traverse* *from* Bus *to* Person *wrapper* Person (@ if (iStopId->g_equal( this->get_destination() )) return_val = 1; @) *wrapper* ~> Person_List, Person (@ if (return_val) return; @) // PP to see if anybody waiting at the specified stop. *operation* int anybody_waiting() *init* (@ 0 @) *traverse* *from* BusStop *to* Person_List *wrapper* Person_List (@ return_val = this->empty(); @) // PP to get the get the length of a BusRoute object as an int. *operation* int get_len() *traverse* *from* BusRoute *to* RouteLen *wrapper* RouteLen (@ return_val = this->get_v()->get_val(); @) // PP to get the get the position of a Bus or BusStop object as an int. *operation* int get_loc() *traverse* *from* {Bus, BusStop} *to* RouteLoc *wrapper* RouteLoc (@ return_val = this->get_v()->get_val(); @) // PP to get the get the capacity of a Bus object as an int. *operation* int get_cap() *traverse* *from* Bus *to* BusCapac *wrapper* BusCapac (@ return_val = this->get_v()->get_val(); @) // PP to get the get the speed of a Bus object as an int. *operation* int get_spd() *traverse* *from* Bus *to* BusSpeed *wrapper* BusSpeed (@ return_val = this->get_v()->get_val(); @) //----------------------------------------------------------------- // main.C : Main function for bus route simulation program. // Written by Ali Ozmez for COM3360 project. // Last update on Tue Nov 28 17:11:23 1995. //----------------------------------------------------------------- #include "proj.h" void out_of_store() { cerr << "proj: operator new failed, out of store\n"; exit( 1 ); } #ifndef __GNUC__ extern PF set_new_handler( PF ); #else extern "C" PF set_new_handler( PF ); #endif /* * GEN_DIR is a global variable containing the path of the generation * environment. This path is used to find the cd-print and cd-parse * class dictionaries. * Do NOT delete the following statement. */ char* GEN_DIR = getenv( "GEN_DIR" ); int main( int argc, char* argv[], char* envp[] ) { // set new handler to catch out of memory exception set_new_handler( &out_of_store ); //---------------------------------------- // Parsing an object //---------------------------------------- // specify file to parse in const int MAXPATH = 256; char Dem_input[MAXPATH]; // Input file is first argument if( argc >= 2 ) strcpy( Dem_input, argv[1] ); else { strcpy( Dem_input, "demeter-input" ); // default input } // parse it in cout << "Parsing in object in: " << Dem_input << "." << endl; BusRoute* iBusRoute = new BusRoute(); if ( ( BusRoute* ) iBusRoute -> g_parse( Dem_input ) == NULL ) { cerr << "Parser error." << endl; exit(1); } cout << endl; //---------------------------------------- // Your own code follows after this //---------------------------------------- int i, stime; // Simulation time is the second argument stime = (argc >= 3) ? atoi(argv[2]) : 30; // Display the initial state of the bus route cout << "Initial state of the input bus route : \n\n"; iBusRoute->g_print(); // Do the simulation here for (i=1; i < stime; i++) { cout << "\n\nNext state (after " << i << " minutes) : \n\n"; iBusRoute->simulate(); iBusRoute->g_print(); } // Display the final state of the bus route cout << "\n\nFinal state of the input bus route (after "; cout << stime << " minutes) : \n\n"; iBusRoute->simulate(); iBusRoute->g_print(); cout << "\n\n*** FINISHED ***" << endl; return ( 0 ); } Question 2: =========== Consider the class dictionary from question 1. It only provides for one bus route. Change the class dictionary so that it describes a bus system consisting of several bus routes. Specifically, you class dictionary should accept the following sentence describing a bus system. Assume that a bus system contains at least one BusRoute-object. (busroutes BusRoute: "Ruggles / Harvard Square" total route length : 5000 ft consisting of bus stops : ( Stop0 at: 0 ft with waiting list : ( Person1 destination: Stop1)) with assigned busses : ( Bus1 at: 0 ft currently at stop : Stop0 capacity: 5 passengers speed: 700 ft/min carrying passenger(s) : ()) ++++ BusRoute: "Alewife / Burlington Square" total route length : 5000 ft consisting of bus stops : ( Stop0 at: 0 ft with waiting list : ( Person1 destination: Stop1)) with assigned busses : ( Bus1 at: 0 ft currently at stop : Stop0 capacity: 5 passengers speed: 700 ft/min carrying passenger(s) : ()) ) Find the UNKNOWNs below. Your new class dictionary should have the following form: BusSystem = UNKNOWN FourPlusList ~ UNKNOWN. followed by the class dictionary from question 1. Traversal directive: *from* { BusRoute } *to* { Bus } Propagation graph for traversal: BusRoute = < buses > Bus_List . Bus_List ~ { Bus }. Bus = . ================================ Traversal directive: *from* { Bus , BusStop } *to* { RouteLoc } Propagation graph for traversal: BusStop = < location > RouteLoc . Bus = < position > RouteLoc . RouteLoc = . Consider the C++ program below which was produced from the simulate propagation pattern from question 1. Find the UNKNOWNs below: void BusRoute::simulate( ) { // variables for carrying in and out UNKNOWN // outgoing calls // construction edge prefix wrappers this->get_buses()->simulate( busRoute ); } void Bus::simulate( UNKNOWN ) { // prefix class wrappers StopId *stopId = this->get_currentStop(); if (stopId != NULL) { // waiting at a stop this->drop_passengers(stopId); this->load_passengers( busRoute->find_stop(stopId) ); this->set_currentStop(NULL); // prepare to move } else { // moving along the route int prevPos = this->get_loc(); int nextPos = (prevPos + this->get_spd()) % busRoute->get_len(); BusStop *stop = busRoute->any_stop_around(prevPos, nextPos); if (stop == NULL) this->proceed_to(nextPos); else if (this->have_stop_request( stop->get_id() )) { this->proceed_to( stop->get_loc() ); this->set_currentStop( stop->get_id() ); // stop here } else { int have_room = this->get_cap() - this->count_passengers(); if ( have_room && stop->anybody_waiting() ) { this->proceed_to( stop->get_loc() ); this->set_currentStop( stop->get_id() ); // stop here } else this->proceed_to(nextPos); } } } void Bus_List::simulate( BusRoute* busRoute ) { // outgoing calls Bus_list_iterator next_Bus(*this); Bus* each_Bus; while ( UNKNOWN = UNKNOWN() ) { each_Bus->simulate( busRoute ); } } #include "proj.h" // BusRoute = "BusRoute:" // RouteName // "total" // "route" // "length" // ":" // RouteLen // "consisting" // "of" // "bus" // "stops" // ":" // BusStop_List // "with" // "assigned" // "busses" // ":" // Bus_List . void BusRoute::simulate( ) { DEM_TRACE("BusRoute","void BusRoute::simulate()"); // variables for carrying in and out BusRoute* busRoute = this ; // assignments for carrying in // prefix class wrappers // outgoing calls // construction edge prefix wrappers this->get_buses()->simulate( busRoute ); // construction edge suffix wrappers // suffix class wrappers // assignments for carrying out } // Bus = BusId // "at:" // RouteLoc // [ StopId ] // "capacity:" // BusCapac // "speed:" // BusSpeed // "carrying" // "passenger(s)" // ":" // Person_List . void Bus::simulate( BusRoute* busRoute ) { DEM_TRACE("Bus","void Bus::simulate(BusRoute* busRoute)"); // variables for carrying in and out // assignments for carrying in // prefix class wrappers StopId *stopId = this->get_currentStop(); if (stopId != NULL) { // waiting at a stop this->drop_passengers(stopId); this->load_passengers( busRoute->find_stop(stopId) ); this->set_currentStop(NULL); // prepare to move } else { // moving along the route int prevPos = this->get_loc(); int nextPos = (prevPos + this->get_spd()) % busRoute->get_len(); BusStop *stop = busRoute->any_stop_around(prevPos, nextPos); if (stop == NULL) this->proceed_to(nextPos); else if (this->have_stop_request( stop->get_id() )) { this->proceed_to( stop->get_loc() ); this->set_currentStop( stop->get_id() ); // stop here } else { int have_room = this->get_cap() - this->count_passengers(); if ( have_room && stop->anybody_waiting() ) { this->proceed_to( stop->get_loc() ); this->set_currentStop( stop->get_id() ); // stop here } else this->proceed_to(nextPos); } } // outgoing calls // suffix class wrappers // assignments for carrying out } // Bus_List ~ { Bus }. . void Bus_List::simulate( BusRoute* busRoute ) { DEM_TRACE("Bus_List","void Bus_List::simulate(BusRoute* busRoute)"); // variables for carrying in and out // assignments for carrying in // prefix class wrappers // outgoing calls Bus_list_iterator next_Bus(*this); Bus* each_Bus; while ( each_Bus = next_Bus() ) { // repetition edge prefix wrappers each_Bus->simulate( busRoute ); // repetition edge suffix wrappers } // suffix class wrappers // assignments for carrying out }