Theoretical Foundations of Information Technology

Chapter 7
Software Theory, Engineering Models and Formal Methods

Doctorate in Information Technology
Theoretical Foundations of Information Technology   •   Doctorate

Chapter 7: Software Theory, Engineering Models and Formal Methods

1. Introduction

Software is not merely a collection of executable instructions. It is a set of abstractions, models, specifications, decisions, and evolving artefacts that collectively implement socio-technical objectives. The theoretical foundations of software engineering explain how software can be structured, reasoned about, verified, maintained, and governed. These foundations are particularly important for doctoral-level information technology because software systems increasingly operate critical infrastructure, financial markets, healthcare services, transportation networks, and public institutions.

Software theory addresses questions such as: What does it mean for a program to be correct? How can complexity be controlled? How can independently developed components interact safely? How should systems evolve without losing reliability? Engineering models and formal methods provide systematic answers. They do not eliminate uncertainty, but they make assumptions explicit, support rigorous reasoning, and improve the dependability of development decisions.

This chapter examines modularity, abstraction, architecture, specification, verification, type systems, concurrency, software evolution, and lifecycle models. It also considers the strategic, ethical, and managerial consequences of choosing particular engineering approaches.

2. Learning Objectives

After studying this chapter, the reader should be able to:

1. Explain the theoretical foundations of modular and maintainable software.

2. Distinguish abstraction, encapsulation, modularity, architecture, and implementation.

3. Compare major software lifecycle models and identify suitable contexts for their use.

4. Describe the purposes of formal specification, verification, validation, and testing.

5. Explain the role of type systems in preventing software defects.

6. Analyse concurrency, synchronization, and distributed-system challenges.

7. Evaluate software evolution and technical debt from technical and managerial perspectives.

8. Apply formal and semi-formal reasoning to practical software problems.

9. Assess ethical, governance, and dependability implications of software engineering decisions.

3. Meaning and Concept

Software engineering is the disciplined application of engineering principles to the development, operation, maintenance, and retirement of software. It differs from programming because it addresses the whole system lifecycle, including requirements, architecture, risk, quality, organizational coordination, deployment, and change.

Software theory provides mathematical and conceptual models for understanding programs. A program may be viewed as a function that maps inputs to outputs, a state-transition system, a set of interacting processes, or a transformation of data. Each view reveals some properties while hiding others. For example, a functional model is useful for input-output correctness, whereas a state model is more appropriate for analysing a banking transaction or an air-traffic controller.

A central difficulty is that software is intangible and highly malleable. Physical systems constrain design through material properties; software can be changed rapidly, but each change may introduce unforeseen interactions. Complexity therefore arises not only from code volume but also from dependencies, concurrency, changing requirements, organizational boundaries, and environmental assumptions.

A dependable system is one that stakeholders can justifiably trust. Dependability commonly includes reliability, availability, safety, security, maintainability, and resilience. These qualities must be designed into architecture and processes rather than inspected into a completed product.

4. Fundamental Principles

Abstraction

Abstraction represents essential properties while suppressing unnecessary detail. A database interface may expose operations such as `create`, `read`, and `update` without exposing storage indexes or disk protocols. Good abstraction reduces cognitive load and enables reasoning at an appropriate level. Poor abstraction either hides information that clients need or exposes implementation details that create unnecessary coupling.

Encapsulation

Encapsulation groups data and operations and restricts access to internal representation. It protects invariants: conditions that must remain true for an object or component to be valid. For example, an account component may prevent a balance from becoming inconsistent by allowing changes only through validated transaction operations.

Modularity

Modularity decomposes a system into units with defined responsibilities and interfaces. A modular design aims for high cohesion within modules and low coupling between them. Cohesion measures how closely related a module’s responsibilities are; coupling measures the extent to which modules depend on one another. Modularity supports parallel development, testing, replacement, reuse, and maintenance.

Separation of concerns

A concern is a responsibility or interest, such as authentication, persistence, logging, or business pricing. Separating concerns prevents unrelated decisions from becoming entangled. Architectural patterns, services, middleware, and aspect-oriented techniques can support this principle, although excessive fragmentation may make systems harder to understand.

Information hiding

A module should hide design decisions likely to change. If a component hides whether it stores data in a relational database or a document store, that decision can change without affecting clients. Information hiding is therefore a strategy for reducing the impact of future change.

Design by contract

