-
Notifications
You must be signed in to change notification settings - Fork 25
Structured Random Value Creation
After covering the basics on random numeric value creation we will now investigate how symbolic or structural parameters can be incorporated into design spaces. We proceed looking at the Examples project and play with the code in here.
InPUT descriptors are supposed to be programming language agnostic; they should work for any programming language. For the treatment of numeric parameters this is not a big issue because all languages offer some principle of handling basic primitive datatypes, achieving Turing-completeness. For structural parameters such as functions, methods or algorithms, the handling often varies greatly among programming languages. We for that reason introduce the code mapping concept which separates the abstract definition of structural parameters from the actual implementation. It is important that all languages can import design descriptors, but it is as important that the abstract parameters can easily get tied to the language specific concepts, such as interfaces in Java or templates in C++. We will introduce the code mapping concept exemplified by the Java programming language.
InPUT can be used to make random structural selections. Let's assume that the user has three operators and would like to compare them in order to see which one is best.
In Java, we would usually encapsulate those operators as three classes ( FirstChoice, SecondChoice, ThirdChoice), each implementing a common interface, say, Decision. Speaking about our source code, we have a variable d of type Decision, which we want to assign an instance of a randomly selected subclass. One way of accomplishing this with traditional Java would be, for example;
Decision d;
switch (rng.nextInt(3))
{
case 0: d = new FirstChoice();
break;
case 1: d = new SecondChoice();
break;
case 2: d = new ThirdChoice();
break;
}
Each time we add a new decision we would have to change the selection code. With InPUT we can outsource the decision part to the XML configuration. This requires two lines of actual code:
IDesignSpace space = new DesignSpace("structuredSpaceBasic.xml");
Decision d = space.next("Decision");
Our call to the design space's next method returns an instance of a randomly selected subclass. There is no need to explicitly refer to the subclasses in the code, nor will the program need to be modified and recompiled should the parameters or the Decision inheritance hierarchy be altered. This is all handled by InPUT, and all configuration is deferred to the XML files.
In our case, our design space defines the parameter Decision
<SParam id="Decision">
<SChoice id="FirstChoice"/>
<SChoice id="SecondChoice"/>
<SChoice id="ThirdChoice"/>
</SParam>
which specifies its value as a choice among the three. The connection between the design space specification, which can only describe the classes as conceptual entities, and a concrete implementation is realized by a so called code mapping descriptor which is referenced from the design space file by the mapping attribute:
<DesignSpace id="spaceId" mapping="mappingFile.xml" ...>
Each structural parameter (with one exception, which we cover further down) requires the definition of a Mapping in the code mapping descriptor. A minimum structural Mapping usually consists of an identifier and a type definition. The identifier is the dot separated element id path from the root of the design space. The type is the full name of the implementing (abstract) class, enum, or interface, including package prefix. It follows the complete description of the example above:
<Mapping id="Decision" type="se.miun.itm.input.example.structured.model.Decision"/>
<Mapping id="Decision.FirstChoice" type="se.miun.itm.input.example.structured.model.FirstChoice"/>
<Mapping id="Decision.SecondChoice" type="se.miun.itm.input.example.structured.model.SecondChoice"/>
<Mapping id="Decision.ThirdChoice" type="se.miun.itm.input.example.structured.model.ThirdChoice"/>
The one structural parameter that does not require a specific code mapping in Java are Strings. If defined in the design space as in
<SParam id="someId" type="String">
<SChoice id="first"/>
<SChoice id="second"/>
<SChoice id="third"/>
</SParam>
the value can be received in the code by
String s = ds.next("someId");
and will be one of the choice ids above.
In this tutorial, we learned the differentiation between design spaces and code mappings, and why this is of relevance. The presented example is most basic, as it defines classes with no customized constructors nor field parameters.