Papers by Aleksandar Nanevski
The exception monad, while an adequate mechanism for providing the denotational semantics of exce... more The exception monad, while an adequate mechanism for providing the denotational semantics of exceptions, is somewhat awkward to program with. Just as any other monad, it forces a programming style in which exceptional computations are explicitly sequentialized in the program text. In addition, values of computation types must usually be tested before use, in order to determine if they correspond to a raised exception. In this paper we propose a type system that rearranges the monadic formulation, so that the above shortcomings are avoided. Instead of the exception monad, we propose the operator from the modal logic S4 to encode exceptional computation. The way tracking of exceptions is organized in the modal system is exactly dual to the monadic case, reflecting the well-known property that is actually a comonad.

From Owicki-Gries’ resource invariants and Jones’ rely/guarantee to modern variants based on sepa... more From Owicki-Gries’ resource invariants and Jones’ rely/guarantee to modern variants based on separation logic, axiomatic program logics for concurrency have a limited form of compositionality. Proving non-trivial properties usually requires the use of auxiliary state, which is “objective” in the sense that each thread’s auxiliary state is given a globally-unique name. Since auxiliary state exposes the program’s global structure to each local thread, axiomatic approaches fail to be compositional in the presence of auxiliary state. We propose “subjective” auxiliary state as a solution to this historical limitation of axiomatic program logics. Each thread can be verified with a subjective view on auxiliary state: auxiliary state can be partitioned to either belong to the self (i.e., the thread itself) or to the other (i.e., its environment). We formulate Subjective Concurrent Separation Logic as a combination of the resource invariant method, separation logic, and subjective auxiliary ...

specification of a lock. What is a suitable abstract specification for a locking structure? To an... more specification of a lock. What is a suitable abstract specification for a locking structure? To answer this question, we adopt the idea of specifying concurrent data structures via abstract predicates [1] and provide a lock interface in the form of two abstract procedures: lock and unlock. Every data structure, implementing the lock protocol, will require to provide the implementation of these procedures. The lock interface is parametrized by two abstract predicates, constraining some part of the state: is_lock and locked. The former denotes the fact that the part of state implements belongs to the locking protocol, while the latter one identifies that the lock is currently being locked by the current thread. Both predicates should satisfy a number of axioms, which are packaged into a dependent record in the section LockStruct (where the predicates are referred to as locked_op and is_lock_op). For instance, the following axiom expresses the lock’s mutual exclusion property: forall s ...

We report on the design and preliminary evaluation of a short introductory course on interactive ... more We report on the design and preliminary evaluation of a short introductory course on interactive theorem proving and program verification using the Coq proof assistant, targeted at students with background in functional programming and software engineering. The course builds on concepts familiar from functional programming to develop understanding of logic and mechanized proving by means of the Curry-Howard isomorphism. A particular emphasis is made of the computational nature of decidable properties of various data structures. This approach is of practical importance, as Coq’s normalization can automatically simplify or discharge such properties, thus reducing the burden of constructing the proofs by hand. As a basis for teaching this style of mechanization, we use Gonthier et al.’s Ssreflect extension of Coq and its associated libraries. In the course, we minimize the exposure to ad-hoc proof automation via tactics, and request that students develop proofs using only a small set o...

In this work, we present a family of operational semantics that gradually approximates the realis... more In this work, we present a family of operational semantics that gradually approximates the realistic program behaviors in the C/C++11 memory model. Each semantics in our framework is built by elaborating and combining two simple ingredients: viewfronts and operation buffers. Viewfronts allow us to express the spatial aspect of thread interaction, i.e., which values a thread can read, while operation buffers enable manipulation with the temporal execution aspect, i.e., determining the order in which the results of certain operations can be observed by concurrently running threads. Starting from a simple abstract state machine, through a series of gradual refinements of the abstract state, we capture such language aspects and synchronization primitives as release/acquire atomics, sequentially-consistent and non-atomic memory accesses, also providing a semantics for relaxed atomics, while avoiding the Out-of-Thin-Air problem. To the best of our knowledge, this is the first formal and e...