Design by contract specifies preconditions, postconditions, and invariants. A precondition states what a caller must guarantee; a postcondition states what the operation guarantees in return; an invariant states what remains true throughout the component’s valid lifetime. Contracts clarify responsibility and provide a basis for verification and testing.

Traceability and evidence

Engineering claims should be connected to evidence. Requirements should be traceable to designs, implementation elements, tests, and operational results. Traceability is especially important in regulated or safety-critical environments, where an organization must demonstrate not only that a system works but also that it was developed under controlled processes.

5. Major Components / Elements

Requirements and specifications

Requirements describe desired capabilities, constraints, quality attributes, and stakeholder obligations. A specification gives a more precise account of externally observable behaviour. Requirements may be informal, semi-formal, or formal. Ambiguity is acceptable in early exploration but becomes dangerous when safety, security, or contractual obligations are involved.

Architecture

Software architecture defines major components, their responsibilities, interfaces, communication mechanisms, data stores, deployment structures, and quality-attribute strategies. Common architectural styles include layered architecture, client-server, event-driven systems, microservices, pipes and filters, and hexagonal architecture. Architecture is not merely a diagram; it is a set of significant decisions and their rationales.

Components and interfaces

A component is a replaceable unit with a provided interface and, often, required interfaces. Interfaces establish assumptions about data formats, timing, failure behaviour, authorization, and resource consumption. An interface that specifies only method names but not error semantics is incomplete.

Behaviour and state

Many systems are best described by states and transitions. A railway crossing, for example, may move among states such as open, closing, closed, and opening. State-machine models support analysis of unreachable states, illegal transitions, deadlocks, and missing event handling.

Data and semantics

Data models define entities, relationships, constraints, ownership, and lifecycle. Semantic correctness matters as much as syntactic correctness. A value may have the correct format but the wrong meaning, unit, time zone, or authorization context.

Quality attributes

Functional requirements state what a system does. Quality attributes state how well it does it. Performance, scalability, security, usability, portability, recoverability, modifiability, and observability are examples. Quality attributes often conflict: stronger security may increase latency, and extreme modularity may increase communication overhead.

Verification and validation

Verification asks whether the system has been built according to its specification: “Are we building the product right?” Validation asks whether the system satisfies real stakeholder needs: “Are we building the right product?” Both are necessary. A program can conform perfectly to an incorrect requirement.

6. Process / Framework / Methodology

A software lifecycle organizes work from conception to retirement. The waterfall model sequences activities such as requirements, design, implementation, testing, and maintenance. It may be appropriate where requirements are stable, contractual baselines are important, and change is expensive or tightly controlled. Its weakness is that assumptions may remain untested until late in the project.

The iterative and incremental models deliver the system in repeated cycles. Each iteration produces learning and potentially useful functionality. Agile methods emphasize short feedback loops, customer collaboration, working software, and adaptive planning. They are valuable in uncertain environments, but agility does not remove the need for architecture, documentation, risk management, or formal evidence where these are required.

The spiral model organizes development around risk analysis. Each cycle identifies objectives, evaluates alternatives, addresses major risks, and plans the next cycle. It is useful for technically complex or high-risk projects, although it requires mature risk-management capability.

The V-model links development activities to corresponding verification and validation activities. System requirements correspond to acceptance testing, architectural design to system testing, detailed design to integration testing, and implementation to unit testing. This model is influential in safety-critical and regulated environments.

DevOps extends lifecycle thinking into continuous integration, delivery, deployment, monitoring, and feedback. Infrastructure as code, automated testing, deployment pipelines, observability, and rollback mechanisms support rapid but controlled change. Continuous delivery is not simply frequent release; it is the capability to release safely and predictably.

A sound methodology is situational. The appropriate process depends on uncertainty, criticality, team structure, regulatory requirements, system novelty, and cost of failure. Mature organizations often combine approaches: iterative discovery, formal architectural review, automated verification, and controlled release governance.

7. Important Theories and Models

Formal specification

Formal methods use mathematically based languages and reasoning techniques to describe and analyse systems. A formal specification may define sets, relations, functions, invariants, preconditions, and state transitions. Examples include Z notation, Alloy, B, TLA+, and temporal-logic-based approaches.

Formal specification is valuable because natural language permits ambiguity. For example, “the system shall process requests promptly” does not define a measurable bound. A formal or semi-formal statement might specify that every accepted request eventually receives a response and that the response occurs within a defined time under stated assumptions.

