Unpredicted hurdles in dealing with integration, variability, and interoperability in software development can be overcome via higher-order process engineering. Even in its simplicity-oriented, tamed form, this approach fosters a powerful _plug&play discipline, where processes and services are created, stored, passed, and moved around like data.


Example

The following illustrations show how the higher-order feature works by describing the execution of a higher-order process. The process is situated in the Chainreaction domain. The green arrows depict the control-flow of the execution, blue arcs represent a read operation (data-flow), as well as orange connections write operations. The pictures are separated into two parts denoting the control-flow (lower part) and the data variables (upper part), respectively.

A generic square placeholder image with rounded corners in a figure.
Fig.1: The constructor activity ‘ExampleGS’ creates a new game strategy process instance and stores it to the context variable ‘player 1 GS’

Fig. 1 introduces a simple process, which creates two game strategies (realized as process models themselves) for the game Chainreaction and stores them to the execution context. Afterwards the process starts a game where both game strategy process instances are passed just like data as higher-order parameters and compete (see activity start game). Each game strategy evaluates the benefit of making a specific game move and returns it as an integer. The execution environment (encapsulated by the activity start game) is responsible for choosing the best rated move and handling the interaction with the game.

In the first image the beginning of the process execution is depicted. Currently, the constructor activity labeled ExampleGS has been executed, i.e., it has created a new process instance of the game strategy ExampleGS and stores it to the context variable player 1 GS.

A generic square placeholder image with rounded corners in a figure.
Fig.2:Process instance ‘ExampleGS’ has been stored to context variable ‘player 1 GS’

Fig. 2 shows that the process instance stored to the context variable is a concrete game strategy implementation. It implements the graph interface GameStrategy, which ensures compatibility between all game strategies.

The strategy evaluates the worthiness of a cell as follows (see Chainreaction for details of the game):

A generic square placeholder image with rounded corners in a figure.
Fig.3:A second constructor activity ‘Standard GS’ stores a game strategy process instance into the context variable ‘player 2 GS’

Fig. 3 depicts:

A generic square placeholder image with rounded corners in a figure.
Fig.4:An implementation of the game strategy process ‘Standard GS’ is stored to the context variable ‘player 2 GS’

In Fig. 4 the implementation of the newly created game strategy process instance is shown. The Standard GS strategy evaluates the worthiness of a cell as follows (see Chainreaction for details of the game):

A generic square placeholder image with rounded corners in a figure.
Fig.5:The game strategies stored to the context variables are used as input parameters to the activity ‘start game’

The activity start game receives two game strategies as input parameters. Fig. 5 shows that the game strategy process instances stored earlier (depicted via the icons labeled exGS and stGS in the context variables) are passed to the activity as parameters. This is where the actual process passing takes place as actual parameters to the subprocess represented by the activity start game. Hence, process instances are treated as first-class citizens.

A generic square placeholder image with rounded corners in a figure.
Fig.6:Reading the passed process instances as input parameter and storing them to context variables

Now the execution dives one hierarchy level deeper into the sub process beneath the activity start game. The respective sub process is shown in Fig. 6. At first, the formal input parameters are evaluated, i.e., at runtime the passed arguments from one hierarchy level above (i.e. the process from the images Fig.1Fig. 5) are stored to context variables. In this example execution the Example GS from the input parameter player 1 GS is stored to context variable with the same name player 1 GS the Standard GS analoguously via input parameter player 2 GS to the equally named context variable.

A generic square placeholder image with rounded corners in a figure.
Fig.7:For turns of player 1 the corresponding game strategy ‘Example GS’ is stored to context variable ‘current GS’

The process manages the game turns where the players do their moves alternatingly until a winner is found. If it is the first player’s turn (see Fig. 7), the activity player 1 GS takes the game strategy process instance stored in the respective context variable and stores it to the context variable current GS. This is currently the game strategy ExampleGS of the first player. The context variable current GS now holds a reference to the corresponding process instance highlighted via the small icon exGS.

A generic square placeholder image with rounded corners in a figure.
Fig.8:For each cell the game strategy ‘Example GS’ (stored in ‘current GS’ ) is executed

For each player’s turn the process iterates through the cells of the board (activity iterate cells). In each loop iteration the process instance of the current game strategy (read from the context variable current GS) is executed as shown in Fig. 8. For the first player this is the game strategy ExampleGS. Hence, the activity evaluate cell uses the process instance currently stored in context variable current GS and executes it in a plug&play manner. Compatibility is guaranteed via the common graph interface GameStrategy.

