Hostname: page-component-89b8bd64d-ktprf Total loading time: 0 Render date: 2026-05-13T08:22:05.457Z Has data issue: false hasContentIssue false

Denotational semantics as a foundation for cost recurrence extraction for functional languages

Published online by Cambridge University Press:  05 July 2022

NORMAN DANNER
Affiliation:
Wesleyan University, Middletown, CT 06459, USA (e-mail: ndanner@wesleyan.edu)
DANIEL R. LICATA
Affiliation:
Wesleyan University, Middletown, CT 06459, USA (e-mail: dlicata@wesleyan.edu)
Rights & Permissions [Opens in a new window]

Abstract

A standard informal method for analyzing the asymptotic complexity of a program is to extract a recurrence that describes its cost in terms of the size of its input and then to compute a closed-form upper bound on that recurrence. We give a formal account of that method for functional programs in a higher order language with $\mathtt{let}$-polymorphism. The method consists of two phases. In the first phase, a monadic translation is performed to extract a cost-annotated version of the original program. In the second phase, the extracted program is interpreted in a model. The key feature of this second phase is that different models describe different notions of size. This plays out in several ways. For example, when analyzing functions that take arguments of inductive types, different notions of size may be appropriate depending on the analysis. When analyzing polymorphic functions, our approach shows that one can formally describe the notion of size of an argument in terms of the data that is common to the notions of size for each type instance of the domain type. We give several examples of different models that formally justify various informal cost analyses to show the applicability of our approach.

Information

Type
Research Article
Creative Commons
Creative Common License - CCCreative Common License - BY
This is an Open Access article, distributed under the terms of the Creative Commons Attribution licence (https://creativecommons.org/licenses/by/4.0/), which permits unrestricted re-use, distribution, and reproduction in any medium, provided the original work is properly cited.
Copyright
© The Author(s), 2022. Published by Cambridge University Press
Figure 0

Fig. 1. A source language with let polymorphism and inductive datatypes. $\mathtt{map}$ and $\mathtt{mapv}$ expressions depend on values, which are defined in Figure 2.

Figure 1

Fig. 2. Grammar and typing rules for values. For any value environment $\theta$, it must be that for all x there is $\sigma$ such that $_\vdash{\theta(x)}:{\sigma}$. The judgment $\Gamma{\vdash e\theta}:{\sigma}$ is defined in Figure 3.

Figure 2

Fig. 3. Typing for closures.

Figure 3

Fig. 4. Some standard types in the source language.

Figure 4

Fig. 5. The operational cost semantics for the source language. We only define evaluation for closures $e\theta$ such that $_\vdash{e\theta}:{\sigma}$ for some $\sigma$, and hence just write $e\theta$. The semantics for $\mathtt{fold}$ depends on the semantics for $\mathtt{map}$, which is given in Figure 6.

Figure 5

Fig. 6. The operational semantics for the source language $\mathtt{map}$ and $\mathtt{mapv}$ constructors. Substitution of values is defined in Figure 7.

Figure 6

Fig. 7. Substitution of values for identifiers in values, ${v'}\{v/y\}$.

Figure 7

Fig. 8. Using suspension types to control evaluation of recursive calls in fold-like constructs.

Figure 8

Fig. 9. The recurrence language grammar and typing.

Figure 9

Fig. 10. Some standard types in the recurrence language corresponding to those in Figure 4.

Figure 10

Fig. 11. The size order relation that defines the semantics of the recurrence language. The macro $F[(y:\rho).e',e$ is defined in Figure 12.

Figure 11

Fig. 12. The macro $F[\rho; y.e', e]$.

Figure 12

Fig. 13. The complexity and potential translation of types. Remember that although we have a grammar for structure functors F, they are actually just a subgrammar of the small types, so we do not require a separate translation function for them.

Figure 13

Fig. 14. Notation related to recurrence language expressions and recurrence extraction.

Figure 14

Fig. 15. The recurrence extraction function on source language terms. On the right-hand sides, $(c, p) = \|e\|$ and $(c_i, p_i) = \|e_i\|$ (note that $\|e\|$ is always a pair).

Figure 15

Fig. 16. The type-indexed bounding relations.

Figure 16

Fig. 17. The shape-indexed bounding relations. When writing $v\preceq^{\mathrm{val}}_{F,\rho}{E}$, $\mathrm{ftv}(F)\subseteq\{t\}$ and $\rho$ is closed.

Figure 17

Fig. 18. The denotation (partial) function of types and type schemes into a type frame.

Figure 18

Fig. 19. The denotation (partial) function into an applicative structure. For constructors and destructors, assume $\delta = \mu t F$ and $\mathop{\mathrm{fv}}\nolimits(\delta) = \{\alpha_0,\dots,\alpha_{n-1}\}$, and define $\eta^* = \eta\{\vec\alpha\mapsto\vec U\}$.

Figure 19

Fig. 20. The monomorphic tree copy function and its extracted recurrence.

Figure 20

Fig. 21. Binary search tree membership and its extracted recurrence.

Figure 21

Fig. 22. A function that sums the nodes of a $\mathtt{nat tree}$.

Figure 22

Fig. 23. Abstraction and concretization functions that relate the all-constructor (concrete) and main-constructor (abstract) models.

Figure 23

Fig. 24. Linear-time list reversal and its extracted recurrences.

Figure 24

Fig. 25. List map and its extracted recurrence.

Figure 25

Fig. 26. Adding general recursion to the source and recurrence languages.

Submit a response

Discussions

No Discussions have been published for this article.