1 / 45

Week 4 – Implementer’s view, conventions and correspondence, representation

Week 4 – Implementer’s view, conventions and correspondence, representation. Jimmy Voss Disclaimer: Not all material is original. Some is taken from the official course slides, and some is taken from Anna’s slides. Implementer’s View.

eliot
Download Presentation

Week 4 – Implementer’s view, conventions and correspondence, representation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Week 4 – Implementer’s view, conventions and correspondence, representation Jimmy Voss Disclaimer: Not all material is original. Some is taken from the official course slides, and some is taken from Anna’s slides.

  2. Implementer’s View • So far, we have taken “Kernel” code as a given for all data structures. • Very few data types are naturally a part of the computer (essentially Integers, Reals, pointers, and arrays). • Abstract data types (ADTs) are built using simpler underlying data structures and pointers.

  3. Primitive Data Types • Computers naturally work with 2 data types: Integers and Floating Point numbers (Reals) • Characters, Booleans, and Pointers are represented as Integer Type objects internally. • All programming languages provide a small number of primitive data types. • Resolve/C++ provides • Integer, Real, Character, Text, Pointer, Boolean, Character_IStream, Character_OStream • Trivia: C++ provides equivalents for all of these, C only for the boldface primitives. • Representations and Reps can be used to combine data types.

  4. Abstract Data Types • In Resolve/C++, Queues, Records, Stacks, Partial Maps, etc. are all Abstract Data Types • In Object Oriented Languages, ADTs are built on top of other data types. • We will mostly be looking at implementing ADTs from simpler ADTs.

  5. Abstract vsConcrete View Abstract Space (Client View) • Abstract View – Data structure modeled by the code. • Concrete View – the underlying implementation in the Kernel code. • There is an onto map from concrete space to abstract space. “represents” relation Concrete Space (Implementer View)

  6. Example: Abstract Set Abstract Space (Set) {0, 5} {1, 2, 3} <5, 0, 0> <1, 2, 3> <5, 0> <0, 5> Concrete Space (using Queue)

  7. Example: Abstract Set Abstract Space (Set) {0, 5} {1, 2, 3} “onto” map, Need not be “one-to-one” <5, 0, 0> <1, 2, 3> <5, 0> <0, 5> Concrete Space (using Queue)

  8. Implementing Abstraction • The Client using a Set does not need to think about how it is implemented. • The Implementer of a class is responsible for making abstract reasoning possible. • Kernel – The class which implements the core functionality of an abstract data structure. • The Kernel code Implementation encapsulates all logic required to create an abstract interface for the client. • Layered Extensions of Kernels are implemented using only calls to Kernel member functions.

  9. Convention and Correspondance • Convention – Acts as ensures and requires clause for all Kernel member functions. • Exceptions (Default Operations): • Initialize (constructor) – ensures, not requires • Finalize (destructor) – requires, not ensures • Clear – ensures, not requires • Swap • Disallows calls to most Kernel functions by Kernel functions. • Correspondence – Gives the mathematical relationship between the abstract and concrete representations of an object.

  10. Example: Set_Kernel_1 classSet_Kernel_1 : implements abstract_instanceSet_Kernel <Item>, encapsulates concrete_instanceRep { private: rep_field_name (Rep, 0, Queue_Of_Item, items); /*! convention |self.items| = |elements (self.items)| correspondence self = elements (self.items) !*/ public: standard_concrete_operations (Set_Kernel_1);

  11. Example: Set_Kernel_1 classSet_Kernel_1 : implements abstract_instanceSet_Kernel <Item>, encapsulates concrete_instanceRep { private: rep_field_name (Rep, 0, Queue_Of_Item, items); /*! convention |self.items| = |elements (self.items)| correspondence self = elements (self.items) !*/ public: standard_concrete_operations (Set_Kernel_1);

  12. Constraints • Constraints – Things which must hold in the abstract space. • Made up Example: Set of Natural Numbers: /*! math subtype NATURAL_MODEL is integer exemplar n constraint n >= 0 !*/ • Note: Constraints can be implemented via conventions.

  13. Example: Set of “natural numbers” Abstract space Concrete space Breaks Convention <5, 0> {0, 5} <5, 0, 5> Correspondence {-2, 5} Breaks Constraints

  14. Default Operations • Constructor • Invokes the special Procedure Initialize(), if it exists. • Invoked when object is created / enters scope. • Destructor • Invoked when an object is destroyed / leaves scope. • Invokes code in member function Finalize(), if it exists. • Swap (&= operator) • Clear • Default operations are created via the following macro: standard_concrete_operations (Kernel_Class_Name);

  15. Example: Set_Kernel_1 concrete_template < concrete_instanceclass Item, concrete_instanceclass Queue_Of_Item = Queue_Kernel_1a <Item>, concrete_instance class Rep = Representation <Queue_Of_Item> > classSet_Kernel_1 : implements abstract_instanceSet_Kernel <Item>, encapsulates concrete_instanceRep { private: rep_field_name (Rep, 0, Queue_Of_Item, items); public: standard_concrete_operations (Set_Kernel_1); Template Parameter (type name place holder) Provides 4 default operations.

  16. Constructors and Destructors • Constructor is used to give each object its default value. • Destructors are more important when dealing with pointers. • Typically used to clean up memory allocations. • Memory is allocated via pointers. • This will become important later.

  17. Representations • Encapsulated version of a Record used in Kernel code. • Representation variables are defined in the concrete Kernel class implementation code. • Representation contains all variables necessary for implementing the underlying logic / storage of the kernel.

  18. Representations • Recall: the accessor mechanism: variable[record_variable] is used to access record variables. • Representations likewise use the accessor to access representation variables. • In kernel code, this looks like: self[rep_variable] • In specifications, we refer to the variables in the form: self.rep_variable

  19. Representations • It is a RESOLVE/C++ coding convention that we use the class name Rep for the inherited Representation.

  20. Initialize() • If no Initialize() function is specified, then the default constructor for Rep is used. • The default constructor for Rep recursively calls the default constructors for all fields. Sometimes this does not give the correct starting state.

  21. Initialize() • Recall Sorting_Machine_Kernel_1? It uses an inserting flag. Internally, it must be set to true when the Sorting Machine is constructed. So, it would have an Initialize procedure similar to the following: local_procedure_body Initialize () { self[inserting_rep] = true; }

  22. Bringing it Together in Code concrete_template < concrete_instance class Item, /*! implements abstract_instanceGeneral_Is_Equal_To <Item> !*/ concrete_instanceclassQueue_Of_Item = Queue_Kernel_1a <Item>, concrete_instanceclass Rep = Representation <Queue_Of_Item> > class Set_Kernel_1 : implements abstract_instanceSet_Kernel <Item>, encapsulates concrete_instance Rep http://www.cse.ohio-state.edu/sce/rcpp/RESOLVE_Catalog-HTML/CT/Set/Kernel_1.html

  23. General_Is_Equal_To • Notice that the previous slide states that Item must implement the General_Is_Equal_To class. • The == operator is NOT supplied by default for all RESOLVE/C++ types, so it is not guaranteed to be in a specified object type. • Resolve objects need not inherit from General_Is_Equal_To, but we are requiring that that must be true for a type to be used in place of Item as a template. • General_Is_Equal_To provides a member function Is_Equal_To • Syntax: X.Is_Equal_To( Y ) • symantically, returns true if X and Y are “the same”, false otherwise.

  24. Example Code (continued) { private: rep_field_name (Rep, 0, Queue_Of_Item, items); /*! convention |self.items| = |elements (self.items)| correspondence self = elements (self.items) !*/ Note: This particular code has no constraint.

  25. Example Code (Continued) public: standard_concrete_operations (Set_Kernel_1); procedure_body Add ( consumes Item& x ) { self[items].Enqueue (x); } . . . function_body Integer Size () { return self[items].Length (); } };

  26. Exercise • Set_Kernel_1 inherits the following Abstract Specification for member function Is_Member from Set_Kernel function Boolean Is_Member ( preserves Item& x ) is_abstract; /*! ensures Is_Member = (x is in self) !*/ • Write the implementation for Is_Member in Set_Kernel_1 • Recall: Set_Kernel_1 inherits a Rep which contains only the field items which is of type Queue_Of_Item. Set_Kernel_1 has the convention: and the correspondence

  27. function_bodyBoolean Is_Member( preserves Item& x ) { object Integer I; object Boolean Success_State = false; // note: Do not call self.Size() while ( (I < self[items].Length()) and (not Success_State)) { if ( x.Is_Equal_To( self[items][current] ) ) { Success_State = true; } // circulate the queue objectcatalyst Item temp; self[items].Dequeue( temp ); self[items].Enqueue( temp ); I = I + 1; } return Success_State; }

  28. Corrections from Yesterday • I introduced General_Is_Equal_To last time. • General_Is_Equal_To is an abstract object, not a function. It provides a member function Is_Equal_To • In Set_Kernel_1, we require that Item instantiates General_Is_Equal_To, giving access to the function Is_Equal_To. • Syntax (given Item X, Y) would be: if ( X.Is_Equal_To( Y ) ) { output << “X and Y are \”the same\””; } else { output << “X and Y are \“different\””; }

  29. Announcements • Lab 2 is due Tuesday January 31st (next week). • You will be building the program from scratch. There is no skeleton code. • Idea – you are taking in an input of words and definitions and creating an html file that allows the user to click the word and get taken to the definition. • Whenever you create a procedure, you should provide specification comments, though the ensures / requires clauses can be written in plain English, encompassed as [ text ].

  30. Abstract vs. Concrete View • In the Kernel, self has 2 meanings: • If self is used in a specification, then it refers to the abstract object that the Kernel represents. • In Set_Kernel_1 we have the correspondance: /*! … correspondence self = elements (self.items) !*/ • The correspondence is used to tell the user precisely what the abstract object is, and how it relates to the underlying concrete representation. • In Set_Kernel_1 specifications, |self| refers to the number of elements in the set.

  31. Abstract vs. Concrete View • The meaning of Self in Source Code: • In source code, self is a special variable accessible in member functions. • self refers to the object which calls the member function in Client Code. • Suppose the client writes (with Integer_Set instantiating Set_Kernel_1): objectInteger_SetMy_Set; object Integer X = 1; My_Set.Add( X ); • Then self in Set_Kernel_1 refers to My_Set on the call above. • self[items] refers to the Queue of Integers which gives the concrete representation of the set self.

  32. Question from Last Class • Set_Kernel_1 inherits the abstract interface for: functionBoolean Is_Member ( preserves Item& x ) is_abstract; /*! ensures Is_Member = (x is in self) !*/ • How do we know that Is_Member preserves the set?

  33. Functions • In functions, all arguments which are passed in are preserved. • When calling member functions, self in its abstract meaning is considered to be passed in as an additional argument. • What self corresponds to in the mathematical model space is preserved for member functions.

  34. Procedures • In RESOLVE/C++ procedures, guarantees about whether variables change or stay the same need to be made explicit in the specifications. • Set_Kernel_1 inherits the following specification from Set_Kernel for Remove procedure Remove ( preserves Item& x, produces Item& x_copy ) is_abstract; /*! requires x is in self ensures self = #self - {x} and x_copy = x !*/

  35. Representations and Encapsulation • Wikipedia Definition of Encapsulation: In a programming language encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination thereof: • A language mechanism for restricting access to some of the object's components. • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

  36. Use of Encapsulation • The Client wants to be able to use a set. • The Client does not truly care about the sets underlying implementation, unless it is inefficient. • By encapsulating the Representation for the set via Rep, the Implementer can work out the underlying details of how the set is implemented in such a way that the Client cannot directly access the concrete space implementation (i.e. the Queue of Item used to implement Set_Kernel_1).

  37. Representation Usage • Every Resolve/C++ representation consists of exactly one internal object, its representation record.

  38. Some notes on Closed Lab 4 • You will be implementing a Sequence using 2 Stacks. /*! correspondence self = reverse (self.before) * self.after !*/ • before and after are stacks. • How would self.before and self.after need to look in order to access self[5] if self = <1, 2, 3, 4, 5, 6, 7, 8>?

  39. You Can’t Call Kernel Functions but. . . • The following appears in Closed Lab 4: local_procedure_bodySet_Length_Of_Before ( alters Stack_Of_Item& before_stack, alters Stack_Of_Item& after_stack, preserves Integer pos ) /*! requires 0 <= pos <= |before_stack| + |after_stack| ensures reverse (before_stack) * after_stack = reverse (#before_stack) * #after_stackand |before_stack| = pos !*/ { //-------- for students to fill in -------- }

  40. What is the Difference? • Set_Length_Of_Before does not act directly on self • Note that before_stack and after_stack are explicitly passed in. They need not refer to self[before] and self[after] • The Kernel’s convention is irrelevant to Set_Length_Of_Before. • Set_Length_Of_Before is a private member procedure of the Kernel class (not accessible by Client code).

  41. Case Study: Tower of Hanoi • http://www.mazeworks.com/hanoi/ • Suppose we were to make a concrete class object that is used to provide a Tower of Hanoi game to the client. It allows the client to start new games, move disks (legally?), and print out the order of how disks are stacked on each rod. • How would we represent this class in the concrete space? • What would be the abstract, mathematical model of the Tower of Hanoi object? • What functionality would we need to provide?

More Related