Towards the Definition of Environment

First the environment will be defined. As soon discussed, the environment definition is built from the definitions of the analysis, design, implementation, and testing phases. Each phase defines a plane which is then defined in terms of atomic, compound, and complex steps that may have a sibling relationship. Together the four planes form a multi-layered space, either static or dynamic. In some cases, a dynamic space may exhibit the non-monotonic property. There are two special steps: the problem statement and the system acceptance test. The environment is the multi-layered finite space consisting of the analysis, design, implementation, and testing planes with two special steps: the initial problem statement and the system acceptance test.

Section 2.2 defined the analysis phase. In summary, the analysis phase defines the problem that the customer is trying to solve. The deliverable result at the end of the analysis phase is a requirement document. Ideally, the requirement document states in a clear and precise fashion what is to be built. The analysis phase represents the ``what'' phase. The requirement document tries to capture the requirements from the customer's perspective by defining goals and interactions at a level removed from the implementation details. The analysis phase was summarized in Table 2.1 on page . The analysis phase builds a declarative model of the system.

Section 2.3 defines the design phase. In summary, the design phase starts with the requirement document delivered by the analysis phase and maps the requirements into an architecture. The architecture defines the components of the software system, their interfaces and behaviors. The deliverable design document is the architecture specification. The design document describes a plan to implement the requirements. This phase represents the ``how'' phase. Details on computer programming languages and environments, machines, packages, application architecture, distributed architecture layering, memory size, platform, algorithms, data structures, global type definitions, interfaces, and many other engineering details are established. The design may include the reuse of existing components. The design phase is summarized in Table 2.2 on page . The architecture is a high level mapping of the declarative model of the system into the imperative model defined by the implementation.

Section 2.4 defines the implementation phase. In summary, in the implementation phase the system is built, performance is enhanced, reusable libraries are established, and errors are corrected. The end deliverable is the product itself. In the implementation phase the team builds the components either from scratch or by composition. Given the architecture document from the design phase and the requirement document from the analysis phase, the team should build what has been requested, though there is still room for flexibility. The implementation phase represents an imperative model of the system

Section 2.5 defines the testing phase. Testing is usually based on the regression paradigm where current results from a test suite are compared to a gold standard. As the testing suite grows the coverage of the system improves and enhances the quality. Testing includes internal testing, unit testing, application testing, and stress testing. The testing phase is summarized in Table 2.4 on page .

Let
be the *n*_{a} requirement steps
leading to a possible analysis *A*.
Let
be the *n*_{d} architecture steps
leading to a possible design *D*.
Let
be the *n*_{i}
implementation steps
leading
to a possible implementation *I*.
Let
be the *n*_{t}
testing steps leading
to a possible testing *T*.
A step is recursively defined in terms of atomic, compound, and complex steps. A step may have sibling relationships with other steps.

Let *a*_{j} be an atomic analysis step then *a*_{j} has no decomposition.
Let *d*_{j} be an atomic design step then *d*_{j} has no decomposition.
Let *i*_{j} be an atomic analysis step then *i*_{j} has no decomposition.
Let *t*_{j} be an atomic analysis step then *t*_{j} has no decomposition.
Each individual step in the analysis, design, implementation, or testing phases may be an atomic step.

Each individual step in the analysis, design, implementation, or testing phases may be a compound step. A compound step can be decomposed into several steps using refinement techniques. A compound step may itself be composed of multiple atomic, compound, or complex steps. See Figure 5.1 on page for a visual representation of a compound step.

Let
be the *n*_{a<<1464>>j} compound requirement steps leading to
a possible analysis *a*_{j}.
Let
be the *n*_{d<<1468>>j} compound architecture steps leading to
a possible design element *d*_{j}.
Let
be the *n*_{i<<1472>>j} compound implementation steps leading to
a possible implementation component *i*_{j}.
Let
be the *n*_{t<<1476>>j} compound testing steps leading to
a possible testing step *t*_{j}.

Steps in the analysis, design, or implementation phases may together form a complex step. In the special case of a testing phase step, the step may be atomic or compound but not complex. An analysis step expands into one or more design steps. A design step expands into one or more implementation steps. While an implementation step expands into one or more testing steps. These expansions include steps to define the parent step as well as sibling steps to support the expansion. The expansions may not be disjoint with other expansion and overlap forming a directed acyclic graph. See Figure 5.2 on page for a visual representation of an example directed acyclic graph complex step consisting of analysis, design, implementation, and testing steps.

Let
be the *m*_{d<<1494>>j} design steps leading to
a possible analysis step *a*_{j}.
Let
be the *m*_{i<<1498>>j} implementation steps leading to
a possible design step *d*_{j}.
Let
be the *m*_{i<<1502>>j} testing steps leading to
a possible implementation step *i*_{j}.

The presence of one step may require the inclusion of several sibling steps. A sibling step supports the accomplishment of another sibling step but was not explicitly in the decomposition of the parent compound step. For example, steps derived directly from the problem statement fulfill functional requirements. A chosen architecture in the design phase that supports the functional requirements introduces non-functional requirements. A sibling step fulfills these non-functional requirements. See Figure 5.3 on page for a visual representation of an example sibling relationship.

