Data Structures   3.  Sorts of Domain Definitions 4.  Manipulations of Domain Definitions 5.  Translating Domain Definitions 6.  Dialogue Sessions 7.  Example of Concentric Circles 8.  Example of Domain Substitution applied to Concentric Circles 9.  Example of an Order Processing Application 10.Example of an Airport Information System 11.Example of a Rental Boat Business 12.Benefits of Domain Definitions

11.  Example of a Rental Boat Business

In the preceding examples we discussed homogeneous lists where all the elements are of the same type. In this section we will discuss the relations between alternative domain definitions and heterogeneous lists. We use as an example a Rental Boat Business.  Let us assume that we want to describe a small start-up company that rents small boats. The company has 4 rowboats, 3 motorboats, and 2 sailboats. With this kind of information we are already able to create a set of related domain definitions because we know the key concepts of the business. See Figure 15.

<<  Alternative Domain Definitions  >>

<<       of a Rental Boat Business       >>

Boat = Sailboat | Rowboat | Motorboat;

Rowboat = ID + Status + Persons + Rent;

Motorboat = ID + Status + Persons + Rent + Speed;

Sailboat = ID + Status + Persons + Rent + Size;

Boatset = collection (Boat);

ID = text;

Status = enum ( Free, Reserved, Occupied);

Persons = integer;

Rent = real;

Size = integer;

Speed = real;

integer = predefined;

real  = predefined;

text = predefined;

Figure 15: Domain definitions of a Rental Boat Business

Mark that we did not include in our domain definitions the numbers of the boats. That will be done later. In general, values are not included in domain definitions. They belong to the following phase.

Every boat has a unique identification (ID). The Status domain is an enumeration domain reflecting the status of the boat. The Persons domain specifies the maximum of allowed persons in the boat when the boat is Free and it specifies the actual number of persons when the boat is Occupied. The Rent domain specifies the amount of rent to be paid for one hour of sailing.

Based on these domain definitions the metaprocessor will generate a skeleton file. If we compare the number of domain definitions in the meta input file (14) with the number of generated lines in the skeleton file (130), we get an expansion factor of almost 10. A complete listing of the skeleton file is given in Appendix A. Because of the size of the skeleton file we will discuss only some parts of the contents of this file. First, we will discuss the three compound domain definitions. Secondly, the alternative domain definition will be discussed.

The domain definitions for Sailboat, Motorboat, and Rowboat are quit similar in nature. That means that the corresponding components are also similar. Therefore we will discuss only one of the three compound domain definitions in detail, namely Sailboat. The corresponding component is described in Figure 16.

component Sailboats;
type Sailboat;
newSailboat(ID, Status, Persons, Rent, Size) -> Sailboat;
getID(Sailboat) -> ID;
getStatus(Sailboat) -> Status;
getPersons(Sailboat) -> Persons;
getRent(Sailboat) -> Rent;
getSize(Sailboat) -> Size;
setID(Sailboat, ID) -> nothing;
setStatus(Sailboat, Status) -> nothing;
setPersons(Sailboat, Persons) -> nothing;
setRent(Sailboat, Rent) -> nothing;
setSize(Sailboat, Size) -> nothing;
begin
newSailboat(ID, Status, Persons, Rent, Size) = Sailboat:[ID; Status; Persons; Rent; Size];
getID(aSailboat) = aSailboat.ID;
getStatus(aSailboat) = aSailboat.Status;
getPersons(aSailboat) = aSailboat.Persons;
getRent(aSailboat) = aSailboat.Rent;
getSize(aSailboat) = aSailboat.Size;
setID(aSailboat, aID) = [ aSailboat.ID:= aID];
setStatus(aSailboat, aStatus) = [ aSailboat.Status:= aStatus];
setPersons(aSailboat, aPersons) = [ aSailboat.Persons:= aPersons];
setRent(aSailboat, aRent) = [ aSailboat.Rent:= aRent];
setSize(aSailboat, aSize) = [ aSailboat.Size:= aSize];
end component Sailboats;

