

This paper focuses on software systems that are subject to continuous evolution, because of changes in the environment in which they are embedded and because of changes in the requirements. Evolution traditionally requires human-intensive re-design and re-deployment of (parts of) an existing system. Increasingly, however, systems are expected to be able to continue to operate as changes occur, and to self-adapt their behavior to continue to provide service. Furthermore, systems are expected to achieve this flexibility without compromising the required level of dependability of the service offered.
After motivating the practical relevance of these issues in modern software systems and providing a general reference framework to systematically reason about evolution and self-adaptation, the paper focuses on three key aspects: architecture, specification, and verification. At the architectural level, systems should be built as dynamic composites, whose parts and interconnections may change over time. At design time, the contractual obligations of the different parts (components, subsystems) should be precisely (formally) specified. Verification that the different parts satisfy their contractual obligations must extend from design time to run time, because of the dynamic nature of these systems. Run-time verification may then support both evolution and self-adaptation.