We describe an axiomatic extension to the Coq proof assistant, that supports writing, reasoning a... more We describe an axiomatic extension to the Coq proof assistant, that supports writing, reasoning about, and extracting higher-order, dependently-typed programs with side-effects. Coq already includes a powerful functional language that supports dependent types, but that language is limited to pure, total functions. The key contribution of our extension, which we call Ynot, is the added support for computations that may have effects such as non-termination, accessing a mutable store, and throwing/catching exceptions. The axioms of Ynot form a small trusted computing base which has been formally justified in our previous work on Hoare Type Theory (HTT). We show how these axioms can be combined with the powerful type and abstraction mechanisms of Coq to build higher-level reasoning mechanisms which in turn can be used to build realistic, verified software components. To substantiate this claim, we describe here a representative series of modules that implement imperative finite maps, in...

Proceedings of the ACM on Programming Languages
Modern highly-concurrent search data structures, such as search trees, obtain multi-core scalabil... more Modern highly-concurrent search data structures, such as search trees, obtain multi-core scalability and performance by having operations traverse the data structure without any synchronization. As a result, however, these algorithms are notoriously difficult to prove linearizable, which requires identifying a point in time in which the traversal's result is correct. The problem is that traversing the data structure as it undergoes modifications leads to complex behaviors, necessitating intricate reasoning about all interleavings of reads by traversals and writes mutating the data structure. In this paper, we present a general proof technique for proving unsynchronized traversals correct in a significantly simpler manner, compared to typical concurrent reasoning and prior proof techniques. Our framework relies only on sequential properties of traversals and on a conceptually simple and widely-applicable condition about the ways an algorithm's writes mutate the data structure. Establishing that a target data structure satisfies our condition requires only simple concurrent reasoning, without considering interactions of writes and reads. This reasoning can be further simplified by using our framework. To demonstrate our technique, we apply it to prove several interesting and challenging concurrent binary search trees: the logical-ordering AVL tree, the Citrus tree, and the full contention-friendly tree. Both the logical-ordering tree and the full contention-friendly tree are beyond the reach of previous approaches targeted at simplifying linearizability proofs. CCS Concepts: • Theory of computation → Program reasoning; Concurrent algorithms.

Proceedings of the ACM on Programming Languages
Programming languages with algebraic effects often track the computations’ effects using type-and... more Programming languages with algebraic effects often track the computations’ effects using type-and-effect systems. In this paper, we propose to view an algebraic effect theory of a computation as a variable context; consequently, we propose to track algebraic effects of a computation with contextual modal types . We develop ECMTT, a novel calculus which tracks algebraic effects by a contextualized variant of the modal □ (necessity) operator, that it inherits from Contextual Modal Type Theory (CMTT). Whereas type-and-effect systems add effect annotations on top of a prior programming language, the effect annotations in ECMTT are inherent to the language, as they are managed by programming constructs corresponding to the logical introduction and elimination forms for the □ modality. Thus, the type-and-effect system of ECMTT is actually just a type system. Our design obtains the properties of local soundness and completeness, and determines the operational semantics solely by β-reductio...
Proceedings of the ACM on Programming Languages
In addition to pre- and postconditions, program specifications in recent separation logics for co... more In addition to pre- and postconditions, program specifications in recent separation logics for concurrency have employed an algebraic structure of resources —a form of state transition systems—to describe the state-based program invariants that must be preserved, and to record the permissible atomic changes to program state. In this paper we introduce a novel notion of resource morphism , i.e. structure-preserving function on resources, and show how to effectively integrate it into separation logic, using an associated notion of morphism-specific simulation . We apply morphisms and simulations to programs verified under one resource, to compositionally adapt them to operate under another resource, thus facilitating proof reuse.

Proceedings of the 2016 ACM SIGPLAN International Conference on Object-Oriented Programming, Systems, Languages, and Applications, 2016
Designing efficient concurrent objects often requires abandoning the standard specification techn... more Designing efficient concurrent objects often requires abandoning the standard specification technique of linearizability in favor of more relaxed correctness conditions. However, the variety of alternatives makes it difficult to choose which condition to employ, and how to compose them when using objects specified by different conditions. In this work, we propose a uniform alternative in the form of Hoare logic, which can explicitly capture-in the auxiliary state-the interference of environment threads. We demonstrate the expressiveness of our method by verifying a number of concurrent objects and their clients, which have so far been specified only by non-standard conditions of concurrency-aware linearizability, quiescent, and quantitative quiescent consistency. We report on the implementation of the ideas in an existing Coq-based tool, providing the first mechanized proofs for all the examples in the paper.