Program correctness

A Hoare triple has the form `{P} C {Q}`, meaning that if precondition P holds and command C terminates, postcondition Q will hold. Hoare logic supports deductive reasoning about programs. In practice, proving correctness requires specifications, loop invariants, and assumptions about the execution environment.

Partial correctness means that if a program terminates, its result satisfies the postcondition. Total correctness additionally requires proof of termination. This distinction is important for loops and recursive algorithms.

Model checking

Model checking automatically explores the states of a finite or abstracted transition system to determine whether properties hold. Temporal logic can express properties such as “something good eventually happens” or “a critical action never occurs without authorization.” Model checking is effective for protocols, controllers, and concurrent systems, but state-space explosion may limit direct application to large systems.

Type systems

A type system classifies expressions and restricts invalid combinations. Static type checking detects many errors before execution, such as passing a string where a number is required. Stronger systems can represent units, ownership, nullability, effects, or security labels. Type systems do not prove all properties, but they shift defect detection earlier and make interfaces more explicit.

Polymorphism permits one interface to support multiple implementations. Subtyping allows values of a more specific type to be used where a general type is expected, provided behavioural substitutability is preserved. The Liskov Substitution Principle emphasizes that subtypes must honour the expectations established by their supertypes.

Concurrency and distributed computation

Concurrent systems execute multiple activities whose ordering may be nondeterministic. A race condition occurs when correctness depends on an uncontrolled ordering of operations. Mutual exclusion, message passing, transactions, immutable data, and actor models are mechanisms for controlling concurrency.

Deadlock can arise when processes wait indefinitely for resources held by one another. Classical prevention strategies include imposing a resource ordering, avoiding circular wait, or using timeout and recovery mechanisms. Distributed systems add partial failure, network delay, clock inconsistency, duplication, and partitioning. Consequently, guarantees such as consistency, availability, and partition tolerance must be considered together rather than treated as independent features.

Software evolution and technical debt

Software evolution includes corrective, adaptive, perfective, and preventive maintenance. Lehman’s laws of software evolution suggest that useful software in changing environments must continually adapt, and that complexity tends to increase unless deliberate effort is invested in its control.

Technical debt is the future cost created by expedient decisions, obsolete dependencies, weak tests, architectural erosion, or undocumented assumptions. Debt is not always irrational; it can finance rapid learning. It becomes harmful when it is invisible, unmanaged, or repeatedly refinanced without repayment.

8. Practical Applications

Formal and engineering models are applied in many domains. In banking, transaction invariants and authorization rules protect account integrity. In healthcare, type-safe representations and traceable requirements reduce medication and identity errors. In aviation and industrial control, state models and formal verification help establish safety properties. In cybersecurity, threat models, security protocols, and information-flow analysis identify unauthorized data paths.

In enterprise systems, modular architecture allows a payment service, customer service, and reporting service to evolve at different rates. In data engineering, contracts define schemas, ownership, quality thresholds, and compatibility rules. In artificial-intelligence systems, engineering discipline is necessary to manage model versioning, data lineage, monitoring, fairness testing, and fallback behaviour.

9. Examples

Consider an online examination system. A simple requirement might state that only authorized students may submit an examination. A more complete specification identifies identity verification, enrollment status, examination time window, submission uniqueness, audit logging, and administrator override rules. A state model can represent an examination as scheduled, active, submitted, expired, or invalidated. Invariants may state that a submitted attempt cannot return to active status and that an unregistered student cannot create a valid attempt.

A modular design could separate identity management, examination delivery, answer storage, grading, and audit services. Each module should expose explicit interfaces and failure behaviour. Automated tests can verify ordinary cases, while model checking or contract verification can examine illegal transitions. Operational monitoring can detect unusual submission patterns without changing the core correctness rules.

10. Technology and Digital Applications

Relevant technologies include version-control systems, continuous-integration platforms, static analyzers, formal-verification tools, model checkers, theorem provers, property-based testing frameworks, container platforms, service meshes, and observability systems. These tools are valuable when integrated into an engineering process rather than adopted as isolated products.

Static analysis can detect unreachable code, data-flow defects, insecure configurations, and violations of coding standards. Property-based testing generates many inputs to assess general behavioural properties rather than a small number of examples. Runtime verification evaluates specified properties during execution. Infrastructure as code makes deployment environments reproducible and reviewable.

