We show that the weak memory model introduced by the 2011 C and C++ standards does not permit many common source-tosource program transformations (such as expression linearisation and "roach motel" reorderings) that modern compilers perform and that are deemed to be correct. As such it cannot be used to define the semantics of intermediate languages of compilers, as, for instance, LLVM aimed to. We consider a number of possible local fixes, some strengthening and some weakening the model. We evaluate the proposed fixes by determining which program transformations are valid with respect to each of the patched models. We provide formal Coq proofs of their correctness or counterexamples as appropriate.
We present a call-by-need strategy for computing strong normal forms of open terms (reduction is admitted inside the body of abstractions and substitutions, and the terms may contain free variables), which guarantees that arguments are only evaluated when needed and at most once. The strategy is shown to be complete with respect to β-reduction to strong normal form. The proof of completeness relies on two key tools: (1) the definition of a strong call-by-need calculus where reduction may be performed inside any context, and (2) the use of non-idempotent intersection types. More precisely, terms admitting a β-normal form in pure lambda calculus are typable, typability implies (weak) normalisation in the strong call-by-need calculus, and weak normalisation in the strong call-by-need calculus implies normalisation in the strong call-by-need strategy. Our (strong) call-by-need strategy is also shown to be conservative over the standard (weak) call-by-need.[2002] have proposed a strong normalisation function N which they have proved to be correct, in the sense that N computes the normal form of strongly normalising, closed λ-terms. This function essentially consists in iterating the standard (weak) call-by-value (CBV) strategy on terms possibly containing free variables, Grégoire and Leroy [2002] refers to this variant of CBV as symbolic CBV.The starting point of this work is the observation that rather than iterating CBV, one should consider an appropriate notion of call-by-need (CBNd) that computes strong normal forms (of open terms). In this paper we replace symbolic CBV by symbolic CBNd, consisting in iterating the standard CBNd strategy on terms possibly containing free variables. Our strategy computes strong normal forms in which, in contrast to N , arguments are evaluated only if they are needed and, moreover, are evaluated at most once thus avoiding duplication of work. For example, the function N in Grégoire and Leroy [2002] computes the value of the argument (λz.z)(λz.z) in the λ-term (λx .λy.(λz.z)y)((λz.z)(λz.z)) even though this value is not required for the strong normal form of the whole term, whereas our strategy will not. Also, our strategy is normalising, i.e. it computes the normal form of weakly normalising terms, that is, of terms that admit a normal form but whose evaluation may diverge along some other strategies.Defining Strong Call-by-Need. Some of the subtleties involved in developing a theory of CBNd to strong normal form are illustrated next. In what follows, we write ⇝ for denoting the CBNd strategy to strong normal form devised in this paper and motivated below.Consider a term (λx .t )(id id), where id abbreviates the identity term λz.z and t is an arbitrary subterm (in Fig. 1, t is chosen to be λy.yxx). The first reduction step for a term of this shape is a common (weak) call-by-need step: the β-redex (λx .t )(id id) is turned into an explicit binding between the variable x and the argument id id in the expression t, which is often written let x = (id id) in t, or here t[x\id id], wher...
The programming language Mezzo is equipped with a rich type system that controls aliasing and access to mutable memory. We give a comprehensive tutorial overview of the language. Then, we present a modular formalization of Mezzo's core type system, in the form of a concurrent λ-calculus, which we successively extend with references, locks, and adoption and abandon, a novel mechanism that marries Mezzo's static ownership discipline with dynamic ownership tests. We prove that well-typed programs do not go wrong and are data-race free. Our definitions and proofs are machine-checked. XXXX:2 T. Balabonski et al. 1 open woref 2 3 val f (x: frozen int , y: frozen int) : int = 4 get x + get y 5 6 val _ : int = 7 let r = new () in 8 set (r, 3); 9 f (r, r) Fig. 1. Using a write-once ref-erence. The Mezzo type system guarantees that the user must call set before using get, and can call set at most once. and robustness; in return, they offer far greater expressiveness than a simple-minded, purely static discipline could hope to achieve.In this paper, we offer a comprehensive overview of Mezzo, including an informal, user-level presentation of the language and a formal, machine-checked presentation of its meta-theory. This unifies and subsumes the two conference papers cited above. Furthermore, we revisit the theory of adoption and abandon, which was presented informally in the first conference paper, and was absent from the second conference paper. Our new account of adoption and abandon is not only machine-checked, but also simpler and more expressive than that of the conference paper. A few examplesWe begin with two short illustrative examples. The first one concerns a type of writeonce references and shows how Mezzo guarantees that the client follows the intended usage protocol. The second example is a racy program, which the type system rejects. We show how to fix this ill-typed program by introducing a lock.A usage protocol. A write-once reference is a memory cell that can be assigned at most once and cannot be read before it has been initialized. Fig. 1 shows some client code that manipulates a write-once reference. The code refers to the module woref, whose implementation we show later on ( §2.1).At line 7, we create a write-once reference by calling woref::new. (Thanks to the declaration open woref, one can refer to this function by the unqualified name new.) The local variable r denotes the address of this reference. In the eyes of the typechecker, this gives rise to a permission, written r @ writable. This permission has a double reading: it describes the layout of memory (i.e., "the variable r denotes the address of an uninitialized memory cell") and grants exclusive write access to this memory cell. That is, the type constructor writable denotes a uniquely-owned writable reference, and the permission r @ writable is a unique token that one must possess in order to write r.Permissions are tokens that exist at type-checking time only. Many permissions have the form x @ t, where x is a program variable and t is a ty...
Abstract. The programming language Mezzo is equipped with a rich type system that controls aliasing and access to mutable memory. We incorporate shared-memory concurrency into Mezzo and present a modular formalization of its core type system, in the form of a concurrent λ-calculus, which we extend with references and locks. We prove that welltyped programs do not go wrong and are data-race free. Our definitions and proofs are machine-checked.
We give an axiomatic presentation of sharing-via-labelling for weak λ-calculi, that makes it possible to formally compare many different approaches to fully lazy sharing, and obtain two important results. We prove that the known implementations of full laziness are all equivalent in terms of the number of β-reductions performed, although they behave differently regarding the duplication of terms. We establish a link between the optimality theories of weak λ-calculi and first-order rewriting systems by expressing fully lazy λ-lifting in our framework, thus emphasizing the firstorder essence of weak reduction.
We show that the weak memory model introduced by the 2011 C and C++ standards does not permit many common source-tosource program transformations (such as expression linearisation and "roach motel" reorderings) that modern compilers perform and that are deemed to be correct. As such it cannot be used to define the semantics of intermediate languages of compilers, as, for instance, LLVM aimed to. We consider a number of possible local fixes, some strengthening and some weakening the model. We evaluate the proposed fixes by determining which program transformations are valid with respect to each of the patched models. We provide formal Coq proofs of their correctness or counterexamples as appropriate.
scite is a Brooklyn-based organization that helps researchers better discover and understand research articles through Smart Citations–citations that display the context of the citation and describe whether the article provides supporting or contrasting evidence. scite is used by students and researchers from around the world and is funded in part by the National Science Foundation and the National Institute on Drug Abuse of the National Institutes of Health.
hi@scite.ai
334 Leonard St
Brooklyn, NY 11211
Copyright © 2024 scite LLC. All rights reserved.
Made with 💙 for researchers
Part of the Research Solutions Family.