Designing efficient concurrent objects often requires abandoning the standard specification techn... more Designing efficient concurrent objects often requires abandoning the standard specification technique of linearizability in favor of more relaxed correctness conditions. However, the variety of alternatives makes it difficult to choose which condition to employ, and how to compose them when using objects specified by different conditions. In this work, we propose a uniform alternative in the form of Hoare logic, which can explicitly capture-in the auxiliary state-the interference of environment threads. We demonstrate the expressiveness of our method by verifying a number of concurrent objects and their clients, which have so far been specified only by non-standard conditions of concurrency-aware linearizability, quiescent, and quantitative quiescent consistency. We report on the implementation of the ideas in an existing Coq-based tool, providing the first mechanized proofs for all the examples in the paper.

The monadic formulation of exceptions forces a programming style in which the program itself must... more The monadic formulation of exceptions forces a programming style in which the program itself must specify a total ordering on the evaluation of exceptional computations. Moreover, unless a callby-name strategy is used, values of monadic types must be tested before they are used, in order to determine whether they correspond to a raised exception or not. In this paper we propose a type system that internalizes the notion of exceptional computations, but avoids the above two properties. In our calculus, exceptional computations need not be ordered explicitly by the program, unless one of them actually depends on the other. Furthermore, the type system ensures that run-time tests are not needed to determine if an exceptional computation evaluates to a value or a raised exception. To this end, we use the necessitation operator from a version of constructive modal logic. The idea is applicable to other control effects as well, and we use it to develop novel calculi for catch-andthrow and composable continuations.

ACM SIGPLAN Notices, 2002
Meta-programming languages provide infrastructure to generate and execute object programs at run-... more Meta-programming languages provide infrastructure to generate and execute object programs at run-time. In a typed setting, they contain a modal type constructor which classifies object code. These code types generally come in two flavors: closed and open. Closed code expressions can be invoked at run-time, but the computations over them are more rigid, and typically produce less efficient residual object programs. Open code provides better inlining and partial evaluation of object programs, but once constructed, expressions of this type cannot in general be evaluated.Recent work in this area has focused on combining the two notions into a sound system. We present a novel way to achieve this. It is based on adding the notion of names from the work on Nominal Logic and FreshML to the λ -calculus of proof terms for the necessity fragment of modal logic S4. The resulting language provides a more fine-grained control over free variables of object programs when compared to the existing la...