Digital twins and simulation environments allow organizations to test control logic and operational scenarios before deployment. However, a simulation is only as reliable as its assumptions and models. Tool output must therefore be interpreted by qualified engineers and supported by independent evidence where consequences are severe.

11. Strategic / Managerial Importance

Software architecture and formal assurance are strategic investments. Architectural decisions influence development speed, vendor dependence, operating cost, cybersecurity exposure, and the ability to respond to market change. Managers should evaluate not only initial delivery cost but also total lifecycle cost and the cost of failure.

Governance should establish decision rights, quality gates, risk ownership, configuration control, and evidence requirements. Technical leaders must balance delivery pressure with sustainable engineering. A release that meets a short-term deadline but creates severe operational fragility may reduce organizational value.

Managers should also recognize that formal methods require skills, training, tool support, and appropriate scope. Applying rigorous analysis to the most critical components often provides greater value than attempting to formalize every detail indiscriminately.

12. Detailed Case Study

The following is a fictional illustrative case.

Background

MetroPay is a regional digital-payment provider processing retail and public-transport transactions. Its original platform was a single application developed over ten years. New features were delivered quickly, but deployment required full-system testing and extended maintenance windows.

Problem

The company experienced duplicate charges, inconsistent refunds, and delayed incident diagnosis. The causes included shared database access, implicit assumptions between teams, weak transaction boundaries, and insufficient automated regression testing. Regulators also requested stronger evidence that payment records could not be altered without authorization.

Analysis

An architectural review identified high coupling between payment, customer support, settlement, and reporting functions. A state analysis showed that refunds could be initiated from several code paths without a common invariant. Static analysis found unsafe handling of nullable values and inconsistent error propagation. Operational logs could not reliably connect a customer request to a settlement event.

The organization also discovered technical debt: temporary database shortcuts had become permanent, and no team owned several critical interfaces. The main challenge was not simply obsolete code; it was the absence of explicit contracts and accountability.

Strategy / Solution

MetroPay introduced bounded modules for authorization, transaction processing, refund management, and settlement. It defined contracts for idempotency, error handling, audit events, and data ownership. Payment operations received unique transaction identifiers, and an invariant required that a transaction be settled at most once.

The company used incremental migration rather than a disruptive rewrite. A compatibility layer isolated legacy functions while new modules were introduced. Contract tests ran in continuous integration, static analysis was mandatory for critical repositories, and property-based tests generated repeated and reordered requests. A state model was used to analyse refund transitions, while independent review assessed authorization and audit requirements.

Deployment pipelines included database migration checks, canary releases, monitoring, and automated rollback. A technical-debt register recorded unresolved risks, owners, remediation dates, and business impact.

Outcome

Duplicate settlements declined substantially, refund behaviour became predictable, and incident investigation improved because transaction events were correlated across services. Releases became smaller and more frequent. The migration required initial investment and temporarily reduced feature capacity, but the organization gained greater control over operational and regulatory risk.

Learning Points

The case demonstrates that modularity is not achieved merely by creating services. Modules require coherent responsibilities, stable contracts, ownership, and controlled data access. Formal reasoning is most useful when applied to critical invariants and transitions. Incremental modernization can reduce risk when supported by architecture governance, testing, observability, and explicit debt management.

13. Advantages / Benefits

Rigorous software engineering provides improved reliability, maintainability, testability, security, and explainability. Modularity enables parallel work and localized change. Abstraction supports reuse and reduces cognitive burden. Formal specification exposes ambiguity, while verification can detect defects before deployment. Lifecycle models create coordination structures, and traceability strengthens accountability. Together, these practices reduce the probability and impact of failure.

14. Limitations / Challenges

Formal methods can be expensive, technically demanding, and difficult to apply when requirements are unstable or poorly understood. Models may omit environmental realities, and a verified implementation can still satisfy an incorrect specification. Automated tools may produce false positives, false negatives, or overwhelming results. Microservices and excessive abstraction can increase operational complexity. Agile practices may become superficial if teams optimize for speed without addressing architecture and quality. Finally, no engineering method can eliminate human error, organizational conflict, or malicious behaviour.

15. Ethical and Governance Considerations

Software decisions affect rights, opportunities, safety, privacy, and access to essential services. Engineers must consider who may be harmed by failure, exclusion, surveillance, or biased data. Requirements should identify affected stakeholders, including those without organizational power.

