Software Engineering with PSF

Example ToolBus Application Specification

As example we have an application consisting of two tools. Tool1 can either send a 'message' to Tool2 and then waits for an acknowledgement from Tool2, or it can send a 'quit' after which the application will shutdown. In this example Tool1 needs a separate adpter for communicating with the ToolBus and Tool2 has this adapter built-in.

Specification of the Tools

data module Data
begin
    exports
    begin
        functions
            message : -> Tterm
            ack : -> Tterm
            quit : -> Tterm
    end
    imports
        ToolTypes
end Data
The first module defines the data that will be used.

process module Tool1
begin
    exports
    begin
        atoms
            snd : Tterm
            rec : Tterm
        processes
            Tool1
    end
    imports
        Data
    definitions
        Tool1 =
                snd(message) .
                rec(ack) .
                Tool1
            +   snd(quit)
end Tool1

process module AdapterTool1
begin
    exports
    begin
        processes
            AdapterTool1
    end
    imports
        Data,
        ToolFunctions,
        ToolAdapterPrimitives,
        ToolToolBusPrimitives
    definitions
        AdapterTool1 =
                tooladapter-rec(message) .
                tooltb-snd-event(tbterm(message)) .
                tooltb-rec-ack-event(tbterm(message)) .
                tooladapter-snd(ack) .
                AdapterTool1
            +   tooladapter-rec(quit) .
                tooltb-snd-event(tbterm(quit))
end AdapterTool1
A specification of Tool1 and its adapter is then obtained.

process module Tool1Adapter
begin
    imports
        NewToolAdapter {
            Tool bound by [
                tool-snd -> snd,
                tool-rec -> rec,
                Tool -> Tool1
            ] to Tool1
            Adapter bound by [
                Adapter -> AdapterTool1
            ] to AdapterTool1
            renamed by [
                ToolAdapter -> Tool1Adapter
            ]
        }
end Tool1Adapter
Tool1 and its adapter are combined by importing NewToolAdapter and binding the parameters.

process module Tool2
begin
    exports
    begin
        processes
            Tool2
    end
    imports
        Data,
        ToolFunctions,
        ToolToolBusPrimitives
    definitions
        Tool2 =
            tooltb-rec(tbterm(message)) .
            tooltb-snd(tbterm(ack)) .
            Tool2
end Tool2
We specify Tool2.

Specification of the ToolBus Processes

data module ID
begin
    exports
    begin
        functions
            T1 : -> TBid
            t1 : -> TBterm
            T2 : -> TBid
            t2 : -> TBterm
    end
    imports
        ToolBusTypes
end ID
Some identifiers are defined in order to distinguish the messages sent between ToolBus processes themselves and between ToolBus processes and their accompanying tools. The lowercase identifiers (of type TBterm) are used with the actions tb-snd-msg and tb-rec-ms. The first argument of a message will always be the origin of the message, and the second argument will serve as its destination. Uppercase identifiers (of type TBid) are used as tool identifiers. Strictly speaking these are not necessary, since there can't be any communication with any other tool because of encapsulation. By using them, however, the actions for communication with a tool will have more similarity to the ones used in the ToolBus.

process module PTool1
begin
    exports
    begin
        processes
            PTool1
    end
    imports
        Tool1Adapter,
        ID,
        ToolBusPrimitives,
        ToolBusFunctions
    processes
        PT1
    definitions
        PTool1 = Tool1Adapter || PT1
        PT1 =
                tb-rec-event(T1, tbterm(message)) .
                tb-snd-msg(t1, t2, tbterm(message)) .
                tb-rec-msg(t2, t1, tbterm(ack)) .
                tb-snd-ack-event(T1, tbterm(message)) .
                PT1
            +   tb-rec-event(T1, tbterm(quit)) .
                snd-tb-shutdown
end PTool1

process module PTool2
begin
    exports
    begin
        processes
            PTool2
    end
    imports
        Tool2,
        ID,
        ToolBusPrimitives
    processes
        PT2
    definitions
        PTool2 = Tool2 || PT2
        PT2 =
            tb-rec-msg(t1, t2, tbterm(message)) .
            tb-snd-eval(T2, tbterm(message)) .
            tb-rec-value(T2, tbterm(ack)) .
            tb-snd-msg(t2, t1, tbterm(ack)) .
            PT2
end PTool2
For both tools a ToolBus process is defined. The specifications for these processes describe the protocol for communication between the tools.

Specification of the ToolBus Application

process module Tools
begin
    exports
    begin
        processes
            System
    end
    imports
        NewTool {
            Tool bound by [
                Tool -> PTool1
            ] to PTool1
            renamed by [
                TBProcess -> XPTool1
            ]
        },
        NewTool {
            Tool bound by [
                Tool -> PTool2
            ] to PTool2
            renamed by [
                TBProcess -> XPTool2
            ]
        },
        ID,
        ToolBusFunctions
    definitions
        System = XPTool1 || XPTool2
end Tools
The ToolBus processes are connected with the tools and together they constitute the process System that merges the resulting two processes.

At this stage renamings are necessary to be able to distinguish the two processes TBProcess (and sets).

process module App
begin
    imports
        NewToolBus {
            Application bound by [
                Application -> System
            ] to Tools
        }
end App
The process System is now transformed into a ToolBus application.

The main process of this application is ToolBus.