Abstracting Denotational Interpreters

Sebastian Graf,Simon Peyton Jones,Sven Keidel
2024-07-12
Abstract:We explore denotational interpreters: denotational semantics that produce coinductive traces of a corresponding small-step operational semantics. By parameterising our denotational interpreter over the semantic domain and then varying it, we recover dynamic semantics with different evaluation strategies as well as summary-based static analyses such as type analysis, all from the same generic interpreter. Among our contributions is the first denotational semantics for call-by-need that is provably adequate in a strong, compositional sense. The generated traces lend themselves well to describe operational properties such as how often a variable is evaluated, and hence enable static analyses abstracting these operational properties. Since static analysis and dynamic semantics share the same generic interpreter definition, soundness proofs via abstract interpretation decompose into showing small abstraction laws about the abstract domain, thus obviating complicated ad-hoc preservation-style proof frameworks.
Programming Languages
What problem does this paper attempt to address?
The main problem that this paper attempts to solve is the challenge of proving the soundness of compositional static analysis under non - compositional small - step operational semantics. Specifically, the authors explore how to unify dynamic semantics and static analysis by defining a new interpreter design pattern - **denotational interpreters**, and enable these analyses to observe operational details, such as the frequency of variable usage. ### Main Problems 1. **Proving the Soundness of Compositional Analysis**: - In traditional denotational semantics, operational details (such as the number of times a variable is evaluated) cannot be expressed, so it is difficult to be directly used for static analysis that requires these details. - Although using operational semantics can capture these details, it will lead to complex and non - modular soundness proofs. 2. **Unifying Dynamic Semantics and Static Analysis**: - Traditional methods either require complex, analysis - specific proof frameworks or need to re - implement the analysis to adapt to operational semantics, which all lead to problems of modularity and extensibility. ### Solutions The author proposes a new denotational interpreter design pattern. This interpreter can generate small - step traces with arbitrary operational details. By parameterizing the semantic domain of the interpreter and making changes to it, different evaluation strategies (such as call - by - name, call - by - need, call - by - value) and summary - based static analyses (such as type analysis) can be recovered from the same general interpreter. This method enables: - **Unifying Dynamic Semantics and Static Analysis**: The two share the same general interpreter definition, simplifying the soundness proof. - **Intuitive and Semantically Meaningful Observation of Operational Details**: Through the generated operational traces, operational properties such as the number of times a variable is evaluated can be directly described and analyzed. - **Modular and Reusable Soundness Proofs**: Since the compositional structure is shared, the soundness proofs of different analyses can be reused, greatly simplifying the proof process. ### Specific Contributions - Proposing the first call - by - need denotational semantics proven sound in a strong compositional sense. - Demonstrating how to instantiate different evaluation strategies and static analyses from a general interpreter. - Avoiding complex, analysis - specific proof frameworks by decomposing the soundness proof into small abstract laws about abstract domains. - Providing specific examples (such as absence analysis) to illustrate the advantages of compositional, summary - based analysis and its modular characteristics. In summary, this paper aims to solve the difficult problem of proving the soundness of compositional static analysis under non - compositional small - step operational semantics by introducing the denotational interpreter design pattern, and provides a unified and modular solution.