Governance should ensure lawful data processing, least-privilege access, explainable decision procedures where appropriate, secure defaults, and meaningful auditability. Formal verification does not justify unethical objectives. A system can be mathematically correct while implementing discriminatory or intrusive policies. Accountability therefore requires both technical evidence and responsible institutional oversight.

16. Current and Emerging Trends

Current practice is moving toward continuous assurance, in which testing, security analysis, policy checks, and operational evidence are integrated into delivery pipelines. Software supply-chain security increasingly addresses dependency provenance, build integrity, signed artefacts, and vulnerability response.

AI-assisted development is increasing code-generation speed, but it also creates risks involving insecure code, licensing, hallucinated APIs, and unclear accountability. Strong typing, automated tests, code review, provenance records, and human approval remain necessary.

Formal methods are becoming more accessible through lightweight specification languages, automated solvers, verified libraries, and integration with mainstream development environments. Runtime adaptation, edge computing, autonomous systems, and cyber-physical systems will increase the need for reasoning about uncertainty, timing, safety, and human interaction.

17. Best Practices

1. Define responsibilities, interfaces, assumptions, and failure behaviour explicitly.

2. Use abstraction and information hiding to protect likely-to-change decisions.

3. Keep modules cohesive and dependencies visible.

4. Treat architecture as an evolving set of documented decisions.

5. Specify critical invariants and properties before implementation.

6. Combine testing, static analysis, runtime monitoring, and formal reasoning.

7. Use strong and precise types where they reduce ambiguity or invalid states.

8. Design concurrency around explicit ownership, synchronization, or message passing.

9. Make deployments reproducible and reversible.

10. Maintain traceability from requirements to operational evidence.

11. Record technical debt, assign ownership, and plan repayment.

12. Match process rigor to system risk, uncertainty, and regulatory context.

13. Involve security, operations, users, and affected stakeholders early.

14. Review not only whether software works, but whether it should be built and used in its intended way.

18. Future Scope

Future software engineering will increasingly combine formal models, empirical operational data, automated reasoning, and human-centred governance. Verified components may become common in security-sensitive libraries and infrastructure. Digital engineering environments may maintain synchronized links among requirements, architecture, code, tests, deployment configurations, and runtime evidence.

Research challenges include scalable verification of distributed and adaptive systems, trustworthy AI-generated code, specification of socio-technical behaviour, energy-aware software architecture, and engineering methods for systems that learn after deployment. The central challenge will be preserving human accountability while software becomes more autonomous, interconnected, and difficult to inspect directly.

19. Chapter Summary

Software theory and engineering models provide the foundations for building dependable and maintainable systems. Abstraction, encapsulation, modularity, separation of concerns, and information hiding control complexity. Architecture organizes significant decisions, while specifications define expected behaviour and quality attributes. Verification, validation, testing, type systems, model checking, and formal proofs provide complementary forms of evidence.

Lifecycle models must be selected according to uncertainty, risk, criticality, and organizational context. Concurrency and distributed computation require explicit reasoning about ordering, failure, and consistency. Software evolution is unavoidable, making maintainability and technical-debt management strategic concerns. Finally, software assurance must be connected to ethics and governance because technically correct systems can still produce socially harmful outcomes.

20. Key Terms

1. Abstraction: Representation of essential properties while suppressing unnecessary detail.

2. Architecture: Significant structural and behavioural decisions governing a software system.

3. Cohesion: Degree to which the responsibilities within a module are related.

4. Coupling: Degree of dependency between modules or components.

5. Encapsulation: Restriction of access to internal data and implementation details.

6. Formal method: Mathematically based technique for specifying or analysing software.

7. Formal specification: Precise description of required behaviour using a formal language or mathematical model.

8. Invariant: Property that must remain true under specified conditions.

9. Model checking: Automated exploration of a model to determine whether stated properties hold.

10. Modularity: Division of a system into relatively independent units with defined interfaces.

11. Postcondition: Condition guaranteed after an operation completes.

12. Precondition: Condition required before an operation begins.

13. Refinement: Transformation of an abstract specification into a more detailed implementation.

14. Technical debt: Future cost created by expedient or inadequate technical decisions.

15. Type system: Rules classifying values and restricting invalid operations.

16. Validation: Evaluation of whether a system satisfies real stakeholder needs.

17. Verification: Evaluation of whether a system conforms to its specification.

