This page lists inactive projects; current projects are on the front page.

Verdi

Verify implementations of distributed systems.

Bagpipe

Verify BGP router configurations.

Optimal Synthesis

Automatically optimize solutions to synthesis problems.

Disel

A program logic for verified distributed components.

Neutrons

Verifying radiotherapy control software.

Œuf

Verfied Gallina to machine code compilation.

Verification Games

Transform program verification into a game.

Lean

Extraction, debugging, and tactics for the Lean theorem prover.

Fast Tree Layout

Synthesize parallel and incremental layout engines from attribute grammars.

STNG

Optimizing stencil codes using verified lifting.

Distributed Components

Making verified distributed systems modular.

Syncro

Synthesis of incremental update rules.

TPS

Temporal protein signaling pathway synthesis.

Floem

Programming NIC-accelerated network applications.

Synthesis for FRP

Automatically generating reactive programs.

Dux

Automatic dependency management.

Wallingford

A constraint reactive programming language.

Tellina

Translating text to bash with deep learning.

Ringer

Programming by demonstration in the browser.

Legato

Statically analyze software configuration update code.

defects4j

Testing the tests that test your tests with real bugs from OSS.

Herbgrind

Detect and extract floating point inaccuraties from binaries.

Rewire

User interface vectorizations from screenshots.

SPARTA

A toolset to verify the security of mobile phone applications.

Ferrite

Specifying and checking crash behavior for file systems.

Staccato

Dynamic configuration update analysis.

SafeMerge

Verifying program diffs and merges.

Peek

Peephole optimizations for CompCert.

PolyPEG

Toward multi-platform query optimization.

AUDACIOUS

Android user-driver access control in only user space.

Probabilistic Debugger

Heling programmers write correct probabilistic programs.

HintsDB

Synthesized hints for programming assignments.

UpGuard

Verifying rolling updates to distributed systems.

TrigGen

Automatic trigger generation for end-user written automation rules.

Disconsistency

Safe inconsistency in distributed datastores with IPA types.

RoboFlow

A flow-based visual programming language for programming robot manipulation tasks.

Staccato

Dynamic bug finder for software configuration update code.

Timelapse

The first user interface for capturing and replaying web application executions directly from the browser's developer tools.

Retroactive Debugging

Capture how a program executes, then go back in time with the debugger to see what happened.

Crust

Verify memory invariants for Rust unsafe blocks.

Program Synthesis

We are collaborating with colleagues at Microsoft Research on automatically synthesizing small programs in key domains. Our approaches are general while remaining domain-specific by providing the synthesizer with a small language in terms of an API in which to synthesizing programs. In recent work, we aim to synthesize programs given only a sequence of program tests. We avoid overfitting to the test sequence by having the synthesizer minimize its use of conditional branches.

Semantics for the Rust Language

We are collaborating with colleagues at Mozilla to investigate and help guide the design of the Rust language by reasoning about the soundness of its type system. By creating formal models of key features, we can identify challenging test cases to type-check as well as (hopefully) prove type soundness. We are particularly interested in modeling Rust's novel support for statically checked manual memory management.

Interference-Free Regions

We, in collaboration with researchers at HP Labs, have developed the notion of interference-free regions for soundly reasoning about programs under memory-consistency models for which data races have undefined behavior (e.g., in C++). We have shown that if another thread has a conflicting memory access that is unsynchronized with respect to an interference-free region, then the accesses must form a data race. We have applied this idea to (1) compiler optimizations, such as redundant-read elimination (even across some synchronization operations), and (2) a dynamic data-race detection tool.

Energy-Aware Programming Models and Architectures

Energy is increasingly a first-order concern in computer systems design. Battery life is a big constraint in mobile systems, and power/cooling costs largely dominate the cost of equipment in data centers. More fundamentally, current trends point toward a "utilization wall," in which the amount of active die area is limited by how much power can be fed to a chip.

Support for Explicit Runtime Concurrency Errors

This project posits that shared-memory multithreaded concurrency errors should be precisely detected and fail-stop at runtime in the way that segmentation faults or division-by-zero errors are today. We aim to generalize some support for concurrency exceptions throughout the system stack. Specifically, we are investigating the semantics and specification of concurrency exceptions at the language level, their implications in the compiler and runtime systems, how they should be delivered, and how they are enabled by efficient architecture support.

API Discovery and Advanced Code Completion

Modern programming languages and programming frameworks include enormous libraries with tens of thousands of API entry points, reducing large portions of application development to searching for and composing already written functionality. We aim to integrate advanced search and code-completion functionality, specialized to this task, into development environments. We leverage the rich type structure of modern statically typed languages to index libraries and define queries in terms of "partial expressions." Project work is being done in collaboration with Sumit Gulwani and Tom Ball at Microsoft Research.

Unit Test Generation for Object-oriented Programs

