Consider the following class dictionary, object graph, corresponding sentence, propagation patterns and corresponding trace information and Tcl/Tk script. Find the UNKNOWNS. Class dictionary: -------------------------------------------------------------------------- Example = MyList MyList DemString. MyList : Empty | NonEmpty. Empty = "e" . NonEmpty = Element MyList. Element = DemNumber. Object graph: -------------------------------------------------------------------------- Example ( < l1 > : NonEmpty ( < first > : Element ( < v > : DemNumber "1" ) < rest > : NonEmpty ( < first > : Element ( < v > : DemNumber "2" ) < rest > : NonEmpty ( < first > : Element ( < v > : DemNumber "3" ) < rest > : NonEmpty ( < first > : Element ( < v > : DemNumber "4" ) < rest > : Empty ( ) ) ) ) ) < l2 > : NonEmpty ( < first > : Element ( < v > : DemNumber "22" ) < rest > : NonEmpty ( < first > : Element ( < v > : DemNumber "33" ) < rest > : NonEmpty ( < first > : Element ( < v > : DemNumber "44" ) < rest > : Empty ( ) ) ) ) < string > : DemString "ABC" ) corresponding sentence: -------------------------------------------------------------------------- // some comment 1 2 3 4 e 22 33 44 e // string "ABC" propagation patterns -------------------------------------------------------------------------- *operation* DemNumber* length() *init* (@ new DemNumber(0) @) *traverse* *from* {MyList, NonEmpty} *to* Element *wrapper* Element *prefix* (@ return_val -> set_val(*return_val + 1); @) // a Lisp-style recursive implementation // copies the first list // conditional-free *operation* MyList* concatenate_rec(MyList* second) *wrapper* MyList (@ @) *wrapper* Empty *suffix* (@ return_val = second; @) *wrapper* NonEmpty *prefix* (@ return_val = new NonEmpty(this -> get_first(), this -> get_rest() -> concatenate_rec(second)); @) trace information -------------------------------------------------------------------------- >> DemNumber* NonEmpty::length(), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void MyList::length_(DemNumber* & return_val), >> at Empty , *** PREMATURELY TERMINATED *** , << at Empty , *** PREMATURELY TERMINATED *** , << void MyList::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << DemNumber* NonEmpty::length(), >> DemNumber* NonEmpty::length(), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void NonEmpty::length_(DemNumber* & return_val), >> void Element::length_(DemNumber* & return_val), << void Element::length_(DemNumber* & return_val), >> void MyList::length_(DemNumber* & return_val), >> at Empty , *** PREMATURELY TERMINATED *** , << at Empty , *** PREMATURELY TERMINATED *** , << void MyList::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << void NonEmpty::length_(DemNumber* & return_val), << DemNumber* NonEmpty::length(), >> MyList* NonEmpty::concatenate_rec(MyList* second), >> void NonEmpty::concatenate_rec_(MyList* & return_val,MyList* second), >> MyList* NonEmpty::concatenate_rec(MyList* second), >> void NonEmpty::concatenate_rec_(MyList* & return_val,MyList* second), >> MyList* NonEmpty::concatenate_rec(MyList* second), >> void NonEmpty::concatenate_rec_(MyList* & return_val,MyList* second), >> MyList* Empty::concatenate_rec(MyList* second), >> void Empty::concatenate_rec_(MyList* & return_val,MyList* second), << void Empty::concatenate_rec_(MyList* & return_val,MyList* second), << MyList* Empty::concatenate_rec(MyList* second), << void NonEmpty::concatenate_rec_(MyList* & return_val,MyList* second), << MyList* NonEmpty::concatenate_rec(MyList* second), << void NonEmpty::concatenate_rec_(MyList* & return_val,MyList* second), << MyList* NonEmpty::concatenate_rec(MyList* second), << void NonEmpty::concatenate_rec_(MyList* & return_val,MyList* second), << MyList* NonEmpty::concatenate_rec(MyList* second), Tcl/Tk script in main.tcl -------------------------------------------------------------------------- set l1 [$iExample get_l1:] set l2 [$iExample get_l2:] activate $l1 NonEmpty activate $l2 NonEmpty $l1 g_equal: $l2 # the last line will return UNKNOWN $l1 g_equal: $l1 # the last line will return UNKNOWN set length_l1 [[$l1 length:] get_val:] set length_l2 [[$l2 length:] get_val:] message .m1 -relief raised -justify center -text "first list $length_l1" message .m2 -relief raised -justify center -text "second list $length_l2" pack .m1 -side left pack .m2 -side left set concatenated [$l2 concatenate_rec: $l1] set lc [[$concatenated length:] get_val:] message .m3 -relief raised -justify center -text "concatenated list $lc" pack .m3 -side left Question 2: =========== 5 points per UNKNOWN. Find the UNKNOWNs in the following class dictionary: A = UNKNOWN B C. B = List(B1) List(B2). B1 = "UNKNOWN". B2 = "UNKNOWN" D. D : E | F. E = "UNKNOWN". F = UNKNOWN. List(S) ~ "UNKNOWN" {S} "UNKNOWN". C : G | H. G = "UNKNOWN". H = A. so that the following sentence // sentence ( x x x ) ( y e y y e) () () u gets parsed correctly. Make your UNKNOWNs of minimal size. Do not introduce extra classes. SOLUTION // Consider the following class dictionary: A = B C. B = List(B1) List(B2). B1 = "x". B2 = "y" D. D : E | F. E = "e". F = . List(S) ~ "(" {S} ")". C : G | H. G = "u". H = A. Question 3: =========== Law of Demeter and propagation patterns 5 points per UNKNOWN Consider the following class dictionary which is a simplification of the cd from the previous question. A = B C. B = B1 B2. B1 = . B2 = D. D : E | F. E = . F = . List(S) ~ {S} . C : G | H. G = . H = A. rewrite the propa Consider the following propagation pattern written for the above class dictionary. 1: *operation* void f1() 2: *wrapper* A 3: (@ this -> get_b() 4: -> get_ds() 5: -> get_d() 6: -> g(); @) On which line is the first violation of the Law of Demeter? Give the line number in UNKNOWN. Rewrite the above function f1 as an equivalent function f2 which is written in terms of propagation patterns. *operation* void f2() *traverse* *from* A *bypassing* -> *,c,* *to* D *wrapper* D (@ this -> g(); @) *operation* void g() *wrapper* D (@ cout << this; @) The above propagation pattern generates C++ code which satisfies the Law of Demeter. Find the UNKNOWNs in the C++ code below. void A::f2( ) { this->get_b()->f2( ); } void B::f2( ) { this->get_ds()->f2( ); } void B2::f2( ) { this->get_d()->f2( ); } void D::f2( ) { this -> g(); }