The *n*_{a} analysis steps
leading to a possible analysis *A* form an
analysis plane.
The *n*_{d} design steps
leading to a possible design *D* form a design plane.
The *n*_{i}
implementation steps
leading
to a possible implementation *I*
form an implementation plane.
The *n*_{t}
testing steps
leading
to a possible testing suite *T*
form a testing plane.

Let the space *S* be represented as <*A*,*D*,*I*,*T*>
where
*A* is a possible analysis of *n*_{a} steps,
*D* is a possible analysis of *n*_{d} steps,
*I* is a possible analysis of *n*_{i} steps, and
*T* is a possible analysis of *n*_{t} steps.
The total number of steps in space *S* is
*n*_{a} + *n*_{d} + *n*_{i} + *n*_{t}. This space is finite and bounded
because we are dealing with the software engineering
of only finite and bounded systems.
See Figure 5.4 on page for a visual representation of the multi-layered space.

In a static space, all steps are known before any analysis, design, implementation, or testing begins. No new steps enter the space. No existing step leaves the space and no step is in conflict with any other existing step.

Let
*S*^{t0} & = & <*A*,*D*,*I*,*T*>

In a dynamic space, steps may enter or leave the space at any time. Let
*S*^{t0} & = & <*A*,*D*,*I*,*T*>

If in a dynamic space when additional steps are discovered, more work may be required to accomplish these steps but the newly discovered steps and their associated work are consistent additions to the system as defined by the already accomplished steps, then the space is monotonic. No part of the system has to be replaced or thrown out to accommodate the newly discovered steps.

In a non-monotonic space, some steps may be in conflict with other steps. The choice of one of these steps will negate the other step even if the negated step is already considered part of the solution. The conflicts are primarily in the analysis plane between different requirements. However, conflicts in the design, implementation, and testing planes may also exist. Same plane conflicts may also occur.

Consider a non-monotonic conflict within the analysis plane.
Let *A*_{1} be a collection of analysis steps that are consistent with themselves.
Let *A*_{2} be a collection of analysis steps that are consistent with themselves but in conflict with the analysis steps found in *A*_{1}. To accomplish steps *A*_{2} one
would first have to mitigate conflicting steps *A*_{1} and
visa versa.
Let *A*_{3} be a collection of analysis steps that are consistent with themselves and consistent with the analysis steps in *A*_{1} and the analysis step in *A*_{2}.
There are then two consistent analysis options. Either
analysis *A* is <*A*_{1},*A*_{3}> or *A* is <*A*_{2},*A*_{3}> but not both. Similar definitions apply for conflict within the design, implementation, and testing planes.

Consider a non-monotonic conflict that crosses many planes.
Let *D*_{1} be a collection of design steps,
let *I*_{1} be a collection of implementation steps, and
let *T*_{1} be a collection of testing steps that are all
consistent with *A*_{1}.
Let *D*_{2} be a collection of design steps,
let *I*_{2} be a collection of implementation steps, and
let *T*_{2} be a collection of testing steps that are all
consistent with *A*_{2} but in conflict with *A*_{1},
*D*_{1}, *I*_{1}, or *T*_{1}.
Let *D*_{3} be a collection of design steps,
let *I*_{3} be a collection of implementation steps, and
let *T*_{3} be a collection of testing steps that are all
consistent with *A*_{3} and consistent with *A*_{1},
*D*_{1}, *I*_{1}, and *T*_{1} but in conflict with
*A*_{2},
*D*_{2}, *I*_{2}, and *T*_{2}.
Then either one of the following holds but not both.

Above the space, defined by the analysis, design, implementation, and testing planes, is the problem statement. The problem statement defines, at a very high level and abstraction, the declarative goal of the system. The problem statement is a requirement but because it is the parent step of all other steps, it is elevated above the analysis plane to emphasize importance. The problem statement may represent a compound step. In a dynamic space the problem statement may also change with time.

For clarity, *a*_{1} will represent the problem statement in the remaining sections.

The system acceptance test is the final step in the testing plane. If the outcome of the system acceptance test is acceptable, then the system is ready for product release and general customer availability. The system acceptance test verifies that the requirements in the problem statement have been satisfied.

For clarity, *t*_{n<<1578>>t} will represent the system acceptance test in the remaining sections.

The environment is the multi-layered finite space consisting of the analysis, design, implementation, and testing planes with two special steps: the initial problem statement and the system acceptance test.

The environment is hierarchical with each node representing an atomic, compound, or complex step. The environment may be static or dynamic. See Figure 5.5 on page for a visual representation of the environment.

To summarize the taxonomy, an environment contains the four disjoint finite planes of analysis, design, implementation, and testing. Each plane may contain many steps. Each plane contains at least one step. Each step may be atomic, compound, or complex. Steps may have sibling relationships. There is a special analysis step called the problem statement and a special testing step called the system acceptance test. See Figure 5.6 on page for a visual representation of the taxonomy.