Proceedings of the 5th ACM SIGPLAN international conference on Principles and practice of declaritive programming - PPDP '03, 2003
In this paper we propose a typed, purely functional calculus for state (with second-class locatio... more In this paper we propose a typed, purely functional calculus for state (with second-class locations) in which types reflect the dichotomy between reading from and writing into the global store. This is in contrast to the usual formulation of state via monads, where the primitives for reading and writing introduce the same monadic type constructor. We hope to argue that making this distinction is useful, simple, and has strong logical foundations. Our type system is based on the proof-term calculus for constructive modal logic S4, which has two modal type operators: £ for necessity and 3 for possibility. We extend this calculus with the notion of names (which stand for locations) and generalize to indexed families of modal operators (indexed by sets of names). Then, the modal type £ C A classifies computations of type A which read from store locations listed in the set C. The dual type 3 C A classifies computations which first write into the locations from C and than use the changed store to obtain a value of type A. There are several benefits to this development. First, the necessitation fragment of the language is interesting in its own: it formulates a calculus of dynamic binding. Second, the possibility operator 3 is a monad, thus forcing the single-threading of memory writes, but not of memory reads (as these are associated with £). Finally, the different status of reads and writes gives rise to a natural way of expressing the allocation of uninitialized memory while also providing guarantees that only initialized locations are dereferenced.

Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 2014
First order logic with transitive closure, and separation logic enable elegant interactive verifi... more First order logic with transitive closure, and separation logic enable elegant interactive verification of heap-manipulating programs. However, undecidabilty results and high asymptotic complexity of checking validity preclude complete automatic verification of such programs, even when loop invariants and procedure contracts are specified as formulas in these logics. This paper tackles the problem of procedure-modular verification of reachability properties of heap-manipulating programs using efficient decision procedures that are complete: that is, a SAT solver must generate a counterexample whenever a program does not satisfy its specification. By (a) requiring each procedure modifies a fixed set of heap partitions and creates a bounded amount of heap sharing, and (b) restricting program contracts and loop invariants to use only deterministic paths in the heap, we show that heap reachability updates can be described in a simple manner. The restrictions force program specifications and verification conditions to lie within a fragment of first-order logic with transitive closure that is reducible to effectively propositional logic, and hence facilitate sound, complete and efficient verification. We implemented a tool atop Z3 and report on preliminary experiments that establish the correctness of several programs that manipulate linked data structures.

Lecture Notes in Computer Science, 2013
This paper proposes a novel method of harnessing existing SAT solvers to verify reachability prop... more This paper proposes a novel method of harnessing existing SAT solvers to verify reachability properties of programs that manipulate linked-list data structures. Such properties are essential for proving program termination, correctness of data structure invariants, and other safety properties. Our solution is complete, i.e., a SAT solver produces a counterexample whenever a program does not satisfy its specification. This result is surprising since even first-order theorem provers usually cannot deal with reachability in a complete way, because doing so requires reasoning about transitive closure. Our result is based on the following ideas: (1) Programmers must write assertions in a restricted logic without quantifier alternation or function symbols. (2) The correctness of many programs can be expressed in such restricted logics, although we explain the tradeoffs. (3) Recent results in descriptive complexity can be utilized to show that every program that manipulates potentially cyclic, singly-and doubly-linked lists and that is annotated with assertions written in this restricted logic, can be verified with a SAT solver. We implemented a tool atop Z3 and used it to show the correctness of several linked list programs.

The monadic formulation of exceptions forces a programming style in which the program itself must... more The monadic formulation of exceptions forces a programming style in which the program itself must specify a total ordering on the evaluation of exceptional computations. Moreover, unless a callby-name strategy is used, values of monadic types must be tested before they are used, in order to determine whether they correspond to a raised exception or not. In this paper we propose a type system that internalizes the notion of exceptional computations, but avoids the above two properties. In our calculus, exceptional computations need not be ordered explicitly by the program, unless one of them actually depends on the other. Furthermore, the type system ensures that run-time tests are not needed to determine if an exceptional computation evaluates to a value or a raised exception. To this end, we use the necessitation operator £ from a version of constructive modal logic. The idea is applicable to other control effects as well, and we use it to develop novel calculi for catch-andthrow and composable continuations.

In this paper we propose a typed, purely functional calculus for state (with second-class locatio... more In this paper we propose a typed, purely functional calculus for state (with second-class locations) in which types reflect the dichotomy between reading from and writing into the global store. This is in contrast to the usual formulation of state via monads, where the primitives for reading and writing introduce the same monadic type constructor. We hope to argue that making this distinction is useful, simple, and has strong logical foundations. Our type system is based on the proof-term calculus for constructive modal logic S4, which has two modal type operators: for necessity and 3 for possibility. We extend this calculus with the notion of names (which stand for locations) and generalize to indexed families of modal operators (indexed by sets of names). Then, the modal type C A classifies computations of type A which read from store locations listed in the set C. The dual type 3 C A classifies computations which first write into the locations from C and than use the changed store to obtain a value of type A. There are several benefits to this development. First, the necessitation fragment of the language is interesting in its own: it formulates a calculus of dynamic binding. Second, the possibility operator 3 is a monad, thus forcing the single-threading of memory writes, but not of memory reads (as these are associated with). Finally, the different status of reads and writes gives rise to a natural way of expressing the allocation of uninitialized memory while also providing guarantees that only initialized locations are dereferenced.
We present a dependent Hoare Type Theory (HTT) which provides support for reasoning about program... more We present a dependent Hoare Type Theory (HTT) which provides support for reasoning about programs with higherorder functions and effects, including non-termination, state with aliasing and pointer arithmetic. The type structure encapsulates effectful commands using a monad indexed by pre-and post-conditions in the style of Hoare logic. The theory carefully distinguishes between an appropriate notion of definitional equality and propositional equality, in order to maintain the relative decidability of type-checking.
Uploads
Papers by Aleksandar Nanevski