A generic square placeholder image with rounded corners in a figure.
Fig.9:For moves of player 2 the game strategy ‘standard GS is stored to context variable ‘current GS’

Fig. 9 depicts that after the worthiness of each cell has been evaluated:

For the second player, the respective game strategy process instance Standard GS — stored in context variable player 2 GS — has been put to context variable current GS replacing the game strategy from the first player.

A generic square placeholder image with rounded corners in a figure.
Fig.10:For each cell the game strategy of player 2 ‘standard GS’ is executed in a plug&play manner

Fig. 10 shows, that this time the very same activity evalute cell reads in the current game strategy Standard GS from the context variable current GS that did execute the game strategy of the first player before (in the same execution!). Hence, the new implementation has been plugged in and played at runtime, which is:


Concept

The (technical) key to our approach is the introduction of type-safe stacked second-order execution contexts (see below) that allow for higher-order process modeling. Tamed by our underlying strict service-oriented notion of abstraction, this approach is tailored also to be used by application experts with little technical knowledge: users can select, modify, construct and then pass (component) processes during process execution as if they were data.


We base on the eXtreme Model-Driven Design (XMDD) paradigm and its incarnation the jABC3 which allows for complex hierarchical graph structures by means of business activities that represents a complete sub-graph. Newly, in our enhancements to XMDD (subsumed by HOPE), we support complete processes as first class objects in the (execution) context of a process leading to second-order process modeling. The main technical idea is to allow virtual process model calls in form of business activities representing sub-models, introducing polymorphic executable process models. This is realized by considering process model instances, denoted by process instance, as first-class objects and therefore introducing a second-order context for exchange between the sub-graphs of a service graph. For higher-order modeling, we go one step further towards higher-order functions known from functional programming, as a process instance may have a context with further process instances and so forth. This is realized via a local context for every hierarchy level, that is implicitly stacked. Hence, our context is still second-order. Furthermore we offer activities for the creation of new process instances denoted by constructor activity.

Hence, we go one step further to a tamed variant of higher-order process modeling, which avoids many of the well-known problems of full higher-order as it is based on a very strong notion of type correctness (cf. [46]). Sub-process instances may be used as input and output parameters of a process — called Service Logic Graphs (SLG) — and also be stored in the execution context of every hierarchy level. The actual parameters of a graph type are process instances with its own runtime execution context, which is second-order. Hence, we slice our higher-order models into second-order contexts, which are stacked implicitly. This results in a ‘tamed’ notion of higher-order which allows us to statically type every parameter and context variable.

The compatibility between process model implementations — the service graphs is ensured via so called interface graphs. The development environment ensures that derived service graphs fullfil the requirements of their interface graph. The graphs have fully defined interface descriptions and hide their internals. This supports loose coupling and reusability as well as the organization of process models in process libraries and is technically achieved by:

The documentation is presented in the GUI of the development environment jABC as tooltips in order to ease communication between the modeler of different hierarchy and therefore abstraction levels. The interface and service graphs are organized in SLG libraries and are published to an application expert for use without any knowledge about the details of the underlying structure. This may even be used for communication of requirements, as an application expert may, e.g., model and document a dummy service or interface graph, that is then implemented by someone else. The realization of the hierarchy levels can be done separately, by different responsible people or groups. Every graph (interface and service graphs) may be equipped with an icon (e.g. a raster or vector graphic) which is used for its representation as it is used as a business activity. This eases the understanding of a model with a lot of sub-processes and serves as a recognition feature that appeared to be very effective in cooperation with industrial partners.

It is only a matter of design on which level of abstraction polymorphism is introduced. This has different dimensions on all hierarchy levels, e.g.:

A business activity representing a service or interface graph SIB is denoted by interface graph SIB resp. service graph SIB, or graph SIB if any of both is meant. In general, their interface description consists of a list of inputs, the origin of the process instance, a list of outputs for each outgoing branch, and a reference to its interface or service graph. Process instances as well as outputs are read from resp. written to the context. The corresponding values are represented by context variables at runtime. A process instance may be initialized and put to the context in the graph itself (via constructor SIBs) or before the process has been started. Input parameters may be provided statically for primitive types as well as a selection of Java types supported by the jABC, e.g., strings, enumerations, and file handles. That means that a modeler can design new SLGs and decide which input values are statically entered and which are retrieved from shared resources on-the-fly at modeling-time.