Figure 16: Example of a compound domain component

As explained earlier, the metaprocessor generates three kinds of functions for compound domains: the new functions, the get functions, and the set functions. The new functions create new descriptors. A descriptor is a data structure that describes a certain type. For example, the newSailboat function generates a new Sailboat descriptor. A get functions retrieves an element of the specified descriptor, and a set function changes an element of the descriptor.

For alternative domain definitions the generated skeleton file contains a special component to handle alternative domains. In our example it is the component Boats. A stripped version is shown in Figure 17. This component introduces (line 2) the category Boat with the members Sailboat, Rowboat, and Motorboat.  In Elisa, categories are used to specify alternative domain types. The following lines of the interface-section (line 3, etc) specify the signatures of the functions defined for the Boat category.  In the implementation-section the corresponding functions are defined. Let us use as an example the getID operation. In the interface-section the one-line signature specifies as input an item of the type Boat. In the implementation-section there are 3 definition lines for getID. Each line tests if the incoming descriptor is one of the category members.  If so, the corresponding function will be executed. For example, the first line of the implementation-section test if the incoming Boat-descriptor is Sailboat-descriptor.  If that is the case, the getID function of the  Sailboats component will be evaluated and the ID value of the Sailboat will be returned. The same procedure applies to other functions and members of the category.

component Boats;
type Boat = category (Sailboat, Rowboat, Motorboat);
getID(Boat) -> ID;
getStatus(Boat) -> Status;
getPersons(Boat) -> Persons;
getRent(Boat) -> Rent;
setID(Boat, ID) -> nothing;
setStatus(Boat, Status) -> nothing;
setPersons(Boat, Persons) -> nothing;
setRent(Boat, Rent) -> nothing;
begin
getID(Sailboat:aSailboat) = getID(aSailboat);
getID(Rowboat:aRowboat) = getID(aRowboat);
getID(Motorboat:aMotorboat) = getID(aMotorboat);
getStatus(Sailboat:aSailboat) = getStatus(aSailboat);
getStatus(Rowboat:aRowboat) = getStatus(aRowboat);
getStatus(Motorboat:aMotorboat) = getStatus(aMotorboat);
getPersons(Sailboat:aSailboat) = getPersons(aSailboat);
getPersons(Rowboat:aRowboat) = getPersons(aRowboat);
getPersons(Motorboat:aMotorboat) = getPersons(aMotorboat);
getRent(Sailboat:aSailboat) = getRent(aSailboat);
getRent(Rowboat:aRowboat) = getRent(aRowboat);
getRent(Motorboat:aMotorboat) = getRent(aMotorboat);
setID(Sailboat:aSailboat, aID) = setID(aSailboat, aID);
setID(Rowboat:aRowboat, aID) = setID(aRowboat, aID);
setID(Motorboat:aMotorboat, aID) = setID(aMotorboat, aID);
setStatus(Sailboat:aSailboat, aStatus) = setStatus(aSailboat, aStatus);
setStatus(Rowboat:aRowboat, aStatus) = setStatus(aRowboat, aStatus);
setStatus(Motorboat:aMotorboat, aStatus) = setStatus(aMotorboat, aStatus);
setPersons(Sailboat:aSailboat, aPersons) = setPersons(aSailboat, aPersons);
setPersons(Rowboat:aRowboat, aPersons) = setPersons(aRowboat, aPersons);
setPersons(Motorboat:aMotorboat, aPersons) = setPersons(aMotorboat, aPersons);
setRent(Sailboat:aSailboat, aRent) = setRent(aSailboat, aRent);
setRent(Rowboat:aRowboat, aRent) = setRent(aRowboat, aRent);
setRent(Motorboat:aMotorboat, aRent) = setRent(aMotorboat, aRent);
end component Boats;

Figure 17: Example of a category component

The skeleton file can now be used as basis for writing programs. We return to our rental boat business. Remember that we want to describe a start-up company that rents small boats. The company has 4 rowboats, 3 motorboats, and 2 sailboats.  First, we need to define those boats. (Figure 18).