18. Concurrency: Execution of multiple activities whose ordering may overlap or vary.

21. Review Questions

Short Answer Questions

1. What is the relationship between abstraction and encapsulation?

2. Distinguish verification from validation.

3. What purpose does an invariant serve?

4. Why are type systems useful in software engineering?

5. Define technical debt and explain one way it can arise.

Long Answer Questions

1. Explain how modularity, cohesion, coupling, and information hiding contribute to maintainable software.

2. Compare waterfall, iterative, spiral, V-model, and DevOps approaches, including suitable application contexts.

3. Discuss the role and limitations of formal specification and model checking.

4. Analyse the principal challenges of concurrency and distributed systems.

5. Explain how software architecture and governance influence organizational risk and strategic flexibility.

Analytical / Application Questions

1. A hospital information system allows medication orders to be edited after dispensing. Develop a state model, identify at least two invariants, and propose verification and governance controls.

2. A team plans to replace a legacy enterprise system with a single large rewrite. Using lifecycle, modularity, and risk principles, evaluate this strategy and propose an alternative.

3. An autonomous transport service uses machine-learning components whose behaviour changes after deployment. Design an assurance approach combining specifications, testing, monitoring, human oversight, and incident response.

22. Multiple Choice Questions with Answers

Question 1

Which design choice best demonstrates information hiding?

A. Exposing database indexes to every client module

B. Allowing clients to depend on a stable interface while concealing storage technology

C. Combining authentication, reporting, and billing in one procedure

D. Duplicating internal data structures across services

Correct Answer: B. Allowing clients to depend on a stable interface while concealing storage technology

Question 2

A payment operation must never settle the same transaction twice. This requirement is best represented as a:

A. Precondition only

B. User-interface preference

C. System invariant

D. Deployment script

Correct Answer: C. System invariant

Question 3

Which lifecycle approach is most explicitly organized around identifying and reducing project risks in repeated cycles?

A. Spiral model

B. Pure waterfall model

C. Big-bang development

D. Code-and-fix model

Correct Answer: A. Spiral model

Question 4

What is the principal distinction between verification and validation?

A. Verification concerns users, while validation concerns compilers

B. Verification asks whether specifications are correct, while validation asks whether code is short

C. Verification checks conformity to specification, while validation checks suitability for stakeholder needs

D. Verification occurs after deployment, while validation occurs before requirements

Correct Answer: C. Verification checks conformity to specification, while validation checks suitability for stakeholder needs

Question 5

Which situation is most likely to produce a race condition?

A. Two processes update shared data without controlled ordering

B. A compiler rejects an invalid type conversion

C. A module uses a private data representation

D. A deployment is stored in version control

Correct Answer: A. Two processes update shared data without controlled ordering

Question 6

What does a Hoare triple of the form {P} C {Q} express?

A. A database schema and its indexes

B. A relationship among a precondition, a command, and a postcondition

C. A method for encrypting source code

D. A project budget and schedule

Correct Answer: B. A relationship among a precondition, a command, and a postcondition

Question 7

Which practice most directly supports continuous assurance in a DevOps environment?

A. Removing automated tests to accelerate releases

B. Using reproducible builds, static analysis, automated tests, and monitored deployments

C. Allowing each developer to deploy unrelated configurations manually

D. Postponing security analysis until system retirement

Correct Answer: B. Using reproducible builds, static analysis, automated tests, and monitored deployments

Question 8

Why can a formally verified program still be harmful?

A. Formal methods always produce syntactically invalid programs

B. Verification proves that every possible social outcome is beneficial

C. The implementation may satisfy an incorrect or unethical specification

D. Formal methods cannot represent any system property

Correct Answer: C. The implementation may satisfy an incorrect or unethical specification

Question 9

Which architectural condition generally improves maintainability?

A. High cohesion and low coupling

B. High coupling and shared mutable state everywhere

C. Unspecified interfaces and implicit dependencies

D. Duplicated business rules in every client

Correct Answer: A. High cohesion and low coupling

Question 10

What is a major challenge in model checking concurrent systems?

A. The absence of any possible system states

B. State-space explosion as processes and possible interleavings increase

C. The inability to represent transitions

D. The requirement that all systems be written in assembly language

Correct Answer: B. State-space explosion as processes and possible interleavings increase

Theoretical Foundations of Information Technology
Chapter 7 of 15