Results 1 - 10
of
11
Static Contract Checking for Haskell
- In Proceedings of the 36 th Annual ACM Symposium on the Principles of Programming Languages
, 2009
"... Program errors are hard to detect and are costly both to programmers who spend significant efforts in debugging, and for systems that are guarded by runtime checks. Static verification techniques have been applied to imperative and object-oriented languages, like Java and C#, but few have been appli ..."
Abstract
-
Cited by 12 (1 self)
- Add to MetaCart
Program errors are hard to detect and are costly both to programmers who spend significant efforts in debugging, and for systems that are guarded by runtime checks. Static verification techniques have been applied to imperative and object-oriented languages, like Java and C#, but few have been applied to a higher-order lazy functional language, like Haskell. In this paper, we describe a sound and automatic static verification framework for Haskell, that is based on contracts and symbolic execution. Our approach is modular and gives precise blame assignments at compile-time in the presence of higher-order functions and laziness. D.3 [Software]: Program-
A Definitional Two-Level Approach to Reasoning with Higher-Order Abstract Syntax
- Journal of Automated Reasoning
, 2010
"... Abstract. Combining higher-order abstract syntax and (co)-induction in a logical framework is well known to be problematic. Previous work [ACM02] described the implementation of a tool called Hybrid, within Isabelle HOL, syntax, and reasoned about using tactical theorem proving and principles of (co ..."
Abstract
-
Cited by 11 (2 self)
- Add to MetaCart
Abstract. Combining higher-order abstract syntax and (co)-induction in a logical framework is well known to be problematic. Previous work [ACM02] described the implementation of a tool called Hybrid, within Isabelle HOL, syntax, and reasoned about using tactical theorem proving and principles of (co)induction. Moreover, it is definitional, which guarantees consistency within a classical type theory. The idea is to have a de Bruijn representation of syntax, while offering tools for reasoning about them at the higher level. In this paper we describe how to use it in a multi-level reasoning fashion, similar in spirit to other meta-logics such as Linc and Twelf. By explicitly referencing provability in a middle layer called a specification logic, we solve the problem of reasoning by (co)induction in the presence of non-stratifiable hypothetical judgments, which allow very elegant and succinct specifications of object logic inference rules. We first demonstrate the method on a simple example, formally proving type soundness (subject reduction) for a fragment of a pure functional language, using a minimal intuitionistic logic as the specification logic. We then prove an analogous result for a continuation-machine presentation of the operational semantics of the same language, encoded this time in an ordered linear logic that serves as the specification layer. This example demonstrates the ease with which we can incorporate new specification logics, and also illustrates a significantly
Type-based data structure verification
- In PLDI
, 2009
"... We present a refinement type-based approach for the static verification of complex data structure invariants. Our approach is based on the observation that complex data structures are typically fashioned from two elements: recursion (e.g., lists and trees), and maps (e.g., arrays and hash tables). W ..."
Abstract
-
Cited by 6 (2 self)
- Add to MetaCart
We present a refinement type-based approach for the static verification of complex data structure invariants. Our approach is based on the observation that complex data structures are typically fashioned from two elements: recursion (e.g., lists and trees), and maps (e.g., arrays and hash tables). We introduce two novel type-based mechanisms targeted towards these elements: recursive refinements and polymorphic refinements. These mechanisms automate the challenging work of generalizing and instantiating rich universal invariants by piggybacking simple refinement predicates on top of types, and carefully dividing the labor of analysis between the type system and an SMT solver [6]. Further, the mechanisms permit the use of the abstract interpretation framework of liquid type inference [22] to automatically synthesize complex invariants from simple logical qualifiers, thereby almost completely automating the verification. We have implemented our approach in DSOLVE, which uses liquid types to verify OCAML programs. We present experiments that show that our type-based approach reduces the manual annotation required to verify complex properties like sortedness, balancedness, binary-search-ordering, and acyclicity by more than an order of magnitude.
A Dependently Typed Programming Language, with applications to Foundational Certified Code Systems
, 2009
"... Certified code systems enable trust to be generated in untrusted pieces of code. This is done by requiring that a machine–verifiable certificate be packaged with code, which can then be proved safe independently. Safety is defined with respect to a defined safety policy. Recent work has focused on “ ..."
Abstract
-
Cited by 2 (0 self)
- Add to MetaCart
Certified code systems enable trust to be generated in untrusted pieces of code. This is done by requiring that a machine–verifiable certificate be packaged with code, which can then be proved safe independently. Safety is defined with respect to a defined safety policy. Recent work has focused on “foundational certified code systems”, which define the safety policy as execution on a concrete machine architecture. This makes the safety guarantees of the system more concrete relative to previous systems. There are two advantages. One, we gain in flexibility since the proof producers can use different assumptions and techniques. Two, the parts of the system that must be trusted become substantially simpler. This work describes our design of a practical foundational certified code system. Foundational systems have new proof obligations, for which we need different proof techniques and verification environments. In common with other such systems, we use an intermediate formal system such as a type system to isolate a group of programs. There are then two proof obligations. A program– specific proof verifies that the program belongs to the group so defined. This is the type checking problem. A generic safety proof says that all programs belonging to the group is safe to execute on the concrete machine. For a type system this is the type safety property.
ΠΣ: Dependent Types without the Sugar
"... Abstract. The recent success of languages like Agda and Coq demonstrates the potential of using dependent types for programming. These systems rely on many high-level features like datatype definitions, pattern matching and implicit arguments to facilitate the use of the languages. However, these fe ..."
Abstract
-
Cited by 2 (0 self)
- Add to MetaCart
Abstract. The recent success of languages like Agda and Coq demonstrates the potential of using dependent types for programming. These systems rely on many high-level features like datatype definitions, pattern matching and implicit arguments to facilitate the use of the languages. However, these features complicate the metatheoretical study and are a potential source of bugs. To address these issues we introduce ΠΣ, a dependently typed core language. It is small enough for metatheoretical study and the type checker is small enough to be formally verified. In this language there is only one mechanism for recursion—used for types, functions and infinite objects— and an explicit mechanism to control unfolding, based on lifted types. Furthermore structural equality is used consistently for values and types; this is achieved by a new notion of α-equality for recursive definitions. We show, by translating several high-level constructions, that ΠΣ is suitable as a core language for dependently typed programming. 1
Supporting Dependently Typed Functional Programming with Testing and User-Assisted Proof Automation
"... Abstract. Developing dependently typed functional programs can be difficult because the user may be required to write proofs and program errors are often hard to identify and fix. We describe a framework, implemented in Coq, that combines testing with user-assisted proof automation to make developme ..."
Abstract
-
Cited by 1 (1 self)
- Add to MetaCart
Abstract. Developing dependently typed functional programs can be difficult because the user may be required to write proofs and program errors are often hard to identify and fix. We describe a framework, implemented in Coq, that combines testing with user-assisted proof automation to make development easier. Testing occurs within Coq and is used to give user feedback to program errors and faulty conjectures, as well as guiding automated proof search. Dependently typed functional programming languages, such as Epigram [1] and ATS [2], offer an approach for developing verified software. These languages use dependent types to assign more accurate typing to terms, compared to simple typing, thereby enabling program properties to be verified at compile-time. However, programming with dependent types can be difficult. The user can be expected to write proofs for the proof obligations that arise and program errors can be hard to identify and fix. In this paper, we describe techniques that use a combination of testing and user-assisted proof automation for making dependently typed functional programming easier. These techniques are generic enough to support user-defined types and functions. We have implemented our ideas in the Coq theorem prover [3]. Coq can be used as a dependently typed programming language. The contributions of this paper are: – A description of how to provide useful counterexample-based program error feedback (see Section 2). – A description of the important role of testing in our user-assisted proof automation (see Section 3). – A small-scale usability study examining the utility of our counterexamplebased program error feedback (see Section 4). 1
Dsolve: Safety Verification via Liquid Types ⋆
"... Abstract. We present Dsolve, a verification tool for OCaml. Dsolve automates verification by inferring “Liquid ” refinement types that are expressive enough to verify a variety of complex safety properties. 1 Overview Refinement types are a means of expressing rich program invariants by combining cl ..."
Abstract
-
Cited by 1 (0 self)
- Add to MetaCart
Abstract. We present Dsolve, a verification tool for OCaml. Dsolve automates verification by inferring “Liquid ” refinement types that are expressive enough to verify a variety of complex safety properties. 1 Overview Refinement types are a means of expressing rich program invariants by combining classical types with logical predicates. For example, using refinement types, one can express the fact that x is an array of positive integers by stating that x has the type {ν: int | 0 < ν} array. While refinement types have been shown to be a powerful technique for verifying higher-order functional programs [1–4], refinement type systems have previously been difficult to use because of a high programmer annotation burden. We present Dsolve, a tool that automates the verification of safety properties of OCaml programs by inferring refinement types. Using Dsolve, we were able to verify properties of real-world OCaml programs as diverse as array bounds safety and correctness of sorting and tree-balancing algorithms while incurring a modest overhead in terms of the annotations and hints required for verification. Further, we were able to use the refinement types inferred by Dsolve on buggy programs to diagnose and correct the problems, demonstrating its value as a tool for program understanding. Dsolve works by inferring Liquid Types, which are refinement types whose refinements are conjunctions of predicates taken from a user-provided finite set of logical qualifiers. Each logical qualifier is a predicate over the program variables and the special value variable ν, which is used to refer to values of the refined type. The Liquid Type restriction makes inference tractable while still retaining enough expressiveness to verify safety properties of real-world OCaml programs.
IOS Press Automation for Dependently Typed Functional Programming
"... Abstract. Writing dependently typed functional programs that capture non-trivial program properties, such as those involving membership, ordering and non-linear arithmetic, is difficult in current system due to lack of proof automation. We identify and discuss proof patterns that occur when programm ..."
Abstract
- Add to MetaCart
Abstract. Writing dependently typed functional programs that capture non-trivial program properties, such as those involving membership, ordering and non-linear arithmetic, is difficult in current system due to lack of proof automation. We identify and discuss proof patterns that occur when programming with dependent types and detail how the automation of such patterns allow us to work more comfortably with types, particularly subset types, that capture such program properties. We describe the application of rippling, both for inductive and non-inductive proofs, and generalisation in discharging proof obligations that arise when programming with dependent types. We then discuss an implementation of our ideas in Coq with examples of practical programs that capture useful properties. We demonstrate that our proof automation is generic in that it can provide support for working with theorems involving user-defined inductive data types and functions. Keywords:
Compositional and Decidable Checking for Dependent Contract Types
, 2008
"... Simple type systems perform compositional reasoning in that the type of a term depends only on the types of its subterms, and not on their semantics. Contracts offer more expressive abstractions, but static contract checking systems typically violate those abstractions and base their reasoning direc ..."
Abstract
- Add to MetaCart
Simple type systems perform compositional reasoning in that the type of a term depends only on the types of its subterms, and not on their semantics. Contracts offer more expressive abstractions, but static contract checking systems typically violate those abstractions and base their reasoning directly upon the semantics of terms. Pragmatically, this noncompositionality makes the decidability of static checking unpredictable. We first show how compositional reasoning may be restored using standard type-theoretic techniques, namely existential types and subtyping. Despite its compositional nature, our type system is exact, in that the type of a term can completely capture its semantics, hence demonstrating that precision and compositionality are compatible. We then address predictability of static checking for contract types by giving a type-checking algorithm for an important
Type-Based Data Structure Verification
"... Author information hidden for double-blind review We present a refinement type-based approach for the static verification of complex data structure invariants. Our approach is based on the observation that complex data structures are often fashioned from two elements: recursion (e.g., lists and tree ..."
Abstract
- Add to MetaCart
Author information hidden for double-blind review We present a refinement type-based approach for the static verification of complex data structure invariants. Our approach is based on the observation that complex data structures are often fashioned from two elements: recursion (e.g., lists and trees), and maps (e.g., arrays and hash tables). We introduce two novel type-based mechanisms targeted towards these elements: recursive refinements and polymorphic refinements. These mechanisms automate the challenging work of generalizing and instantiating rich universal invariants by piggybacking simple refinement predicates on top of types, and carefully dividing the labor of analysis between the type system and an SMT solver [6]. Further, the mechanisms permit the use of the abstract interpretation framework of liquid type inference [18] to automatically synthesize complex invariants from simple logical qualifiers, thereby almost completely automating the verification. We have implemented our approach in DSOLVE, which uses liquid types to verify OCAML programs. We present experiments that show that our type-based approach reduces the manual annotations required to verify complex properties like sortedness, balancedness, binary-search-ordering, and acyclicity by more than an order of magnitude. 1.