In an object-oriented program, a unit test often consists of a sequence of method calls that create and mutate objects, then use them as arguments to a method under test. It is challenging to automatically generate sequences that are legal and behaviorally diverse, that is, reaching as many different program states as possible.

Automated Techniques for Explaining Failed Tests

A Failed tests reveals a potential bug in the tested code. Developers need to understand which parts of the test are relevant to the failure before they start bug-fixing. This project investigates automated techniques to explain why a test fails. As an initial result, we presented a fully automated technique and its tool implementation, called FailureDoc, to infer explanatory documentation. FailureDoc augments the failed test with explanatory documentation in the form of code comments.

Static Deadlock Freedom

Deadlock remains a problem in concurrent programs, and we want to statically verify programs as deadlock-free. While there are effective static approaches for coarse-grained locking, fine-grained locking (e.g., where each node of a data structure is protected by its own lock) remains challenging. We propose lock capabilities as an approach to statically verifying the absence of deadlock in code for fine-grained locking. A lock capability is a static capability that permits the acquisition of a specific set of locks.

Atomic Blocks (Transactional Memory)

We have a long-standing interest in using atomic blocks (e.g., atomic { s }), where s is a statement as a synchronization primitive that is easier-to-use but harder-to-implement than conventional synchronization primitivites, such as mutual-exclusion locks. Atomic blocks are often implemented using transactional memory. Many language design and semantics isssues arise from their interaction with other language features. We have done work on design, theory, and implementation for a variety of languages, including Caml, Java, Haskell, Scheme, and x86 assembly.

Software Reflexion Models

Many software design models evolve over time, becoming increasingly inconsistent with the system's source code. The reflexion model approach helps an engineer use a high-level model of a software system to show where the high-level model agrees with and differs from the source code. Our results (and Gail Murphy's dissertation!) include a use of reflexion models to aid in the understanding and experimental reengineering of the Microsoft Excel spreadsheet product.

Dependent Tests

Almost all results in software testing, and almost all software testing tools, assume that each test in a test suite will produce the same result regardless of the order in which the tests are executed. We have shown that this "test independence" assumption does not hold by identifying test suites in publicly available source where executing the tests in "isolation" (i.e., in a clean virtual machine) produces a different results from executing them one after another.

Finding Errors in Multithreaded GUI Applications

To keep a Graphical User Interface (GUI) responsive and active, a GUI application often has a main UI thread (or event dispatching thread) and spawns separate threads to handle lengthy operations in the background. Many GUI frameworks require all GUI objects to be accessed exclusively by the UI thread. If a GUI object is accessed through a non-UI thread, an invalid thread access error occurs and the whole application may abort.

Collabopt: Profile-guided Optimization for the Web

Recent advances in just-in-time compilation for JavaScript have made it possible to deploy large-scale applications using the HTML 5 platform. Unfortunately, web applications are still orders of magnitude slower than native applications. We propose collaborative optimization as a way to transparently improve performance by harnessing the "collective knowledge" about how individual web applications run.

Detecting Behavioral Anomalies

Developers change a program with an explicit and an implicit intention: to realize a particular objective and to avoid affecting other program properties. Testing and analysis help developers satisfy both intentions, but subtle bugs are still common. We earlier showed how a simple comparison of the static and dynamic call graphs from two related program versions can identify anomalies that detect some of these subtle bugs.

Speculative Analysis

Software developers primarily rely on experience and intuition to make development decisions. We believe that developers can make even better decisions if they are informed of the consequences of their choices. Speculative analysis is a family of techniques that attempt likely developer actions in the background and deliver precise information to the developers about their choices right as they are making the relevant decisions.

Synoptic: Studying Logged Behavior with Inferred Models

Computer systems are often difficult to understand and debug. A common way of gaining insight into a system's behavior is to inspect execution logs. Unfortunately, manual inspection of logs is an arduous process. We have developed a tool called Synoptic that helps developers by inferring a concise and accurate system model, in the form of a finite state machine, from execution logs. Synoptic processes the logs that most systems already produce, and it requires developers only to specify a set of regular expressions for parsing the logs. Synoptic models have been used to find new bugs, increase developer confidence in the correctness of their code, and help developers better understand their programs.

Timelapse: Back-in-time Debugging for the Web

Current web browser debuggers are inadequate for today's complex, event-driven, and nondeterministic web applications. The Timelapse project adapts "back-in-time" debugging techniques to the domain of client-side web programming. Unlike traditional breakpoint debuggers, Timelapse creates an exact recording of a web program's execution. This recording can be then played forward and backward and freely inspected at any time, using existing debugging tools.

VeriWeb: Crowdsourced Verification

VeriWeb is a web-interface for verifying Java programs with ESC/Java2. It introduces several innovative features to lower the skill barrier to formal verification and enable crowdsourced verification.

Iorek

Iorek is a solver-aided language for testing web services.

Domino

Domino is a a high-level language for programmable switches.

Genie

Interactive commands from web pages for input retargeting.

Ouro

Ouro is a self-hosted, verified compiler.