include "BoatRental12.txt";

Rbt01  = newRowboat("RB01", Occupied, 2, 10.);
Rbt02  = newRowboat("RB02", Occupied, 2, 10.);
Rbt03  = newRowboat("RB03", Free, 4, 15.);
Rbt04  = newRowboat("RB04", Occupied, 4, 15.);

Mbt01  = newMotorboat("MB01", Occupied, 6, 20., 25.);
Mbt02  = newMotorboat("MB02", Occupied , 6, 20., 25.);
Mbt03  = newMotorboat("MB03", Free, 6, 30., 25.);

Sbt01  = newSailboat("SB01", Occupied, 6, 40., 4);
Sbt02  = newSailboat("SB02", Free, 6, 50., 4);

AllBoats = {Boat: Rbt01, Rbt02, Rbt03, Rbt04, Mbt01, Mbt02, Mbt03, Sbt01, Sbt02);

Figure 18: Heterogeneous list of Boats

All the boats of the company are defined, including their status. The boats are collected in the AllBoats list. Mark that this is a heterogeneous list, containing descriptors of different types all belonging to the category Boat. Let us assume the following scenario: at a certain moment in time the manager of the company  wants an overview of the free boats. He uses in the following session (Figure 18) the AllFreeBoats procedure. This procedure operates on all elements belonging to the Boat category. The result is a series of free boats.

AllFreeBoats(list(Boat)) -> multi(Boat);
AllFreeBoats(boats) =
[ aBoat = items(boats);
if getStatus(aBoat) == Free then aBoat;
];

AllFreeBoats(AllBoats)?
Rowboat:[ID = "RB03";
Status = Free;
Persons = 4;
Rent = 15.]
Motorboat:[ID = "MB03";
Status = Free;
Persons = 6;
Rent = 30.;
Speed = 25.]
Sailboat:[ID = "SB02";
Status = Free;
Persons = 6;
Rent = 50.;
Size = 4]

Figure 19: Heterogeneous series of free Boats

In the mean time a potential customer comes with a special request. He wants to rent the cheapest boat there is for 4 persons. The rent may not exceed 20 dollars. The manager returns to his computer and uses the following procedure (Figure 20).

AllCheapestBoats(list(Boat), Persons, Rent) -> multi(Boat);
AllCheapestBoats(boats, persons, rent) =
[ aBoat = items(boats);
if getStatus(aBoat) == Free &
getPersons(aBoat) >= persons &
getRent(aBoat) <= rent
then aBoat;
];

AllCheapestBoats(AllBoats, 4, 20.)?
Rowboat:[ID = "RB03";
Status = Free;
Persons = 4;
Rent = 15.]

Figure 20: Selection of free Boats

The result is that only one rowboat fulfills the requirements.   Also this procedure operates on all elements belonging to the Boat category. That means that, for example, the getStatus operation should be able to activate the getStatus operations of Rowboat, Motorboat, or Sailboat, depending on the actual descriptor type.

 Part 6: Metaprogramming 11. Example of a Rental Boat Business

 Introduction: Home | Highlights of Elisa | Integrating Different Paradigms | Getting Started with Elisa | Demo's  | What is Domain Orientation | Bibliography | Copyright | News | Contact Language Description: Lexical Elements | Basic Data Types and Expressions | Definitions | Streams | Backtracking | Statements and Special Expressions | Arrays | Lists | Descriptors | Components | Collections | Generic Components | Terms | Categories | Types | Built-in Definitions | Higher-order Definitions | External Interfaces | Index Data Structures: Sequences | Examples involving Lists | Trees | Graphs | Searching State Spaces | Language Processing | Knowledge Representations Domain Modeling: Design Patterns: Introduction | Abstract Factory | Builder | Factory Method | Prototype | Singleton | Adapter | Bridge | Composite | Decorator | Facade | Flyweight | Proxy | Chain of Responsibility | Command | Interpreter | Iterator | Mediator | Memento | Observer | State | Strategy | Template Method | Visitor