1
On Syntactic and Semantic Dependencies in Service-Oriented Architectures
Diego Marmsoler Technical University of Munich
Email: diego.marmsoler@tum.de
Abstract—In service oriented architectures, compo-nents provide services on their output ports and con-sume services from other components on their input ports. Thereby, a component is said to depend on another component if the former consumes a service provided by the latter. This notion of dependency (which we call syntactic dependency) is used by many architecture analysis tools as a measure for system maintainability. With this paper, we introduce a weaker notion of dependency, still sufficient, however, to guar-antee semantic independence between components. Thereby, we discover the concepts of weak and strong semantic dependency and prove that strong semantic dependency indeed implies syntactic dependency. Our alternative notion of dependency paves the way to more precise dependency analysis tools. Moreover, our results about the different types of dependencies can be used for the verification of semantic independence.
Index Terms—Syntactic Dependency; Semantic De-pendency; Service Oriented Architectures;
I. Introduction
The architecture of a system describes its overall orga-nization into components and connections between these components. In service oriented architectures (SOA), com-ponents provide services on their output ports which are realized by consuming services of other, connected compo-nents on their input ports [1], [2]. In such architectures, a component A is said to depend on another component B, if an input port of A is (transitively) connected to any out-put port of B. The notion of dependency is important in software architecture since it is used by many architecture analysis tools [3], [4], [5], [6], especially for maintainability analyses.
However, as the following example shows, not every such dependency is indeed influencing the semantics of a component. Assume, for example, a component A is offering some service mult implemented as follows:
int mult(int x, int y) {
int z:=B.add(x,y);
return x∗y;
}
In this simple example, service mult provided by compo-nent A consumes a service add from another component B and stores its results into variable z. Therefore, according to the traditional definition of dependency, component A would depend on component B. However, mult does not use the result of add to compute its own result. Thus,
changing the implementation of add (provided by compo-nent B) would not have any impact on the semantics of service mult (provided by component A). Thus, syntactic dependency does not necessarily impact the semantics of components and dependency analysis tools which rely on syntactic dependency may be improved by considering semantic dependency instead.
Approach: To address this problem, we provide a weaker notion of dependency and investigate its relation-ship to syntactic dependency. Therefore, we first formalize the notion of syntactic and semantic dependency in terms of a formal model of service oriented architectures. Then, we investigated their relationships by proving properties about it. Thereby, we discover the concepts of weak and strong semantic dependency and prove, i.a., that strong semantic dependency indeed implies syntactic dependency.
Contributions: The contribution of this paper is twofold:
First, it provides a formal characterization of the no-tion of syntactic and semantic dependency in service oriented architectures.
Moreover, it provides several, theoretical results about the relationship between these two concepts.
Thereby, to the best of our knowledge, this is the first formalization of these two important notions of software architectures. Moreover, it is the first work which formally proves that strong semantic dependency indeed requires syntactic dependency.
Implications: The formal characterization of semantic dependency may be used to improve architecture analy-ses. Moreover, the theoretical results provide us with a powerful tool to verify semantic independence of certain components.
Overview: The remainder of the paper is structured as follows: In Sec. II, we introduce our model of ser-vice oriented architectures which serves as a foundation to characterize syntactic and semantic dependency. The different types of dependencies are then characterized and analyzed in Sec. III. The paper concludes with a review of related work in Sec. IV and a brief summary of the major results as well as a brief outlook in Sec. V.
II. A Model of Service-Oriented Architectures
In [1], [2] we introduce an abstract model of service-oriented architectures. In the following, we summarize the main concepts and notations such as ports which can be
valuated by services (Sec. II-A), components (Sec. II-B), architecture configurations (Sec. II-C), and the seman-tics of a component within an architecture configuration (Sec. II-D).
A. Ports and Services
For our model of service-oriented architectures, we as-sume the existence of sets P and S which contain all ports and services, respectively. Thereby, our notion of service is rather abstract; a service can be everything, from a simple procedure of a programming language to a complex web-service consisting of a series of interactions. A port is just a placeholder for a set of related services; one can think of the procedure’s declaration (in the sense of a programming language) or of the address of the web service. Thus, we assume the existence of a function type : P → ℘ (S ), (where ℘ (X) is the power set of a set X) which assigns a type to each port. That is, the type of a port is simply a set of services. We require that each port is classified either as an input port or as an output port, but not as both. We let I be the set of input ports and O be the set of output ports, such that:
I ∪ O = P and I ∩ O = ∅ .
Ports and services constitute the parameters of our theory. By saying what ports and services are, our theory can be applied to different contexts.
To provide a better intuition for our model, in the following, we provide some examples about concrete in-stantiations of the model. Thereby, we denote with N+ be the set of positive integers and Z the set of all integers.
Example II.1 (Modeling stateless services). Consider the code depicted in Fig. 1, where we write bint for bigint, a programming language type of large but fixed-size integers. We define the set of input ports as I = {i1, i2}, the set of output ports as O = {o}, where the ports are function declarations, i.e., simplifying, strings:
i1 = “bint add(bint,bint)”, i2 = “bint sub(bint,bint)”,
= “bint mult(bint,bint)”.
Intuitively, a service at a port will be a (set-theoretic) map that fits the declaration given by the port. Formally, we fix some M ∈ N+ and let bint = [ −2M , 2M −1], which we use as the set of representatives of integers modulo 2M+1. The types of the ports are sets containing certain partial or total maps from bint×bint to bint:
type(i1) is the singleton set containing exactly the modular addition, which is defined for all arguments.
type(i2) is the set containing partial and total maps whose result coincides with that of modular subtrac-tion, whenever the first argument is positive and the second is 1.
type(o) is the set of total maps m that multiply the arguments x, y modulo 2M+1, whenever y is nonnegative. Such m must return some result also for negative y.
i1
bint mult(bint x, bint y) {
bint z := 0;
while (y>0) {
o
z := add(x,z) ;
y := sub(y,1) ;
}
i2
return z;
}
Figure 1: Instantiation of the model with stateless services.
In this example, the types abstract away some details about termination and outcome and all details about the way the computations are performed.
If even more abstraction would be wished, we would redefine the above types as, e.g., the set of all partial and total maps from bint×bint to bint. In this alterna-tive situation, the correctness of a service provided by a component (here mult) would depend on the correctness of the services required by a component (here add and sub). That is, if these services would not work properly, the service provided by a component would not work as
expected.
The above example does not use any global state. In a more complex model, a component may also have an encapsulated state, e.g. in class instances in object-oriented programming languages. As shown in [7], we can easily encode stateful models by changing the notion of a service to relate streams of concrete values of the input parameters to streams [8] of concrete return values.
B. Components
Informally speaking, a component consists of input ports, output ports, and some behavior that generates services at output ports from services at input ports. The behavior may be nondeterministic, so we represent it by a map that assigns a set of output-port valuations to every input-port valuation. In the following, we are not interested in all details about a component. Rather, we assume the existence of a set C containing all components.
In our model, ports can be reused by different compo-nents which leads to the notion of component port, i.e., a port combined with the corresponding component. For a set of component ports P ⊆ C × P, a valuation is a function from the set P to the set of services that respects the corresponding port type. By P we denote the set of all valuations for P , formally,
P = µ ∈ (P → S ) | ∀p ∈ P : µ(p) ⊆ type(p) .
For pairwise different ports pi (i∈N0, i≤n) and any services Si (i∈N0, i≤n), we write
[p0, . . . , pn 7→S0, . . . , Sn] = {(pi, Si) | i ∈ N0 ∧ i≤n}
to denote the valuation that maps each port pi to the corresponding service Si (i∈N0, i≤n).
2
Now we can define the concept of a component setup.
Definition II.2 (Component setup). A component setup is a triple (C, in, out, bhv), consisting of:
a set of components C ⊆ C,
a mapping to assign a set of input ports to a compo-nent in : C → ℘ (I ),
a mapping to assign a set of output ports to a component out : C → ℘ (O), and
a mapping to assign a behavior to each component
bhv : c ∈ C 7→ in(c) → ℘
out(c) .
For a component
setup S = (C, in, out, bhv) and a subset
of components C0 ⊆ C, we
define the notion of port
selection to obtain the ports of components:
def
[
Πi(S, C0)
=
c∈C0
{c} × in(c) , and
def
[
Πo(S, C0)
=
{c} × out(c) .
c∈C0
To select all component ports of a component setup S, we write
0 def 0 ∪ 0
Π(S, C ) = Πi(S, C ) Πo(S, C ).
For the case C0 = C we just write Πi(S), Πo(S), and Π(S),
respectively.
C. Architecture Configuration
An architecture configuration, informally, consists of a set of components and a so-called attachment describing the connections between the components. (From now on we say simply “configuration” for “architecture configura-
tion”.)
In the following, we denote by
(
y11)
= y2 2
∈
XdY = f ⊆ X×Y ∀ x, y1, y2 :
)
x, y
, (x, y
f
⇒
the set of partial maps
from a set X to a set Y .
Definition II.3 (Architecture Configuration). An (ar-chitecture) configuration is a pair (S, A) consisting of a component setup S and a so-called attachment A ∈ (Πi(C) d Πo(C)), such that, if a service is provided at an output port that is connected to an input port, the component owning the input port must be able to employ the service, i.e., the port types are compatible. Formally:
∀ (pi, po) ∈ A: type(po) ⊆ type(pi).
Note that the domain of an attachment is a subset of the occurring input-ports, and the range is a subset of the occurring output-ports, meaning that the input ports are connected to the output ports. Moreover, the attachment is modeled as a partial map which means that not necessarily all input ports are internally connected. These, unconnected, input ports are called open input ports and they are obtained by the following mapping:
def
{i ∈ Πi(S, C0) | i < dom A ∨ A(i) < C0}
Πin((S, A), C0) =
Again, for all C0
we simply write Πin((S, A)) = Πi(S)
(dom A).
D. Composition
In the following, we define the semantics of a component within an architecture configuration. Therefore, we first introduce the concept of architecture valuation. In the following, we write f|Z for the restriction of a (partial) map f to the domain (dom f) ∩ Z.
Definition II.4 (Architecture valuation). Given an archi-tecture configuration z = (S, A) over a component setup
= (C, in, out, bhv) and a set of components C0 ⊆ C, a valuation ν ∈ Π(S, C0) is an architecture valuation iff the following conditions hold:
ν respects every connection in A which is closed under
C0: ∀(i, o) ∈ A∩(Πi(S, C0)×Πo(S, C0)) : ν(i) = ν(o) and
ν respects the behavior of every component in C0:
∀ c0 ∈ C0 : ν|out(c0 ) ∈ bhv(c0)(ν|in(c0 )).
The set of all architecture valuations for a configuration
and set of components C0 is denoted Cz0. If C0 = C we
just write z.
Now we can use the notion of architecture valuation to define the semantics of the composition.
Definition II.5 (Composition). Given a configuration
= (S, A) over a component setup S = (C, in, out, bhv),
the semantics of a component c ∈ C is given by a map
~c•z : Πin(z) → ℘ out(c) , defined as
µ 7→ (λp ∈ out(c). ν(c, p)) | ν ∈ z ∧ ν|Πin(z) = µ} .
Intuitively, given a valuation µ of the open input ports, an element of the component semantics ~c•z(µ) is created by restricting an architecture valuation ν that is consistent with µ on the configuration’s input ports Πin(z).
Note II.6. Whenever ~c•z(µ) = ∅ for one component, it follows that ~c0•z(µ) = ∅ for all components.
We say that an architecture configuration z is consistent whenever for each µ ∈ Πin(z) there exists a c ∈ C, such that ~c•z(µ) , ∅.
III. Dependencies
In the following, we introduce and study the concepts of syntactic and semantic dependency. We begin with the notion of syntactic dependency.
A. Syntactic Dependency
Syntactic dependency of components is induced by the attachment relation of a configuration. We say that a com-ponent c syntactically depends on another components c0, if any input port of c is connected to any output port of c0.
Definition III.1 (Syntactic dependency). Syntactic de-pendency for a configuration z = ((C, in, out, bhv), A) is a
z
relation € ⊆ C × ℘ (C) defined by
z
def
c € C0
⇐⇒ ∃i ∈ Πi(z, {c}), o ∈ Πo(z, C0) : (i, o) ∈ A .
Note that the syntactic dependency relation is not
transitive, in general: just because a component
c1
3
depends on another component c2 which depends on a third component c3, this does not necessarily mean that c1 depends on c3.
z
For a configuration z, we denote by €+ the transitive
z z
closure of € and by €∗ the reflexive-transitive closure of
z z
€. Moreover, we denote by [_] €∗: C → ℘ (C), defined via
z def 0 z 0
c €∗ = {c ∈ C | c €∗ c } for c ∈ C ,
all components c0 that a given component c syntactically (transitively) depends on.
B. Semantic Dependency
In this section, we are going to investigate the notion of semantic dependency. To define it, we first have to introduce the concept of an architecture update.
1) Architecture Update: A key concept for the discus-sion of semantic dependency is the notion of semantic update. We model such a change of the semantics of a component through an update function.
Definition III.2 (Semantic update). For a component setup S = (C, in, out, bhv), a subset of components C0 ⊆ C, and a family of maps (fc)c∈C0 with fc : in(c) →
℘ out(c) , a semantic update [S / f] is a component setup
(C, in, out, fun0), such that
fun0(c) =
(bhv(c)
else .∈
fc
if c
C0
The notion of semantic update easily generalizes to con-
figurations: [(S, A) / f0
def
] = ([S / f0] , A) .
Note that since an update does not change the interface of a component, an update of an architecture configuration is still an architecture configuration according to Def. II.3.
2) Semantic Dependency: Definition: Using the notion of semantic update, we can now define the concept of semantic dependency. Informally, a component c semantically depends on a component c0 if updating c0 may influence the semantics of c in an architecture configuration z. Note that the semantics of a component may be independent from isolated semantic changes of other components, but it may change if the semantics of these components changes simultaneously. Thus, the definition of semantic dependency needs to consider sets of components, rather than single components:
Definition III.3 (Semantic dependency). Semantic de-pendency for a configuration z = ((C, in, out, fun), A) is a
z
relation ˆ ⊆ C × ℘ (C) defined by
z
def (
(fc)c C0
: ~c•z ,~c•[z/f])
c ˆ C0
∃
∧
⇐⇒
∈
@C00
⊆ C0, (fc)c∈C00 : ~c•z ,~c•[z/f] .
3) Relating Syntactic and Semantic Dependencies: As shown in the introduction, syntactic dependency does not necessarily imply weak semantic dependency. However, one may expect that semantic dependency indeed implies
o = {S1} o = {S2}
C1 C2
Figure 2: Architecture configuration with two components.
syntactic dependency. However, as the following example shows, this is not the case, in general.
Example III.4 (Why weak semantic dependency does not necessarily imply syntactic dependency). Consider the architecture configuration z depicted in Fig. 2. According to Def. II.5, the semantics of the composition is given by
valuation ν : {(C1, o), (C2, o)}, such that ν((C1, o)) = S1 and ν((C2, o)) = S2 and the restriction to the output ports of C1 provides us with the semantics of C1 in z: ~C1•z =
{[(C1, o) 7→S1]}.
Now assume that we are updating component C2 with the empty behavior function. Note that it is not possible to satisfy Def. II.4 by any valuation ν : {(C1, o), (C2, o)}, which is why the semantics of C1 in z is given by the empty
set: ~C1•z[C2/∅] = ∅.
Thus, the semantics of C1 in the original configuration is different from the semantics of C1 after updating C2 which is why C1 depends semantically on C2 according to Def. III.3. However, since we do not have any connection between the ports of C1 and C2, they are syntactically
independent according to Def. III.1.
In this example we leverage the fact that Def. III.2 allows an update with the empty function. Note, however, that a similar example can be given without using an empty update. Instead we would use an update which creates an inconsistency in a part of the configuration which is not connected.
The intuition behind a semantic dependency is that this kind of dependency also considers compilation issues. If one component does not compile, than the whole archi-tecture does so, as well.
C. Strong Semantic Dependency
In the following, we define a stronger, more fine-grained notion of semantic dependency. We start with an auxiliary definition.
For a component setup (C, in, out, bhv), a subset of components C0 ⊆ C, and a family of maps (fc)c∈C0 with
fc : in(c) → ℘ out(c) , we say that the updating of C0 in z by f is consistency preserving iff
∀ µ ∈
Πin(z)
: ~c•z(µ) , ∅
(1)
=⇒ ∀ µ ∈
: ~c•[z/f](µ) , ∅ ,
Πin(z)
i.e., informally, [z / f] continues to produce some output whenever z did so.
We can use the concept of a consistency preserving update to introduce the notion of strong semantic depen-dency. Informally, a component c strongly semantically
4
depends
on
a component c0
if
a
consistency
preserving
Proof sketch. Follows from Lem. III.9, since there exists no
update of c0
may influence the semantics of c in z.
z
input port of c € which is connected with any output
Definition III.5 (Strong semantic dependency). Strong
z
∗
port of C (c €∗).
semantic dependency for a consistent configuration z
=
This lemma can now be used to proof the following key
z
⊆ C × ℘ (C) defined
((C, in, out, fun), A) is a relation Š
result of this paper.
by
Theorem III.11. For a consistent architecture configura-
z
def
( (fc)c
: [z / f] is cp
~c•z ,~c•[z/f])
c Š C0
∈
C0
∧
∧
tion z = (S, A) over component setup S = (C, in, out, bhv),
⇐⇒
∃
strong semantic dependency implies the transitive closure
@C
00
⊆
C0,
f
z / f
] is cp ∧ ~
c
c
.
( c)c∈C00 :
[
•z
,~
•[z/f]
of syntactic dependency:
Note III.6. Note that strong semantic dependency is only
z
z
defined for consistent architecture configurations.
∀c ∈ C, C0
0
⊆ C : c Š C0
=⇒ c €∗ C
1) Relating Weak and Strong Semantic Dependency:
The contrapositive
provides us with a powerful rule
As expected, strong semantic dependency implies weak
which is often employed in software architecture:
semantic dependency.
Proposition III.7. Given a consistent architecture con-
Corollary III.12. If a component does not tran-
figuration z = ((C, in, out, fun), A), we have:
sitively connect to another component, it is guar-
z
z
anteed that it does not semantically depend on that
(c Š C0) =⇒
(c ˆ C0) .
component!
As the following example shows, the backward direction
One final interesting observation is, that a component
does not hold in general.
Example III.8 (Why weak semantic dependency does
may be semantic independent of one component and of
another component but semantically dependent on both!
not imply strong semantic dependency?). Consider again
the architecture configuration depicted in Fig. 2. Accord-
D. Dependencies: Summary
ing to Ex. III.4, C1 is
weakly semantic
dependent
on
In the following, we summarize our results about the
C2. Moreover, recall, that the semantic update used in
Ex. III.4 to demonstrate weak semantic dependency was
relationships between syntactic and semantic dependency:
non consistency
preserving. Indeed,
there is
no
consis-
syntactic
: Implies
tency preserving update f∈(C2.in→℘(C2.out)), such that
~C1•z , ~C1•z[C2/f].
dependency
: Not nec. Imply
2) Relating Syntactic and Strong Semantic Dependency:
*Only for consistent
Since strong semantic dependency implies weak semantic
architectures.
dependency (Prop. III.7) and syntactic dependency does
weak semantic
strong semantic
not necessarily imply weak semantic dependency, we can
dependency
dependency*
conclude that syntactic dependency does not necessarily
imply strong semantic dependency either.
Figure 3: Relating syntactic, weak semantic, and strong
Lemma III.9. Given an architecture configuration z =
semantic dependency.
(S, A) over component setup S
= (C, in, out, fun) and a
set of components C0 ⊆ C. Then,
IV. Related Work
(ν0 ∪ ν00) ∈
⇐⇒
z
To the best of our knowledge, this paper provides the
ν0
∈
C
0
∧
ν00
∈
(C
C0)z
∧
first formalization of semantic dependency of components
z
∩
(i, o)
A
Πi(S, C0) × Πo(S, C C0)
: ν0(i) = ν00(o) ∧ and results about
its
relation to
syntactic dependency.
∀(i, o)
∈
A
Πi(S, C
C0)
×
Πo(S, C0)
: ν00
(i) = ν0(o)
. However, related work can be found in two related areas:
∀
∈
∩
transitive closure
One source for
related work can be found in code
Applying the lemma to the syntactic
dependency analyses. One of the first works in this area is
leads to a lemma which turns out to be useful later on.
Podgurksi and Clarke [9] which provide formal definitions
Lemma III.10. Given an architecture configuration z =
of weak and strong syntactic dependency between program
(S, A) over component setup S = (C, in, out, bhv) and a
statements. Moreover, they provide also a notion of seman-
component c ∈ C. Then,
tic dependency between statements. In their work about
the Dependent Core Calculus, Abadi et. al [10] provide a
(ν0
∪ ν00) ∈
⇐⇒
z
calculus of dependency to reason about different types of
ν0 ∈
z
z
∧ ν
00 ∈
z
z
∧
program dependencies. While many of the ideas in these
c €∗
C c €∗
(i, o)
A
Πi(S, C
(c €z
))
Πo(S, c €z
)
:
works are similar to our work, these works are concerned
∀ ν00(i)∈= ν∩0(o) .
∗
×
∗
with dependenciess at the level of code and therefore they
cannot be used at the architecture level. With our work,
5
we provide a more abstract characterization at the level of components which allows our results to be applied to architecture analyses.
Related work can also be found in studies of dependen-cies at the architectural level. An example of work in this area comes from Gu et al. [11] which use the concept of Port Dependency Graph as a notion of component dependency. Another approach in this area comes from Guo [12] who applies category theory to model software component dependencies. While these approaches indeed investigate dependencies at the architecture level, they focus only on the notion of syntactic dependencies. With our work we complement these works by providing a characterization and analysis of semantic dependency.
One exception to the above approaches is Broy’s work on traceability [13] in which he introduces a notion of seman-tic dependency between system specifications. Roughly speaking, two specifications are considered dependent if one implies the other. While this definitions allows to in-vestigate dependencies at the specification level, our work focuses on dependencies between concrete components of an architecture.
V. Conclusion
This paper presents a formalization and analysis of different types of component dependencies. Thereby, the major results of the paper can be summarized as follows:
We provide a formal characterization of the notion of syntactic dependency in SOA.
We provide a formal characterization of the notion of semantic dependency in SOA.
– Thereby we introduce the notion of semantic up-date.
– Moreover, we distinguish between weak and strong semantic dependency.
We show that syntactic dependency does not neces-sarily imply weak semantic dependency
We show that weak semantic dependency does not necessarily imply syntactic dependency
We show that strong semantic dependency implies weak semantic dependency
We show that weak semantic dependency does not necessarily imply strong semantic dependency
We show that syntactic dependency does not neces-sarily imply strong semantic dependency
As a major result we show that strong semantic dependency implies the transitive closure of weak semantic dependency.
Possible Implications: Taking the contrapositive of the last result provides us with a powerful tool for the verification of semantic independence in service oriented architectures.
Moreover, the results provided in this paper can serve as a foundation for the development of tools which can be used to investigate semantic dependencies in service oriented architectures.
6
Future Work: Future work arises in two directions:
Based on the results provided in this paper, a calculus should be developed which can be used to verify se-mantic and syntactic dependencies in service oriented architectures.
Second, the results should be implemented into tools which can be used to investigate semantic dependen-cies in service oriented architectures.
Acknowledgments: We would like to thank Manfred Broy for useful discussions about the topic. Moreover, we would like to thank Wolfgang Boehm and all the anonymous reviewers of TASE 2018 for comments and helpful suggestions on earlier versions of this paper. Parts of the work on which we report in this paper was funded by the German Federal Ministry of Education and Research (BMBF) under grant no. 01Is16043A.
References
[1] A. Malkis and D. Marmsoler, “A model of service-oriented ar-chitectures,” in Components, Architectures and Reuse Software (SBCARS), 2015 IX Brazilian Symposium on. IEEE, 2015,
pp. 110–119.
[2] D. Marmsoler, “Towards a theory of architectural styles,” in Proceedings of the 22nd ACM SIGSOFT International Sym-posium on Foundations of Software Engineering – FSE 2014, ACM. ACM Press, 2014, pp. 823–825.
[3] C. Pich, L. Nachmanson, and G. G. Robertson, “Visual analysis of importance and grouping in software dependency graphs,” in Proceedings of the 4th ACM symposium on Software visualiza-tion. ACM, 2008, pp. 29–32.
[4] N. Sangal, E. Jordan, V. Sinha, and D. Jackson, “Using de-pendency models to manage complex software architecture,” in ACM Sigplan Notices, vol. 40, no. 10. ACM, 2005, pp. 167–176.
[5] A. Srivastava, J. Thiagarajan, and C. Schertz, “Efficient inte-gration testing using dependency analysis,” Technical Report MSR-TR-2005-94, Microsoft Research, Tech. Rep., 2005.
[6] L. Xiao, Y. Cai, and R. Kazman, “Design rule spaces: A new form of architecture insight,” in Proceedings of the 36th Inter-national Conference on Software Engineering. ACM, 2014, pp. 967–977.
[7] D. Marmsoler, A. Malkis, and J. Eckhardt, “A model of layered architectures,” in Proceedings 12th International Workshop on Formal Engineering approaches to Software Components and Architectures, FESCA 2015, London, United Kingdom, April 12th, 2015., ser. EPTCS, B. Buhnova, L. Happe, and J. Kofron, Eds., vol. 178, 2015, pp. 47–61. [Online]. Available: https://doi.org/10.4204/EPTCS.178.5
[8] M. Broy, “A logical basis for component-oriented software and systems engineering,” The Computer Journal, vol. 53, no. 10,
pp. 1758–1782, Feb. 2010.
[9] A. Podgurski and L. A. Clarke, “A formal model of program de-pendences and its implications for software testing, debugging, and maintenance,” IEEE Transactions on software Engineering, vol. 16, no. 9, pp. 965–979, 1990.
[10] M. Abadi, A. Banerjee, N. Heintze, and J. G. Riecke, “A core calculus of dependency,” in Proceedings of the 26th ACM SIGPLAN-SIGACT symposium on Principles of programming languages. ACM, 1999, pp. 147–160.
[11] Z. Gu, S. Kodase, S. Wang, and K. G. Shin, “A model-based approach to system-level dependency and real-time analysis of embedded software,” in Real-Time and Embedded Technology and Applications Symposium, 2003. Proceedings. The 9th IEEE. IEEE, 2003, pp. 78–85.
[12] J. Guo, “Using category theory to model software component dependencies,” in Engineering of Computer-Based Systems, 2002. Proceedings. Ninth Annual IEEE International Confer-ence and Workshop on the. IEEE, 2002, pp. 185–192.
[13] M. Broy, “A logical approach to systems engineering arti-facts: semantic relationships and dependencies beyond traceability—from requirements to functional and architectural views,” Software & Systems Modeling, pp. 1–29, 2017.